<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>一个故事@MySQL DBA &#187; 图解</title>
	<atom:link href="http://www.orczhou.com/index.php/tag/%e5%9b%be%e8%a7%a3/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.orczhou.com</link>
	<description>一个故事@MySQL DBA</description>
	<lastBuildDate>Tue, 20 Dec 2011 15:51:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>MySQL如何传输二进制日志</title>
		<link>http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/</link>
		<comments>http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/#comments</comments>
		<pubDate>Sun, 20 Nov 2011 15:53:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=3279</guid>
		<description><![CDATA[<p>MySQL Replication可以很方便的用来做应用的读扩展，也可以帮MySQL实现一定程度的HA方案。MySQL通过<a href="http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/">向备库传送二进制日志来实现Replication</a>，本文将通过二进制日志相关源代码的主要接口来解释：“<strong>MySQL如何传输二进制日志，是主库推，还是备库拉？MySQL日志传输的实时性如何？</strong>”。</p>
<p>在MySQL Replication结构中，备库端初次通过<a href="http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html">CHANGE MASTER TO</a>完成Replication配置，再使用start slave命令开始复制。更细致的，备库通过IO Thread向主库发起读取binlog的请求（COM_BINLOG_DUMP命令），主库收到COM_BINLOG_DUMP请求后，使用单独线程（dump thread）不断向备库IO Thread发送Binlog。示意图(<a href="http://farm7.staticflickr.com/6237/6369693149_49d43db964_b.jpg">大图</a>)：<br />
<a href="http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg"><img src="http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg" alt="" title="how_mysql_send_binary_log" width="686" height="369" class="alignleft size-full wp-image-3292" /></a></p>
<p>[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>MySQL Replication可以很方便的用来做应用的读扩展，也可以帮MySQL实现一定程度的HA方案。MySQL通过<a href="http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/">向备库传送二进制日志来实现Replication</a>，本文将通过二进制日志相关源代码的主要接口来解释：“<strong>MySQL如何传输二进制日志，是主库推，还是备库拉？MySQL日志传输的实时性如何？</strong>”。</p>
<p>在MySQL Replication结构中，备库端初次通过<a href="http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html">CHANGE MASTER TO</a>完成Replication配置，再使用start slave命令开始复制。更细致的，备库通过IO Thread向主库发起读取binlog的请求（COM_BINLOG_DUMP命令），主库收到COM_BINLOG_DUMP请求后，使用单独线程（dump thread）不断向备库IO Thread发送Binlog。示意图(<a href="http://farm7.staticflickr.com/6237/6369693149_49d43db964_b.jpg">大图</a>)：<br />
<a href="http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg"><img src="http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg" alt="" title="how_mysql_send_binary_log" width="686" height="369" class="alignleft size-full wp-image-3292" /></a></p>
<p><span id="more-3279"></span></p>
<p>在主库端一旦有新的日志产生后，立刻会发送一次广播，dump线程在收到广播后，则会读取二进制日志并通过网络向备库传输日志，所以这是一个主库向备库不断推送的过程；</p>
<p>新日志在产生后，只需一次广播和网络就会立刻（<1ms）向发送到备库，如果主备之间网络较好的话（例如RTT<1ms），备库端的日志也就小于2ms了。所以，一般的（依赖于RTT），备库的实时性都非常好。</p>
<p>参考：</p>
<p>1. <a href="http://dev.mysql.com/doc/refman/5.1/en/replication.html">MySQL Replication Manual</a></p>
<p>2. <a href="http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/">图解"How MySQL Replication Works" </a></p>
<p>Have fun!</p>
<p><embed src="http://www.xiami.com/widget/0_1025147/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed></p>
<p>广告：<a href="http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/">我们寻找靠谱的人</a> | <a href="http://www.orczhou.com/index.php/wish-list/">感谢作者</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flachcache初探</title>
		<link>http://www.orczhou.com/index.php/2010/09/flachcache-first-view/</link>
		<comments>http://www.orczhou.com/index.php/2010/09/flachcache-first-view/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 03:38:34 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Flashcache]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=2368</guid>
		<description><![CDATA[<p>Flashcache是Facebook技术团队的又一力作，最初是为加速MySQL设计的。Flashcache是在Linux层面的，所以任何受磁盘IO困绕的软件或应用都可以方便的使用之。</p>
<div class="myt1">1. Why Flashcache</div>
<p>随着时间的流逝，网站上的数据一直在不停的积累。如果你经营的只是一个博客的话，这不会是问题，因为10G的空间，大概就够你写一辈子了（如果放在硬盘上，其实一辈子很短）。如果你恰巧在一个快速增长的公司，数据会越来越多，从MB，到GB，再到TB。</p>
<p>如果将这些数据全部放在大容量的SATA、SAS盘上时，会发现性能（响应时间）不够；如果全放在SSD上时，又会发现成本很高。即使公司能够大气到都放到SSD上，你会发现1TB的数据里面可能只有200G是经常被访问的，300G可能偶尔被访问到，最后剩下的500G可能已经成为历史数据了，几乎不被访问到，如果全部都放在SSD上有略有浪费。于是就有了<a href="http://www.facebook.com/note.php?note_id=388112370932">Flashcache</a>。</p>
<p>Flashcache一个非常不错的软件（准确的说是一个<a href="http://tldp.org/LDP/lkmpg/2.6/html/">Linux的模块</a>），可以动态加载。Flashcache通过在文件系统（VFS）和设备驱动之间新增了一次缓存层，来实现对热门的缓存。Flashcache是另一种缓存，一般用SSD作为介质的缓存（一般的缓存用的是内存），通过将传统硬盘上的热门数据缓存到SSD上，然后利用SSD优秀的读性能，来加速系统。这个方法较之内存缓存，没有内存快，但是空间可以比内存大很多。</p>
<p>本文是一个关于Flashcache的初步介绍。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/09/flachcache-first-view/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>Flashcache是Facebook技术团队的又一力作，最初是为加速MySQL设计的。Flashcache是在Linux层面的，所以任何受磁盘IO困绕的软件或应用都可以方便的使用之。</p>
<div class="myt1">1. Why Flashcache</div>
<p>随着时间的流逝，网站上的数据一直在不停的积累。如果你经营的只是一个博客的话，这不会是问题，因为10G的空间，大概就够你写一辈子了（如果放在硬盘上，其实一辈子很短）。如果你恰巧在一个快速增长的公司，数据会越来越多，从MB，到GB，再到TB。</p>
<p>如果将这些数据全部放在大容量的SATA、SAS盘上时，会发现性能（响应时间）不够；如果全放在SSD上时，又会发现成本很高。即使公司能够大气到都放到SSD上，你会发现1TB的数据里面可能只有200G是经常被访问的，300G可能偶尔被访问到，最后剩下的500G可能已经成为历史数据了，几乎不被访问到，如果全部都放在SSD上有略有浪费。于是就有了<a href="http://www.facebook.com/note.php?note_id=388112370932">Flashcache</a>。</p>
<p>Flashcache一个非常不错的软件（准确的说是一个<a href="http://tldp.org/LDP/lkmpg/2.6/html/">Linux的模块</a>），可以动态加载。Flashcache通过在文件系统（VFS）和设备驱动之间新增了一次缓存层，来实现对热门的缓存。Flashcache是另一种缓存，一般用SSD作为介质的缓存（一般的缓存用的是内存），通过将传统硬盘上的热门数据缓存到SSD上，然后利用SSD优秀的读性能，来加速系统。这个方法较之内存缓存，没有内存快，但是空间可以比内存大很多。</p>
<p>本文是一个关于Flashcache的初步介绍。<span id="more-2368"></span></p>
<div class="myt1">2. 谁适合用Flashcache</div>
<p>数据量很大（例如4TB），热门数据也很大（800GB），不必要或者不舍得全部买内存来缓存。</p>
<div class="myt1">3. 谁<strong>不</strong>适合用Flashcache</div>
<p>数据量不大的话，一般Flashcache就没什么用武之地了，内存就可以帮你解决问题了；</p>
<p>不差钱，买内存呗；</p>
<p>另外Flashcache的加入也使得系统的复杂度增加了一层，如果你坚持<a href="http://en.wikipedia.org/wiki/KISS_principle">KISS原则</a>（Keep it simple, Stupid!），也可以弃用之。</p>
<div class="myt1">4. 基本原理图</div>
<p><a href="http://www.flickr.com/photos/26825745@N06/5023251788/" title="Flashcache_orczhou by orczhou, on Flickr"><img src="http://farm5.static.flickr.com/4146/5023251788_f67a46dc7d.jpg" width="500" height="296" alt="Flashcache_orczhou" /></a></p>
<p>上图中，Flashcache将普通的SAS盘（/dev/sda）和一个高速的SSD(/dev/sdb)虚拟成一个带缓存的块设备（/dev/mapper/cachedev）。后续还将会有更多关于Flashcache相关的文章出现，敬请期待。</p>
<div class="myt1">5. Flashcache是否只是一个过渡产品</div>
<p>对于当前，PCI接口的SSD价格还十分昂贵，而随着时间的推移，价格会降；另外，根据<a href="http://zh.wikipedia.org/zh-hk/%E6%91%A9%E5%B0%94%E5%AE%9A%E5%BE%8B">摩尔定律</a>，未来会有更快的设备出现，所以Flashcache是一个“持久的”产品，还只是一个过渡软件，这并不好说。</p>
<p>关注未来新技术的发展吧:)</p>
<p>参考：</p>
<p>1. <a href="http://github.com/facebook/flashcache/">Facebook / Flashcache</a></p>
<p>2. <a href="http://www.facebook.com/note.php?note_id=388112370932">Releasing Flashcache of Facebook</a></p>
<p>3. <a href="http://github.com/facebook/flashcache/blob/master/doc/flashcache-doc.txt">flashcache-doc.txt</a></p>
<p>PS：写完整篇文章，最大的收获是：发现人的一生其实很短、很短，可能连1GB都不到。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/09/flachcache-first-view/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>详解MyISAM Key Cache(前篇)</title>
		<link>http://www.orczhou.com/index.php/2010/01/myisam-key-buffer-1/</link>
		<comments>http://www.orczhou.com/index.php/2010/01/myisam-key-buffer-1/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 02:12:40 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MyISAM]]></category>
		<category><![CDATA[MyISAM Key Buffer]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://www.orczhou.com/?p=1252</guid>
		<description><![CDATA[<p>本文将分为前、中、后三篇，分别介绍MyISAM Key Cache的一般机制、Mid-point strategy、状态、参数和命令。</p>
<p>“Cache为王”，<a href="http://www.orczhou.com/index.php/2009/08/query-cache-1/">无所不在</a>。为了最小化磁盘I/O，MyISAM将最频繁访问的索引块（“index block”）都放在内存中，这样的内存缓冲区我们称之为Key Cache，它的大小可以通过参数key_buffer_size来控制。在MyISAM的索引文件中（MYI），连续的单元（contiguous unit）组成一个Block，Index block的大小等于该BTree索引节点的大小。Key Cache就是以Block为单位的。[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2010/01/myisam-key-buffer-1/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>本文将分为前、中、后三篇，分别介绍MyISAM Key Cache的一般机制、Mid-point strategy、状态、参数和命令。</p>
<p>“Cache为王”，<a href="http://www.orczhou.com/index.php/2009/08/query-cache-1/">无所不在</a>。为了最小化磁盘I/O，MyISAM将最频繁访问的索引块（“index block”）都放在内存中，这样的内存缓冲区我们称之为Key Cache，它的大小可以通过参数key_buffer_size来控制。在MyISAM的索引文件中（MYI），连续的单元（contiguous unit）组成一个Block，Index block的大小等于该BTree索引节点的大小。Key Cache就是以Block为单位的。<span id="more-1252"></span></p>
<p><font color="red">1. MyISAM如何使用Key Cache</font></p>
<p>当MySQL请求(读或写)MyISAM索引文件中某个Index Block时，首先会看Key Cache队列中是否已经缓存了对应block。如果有，就直接在Key Cache队列中进行读写了，不再需要请求磁盘。如果是写请求，那么Key Cache中的对应Block就会被标记为Dirty（和磁盘不一致）。在MyISAM在Key Cache成功请求（读写）某个Block后，会将该Block放到Key Cache队列的头部。</p>
<p>如果Key Cache中没有待请求（读或写）的Block，MyISAM会向磁盘请求对应的Block，并将其放到Key Cache的队列头部。队列如果满了，会将队列尾部的Block删除，该Block如果是Dirty的，会将其Flush到磁盘上。我们看到MyISAM维护了一个LRU（Least Recently Used）的Key Cache队列。队列中的Dirty Block会在Block被踢出队列时Flush到磁盘上。</p>
<p><font color="red">2. 图解</font></p>
<p>下图展示了访问Index Block的过程：（黑色部分为磁盘中的Index文件）</p>
<p><a href="http://www.flickr.com/photos/26825745@N06/4268165359/" title="Key_Cache by orczhou, on Flickr"><img src="http://farm3.static.flickr.com/2776/4268165359_9f4e322c1f_o.png" width="550" height="598" alt="Key_Cache" /></a></p>
<p><font color="red">3. 并发访问</font></p>
<p>Key Cache中的index Block是可以被并发访问的（Shared access ），下面是一些规则：</p>
<ol>
<li>多个没有更新操作的session可以并发同一个block buffer</li>
<li>多个session同时访问某一个block buffer，如果某个session是update操作，则优先访问</li>
<li>多个session如果都需要进行block replacement，是可以并发操作。（从index file中读取block更新到key cache，但是key cache已满，需要删除一些block buffer的操作叫做block replacement）</li>
</ol>
<p>&nbsp;</p>
<p><font color="red">4. 补充说明</font></p>
<p>Key cache中的Block大小可能和索引文件中的Index Block大小不同，可能是大于、小于、等于中的任何一种，但是一般都是成倍数关系的。Key Cache的block大小由参数<a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_key_cache_block_size">Key_cache_block_size</a>控制。</p>
<p>（未完待续）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2010/01/myisam-key-buffer-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Query Cache，看上去很美</title>
		<link>http://www.orczhou.com/index.php/2009/08/query-cache-1/</link>
		<comments>http://www.orczhou.com/index.php/2009/08/query-cache-1/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 10:56:52 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[query cache]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://orczhou.com/?p=669</guid>
		<description><![CDATA[<p>当你的数据库打开了Query Cache（简称QC）功能后，数据库在执行SELECT语句时，会将其结果放到QC中，当下一次处理同样的SELECT请求时，数据库就会从QC取得结果，而不需要去数据表中查询。</p>
<p>[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2009/08/query-cache-1/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>当你的数据库打开了Query Cache（简称QC）功能后，数据库在执行SELECT语句时，会将其结果放到QC中，当下一次处理同样的SELECT请求时，数据库就会从QC取得结果，而不需要去数据表中查询。</p>
<p><span id="more-669"></span></p>
<p><a title="Query-Cache-1 by orczhou, on Flickr" href="http://www.flickr.com/photos/26825745@N06/3854812215/"><img src="http://farm4.static.flickr.com/3498/3854812215_c316040392_o.png" alt="Query-Cache-1" width="505" height="321" /></a></p>
<p>在这个“Cache为王”的时代，我们总是通过不同的方式去缓存我们的结果从而提高响应效率，但一个缓存机制是否有效，效果如何，却是一个需要好好思考的问题。在MySQL中的Query Cache就是一个适用较少情况的缓存机制。在上图中，如果缓存命中率非常高的话，有测试表明在极端情况下可以提高效率238%<sup>[1]</sup>。但实际情况如何？<strong>Query Cache有如下规则，如果数据表被更改，那么和这个数据表相关的全部Cache全部都会无效，并删除之。这里“数据表更改”包括: </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/insert.html"><strong>INSERT</strong></a><strong>, </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/update.html"><strong>UPDATE</strong></a><strong>, </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/delete.html"><strong>DELETE</strong></a><strong>, </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/truncate.html"><strong>TRUNCATE</strong></a><strong>, </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/alter-table.html"><strong>ALTER TABLE</strong></a><strong>, </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/drop-table.html"><strong>DROP TABLE</strong></a><strong>, or </strong><a href="http://dev.mysql.com/doc/refman/5.0/en/drop-database.html"><strong>DROP DATABASE</strong></a><strong>等。</strong>举个例子，如果数据表posts访问频繁，那么意味着它的很多数据会被QC缓存起来，但是每一次posts数据表的更新，无论更新是不是影响到了cache的数据，都会将全部和posts表相关的cache清除。如果你的数据表更新频繁的话，那么Query Cache将会成为系统的负担。有实验表明，糟糕时，QC会降低系统13%<sup>[1]</sup>的处理能力。</p>
<p>如果你的应用对数据库的更新很少，那么QC将会作用显著。比较典型的如博客系统，一般博客更新相对较慢，数据表相对稳定不变，这时候QC的作用会比较明显。</p>
<p>再如，一个更新频繁的BBS系统。下面是一个实际运行的论坛数据库的状态参数：</p>
<table border="0" cellspacing="0" cellpadding="2" width="300">
<tbody>
<tr>
<td width="150" valign="top">QCache_hit</td>
<td width="150" valign="top">5280438</td>
</tr>
<tr>
<td width="150" valign="top">QCache_insert</td>
<td width="150" valign="top">8008948</td>
</tr>
<tr>
<td width="150" valign="top">Qcache_not_cache</td>
<td width="150" valign="top">95372</td>
</tr>
<tr>
<td width="150" valign="top">Com select</td>
<td width="150" valign="top">8104159</td>
</tr>
</tbody>
</table>
<p>可以看到，数据库一共往QC中写入了约800W次缓存，但是实际命中的只有约500W次。也就是说，每一个缓存的使用率约为0.66次。很难说，该缓存的作用是否大于QC系统所带来的开销。但是有一点是很肯定的，QC缓存的作用是很微小的，如果应用层能够实现缓存，将可以忽略QC的效果。</p>
<p style="text-align: left;">-------------下面是关于QC的一些其他细节-----------------</p>
<p style="text-align: left;">一、Query Cache相关参数：</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_query_cache_size">query_cache_size</a> QC占用空间大小，通过将其设置为0关闭QC功能</li>
<li>query_cache_type 0表示关闭QC；1表示正常缓存；2表示SQL_CACHE才缓存</li>
<li>query_cache_limit 最大缓存结果集</li>
<li>query_cache_min_res_unit 手册上说，QC会按照这个值分配缓存block的大小。</li>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html#statvar_Qcache_lowmem_prunes">Qcache_lowmem_prunes</a> 这是一个状态变量(show status)，当缓存空间不够需要释放旧的缓存时，该值会自增。</li>
</ul>
<p style="text-align: left;">二、Query Cache观察：</p>
<pre class="brush:sql">CREATE TABLE t1(id INT,var1 varchar(10));
	//Com_select:8	Qcache_hits:1
INSERT INTO t1 VALUES(1,’WWW’);
	//Com_select:8	Qcache_hits:1
SELECT * FROM t1 WHERE id=1;
	//Com_select:9	Qcache_hits:1
SELECT * FROM t1 WHERE id=1;
	//Com_select:9	Qcache_hits:2 Qcache_queries_in_cache:1
INSERT INTO t1 VALUES(2,’RRRR’);
	//Com_select:9	Qcache_hits:2 Qcache_queries_in_cache:0
SELECT * FROM t1 WHERE id=1; //INSERT后Cache失效
	//Com_select:10  Qcache_hits:2 Qcache_queries_in_cache:1</pre>
<p>参考：</p>
<ol>
<li><a title="http://dev.mysql.com/doc/refman/5.0/en/query-cache.html" href="http://dev.mysql.com/doc/refman/5.0/en/query-cache.html">http://dev.mysql.com/doc/refman/5.0/en/query-cache.html</a></li>
<li><a title="http://dev.mysql.com/doc/refman/5.0/en/query-cache.html" href="http://dev.mysql.com/doc/refman/5.0/en/query-cache.html"></a><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_query_cache_min_res_unit">http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_query_cache_min_res_unit"></a><a href="http://www.mysqlperformanceblog.com/2006/07/27/mysql-query-cache/">http://www.mysqlperformanceblog.com/2006/07/27/mysql-query-cache/</a></li>
</ol>
<p>(全文完)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2009/08/query-cache-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>InnoDB之Dirty page、Redo log</title>
		<link>http://www.orczhou.com/index.php/2009/08/innodb-dirty-page-redo-log-2/</link>
		<comments>http://www.orczhou.com/index.php/2009/08/innodb-dirty-page-redo-log-2/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 01:55:51 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[技术细节]]></category>
		<category><![CDATA[dirty page]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[redo log]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://orczhou.com/?p=624</guid>
		<description><![CDATA[<p>在InnoDB中，buffer pool里面的dirty page一方面可以加快数据处理速度，同时也会造成数据的不一致(RAM vs DISK)。本文介绍了dirty page是如何产生，以及InnoDB如何利用redo log如何消除dirty page产生的数据不一致。</p>
<ol>
<li>当事务(Transaction)需要修改某条记录（row）时，InnoDB需要将该数据所在的page从disk读到buffer pool中，事务提交后，InnoDB修改page中的记录(row)。这时buffer pool中的page就已经和disk中的不一样了，我们称buffer pool中的page为dirty page。Dirty page等待flush到disk上。<br />
<a title="dirty_pages by orczhou, on Flickr" href="http://www.flickr.com/photos/26825745@N06/3813766302/"><img src="http://farm3.static.flickr.com/2502/3813766302_ba5659f61d_o.png" alt="dirty_pages" width="508" height="387" /></a><br />
[......]</li></ol><p class='read-more'><a href='http://www.orczhou.com/index.php/2009/08/innodb-dirty-page-redo-log-2/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>在InnoDB中，buffer pool里面的dirty page一方面可以加快数据处理速度，同时也会造成数据的不一致(RAM vs DISK)。本文介绍了dirty page是如何产生，以及InnoDB如何利用redo log如何消除dirty page产生的数据不一致。</p>
<ol>
<li>当事务(Transaction)需要修改某条记录（row）时，InnoDB需要将该数据所在的page从disk读到buffer pool中，事务提交后，InnoDB修改page中的记录(row)。这时buffer pool中的page就已经和disk中的不一样了，我们称buffer pool中的page为dirty page。Dirty page等待flush到disk上。<br />
<a title="dirty_pages by orczhou, on Flickr" href="http://www.flickr.com/photos/26825745@N06/3813766302/"><img src="http://farm3.static.flickr.com/2502/3813766302_ba5659f61d_o.png" alt="dirty_pages" width="508" height="387" /></a><br />
<span id="more-624"></span></li>
<li>dirty page既然是在Buffer pool中，那么如果系统突然断电Dirty page中的数据修改是否会丢失？这个担心是很有必要的，例如如果一个用户完成一个操作（数据库完成了一个事务，page已经在buffer pool中修改，但dirty page尚未flush），这时系统断电，buffer pool数据全部消失。那么，这个用户完成的操作（导致的数据库修改）是否会丢失呢？答案是不会(innodb_flush_log_at_trx_commit=1)。这就是redo log要做的事情，在disk上记录更新。</li>
<li>redo log在每次事务commit的时候，就立刻将事务更改操作记录到redo log。所以即使buffer pool中的dirty page在断电时丢失，InnoDB在启动时，仍然会根据redo log中的记录完成数据恢复。</li>
<li>redo log的另一个作用是，通过延迟dirty page的flush最小化磁盘的random writes。（redo log会合并一段时间内TRX对某个page的修改）<br />
<a title="dirty_pages AND redo_log by orczhou, on Flickr" href="http://www.flickr.com/photos/26825745@N06/3813218413/"><img src="http://farm3.static.flickr.com/2462/3813218413_b21477573e_o.png" alt="dirty_pages AND redo_log" width="591" height="452" /></a></li>
<li><a title="dirty_pages_redo_log by orczhou, on Flickr" href="http://www.flickr.com/photos/26825745@N06/3813891252/"></a>正常情况下，dirty page什么时候flush到disk上？<br />
<span lang="EN-US">1).</span>redo log是一个环(ring)结构，当redo空间占满时，将会将部分dirty page flush到disk上，然后释放部分redo log。这种情况可以通过Innodb_log_wait(SHOW GLOBAL STATUS)观察，情况发生该计数器会自增一次。<br />
2).当需要在Buffer pool分配一个page，但是已经满了，并且所有的page都是dirty的（否则可以释放不dirty的page），通常是不会发生的。这时候必须flush dirty pages to disk。这种情况将会记录到Innodb_buffer_pool_wait_free中。一般地，可以可以通过启动参数innodb_max_dirty_pages_pct控制这种情况，当buffer pool中的dirty page到达这个比例的时候，将会强制设定一个checkpoint，并把dirty page flush到disk中。<br />
3).检测到系统空闲的时候，会flush，每次64 pages。</li>
<li>涉及的InnoDB配置参数：innodb_flush_log_at_trx_commit、innodb_max_dirty_pages_pct；状态参数：Innodb_log_wait、Innodb_buffer_pool_wait_free。</li>
</ol>
<p>参考文献</p>
<ol>
<li><a href="http://mysqldump.azundris.com/archives/78-Configuring-InnoDB-An-InnoDB-tutorial.html">http://mysqldump.azundris.com/archives/78-Configuring-InnoDB-An-InnoDB-tutorial.html</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/innodb.html">http://dev.mysql.com/doc/refman/5.0/en/innodb.html</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2009/08/innodb-dirty-page-redo-log-2/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>图说：InnoDB之表空间</title>
		<link>http://www.orczhou.com/index.php/2009/08/image-innodb-tablespace/</link>
		<comments>http://www.orczhou.com/index.php/2009/08/image-innodb-tablespace/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 02:29:13 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL InnoDB Tablespace]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://orczhou.com/?p=575</guid>
		<description><![CDATA[<p>InnoDB是MySQL的重要存储引擎，为数据提供了很好的稳定性。一方面，它借鉴了很多ORACLE特性，另一方面InnoDB也有很多自己的特点诸如Insert buffering、Double write等<sup>[2]</sup>。了解InnoDB的内部机制，可以帮助我们更好的配置和优化它。本文概述了InnoDB的表空间的结构，算是深入了解的第一步。上图先：[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2009/08/image-innodb-tablespace/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>InnoDB是MySQL的重要存储引擎，为数据提供了很好的稳定性。一方面，它借鉴了很多ORACLE特性，另一方面InnoDB也有很多自己的特点诸如Insert buffering、Double write等<sup>[2]</sup>。了解InnoDB的内部机制，可以帮助我们更好的配置和优化它。本文概述了InnoDB的表空间的结构，算是深入了解的第一步。上图先：<span id="more-575"></span></p>
<p><a href="http://www.flickr.com/photos/26825745@N06/3816552607/" title="TableSpaceInnoDB by orczhou, on Flickr"><img src="http://farm3.static.flickr.com/2487/3816552607_77f7a25122.jpg" width="500" height="500" alt="TableSpaceInnoDB" /></a></p>
<ol>
<li>在配置文件中可以配置InnoDB的表空间<sup>[1]</sup>，一般格式如下(共享表空间)：<br />
datadir = /opt/mysql/data<br />
innodb_data_file_path=ibdata1:1G;ibdata2:1G;ibdata3:1G;ibdata4:1G;ibdata5:1G</li>
<li>完整的表空间，会被分成如下结构供给InnoDB使用。最小单位是page，每个page为16K；64个连续的page组成一个extent；多个extent和page构成一个segment。Segment初始时InnoDB会为它分配32个pages，之后根据需要会将extent分配给segment，单次最多会分配4个extends给segment。<sup>[1]</sup></li>
<li>具体的，InnoDB中一个索引（B-tree）由两个segment组成。其中，所有的叶子节点（leaf nodes）存放在一个segment中，所有的非叶子节点（nonleaf nodes）存放在一个segment中。<sup>[1]</sup></li>
<li>一个存放记录(row)的page，由page header、page trailer、page body组成。如下图:<sup>[2]</sup><br />
<a title="page_with_rows by orczhou, on Flickr" href="http://www.flickr.com/photos/26825745@N06/3813634200/"><img src="http://farm4.static.flickr.com/3427/3813634200_50f97d8fa2_o.png" alt="page_with_rows" width="581" height="395" /></a></li>
<li>相关的InnoDB的参数:innodb_data_file_path。</li>
</ol>
<p>参考文献:</p>
<ol>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-file-space.html">http://dev.mysql.com/doc/refman/5.0/en/innodb-file-space.html</a></li>
<li>InnoDB Internals: InnoDB File Formats and Source Code Structure,MySQL Conference, April 2009, Heikki Tuuri CEO Innobase, Calvin Sun Principal Engineer, Oracle Corporation</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2009/08/image-innodb-tablespace/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>图解&quot;How MySQL Replication Works&quot;</title>
		<link>http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/</link>
		<comments>http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 10:10:13 +0000</pubDate>
		<dc:creator>orczhou</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[图解]]></category>

		<guid isPermaLink="false">http://orczhou.com/?p=192</guid>
		<description><![CDATA[<p>上图先：<br />
<a href="http://www.flickr.com/photos/26825745@N06/3455232156/" title="replication by orczhou, on Flickr"><img src="http://farm4.static.flickr.com/3660/3455232156_dc09e11b22_o.jpg" width="616" height="610" alt="replication" /></a>[......]</p><p class='read-more'><a href='http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/'>继续阅读</a></p>]]></description>
			<content:encoded><![CDATA[<p>上图先：<br />
<a href="http://www.flickr.com/photos/26825745@N06/3455232156/" title="replication by orczhou, on Flickr"><img src="http://farm4.static.flickr.com/3660/3455232156_dc09e11b22_o.jpg" width="616" height="610" alt="replication" /></a><span id="more-192"></span></p>
<p><a href="http://farm4.static.flickr.com/3660/3455232156_c16f2f1d66.jpg?v=0" target="_blank"></a>在使用MySQL的应用中，如果你的MySQL Server压力逐渐增大，在应用层优化已经到了一定瓶颈时，那么你应该首先考虑<a href="http://dev.mysql.com/doc/refman/5.0/en/replication.html" target="_blank">MySQL_Replication</a>。本文将利用图示的方式简单的描述出MySQL Replication是如何工作的。</p>
<p><span style="color: #0000ff;"><strong>如何同步</strong></span></p>
<ol>
<li>主库将所有的更新操作，写入二进制日志。</li>
<li>从库运行"IO线程"（Slave IO Thread）读取主库的二进制日志。</li>
<li>从库运行"SQL线程"（Slave SQL Thread）执行IO线程（Slave IO Thread）读取的日志中的SQL,从而保持和主库的一致。</li>
</ol>
<p><strong><span style="color: #0000ff;">如何分配请求</span></strong></p>
<ol>
<li>目前，这部分需要在应用层实现。</li>
<li>执行更新SQL(UPDATE，INSERT，DELETE)时，请求主库。</li>
<li>执行查询SQL(SELECT)时，请求从库。</li>
</ol>
<p>所以，当你的应用(Application)SELECT请求所占的比率越大，那么Relication就会越有效。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

