<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/orczhou" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/orczhou" type="application/rss+xml"></fs:self_link><lastBuildDate>Tue, 20 Dec 2011 15:51:20 GMT</lastBuildDate><title>Orczhou</title><description>一个故事 一个心情</description><image><url>http://www.feedsky.com/feed/orczhou/sc/gif</url><title>Orczhou</title><link>http://www.orczhou.com</link></image><link>http://www.orczhou.com</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><language>en</language><pubDate>Tue, 20 Dec 2011 15:51:20 GMT</pubDate><item><title>MySQL/InnoDB和Group Commit(2)</title><link>http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/</link><content:encoded>&lt;p&gt;今天发现Percona Release的&lt;a href=&quot;http://www.mysqlperformanceblog.com/2011/12/19/percona-server-5-5-18-23-0-now-with-group-commit/&quot;&gt;Percona-Server-5-5-18-23-0&lt;/a&gt;已经完成了Group Commit工作，而且是用最优雅的方式（移植了MariaDB的实现，而不是workaround），心里难掩激动。&lt;/p&gt;
&lt;p&gt;这篇文章接&lt;a href=&quot;http://www.orczhou.com/index.php/2010/08/time-to-group-commit-1/&quot;&gt;前篇&lt;/a&gt;继续介绍一下问题的背景：什么是Group Commit，现在的官方版本Group Commit做到了什么程度？&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 什么是Group Commit&lt;/div&gt;
&lt;p&gt;MySQL/InnoDB在做事务的时候使用的日志先行（&lt;a href=&quot;http://en.wikipedia.org/wiki/Write-ahead_logging&quot;&gt;Write-ahead logging&lt;/a&gt;）的方式保证事务的快速和持久，所以每次事务完成都要求日志必须持久化到磁盘，在Linux上对应的操作就是“&lt;a href=&quot;http://www.orczhou.com/index.php/2009/08/innodb_flush_method-file-io/&quot;&gt;write and fsync&lt;/a&gt;”，write速度是很快的，一般对应的写Page Cache，而fsync则要求文件系统把对应文件的哦Page Cache必须持久化到磁盘上，而对于传统磁盘一次写操作大约需要1~3ms（不说BBU），这意味着对于传统磁盘1秒钟最多最多做333～1000个事务，这是不理想的，对硬件的利用率（吞吐量）也是非常低。&lt;/p&gt;
&lt;p&gt;所以，这里就有了Group操作的概念，即当好几个线程都要fsync同一个日志文件时，我们将这些fsync合并到一次来做。简单举例：我们让系统每2ms做一次fsync，这样如果这2ms内有100个线程都需要做fsync，那就赚到了，原本100个fsync都独立来做那耗时会非常多的。&lt;/p&gt;
&lt;p&gt;你肯定会说，难道这不是很简单的想法吗？是的，这就是原本是很简单、也很自然的想法。&lt;/p&gt;
&lt;p&gt;但对MySQL来说却变成了一种奢求（看看这个&lt;a href=&quot;http://bugs.mysql.com/bug.php?id=13669&quot;&gt;Bug讨论&lt;/a&gt;）。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 为啥MySQL一直没有实现？&lt;/div&gt;
&lt;p&gt;MySQL是不是太弱了，这么简单的事情都搞不定？不是的。&lt;/p&gt;
&lt;p&gt;MySQL从开源到现在，成功的一个非常重要的原因，就是MySQL的插件式架构。如果MySQL只是MyISAM估计不会有现在的流行程度，插件式的架构让诸如Heikki Tuuri有了发挥空间，在InnoDB和MySQL一起时，MySQL才能算是一个真正的DBMS。再到后来，有Infobright、 FEDERATED、PBXT等等。&lt;/p&gt;
&lt;p&gt;插件式的架构给MySQL带来了活力，做出牺牲便是在上层(MySQL)和下层(存储引擎)交互时带来的额外消耗，有时甚至上层和下层需要做一些重复工作。无法做Group Commit就是这其中的牺牲之一。&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-3397&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;3. 现在的官方版本Group Commit做到了什么程度&lt;/div&gt;
&lt;p&gt;InnoDB在一次事务中，有两次fsync，分别是prepare阶段和commit阶段，对于这两次操作InnoDB都是&lt;a href=&quot;http://www.innodb.com/wp/products/innodb_plugin/plugin-performance/innodb-plugin-1-0-4-group-commit-test-sysbench/&quot;&gt;实现了Group操作&lt;/a&gt;的。&lt;/p&gt;
&lt;p&gt;如果你设置了binlog_sync=1，则又多了一次fsync操作（参考MYSQL_BIN_LOG::flush_and_sync），这次操作在innobase_xa_prepare和innodb_commit之间：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;binlog_prepare (do nothing)&lt;br /&gt;
innodb_prepare&lt;br /&gt;
...&lt;br /&gt;
binlog_commit&lt;br /&gt;
innobase_commit&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;这次fsync，在MySQL中一直都无法做Group&lt;/strong&gt;。所以，一直以来当innodb_flush_log_at_trx_commit和binlog_sync都等于1的时候，MySQL的性能就&lt;a href=&quot;http://www.mysqlperformanceblog.com/2011/07/13/testing-the-group-commit-fix/&quot;&gt;非常、非常糟糕&lt;/a&gt;。原因是为了保证InnoDB&lt;strong&gt;内部Commit&lt;/strong&gt;的顺序和MySQL日志的顺序一致（&lt;a href=&quot;http://www.orczhou.com/index.php/2010/08/time-to-group-commit-1/&quot;&gt;参考&lt;/a&gt;）。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;4. 开源社区的努力&lt;/div&gt;
&lt;p&gt;难道没人去解决这个问题吗？不是的。有很多人已经做出了努力，直到Kristian Nielsen@MariaDB提出了理论和实际上的最优解决方案。&lt;/p&gt;
&lt;p&gt;Mark Callaghan@Facebook关于Group Commit做的工作：&lt;a href=&quot;http://www.facebook.com/note.php?note_id=386328905932&quot;&gt;FB的基本实现&lt;/a&gt; | &lt;a href=&quot;http://www.facebook.com/note.php?note_id=438641125932&quot;&gt;FB的问题和改进&lt;/a&gt; | &lt;a href=&quot;http://www.facebook.com/note.php?note_id=10150261692455933&quot;&gt;性能&lt;/a&gt; | &lt;a href=&quot;http://www.facebook.com/note.php?note_id=10150211546215933&quot;&gt;对比MariaDB的实现&lt;/a&gt;(对比的结果是MariaDB完胜，无论是方案架构还是性能)&lt;/p&gt;
&lt;p&gt;Facebooke可以说是通过&lt;a href=&quot;http://www.facebook.com/note.php?note_id=386328905932&quot;&gt;一个Trick&lt;/a&gt;快速实现了Group Commit。而Kristian Nielsen@MariaDB这是从架构上根本的解决了这个问题。&lt;/p&gt;
&lt;p&gt;MariaDB关于Group Commit架构和实现： &lt;a href=&quot;http://askmonty.org/worklog/Server-Sprint/?tid=116&quot;&gt;WL116&lt;/a&gt; | &lt;a href=&quot;http://askmonty.org/worklog/Server-Sprint/?tid=132&quot;&gt;WL132&lt;/a&gt; | &lt;a href=&quot;http://askmonty.org/worklog/Server-RawIdeaBin/?tid=164&quot;&gt;WL164&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;5. 未完待续&lt;/div&gt;
&lt;p&gt;后面还有很多值得写的，我希望自己能够一直写完这个系列。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/589153714/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>&lt;p&gt;今天发现Percona Release的&lt;a href=&quot;http://www.mysqlperformanceblog.com/2011/12/19/percona-server-5-5-18-23-0-now-with-group-commit/&quot;&gt;Percona-Server-5-5-18-23-0&lt;/a&gt;已经完成了Group Commit工作，而且是用最优雅的方式（移植了MariaDB的实现，而不是workaround），心里难掩激动。&lt;/p&gt;
&lt;p&gt;这篇文章接&lt;a href=&quot;http://www.orczhou.com/index.php/2010/08/time-to-group-commit-1/&quot;&gt;前篇&lt;/a&gt;继续介绍一下问题的背景：什么是Group Commit，现在的官方版本Group Commit做到了什么程度？&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 什么是Group Commit&lt;/div&gt;
&lt;p&gt;MySQL/InnoDB在做事务的时候使用的日志先行（&lt;a href=&quot;http://en.wikipedia.org/wiki/Write-ahead_logging&quot;&gt;Write-ahead logging&lt;/a&gt;）的方式保证事务的快速和持久，所以每次事务完成都要求日志必须持久化到磁盘，在Linux上对应的操作就是“&lt;a href=&quot;http://www.orczhou.com/index.php/2009/08/innodb_flush_method-file-io/&quot;&gt;write and fsync&lt;/a&gt;”，write速度是很快的，一般对应的写Page Cache，而fsync则要求文件系统把对应文件的哦Page Cache必须持久化到磁盘上，而对于传统磁盘一次写操作大约需要1~3ms（不说BBU），这意味着对于传统磁盘1秒钟最多最多做333～1000个事务，这是不理想的，对硬件的利用率（吞吐量）也是非常低。&lt;/p&gt;
&lt;p&gt;所以，这里就有了Group操作的概念，即当好几个线程都要fsync同一个日志文件时，我们将这些fsync合并到一次来做。简单举例：我们让系统每2ms做一次fsync，这样如果这2ms内有100个线程都需要做fsync，那就赚到了，原本100个fsync都独立来做那耗时会非常多的。&lt;/p&gt;
&lt;p&gt;你肯定会说，难道这不是很简单的想法吗？是的，这就是原本是很简单、也很自然的想法。&lt;/p&gt;
&lt;p&gt;但对MySQL来说却变成了一种奢求（看看这个&lt;a href=&quot;http://bugs.mysql.com/bug.php?id=13669&quot;&gt;Bug讨论&lt;/a&gt;）。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 为啥MySQL一直没有实现？&lt;/div&gt;
&lt;p&gt;MySQL是不是太弱了，这么简单的事情都搞不定？不是的。&lt;/p&gt;
&lt;p&gt;MySQL从开源到现在，成功的一个非常重要的原因，就是MySQL的插件式架构。如果MySQL只是MyISAM估计不会有现在的流行程度，插件式的架构让诸如Heikki Tuuri有了发挥空间，在InnoDB和MySQL一起时，MySQL才能算是一个真正的DBMS。再到后来，有Infobright、 FEDERATED、PBXT等等。&lt;/p&gt;
&lt;p&gt;插件式的架构给MySQL带来了活力，做出牺牲便是在上层(MySQL)和下层(存储引擎)交互时带来的额外消耗，有时甚至上层和下层需要做一些重复工作。无法做Group Commit就是这其中的牺牲之一。&lt;/p&gt;
&lt;p&gt;[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/589153714/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>InnoDB</category><category>MySQL</category><category>Group Commit</category><pubDate>Tue, 20 Dec 2011 23:51:20 +0800</pubDate><author>orczhou</author><comments>http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3397</guid><dc:creator>orczhou</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/12/time-to-group-commit-2/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/589153714/4031936</fs:itemid></item><item><title>使用tbdba-restore-mysqldump.pl切割mysqldump文件</title><link>http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/</link><content:encoded>&lt;p&gt;这里介绍一个最近用得很多的一个小工具：&lt;a href=&quot;https://github.com/orczhou/dba-tool/blob/master/tbdba-restore-mysqldump.pl&quot;&gt;tbdba-restore-mysqldump.pl&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要有两个功能：&lt;/p&gt;
&lt;p&gt;(1) 尽可能快的从一个非常大的mysqldump文件的分离出某个单表的备份文件&lt;/p&gt;
&lt;p&gt;(2) 可以帮你把一个大的mysqldump文件，切割成非常小的单表备份文件（可继续做并行恢复）&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 什么时候需要这么做&lt;/div&gt;
&lt;p&gt;(1) 如果把MySQL中&lt;strong&gt;某一个表&lt;/strong&gt;数据弄丢了，需要从很大的mysqldump备份文件中恢复这个表&lt;/p&gt;
&lt;p&gt;(2) 如果你想并行恢复整个mysqldump备份文件时，这个脚本可以帮你把大文件切割成多个小的单表备份文件，然后就可以方便并行恢复多个文件了&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 如何使用这个脚本&lt;/div&gt;
&lt;p&gt;这里以实例的方式介绍如何使用该脚本：&lt;/p&gt;
&lt;p&gt;(1) 从backup.sql文件中获取表process的备份：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;tbdba-restore-mysqldump.pl -t process -f backup.sql&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;(2) 从backup.sql文件中获取数据库monitor中的表process的备份：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;tbdba-restore-mysqldump.pl -t process -s monitor -f backup.sql&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span id=&quot;more-3364&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(3) 从backup.sql文件中获取多个表的备份文件（例如表process、users）：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;tbdba-restore-mysqldump.pl -t process,user -s monitor -f backup.sql&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;(4) 直接接收来自管道的输出（如果你的mysqldump备份是压缩后，则可以使用）：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;gunzip -c backup.sql.gz|tbdba-restore-mysqldump.pl -t process,user -s monitor&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;(5) 从backup.sql文件中获取数据库monitor下&lt;strong&gt;所有表&lt;/strong&gt;的备份文件：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;gunzip -c backup.sql.gz|tbdba-restore-mysqldump.pl -s monitor &lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;(6) 从backup.sql文件中获取&lt;strong&gt;所有数据库下所有表&lt;/strong&gt;的备份文件：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;gunzip -c backup.sql.gz|tbdba-restore-mysqldump.pl --all-tables&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;(7) 使用-d参数，则可以看到切割的过程中的更多信息：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;date &amp;#038;&amp; gunzip -c /backdir/backup.sql.gz|tbdba-restore-mysqldump.pl -d -a &amp;#038;&amp; date&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;myt1&quot;&gt;3. tbdba-restore-mysqldump.pl有什么优势&lt;/div&gt;
&lt;p&gt;(1) 如果指定了-s（获取&lt;strong&gt;某个&lt;/strong&gt;数据库中的备份）参数，则脚本在成功截取需要恢复的&lt;strong&gt;表&lt;/strong&gt;后就会立刻退出，所以如果你要恢复的表恰好在备份文件的比较靠前的位置时，该脚本的速度会非常快。&lt;/p&gt;
&lt;p&gt;一个实际工作例子：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;$ls -lh backup.sql.gz&lt;br /&gt;
 -rw-r--r-- 1 mysql dba 14G Nov 21 04:49 backup.sql.gz&lt;br /&gt;
$date &amp;#038;&amp; gunzip -c backup.sql.gz|./tbdba-restore-mysqldump.pl -s monitor_general -t monitor_host_info &amp;#038;&amp; date&lt;br /&gt;
Fri Nov 25 14:35:06 CST 2011&lt;br /&gt;
Fri Nov 25 14:46:49 CST 2011&lt;br /&gt;
(the unzip of backup.sql.gz is 88G)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;如果要全量恢复的话，根据经验值：88GB的sql文件完全恢复约需要400分钟（&lt;a href=&quot;http://www.orczhou.com/index.php/2009/12/more-about-mysqldump/&quot;&gt;经验值&lt;/a&gt;）。&lt;/p&gt;
&lt;p&gt;(2) 为了让每个独立的单表备份文件能够准确恢复，脚本做了两个额外的处理工作：在每个单表备份前加上'use db'，让该表能够恢复到正确的数据库；为了让单表恢复时字符集不出错误，脚本在某个单表备份前加上了对应的SET NAMES utf8、SET TIME_ZONE等命令。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;4. 其他人都怎么做&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.tsheets.com/2008/tips-tricks/extract-a-single-table-from-a-mysqldump-file.html&quot;&gt;Extract a Single Table from a mysqldump File&lt;/a&gt;：这篇文章提到了三个办法，分别是：perl脚本（我这里的做法基本“雷同”），awk解析后切割，先恢复到临时库(对大文件这个不现实...)。对比了我们的Perl脚本，这里做了几个改进：可以同时解析出多个表；完成目标表的切割后，则立刻退出，不再扫描剩余部分；会把mysqldump头部输出放到每一个切割文件中，方便各种字符集的恢复；&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://gtowey.blogspot.com/2009/11/restore-single-table-from-mysqldump.html&quot;&gt;Restore a Single Table From mysqldump&lt;/a&gt;：这篇文章介绍如何用Sed来完成这个工作。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ushastry.blogspot.com/2009/08/mysql-restoring-single-table-from.html&quot;&gt;MySQL - Restoring a single table from nightly backup &lt;/a&gt;：这位朋友则，想出一个“更损”的招：只给恢复用户赋予需要恢复的表的权限，然后用--force参数恢复整个mysqldump文件。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://code.openark.org/blog/mysql/on-restoring-a-single-table-from-mysqldump&quot;&gt;On restoring a single table from mysqldump&lt;/a&gt;：这篇文章则对比了使用grep sed 和“权限控制”三种方法的速度。&lt;/p&gt;
&lt;p&gt;最后，如果不喜欢mysqldump这种一股脑的备份方式，可以考虑试用mydumper。&lt;/p&gt;
&lt;p&gt;OK，That's all.&lt;/p&gt;
&lt;p&gt;&lt;embed src=&quot;http://www.xiami.com/widget/318706_184466/singlePlayer.swf&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;257&quot; height=&quot;33&quot; wmode=&quot;transparent&quot;&gt;&lt;/embed&gt;&lt;/p&gt;
&lt;p&gt;广告：&lt;a href=&quot;http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/&quot;&gt;我们寻找靠谱的人&lt;/a&gt; | &lt;a href=&quot;http://www.orczhou.com/index.php/wish-list/&quot;&gt;感谢作者&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806438/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>&lt;p&gt;这里介绍一个最近用得很多的一个小工具：&lt;a href=&quot;https://github.com/orczhou/dba-tool/blob/master/tbdba-restore-mysqldump.pl&quot;&gt;tbdba-restore-mysqldump.pl&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要有两个功能：&lt;/p&gt;
&lt;p&gt;(1) 尽可能快的从一个非常大的mysqldump文件的分离出某个单表的备份文件&lt;/p&gt;
&lt;p&gt;(2) 可以帮你把一个大的mysqldump文件，切割成非常小的单表备份文件（可继续做并行恢复）&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 什么时候需要这么做&lt;/div&gt;
&lt;p&gt;(1) 如果把MySQL中&lt;strong&gt;某一个表&lt;/strong&gt;数据弄丢了，需要从很大的mysqldump备份文件中恢复这个表&lt;/p&gt;
&lt;p&gt;(2) 如果你想并行恢复整个mysqldump备份文件时，这个脚本可以帮你把大文件切割成多个小的单表备份文件，然后就可以方便并行恢复多个文件了&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 如何使用这个脚本&lt;/div&gt;
&lt;p&gt;这里以实例的方式介绍如何使用该脚本：&lt;/p&gt;
&lt;p&gt;(1) 从backup.sql文件中获取表process的备份：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;tbdba-restore-mysqldump.pl -t process -f backup.sql&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;(2) 从backup.sql文件中获取数据库monitor中的表process的备份：&lt;/p&gt;
&lt;blockquote&gt;&lt;div style=&quot;color:blue&quot;&gt;tbdba-restore-mysqldump.pl -t process -s monitor -f backup.sql&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806438/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>mysqldump</category><category>MySQL</category><category>备份</category><pubDate>Wed, 14 Dec 2011 22:40:42 +0800</pubDate><author>orczhou</author><comments>http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3364</guid><dc:creator>orczhou</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/588806438/4031936</fs:itemid></item><item><title>使用mod_proxy_html完善Apache反向代理</title><link>http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/</link><content:encoded>&lt;p&gt;在使用和配置过程中，还是遇到了一些波折，这里分享、记录一下。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 模块mod_proxy_html可以做些什么&lt;/div&gt;
&lt;p&gt;使用Apache内置的mod_proxy的&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass&quot;&gt;Proxypass&lt;/a&gt;可以帮助我们实现基本的&lt;a href=&quot;http://httpd.apache.org/docs/2.2/urlmapping.html#proxy&quot;&gt;反向代理&lt;/a&gt;功能。但是，代理返回的结果页面包含的链接并不会被重写，所以如果被代理的Server返回的是绝对地址，用户则无法正确访问这些链接。例如：&lt;/p&gt;
&lt;p&gt;我们有反向代理服务器http://myproxy.taobao.org/，而内网有需要代理的服务器http://internalserver.taobao.org/，通过基本的反向代理指令&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass&quot;&gt;Proxypass&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;ProxyPass  ^/proxy_internal/(.*)$ http://internalserver.taobao.org/$1&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;可以完成基本的反向代理任务，但是如果internalserver.taobao.org返回的HTML代码中有如下链接，则客户端则无法正常链接到目标页面了：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;lt;a href=&quot;/test/index.html&quot;&gt;Sample Link&amp;lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;因为，客户端点击该链接时会定向到http://myproxy.taobao.org/test/index.html，而资源实际是在http://internalserver.taobao.org/test/index.html上。&lt;/p&gt;
&lt;p&gt;Apache自带的mod_proxy&lt;a href=&quot;http://httpd.apache.org/docs/2.2/urlmapping.html#proxy&quot;&gt;无法解决这个问题&lt;/a&gt;，开源的第三方模块&lt;a href=&quot;http://apache.webthing.com/mod_proxy_html/&quot;&gt;mod_proxy_html&lt;/a&gt;为此而生。经过代理服务器的HTML可以通过该模块做一次替换，从而变成可以正常访问的URL（上例中会把/oninternal/index.html替换成/proxy_internal/test/index.html）。&lt;br /&gt;
&lt;span id=&quot;more-3335&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 编译安装mod_proxy_html模块&lt;/div&gt;
&lt;p&gt;我是在RHEL5.4上安装的，并不容易。&lt;strong&gt;理想的安装步骤&lt;/strong&gt;（为了支持多字符集需要同时安装mod_xml2enc）：&lt;/p&gt;
&lt;p&gt;1. 检查是否安装了libxml2。&lt;/p&gt;
&lt;p&gt;2. 下载mod_proxy_html源码：&lt;a href=&quot;http://apache.webthing.com/mod_proxy_html/&quot;&gt;地址&lt;/a&gt;；下载mod_xml2enc的源码：地址&lt;a href=&quot;http://apache.webthing.com/mod_xml2enc/&quot;&gt;mod_xml2enc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3. 编译mod_proxy_html和mod_xml2enc：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
sudo /usr/sbin/apxs -c -I/usr/include/libxml2 -I. -I /usr/lib -i mod_proxy_html.c&lt;br /&gt;
sudo /usr/sbin/apxs -c -I/usr/include/libxml2 -I. -i mod_xml2enc.c&lt;br /&gt;
chmod 755 /usr/lib64/httpd/modules/mod_proxy_html.so
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;如果你这么顺利就编译好了模块，那你很幸运。&lt;/p&gt;
&lt;div class=&quot;myt2&quot;&gt;编译中的问题&lt;/div&gt;
&lt;blockquote&gt;&lt;p&gt;$ /usr/sbin/apxs -c -I/usr/include/libxml2 -I. -I /usr/lib -i mod_proxy_html.c&lt;br /&gt;
&quot;my&quot; variable $libdir masks earlier declaration in same scope at /usr/sbin/apxs line 36.&lt;br /&gt;
/apr-1/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fno-strict-aliasing  -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/httpd  -I/usr/include/apr-1   -I/usr/include/apr-1  -I/usr/include/libxml2 -I. -I/usr/lib  -c -o mod_proxy_html.lo mod_proxy_html.c &amp;#038;&amp; touch mod_proxy_html.slo&lt;br /&gt;
sh: /apr-1/build/libtool: No such file or directory&lt;br /&gt;
apxs:Error: Command failed with rc=8323072&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;仔细看是：&lt;strong&gt;/apr-1/build/libtool: No such file or directory&lt;/strong&gt;。对libtool和apr-1不很熟悉，看出是因为没有正确找到libtool的路径导致的，所以修改了一下脚本apxs，强制指定libtool的位置，虽然这不是“优雅的”解决办法：&lt;/p&gt;
&lt;div class=&quot;mycode&quot;&gt;
$locate libtool   #找到你的libtool&lt;br /&gt;
......&lt;br /&gt;
$vi /usr/sbin/apxs&lt;br /&gt;
...&lt;br /&gt;
my $libtool = `$apr_config --apr-libtool`;&lt;br /&gt;
chomp($libtool);&lt;br /&gt;
$libtool = &quot;/usr/lib64/apr-1/build/libtool&quot;;&lt;br /&gt;
...
&lt;/div&gt;
&lt;p&gt;It works!  如果有个有更好的办法，或者知道根本原因的，请告诉我，谢过先。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;3. 配置该模块&lt;/div&gt;
&lt;p&gt;强烈建议参考mod_proxy_html源码中的proxy_html.conf，这是一个示例配置文件，非常有指导意义。我这里的配置如下：&lt;/p&gt;
&lt;p&gt;1. 加载必要的模块：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;LoadFile /usr/lib64/libxml2.so&lt;br /&gt;
LoadModule xml2enc_module modules/mod_xml2enc.so&lt;br /&gt;
LoadModule proxy_html_module modules/mod_proxy_html.so&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;2. 指定需要修改的链接标签：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;SetOutputFilter proxy-html&lt;br /&gt;
ProxyHTMLExtended On&lt;br /&gt;
ProxyHTMLLinks  a           href&lt;br /&gt;
ProxyHTMLLinks  area        href&lt;br /&gt;
ProxyHTMLLinks  link        href&lt;br /&gt;
ProxyHTMLLinks  img         src longdesc usemap&lt;br /&gt;
ProxyHTMLLinks  object      classid codebase data usemap&lt;br /&gt;
ProxyHTMLLinks  q           cite&lt;br /&gt;
ProxyHTMLLinks  blockquote  cite&lt;br /&gt;
ProxyHTMLLinks  ins         cite&lt;br /&gt;
ProxyHTMLLinks  del         cite&lt;br /&gt;
ProxyHTMLLinks  form        action&lt;br /&gt;
ProxyHTMLLinks  input       src usemap&lt;br /&gt;
ProxyHTMLLinks  head        profile&lt;br /&gt;
ProxyHTMLLinks  base        href&lt;br /&gt;
ProxyHTMLLinks  script      src for&lt;br /&gt;
ProxyHTMLEvents onclick ondblclick onmousedown onmouseup \&lt;br /&gt;
        onmouseover onmousemove onmouseout onkeypress \&lt;br /&gt;
        onkeydown onkeyup onfocus onblur onload \&lt;br /&gt;
        onunload onsubmit onreset onselect onchange&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;3. 指定的URL替换规则：&lt;/p&gt;
&lt;pre&gt;
&lt;blockquote&gt;
ProxyPassMatch ^/proxy_dir/(.*)$ http://yourdomain/$1
&amp;lt;LocationMatch &quot;/proxy_dir/&quot;&gt;
        ProxyPassReverse /
        ProxyHTMLURLMap  / /proxy_dir/
        ProxyHTMLURLMap  http://some_(reg_exp)_url_(is_supported)you_wanna_replace/  /proxy_dir/$1/$2/ R
        RequestHeader    unset  Accept-Encoding
&amp;lt;/LocationMatch&gt;&lt;/blockquote&gt;
&lt;/pre&gt;
&lt;p&gt;OK，That's all.&lt;/p&gt;
&lt;p&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.xiami.com/widget/player-single?uid=318706&amp;#038;sid=1769953757&amp;#038;mode=js&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;广告：&lt;a href=&quot;http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/&quot;&gt;我们寻找靠谱的人&lt;/a&gt; | &lt;a href=&quot;http://www.orczhou.com/index.php/wish-list/&quot;&gt;感谢作者&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;1. &lt;a href=&quot;http://apache.webthing.com/mod_proxy_html/&quot;&gt;mod_proxy_html主页&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;a href=&quot;http://www.apachetutor.org/admin/reverseproxies&quot;&gt;Running a Reverse Proxy in Apache&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806439/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>&lt;p&gt;在使用和配置过程中，还是遇到了一些波折，这里分享、记录一下。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 模块mod_proxy_html可以做些什么&lt;/div&gt;
&lt;p&gt;使用Apache内置的mod_proxy的&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass&quot;&gt;Proxypass&lt;/a&gt;可以帮助我们实现基本的&lt;a href=&quot;http://httpd.apache.org/docs/2.2/urlmapping.html#proxy&quot;&gt;反向代理&lt;/a&gt;功能。但是，代理返回的结果页面包含的链接并不会被重写，所以如果被代理的Server返回的是绝对地址，用户则无法正确访问这些链接。例如：&lt;/p&gt;
&lt;p&gt;我们有反向代理服务器http://myproxy.taobao.org/，而内网有需要代理的服务器http://internalserver.taobao.org/，通过基本的反向代理指令&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass&quot;&gt;Proxypass&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;ProxyPass  ^/proxy_internal/(.*)$ http://internalserver.taobao.org/$1&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;可以完成基本的反向代理任务，但是如果internalserver.taobao.org返回的HTML代码中有如下链接，则客户端则无法正常链接到目标页面了：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;#60;a href=&quot;/test/index.html&quot;&gt;Sample Link&amp;#60;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;因为，客户端点击该链接时会定向到http://myproxy.taobao.org/test/index.html，而资源实际是在http://internalserver.taobao.org/test/index.html上。&lt;/p&gt;
&lt;p&gt;Apache自带的mod_proxy&lt;a href=&quot;http://httpd.apache.org/docs/2.2/urlmapping.html#proxy&quot;&gt;无法解决这个问题&lt;/a&gt;，开源的第三方模块&lt;a href=&quot;http://apache.webthing.com/mod_proxy_html/&quot;&gt;mod_proxy_html&lt;/a&gt;为此而生。经过代理服务器的HTML可以通过该模块做一次替换，从而变成可以正常访问的URL（上例中会把/oninternal/index.html替换成/proxy_internal/test/index.html）。&lt;br /&gt;
[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806439/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Reverse Proxy</category><category>Apache</category><category>技术细节</category><category>反向代理</category><pubDate>Fri, 09 Dec 2011 22:37:02 +0800</pubDate><author>admin</author><comments>http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3335</guid><dc:creator>admin</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/12/apache-reverse-proxy-with-mod-proxy-html/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/588806439/4031936</fs:itemid></item><item><title>MySQL如何传输二进制日志</title><link>http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/</link><content:encoded>&lt;p&gt;MySQL Replication可以很方便的用来做应用的读扩展，也可以帮MySQL实现一定程度的HA方案。MySQL通过&lt;a href=&quot;http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/&quot;&gt;向备库传送二进制日志来实现Replication&lt;/a&gt;，本文将通过二进制日志相关源代码的主要接口来解释：“&lt;strong&gt;MySQL如何传输二进制日志，是主库推，还是备库拉？MySQL日志传输的实时性如何？&lt;/strong&gt;”。&lt;/p&gt;
&lt;p&gt;在MySQL Replication结构中，备库端初次通过&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html&quot;&gt;CHANGE MASTER TO&lt;/a&gt;完成Replication配置，再使用start slave命令开始复制。更细致的，备库通过IO Thread向主库发起读取binlog的请求（COM_BINLOG_DUMP命令），主库收到COM_BINLOG_DUMP请求后，使用单独线程（dump thread）不断向备库IO Thread发送Binlog。示意图(&lt;a href=&quot;http://farm7.staticflickr.com/6237/6369693149_49d43db964_b.jpg&quot;&gt;大图&lt;/a&gt;)：&lt;br /&gt;
&lt;a href=&quot;http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg&quot;&gt;&lt;img src=&quot;http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg&quot; alt=&quot;&quot; title=&quot;how_mysql_send_binary_log&quot; width=&quot;686&quot; height=&quot;369&quot; class=&quot;alignleft size-full wp-image-3292&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-3279&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;在主库端一旦有新的日志产生后，立刻会发送一次广播，dump线程在收到广播后，则会读取二进制日志并通过网络向备库传输日志，所以这是一个主库向备库不断推送的过程；&lt;/p&gt;
&lt;p&gt;新日志在产生后，只需一次广播和网络就会立刻（&lt;1ms）向发送到备库，如果主备之间网络较好的话（例如RTT&lt;1ms），备库端的日志也就小于2ms了。所以，一般的（依赖于RTT），备库的实时性都非常好。&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;1. &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/replication.html&quot;&gt;MySQL Replication Manual&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;a href=&quot;http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/&quot;&gt;图解&quot;How MySQL Replication Works&quot; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
&lt;p&gt;&lt;embed src=&quot;http://www.xiami.com/widget/0_1025147/singlePlayer.swf&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;257&quot; height=&quot;33&quot; wmode=&quot;transparent&quot;&gt;&lt;/embed&gt;&lt;/p&gt;
&lt;p&gt;广告：&lt;a href=&quot;http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/&quot;&gt;我们寻找靠谱的人&lt;/a&gt; | &lt;a href=&quot;http://www.orczhou.com/index.php/wish-list/&quot;&gt;感谢作者&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806440/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</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><description>&lt;p&gt;MySQL Replication可以很方便的用来做应用的读扩展，也可以帮MySQL实现一定程度的HA方案。MySQL通过&lt;a href=&quot;http://www.orczhou.com/index.php/2009/04/how-mysql-replication-works/&quot;&gt;向备库传送二进制日志来实现Replication&lt;/a&gt;，本文将通过二进制日志相关源代码的主要接口来解释：“&lt;strong&gt;MySQL如何传输二进制日志，是主库推，还是备库拉？MySQL日志传输的实时性如何？&lt;/strong&gt;”。&lt;/p&gt;
&lt;p&gt;在MySQL Replication结构中，备库端初次通过&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html&quot;&gt;CHANGE MASTER TO&lt;/a&gt;完成Replication配置，再使用start slave命令开始复制。更细致的，备库通过IO Thread向主库发起读取binlog的请求（COM_BINLOG_DUMP命令），主库收到COM_BINLOG_DUMP请求后，使用单独线程（dump thread）不断向备库IO Thread发送Binlog。示意图(&lt;a href=&quot;http://farm7.staticflickr.com/6237/6369693149_49d43db964_b.jpg&quot;&gt;大图&lt;/a&gt;)：&lt;br /&gt;
&lt;a href=&quot;http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg&quot;&gt;&lt;img src=&quot;http://www.orczhou.com/wp-content/uploads/2011/11/how_mysql_send_binary_log.jpg&quot; alt=&quot;&quot; title=&quot;how_mysql_send_binary_log&quot; width=&quot;686&quot; height=&quot;369&quot; class=&quot;alignleft size-full wp-image-3292&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806440/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>图解</category><category>MySQL</category><category>Replication</category><pubDate>Sun, 20 Nov 2011 23:53:29 +0800</pubDate><author>admin</author><comments>http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3279</guid><dc:creator>admin</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/11/how-mysql-send-the-binary-log/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/588806440/4031936</fs:itemid></item><item><title>TCP/IP重传超时--RTO</title><link>http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/</link><content:encoded>&lt;p&gt;概述：本文讨论主机在发送一个TCP数据包后，如果迟迟没有收到ACK，主机多久后会重传这个数据包。主机从发出数据包到第一次TCP重传开始，&lt;a href=&quot;http://zh.wikipedia.org/wiki/RFC#RFC.E6.96.87.E4.BB.B6.E7.9A.84.E7.94.A2.E7.94.9F&quot;&gt;RFC&lt;/a&gt;中这段时间间隔称为retransmission timeout，缩写做RTO。本文会先看看RFC中如何定义RTO，然后看看Linux中如何实现。&lt;strong&gt;本文旨在分享&lt;/strong&gt;：当遇到了TCP层问题改如何去查找、阅读文档，该如何去在Linux源码中寻求答案。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 起源&lt;/div&gt;
&lt;p&gt;在分析MySQL Semi-sync故障时，我们用Tcpdump+Wireshark（感谢淘宝雕梁）抓住当时的网络包传送细节，观察到了一次TCP重传最终导致了Semi-sync超时：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;第一次传输
13:55:11.893291 master =&gt; slave	Binlog pos:319890197
重传：
13:55:12.094596	master =&gt; slave	Binlog pos:319890197
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;看到两次传送间隔约201毫秒，即第一次传输201毫秒后，还没有收到ACK响应，TCP认为传输超时，开始重传。&lt;/p&gt;
&lt;p&gt;疑问：host和host之间的RTT大约是0.5毫秒，为什么第一次重传需要等200毫秒？（我希望是&lt;20ms）socket程序可以配置吗RTO吗？TCP有参数可配置RTO吗？&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. Google/书籍/RFC&lt;/div&gt;
&lt;p&gt;翻开TCP/IP详解找到关于TCP Retransmission章节，较详细的介绍TCP的超时机制，书中是个概述，于是又找到RFC1122。&lt;/p&gt;
&lt;p&gt;RFC1122的4.2.2.15和4.2.3.1都介绍了Retransmission Timeout的处理（说来惭愧，这是第一次阅读TCP相关RFC）。&lt;/p&gt;
&lt;p&gt;在&lt;a href=&quot;http://www.ietf.org/rfc.html&quot;&gt;RFC中搜索&lt;/a&gt;Retransmission发现RFC 793 1122 2988 6298都有对重传算法、和初次重传超时的描述。于是开始阅读这个四个RFC，耗时约2小时，了解了大致的重传超时算法。&lt;span id=&quot;more-3162&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;3. RFC中如何计算RTO(Retransmission Timeout)&lt;/div&gt;
&lt;div class=&quot;myt2&quot;&gt;3.1 RFC-793如何计算RTO&lt;/div&gt;
&lt;p&gt;概述：先根据该socket的RTT计算出SRTT（Smoothed Round Trip Time），然后根据一个最大、最小超时时间确定当前RTO。说明：srtt可以理解为“平滑化”的RTT，即在保持计算简单的情况尽量考虑历史RTT。&lt;/p&gt;
&lt;p&gt;详细计算：SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)&lt;/p&gt;
&lt;p&gt;基于SRTT，我们再来计算RTO：RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]]&lt;/p&gt;
&lt;p&gt;UBOUND是RTO上线，ALPHA是平滑因子（smoothing factor， e.g., .8 to .9），BETA是一个延迟方差因子（BETA is a delay variance factor (e.g., 1.3 to 2.0)）。&lt;/p&gt;
&lt;p&gt;仔细看这两个公式大概就能理解了RTO的计算了。&lt;/p&gt;
&lt;p&gt;这里对上面两个公式做一个简单的注释：公式1中计算SRTT，ALPHA越接近于0，则表示SRTT越相信这一次的RTT；越接近于1，则表示SRTT越相信上次统计的RTT。公式二给RTO分别设置了一个上限和下限。&lt;/p&gt;
&lt;div class=&quot;myt2&quot;&gt;3.2 RTO重传间隔是指数增加的&lt;/div&gt;
&lt;p&gt;上面我们介绍的是初次重传时的RTO，如果重传后还没收到另一端的响应，下一次重传RTO则会指数增加，例如第一次重传RTO是1，之后分别2，4，8，16...。&lt;/p&gt;
&lt;div class=&quot;myt2&quot;&gt;3.3 RFC-2988和RFC-6298中的RTO计算&lt;/div&gt;
&lt;p&gt;在RFC-2988和RFC-6298中又重新改进了RTO的计算方法，Linux中的实现即使参考RFC-2988。算法核心公式：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;初始：
SRTT &lt;- R
RTTVAR &lt;- R/2
RTO &lt;- SRTT + max (G, K*RTTVAR)
where K = 4.

根据RTT计算SRTT：
RTTVAR &lt;- (1 - beta) * RTTVAR + beta * |SRTT - R'|
SRTT &lt;- (1 - alpha) * SRTT + alpha * R'

最后RTO：
RTO &lt;- SRTT + max (G, K*RTTVAR)
&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;myt1&quot;&gt;4. Linux中的RTO(Retransmission Timeout)&lt;/div&gt;
&lt;p&gt;这里说的是RHEL5.4的2.6.18内核，RFC-2988实现参考net/ipv4/tcp_input.c中的tcp_rtt_estimator和tcp_set_rto。可以看到，在Linux中alpha=1/8，RTO最小为TCP_RTO_MIN。因为我们的系统中RTT总是很小，所以RTO取值总是能够取到TCP_RTO_MIN。&lt;/p&gt;
&lt;p&gt;在看看TCP_RTO_MIN在Linux中的定义：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;123#define TCP_RTO_MAX     ((unsigned)(120*HZ))
124#define TCP_RTO_MIN     ((unsigned)(HZ/5))
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;(这里简单的介绍介绍一下HZ，HZ可以理解为1s，所以120*HZ就是120秒，HZ/5就是200ms。详细的：HZ表示CPU一秒种发出多少次时间中断--IRQ-0，Linux中通常用HZ来做时间片的计算，&lt;a href=&quot;http://blog.csdn.net/bdc995/article/details/4144031&quot;&gt;参考&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;5. 其他：Linux中可配置重传参数&lt;/div&gt;
&lt;p&gt;/proc/sys/net/ipv4/tcp_retries1  (integer; default: 3)&lt;/p&gt;
&lt;p&gt;TCP尝试了3次（tcp_retries1默认3）重传后，还没有收到ACK的话，则后续每次重传都需要network layer先更新路由。&lt;/p&gt;
&lt;p&gt;/proc/sys/net/ipv4/tcp_retries2  (integer; default: 15)&lt;/p&gt;
&lt;p&gt;TCP默认最多做15次重传。根据RTO(retransmission timeout)不同，最后一次重传间隔大概是13到30分钟左右。如果15次重传都做完了，TCP/IP就会告诉应用层说：“搞不定了，包怎么都传不过去！”&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;6. 最后&lt;/div&gt;
&lt;p&gt;回答前面的问题：即使RTT很小（0.8ms），但是因为RTO有下限，最小必须是200ms，所以这是RTT再小也白搭；RTO最小值是内核编译是决定的，socket程序中无法修改，Linux TCP也没有任何参数可以改变这个值。&lt;/p&gt;
&lt;p&gt;好了，不容易。&lt;/p&gt;
&lt;p&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.xiami.com/widget/player-single?uid=318706&amp;#038;sid=382457&amp;#038;mode=js&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;广告：&lt;a href=&quot;http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/&quot;&gt;我们寻找靠谱的人&lt;/a&gt; | &lt;a href=&quot;http://www.orczhou.com/index.php/wish-list/&quot;&gt;感谢作者&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考文献&lt;/p&gt;
&lt;p&gt;1. RFC 1122 ... (&lt;a href=&quot;http://www.ietf.org/rfc.html&quot;&gt;在哪儿查找RFC&lt;/a&gt;) TCP协议相关的RFC：&lt;br /&gt;
RFC 675 - Specification of Internet Transmission Control Program, December 1974 Version&lt;br /&gt;
RFC 793 - TCP v4&lt;br /&gt;
RFC 1122 - includes some error corrections for TCP&lt;br /&gt;
RFC 1323 - TCP-Extensions&lt;br /&gt;
RFC 1379 - Extending TCP for Transactions—Concepts&lt;br /&gt;
RFC 1948 - Defending Against Sequence Number Attacks&lt;br /&gt;
RFC 2018 - TCP Selective Acknowledgment Options&lt;br /&gt;
RFC 2988 - Computing TCP's Retransmission Timer&lt;br /&gt;
RFC 4614 - A Roadmap for TCP Specification Documents&lt;br /&gt;
RFC 5681 - TCP Congestion Control&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806441/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/feed/</wfw:commentRss><slash:comments>1</slash:comments><description>&lt;p&gt;概述：本文讨论主机在发送一个TCP数据包后，如果迟迟没有收到ACK，主机多久后会重传这个数据包。主机从发出数据包到第一次TCP重传开始，&lt;a href=&quot;http://zh.wikipedia.org/wiki/RFC#RFC.E6.96.87.E4.BB.B6.E7.9A.84.E7.94.A2.E7.94.9F&quot;&gt;RFC&lt;/a&gt;中这段时间间隔称为retransmission timeout，缩写做RTO。本文会先看看RFC中如何定义RTO，然后看看Linux中如何实现。&lt;strong&gt;本文旨在分享&lt;/strong&gt;：当遇到了TCP层问题改如何去查找、阅读文档，该如何去在Linux源码中寻求答案。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 起源&lt;/div&gt;
&lt;p&gt;在分析MySQL Semi-sync故障时，我们用Tcpdump+Wireshark（感谢淘宝雕梁）抓住当时的网络包传送细节，观察到了一次TCP重传最终导致了Semi-sync超时：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;第一次传输
13:55:11.893291 master =&gt; slave	Binlog pos:319890197
重传：
13:55:12.094596	master =&gt; slave	Binlog pos:319890197
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;看到两次传送间隔约201毫秒，即第一次传输201毫秒后，还没有收到ACK响应，TCP认为传输超时，开始重传。&lt;/p&gt;
&lt;p&gt;疑问：host和host之间的RTT大约是0.5毫秒，为什么第一次重传需要等200毫秒？（我希望是&amp;#60;20ms）socket程序可以配置吗RTO吗？TCP有参数可配置RTO吗？&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. Google/书籍/RFC&lt;/div&gt;
&lt;p&gt;翻开TCP/IP详解找到关于TCP Retransmission章节，较详细的介绍TCP的超时机制，书中是个概述，于是又找到RFC1122。&lt;/p&gt;
&lt;p&gt;RFC1122的4.2.2.15和4.2.3.1都介绍了Retransmission Timeout的处理（说来惭愧，这是第一次阅读TCP相关RFC）。&lt;/p&gt;
&lt;p&gt;在&lt;a href=&quot;http://www.ietf.org/rfc.html&quot;&gt;RFC中搜索&lt;/a&gt;Retransmission发现RFC 793 1122 2988 6298都有对重传算法、和初次重传超时的描述。于是开始阅读这个四个RFC，耗时约2小时，了解了大致的重传超时算法。[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806441/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>TCP</category><category>RTO</category><category>Linux</category><category>retransmission timeout</category><category>技术细节</category><pubDate>Thu, 27 Oct 2011 20:19:27 +0800</pubDate><author>orczhou</author><comments>http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3162</guid><dc:creator>orczhou</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/10/tcpip-protocol-start-rto/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/588806441/4031936</fs:itemid></item><item><title>MySQL5.5 Semi-sync备库响应协议分析</title><link>http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/</link><content:encoded>&lt;p&gt;这又是一篇介绍Semi-sync的文章。&lt;/p&gt;
&lt;p&gt;Semi-sync主库在一定时间内（可配置的超时时间），如果没有收到备库的响应，则会超时从而降级为普通的replication复制。如果超时发生，有时需要查清什么原因导致备库没有及时响应，一方面可以从备库的日志着手，另一方面，如果需要更细致的信息则需要从备库端的网络包查找原因。这里介绍如何分析一个Semi-sync备库响应主库的数据包。&lt;/p&gt;
&lt;p&gt;概述：先使用tcpdump抓取正确（主要是src和dst都正确）的数据包；然后借助wireshark玻璃TCP/IP等层的头信息，仅保留发送的MySQL数据包；再分析MySQL Semi-sync Slave响应的协议。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. tcpdump原始数据包&lt;/div&gt;
&lt;p&gt;通过如下tcpdump抓取主机的网络包：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;nohup tcpdump -n -nn -tttt -i bond0 -s 65535 'port 3306 and ((dst host master.host and src host slave.host and len &amp;#038;lt 100) or (dst host slave.host and src host master.host))' -w tcpdump.ret -C 50 &amp;#038;
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;参数简单说明：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;-n  表示ip不要转换为主机名
-nn表示端口号，不要转为为服务名（例如3306会被转换为mysql）
-tttt 打印出完成的格式化的时间戳
-C 50 表示抓取的结果放到文件中，文件大小不超过50MB
&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 使用wireshark找到对应的包&lt;/div&gt;
&lt;p&gt;&lt;span id=&quot;more-3125&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Semi-sync备库响应主库包，一般大小整个包大小约95字节。找到该网络包如下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.orczhou.com/wp-content/uploads/2011/10/tmp.jpg&quot;&gt;&lt;img src=&quot;http://www.orczhou.com/wp-content/uploads/2011/10/tmp.jpg&quot; alt=&quot;&quot; title=&quot;tmp&quot; width=&quot;618&quot; height=&quot;156&quot; class=&quot;alignleft size-full wp-image-3151&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;完整网络包内容：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;0000  00 24 e8 57 76 5e 00 1d  70 82 ca c0 08 00 45 00   .$.Wv^.. p.....E.
0010  00 51 a6 e2 40 00 3e 06  89 34 ac 13 46 44 ac 17   .Q..@.&gt;. .4..FD..
0020  6e 21 b3 35 0c ea b2 2d  26 2a da 46 3c df 80 18   n!.5...- &amp;#038;*.F&lt;...
0030  04 82 35 ef 00 00 01 01  08 0a 5a a2 7f cd 50 43   ..5..... ..Z...PC
0040  c1 5b 19 00 00 00 ef 38  40 01 00 00 00 00 00 6d   .[.....8 @......m
0050  79 73 71 6c 2d 62 69 6e  2e 30 30 31 35 31 36      ysql-bin .001516
&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;myt1&quot;&gt;3. MySQL数据包分析&lt;/div&gt;
&lt;p&gt;剥去TCP/IP等层（使用wireshark就可以了），剩下MySQL 包如下：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;0040        19 00 00 00 ef 38  40 01 00 00 00 00 00 6d   .[.....8 @......m
0050  79 73 71 6c 2d 62 69 6e  2e 30 30 31 35 31 36      ysql-bin .001516
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;更具Semi-sync备库响应源码分析如下：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;+============================+
| packetlength      0 : 4    | 对应的：19 00 00 00 表示包数据长度为0x19=25字节
+----------------------------+
| magic_num         4 : 1    | 对应的：ef 这是一个kPacketMagicNum，表示这是一个Semi-sync slave响应
+----------------------------+
| binlog_pos        5 : 4    | 对应的：38  40 01 00 Binlog Pos:0x14038 = 81976
+----------------------------+
| event_length      9 : 20   | 对应的：00 00 00 00 6d 79 73 71 6c .... 31 36 （mysql-bin.001516）
+----------------------------+
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;可以看出，改网络包，响应主库端的mysql-bin.001516中的偏移为81976的事务。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;4. 最后【更新2011-10-19】&lt;/div&gt;
&lt;p&gt;通过tcpdump的网络包，我们可以看到毫秒（甚至微秒）级别数据包的传送情况。依据此，通常可以精确分析出Semi-sync在何时、何处出现超时。然后，可以继续分析为何出现超时。&lt;/p&gt;
&lt;p&gt;That's all...  这篇枯燥吧，哈哈  &lt;/p&gt;
&lt;p&gt;&lt;embed src=&quot;http://www.xiami.com/widget/0_1769845026/singlePlayer.swf&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;257&quot; height=&quot;33&quot; wmode=&quot;transparent&quot;&gt;&lt;/embed&gt;&lt;/p&gt;
&lt;p&gt;广告：&lt;a href=&quot;http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/&quot;&gt;我们寻找靠谱的人&lt;/a&gt; | &lt;a href=&quot;http://www.orczhou.com/index.php/wish-list/&quot;&gt;感谢作者&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806442/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>&lt;p&gt;这又是一篇介绍Semi-sync的文章。&lt;/p&gt;
&lt;p&gt;Semi-sync主库在一定时间内（可配置的超时时间），如果没有收到备库的响应，则会超时从而降级为普通的replication复制。如果超时发生，有时需要查清什么原因导致备库没有及时响应，一方面可以从备库的日志着手，另一方面，如果需要更细致的信息则需要从备库端的网络包查找原因。这里介绍如何分析一个Semi-sync备库响应主库的数据包。&lt;/p&gt;
&lt;p&gt;概述：先使用tcpdump抓取正确（主要是src和dst都正确）的数据包；然后借助wireshark玻璃TCP/IP等层的头信息，仅保留发送的MySQL数据包；再分析MySQL Semi-sync Slave响应的协议。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. tcpdump原始数据包&lt;/div&gt;
&lt;p&gt;通过如下tcpdump抓取主机的网络包：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;nohup tcpdump -n -nn -tttt -i bond0 -s 65535 'port 3306 and ((dst host master.host and src host slave.host and len &amp;#038;lt 100) or (dst host slave.host and src host master.host))' -w tcpdump.ret -C 50 &amp;#038;
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;参数简单说明：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;-n  表示ip不要转换为主机名
-nn表示端口号，不要转为为服务名（例如3306会被转换为mysql）
-tttt 打印出完成的格式化的时间戳
-C 50 表示抓取的结果放到文件中，文件大小不超过50MB
&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;myt1&quot;&gt;2. 使用wireshark找到对应的包&lt;/div&gt;
&lt;p&gt;[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806442/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>semi-sync replication</category><category>半同步</category><category>MySQL</category><category>MySQL5.5</category><category>代码细节</category><pubDate>Tue, 18 Oct 2011 22:53:58 +0800</pubDate><author>orczhou</author><comments>http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3125</guid><dc:creator>orczhou</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/10/semy-sync-slave-protocol-slave-reply/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/588806442/4031936</fs:itemid></item><item><title>orczhou@Google Reader [2011-09-20]</title><link>http://www.google.com/reader/shared/17790666245306540771#2011-09-20</link><guid>http://www.google.com/reader/shared/17790666245306540771#2011-09-20</guid><pubDate>Tue, 20 Sep 2011 00:00:00 +0800</pubDate><description>&lt;ul&gt;&lt;li&gt;&lt;a href='http://monty-says.blogspot.com/2011/09/oracle-adding-close-source-extensions.html' title='link to ..'&gt;Oracle adding close source extensions to MySQL&lt;/a&gt;&lt;br/&gt;&lt;div&gt;Oracle has now officially announced that MySQL is not a full free software project anymore and that they will go for an Open Core model.This is inconsistent to the original MySQL business model. The main strength of MySQL has always been that all M..&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description><fs:burntype>mark day</fs:burntype><fs:srclink>http://monty-says.blogspot.com/2011/09/oracle-adding-close-source-extensions.html</fs:srclink><fs:srcfeed>http://www.google.com/reader/public/atom/user/17790666245306540771/state/com.google/broadcast</fs:srcfeed><fs:itemid>feedsky/orczhou/~8092345/595001588/4031936</fs:itemid></item><item><title>Percona-Server/MySQL响应时间统计</title><link>http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/</link><content:encoded>&lt;p&gt;在Percona的5.1.53和5.5.8版本，开始将RT的统计内置到MySQL Server端。Thanks, Percona.&lt;/p&gt;
&lt;p&gt;Percona在提供了&lt;a href=&quot;http://www.mysqlperformanceblog.com/2010/08/31/introducing-tcprstat-a-tcp-response-time-tool/&quot;&gt;tcprstat工具&lt;/a&gt;统计RT时间之后，很快就在Percona Server中集成了响应时间统计的功能。这里介绍一下该功能，各位看官如果在犹豫选择&lt;a href=&quot;http://www.percona.com/software/percona-server/&quot;&gt;Percona Server&lt;/a&gt;还是&lt;a href=&quot;http://dev.mysql.com/downloads/mysql/&quot;&gt;MySQL Community Server&lt;/a&gt;，这里给Percona Server加一个筹码。&lt;/p&gt;
&lt;p&gt;&quot;响应时间&quot;（Response time，后面简称RT）在数据库应用中，特别是OLTP的场景，可以说非常重要，不过，MySQL官方版本中一直没有加上这个统计功能。最早，社区开始尝试tcmdump+perl脚本的方式查看RT，后来告警一点用&lt;a href=&quot;http://ronaldbradford.com/blog/take-a-look-at-mk-query-digest-2009-10-08/&quot;&gt;tcpdump+mk-query-digest&lt;/a&gt;，再后来Ignacio Nin和Baron Schwartz完成了tcprstat。&lt;/p&gt;
&lt;p&gt;在Percona的5.1.53和5.5.8版本，开始将RT的统计内置到MySQL Server端。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 配置该功能&lt;/div&gt;
&lt;p&gt;这个是功能默认是关闭的，可以通过设置参数query_response_time_stats=1打开这个功能，这是一个动态参数，所以在服务器上可以很方便的打开或者关闭这个功能。可以通过命令SHOW QUERY_RESPONSE_TIME查看响应时间统计。&lt;span id=&quot;more-3068&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;myt2&quot;&gt;默认关闭状态：&lt;/div&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;SHOW QUERY_RESPONSE_TIME;
+----------------+---+----------------+
|                |   |                |
+----------------+---+----------------+
|       0.000001 | 0 |       0.000000 |
|       0.000010 | 0 |       0.000000 |
|       0.000100 | 0 |       0.000000 |
|       0.001000 | 0 |       0.000000 |
......
|  1000000.00000 | 0 |       0.000000 |
| TOO LONG       | 0 | TOO LONG       |
+----------------+---+----------------+&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;myt2&quot;&gt;打开参数后：&lt;/div&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;set global query_response_time_stats=1;
Query OK, 0 rows affected (0.00 sec)

08:23:13&gt;SHOW QUERY_RESPONSE_TIME;
+----------------+-------+----------------+
|                |       |                |
+----------------+-------+----------------+
|       0.000001 |  7982 |       0.000000 |
|       0.000010 | 13927 |       0.014511 |
|       0.000100 | 43811 |       1.553811 |
|       0.001000 |    29 |       0.007936 |
|       0.010000 |     1 |       0.001711 |
|       0.100000 |     0 |       0.000000 |
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;这里可以看到，响应时间小于0.000001&lt;strong&gt;秒&lt;/strong&gt;的SQL有7982个，0.000001 &amp;lt; RT &amp;lt;  0.000010有13927个， 0.000010 &amp;lt; RT &amp;lt; 0.000100有43811  ...... 。这样整个系统的响应时间就清晰了。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;2. INFORMATION_SCHEMA.QUERY_RESPONSE_TIME&lt;/div&gt;
&lt;p&gt;除了用命令SHOW QUERY_RESPONSE_TIME，还可以通过INFORMATION_SCHEMA里面的表QUERY_RESPONSE_TIME来查看MySQL的响应时间。&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;08:25:16&gt;SELECT * from INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+----------------+--------+----------------+
| time           | count  | total          |
+----------------+--------+----------------+
|       0.000001 |  33824 |       0.000000 |
|       0.000010 |  59222 |       0.060457 |
|       0.000100 | 186003 |       6.659908 |
|       0.001000 |    117 |       0.025163 |
|       0.010000 |      8 |       0.014534 |&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;使用INFORMATION_SCHEMA.QUERY_RESPONSE_TIME，就可以稍微定制一下输出结果了：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;
SELECT time, CONCAT(ROUND(100*count/query_count,2),&quot;%&quot;) as percent,count
FROM(
    SELECT
    	c.count,
    	c.time,
    	(
    	    SELECT SUM(a.count)
    	    FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a
    	    WHERE a.count != 0
    	) as query_count
    FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c
    WHERE c.count &gt; 0
) d;
+----------------+---------+--------+
| time           | percent | count  |
+----------------+---------+--------+
|       0.000001 | 12.64%  |  81557 |
|       0.000010 | 20.69%  | 133440 |
|       0.000100 | 66.62%  | 429705 |
|       0.001000 | 0.05%   |    339 |
|       0.010000 | 0.00%   |     10 |
|    1000.000000 | 0.00%   |      1 |
+----------------+---------+--------+
&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;myt1&quot;&gt;3. 高端一点的功能：定制化时间区间&lt;/div&gt;
&lt;p&gt;默认的时间区间是：&lt;/p&gt;
&lt;p&gt;(0; 10 ^ -6], (10 ^ -6; 10 ^ -5], (10 ^ -5; 10 ^ -4], ..., (10 ^ -1; 10 ^1], (10^1; 10^2]...(10^&lt;/p&gt;
&lt;p&gt;你可以通过修改参数query_response_time_range_base来缩小时间区间，默认该参数是10，时间区间如上。&lt;/p&gt;
&lt;p&gt;例如我们修个set global query_response_time_range_base=2; 则区间如下：&lt;/p&gt;
&lt;p&gt;(0; 2 ^ -19], (2 ^ -19; 2 ^ -18], (2 ^ -18; 2 ^ -17], ..., (2 ^ -1; 2 ^1], (2 ^ 1; 2 ^ 2]...(2 ^&lt;/p&gt;
&lt;p&gt;第一个区间总是最接近0.000001区间开始(2^19次方最接近)；最后一个区间是到最接近且小于10000000处结束。&lt;/p&gt;
&lt;p&gt;具体的：&lt;/p&gt;
&lt;div class=&quot;mycode&quot;&gt;set global query_response_time_range_base=2;&lt;br /&gt;
flush QUERY_RESPONSE_TIME;&lt;br /&gt;
SHOW QUERY_RESPONSE_TIME;&lt;br /&gt;
|       0.000001 |  711 |       0.000000 |&lt;br /&gt;
|       0.000003 | 1456 |       0.001456 |&lt;br /&gt;
......&lt;br /&gt;
|       0.125000 |    0 |       0.000000 |&lt;br /&gt;
|       0.250000 |    0 |       0.000000 |&lt;br /&gt;
|       0.500000 |    0 |       0.000000 |&lt;br /&gt;
|       1.000000 |    0 |       0.000000 |&lt;br /&gt;
|       2.000000 |    0 |       0.000000 |&lt;br /&gt;
|       4.000000 |    0 |       0.000000 |&lt;br /&gt;
|       8.000000 |    0 |       0.000000 |&lt;br /&gt;
|      16.000000 |    0 |       0.000000 |&lt;br /&gt;
......&lt;br /&gt;
|  8388608.00000 |    0 |       0.000000 |&lt;br /&gt;
| TOO LONG       |    0 | TOO LONG       |
&lt;/div&gt;
&lt;div class=&quot;myt1&quot;&gt;一些注意事项&lt;/div&gt;
&lt;p&gt;在备库上，只有打开了参数&lt;a href=&quot;log_slow_slave_statements&quot;&gt;log_slow_slave_statements&lt;/a&gt;(这个参数也是Percona Server上特有的)时，slave sql线程的SQL才会被统计。&lt;/p&gt;
&lt;p&gt;启动变量have_response_time_distribution，不能配置，该参数只表示该Server是否具有上述的RT统计功能。&lt;/p&gt;
&lt;p&gt;设置了query_response_time_range_base，必须flush QUERY_RESPONSE_TIME后才生效。这里flush做两件事情，使得QUERY_RESPONSE_TIME生效，另外清空之前的统计结果。&lt;/p&gt;
&lt;p&gt;累了，听首歌，扭扭脖子吧:)&lt;/p&gt;
&lt;p&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.xiami.com/widget/player-single?uid=0&amp;#038;sid=3599116&amp;#038;mode=js&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;广告：&lt;a href=&quot;http://www.orczhou.com/index.php/projects/we-are-hunting-mysql-hacker/&quot;&gt;我们寻找靠谱的人&lt;/a&gt; | &lt;a href=&quot;http://www.orczhou.com/index.php/wish-list/&quot;&gt;感谢作者&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考文献：&lt;/p&gt;
&lt;p&gt;1. &lt;a href=&quot;http://www.mysqlperformanceblog.com/2010/08/31/introducing-tcprstat-a-tcp-response-time-tool/&quot;&gt;Introducing tcprstat, a TCP response time tool&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;a href=&quot;http://www.percona.com/docs/wiki/tcprstat:start&quot;&gt;The tcprstat User's Manual&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3. &lt;a href=&quot;http://www.megalinux.net/using-tcpdump-for-mysql-query-logging/&quot;&gt;Using Tcpdump for MySQL query logging&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4. &lt;a href=&quot;http://www.mysqlperformanceblog.com/2011/04/18/how-to-use-tcpdump-on-very-busy-hosts/&quot;&gt;How to use tcpdump on very busy hosts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;5. &lt;a href=&quot;http://ronaldbradford.com/blog/take-a-look-at-mk-query-digest-2009-10-08/&quot;&gt;Take a look at mk-query-digest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;6. &lt;a href=&quot;http://www.percona.com/docs/wiki/percona-server:features:implementation_details:details_response_time_distribution&quot;&gt;Implementation Details: Response Time Distribution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;7. &lt;a href=&quot;http://www.percona.com/docs/wiki/percona-server:features:response_time_distribution&quot;&gt;Percona Software Documentation :Response Time Distribution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;【附录】&lt;/p&gt;
&lt;p&gt;既然上面读取INFORMATION_SCHEMA的SQL已经有些复杂了，那就不怕再复杂一些：&lt;/p&gt;
&lt;pre&gt;
&lt;div class=&quot;mycode&quot;&gt;SELECT
    case TRIM(time)
    	when '0.000001' then '&lt;  1us'
    	when '0.000010' then '&lt; 10us'
    	when '0.000100' then '&lt;100us'
    	when '0.001000' then '&lt;  1ms'
    	when '0.010000' then '&lt; 10ms'
    	when '0.100000' then '&lt;100ms'
    	when '1.000000' then '&lt;   1s'
    	when '10.000000' then '&lt;  10s'
    	when '100.000000' then '&lt;100s'
    	else '&gt;100s'
    END as `RT area`,
    CONCAT(ROUND(100*count/query_count,2),&quot;%&quot;) as percent,
    count
FROM(
    SELECT
    	c.count,
    	c.time,
    	(
    	    SELECT SUM(a.count)
    	    FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a
    	    WHERE a.count != 0
    	) as query_count
    FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c
    WHERE c.count &gt; 0
) d;
+---------+---------+--------+
| RT area | percent | count  |
+---------+---------+--------+
| &lt; 10us  | 41.92%  | 404409 |
| &lt;100us  | 21.34%  | 205881 |
| &lt;  1ms  | 35.20%  | 339574 |
| &lt; 10ms  | 1.30%   |  12586 |
| &lt;100ms  | 0.18%   |   1736 |
| &lt;   1s  | 0.02%   |    160 |
| &lt;  10s  | 0.04%   |    340 |
+---------+---------+--------+
&lt;/div&gt;
&lt;/pre&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806443/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>&lt;p&gt;在Percona的5.1.53和5.5.8版本，开始将RT的统计内置到MySQL Server端。Thanks, Percona.&lt;/p&gt;
&lt;p&gt;Percona在提供了&lt;a href=&quot;http://www.mysqlperformanceblog.com/2010/08/31/introducing-tcprstat-a-tcp-response-time-tool/&quot;&gt;tcprstat工具&lt;/a&gt;统计RT时间之后，很快就在Percona Server中集成了响应时间统计的功能。这里介绍一下该功能，各位看官如果在犹豫选择&lt;a href=&quot;http://www.percona.com/software/percona-server/&quot;&gt;Percona Server&lt;/a&gt;还是&lt;a href=&quot;http://dev.mysql.com/downloads/mysql/&quot;&gt;MySQL Community Server&lt;/a&gt;，这里给Percona Server加一个筹码。&lt;/p&gt;
&lt;p&gt;&quot;响应时间&quot;（Response time，后面简称RT）在数据库应用中，特别是OLTP的场景，可以说非常重要，不过，MySQL官方版本中一直没有加上这个统计功能。最早，社区开始尝试tcmdump+perl脚本的方式查看RT，后来告警一点用&lt;a href=&quot;http://ronaldbradford.com/blog/take-a-look-at-mk-query-digest-2009-10-08/&quot;&gt;tcpdump+mk-query-digest&lt;/a&gt;，再后来Ignacio Nin和Baron Schwartz完成了tcprstat。&lt;/p&gt;
&lt;p&gt;在Percona的5.1.53和5.5.8版本，开始将RT的统计内置到MySQL Server端。&lt;/p&gt;
&lt;div class=&quot;myt1&quot;&gt;1. 配置该功能&lt;/div&gt;
&lt;p&gt;这个是功能默认是关闭的，可以通过设置参数query_response_time_stats=1打开这个功能，这是一个动态参数，所以在服务器上可以很方便的打开或者关闭这个功能。可以通过命令SHOW QUERY_RESPONSE_TIME查看响应时间统计。[......]&lt;/p&gt;&lt;p class='read-more'&gt;&lt;a href='http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/'&gt;继续阅读&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/588806443/orczhou/feedsky/s.gif?r=http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Percona MySQL</category><category>MySQL</category><pubDate>Mon, 19 Sep 2011 21:02:57 +0800</pubDate><author>orczhou</author><comments>http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/#comments</comments><guid isPermaLink="false">http://www.orczhou.com/?p=3068</guid><dc:creator>orczhou</dc:creator><fs:srclink>http://www.orczhou.com/index.php/2011/09/thanks-percona-response-time-distribution/</fs:srclink><fs:srcfeed>http://www.orczhou.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/orczhou/~5903491/588806443/4031936</fs:itemid></item><item><title>orczhou@Google Reader [2011-08-16]</title><link>http://www.google.com/reader/shared/17790666245306540771#2011-08-16</link><guid>http://www.google.com/reader/shared/17790666245306540771#2011-08-16</guid><pubDate>Tue, 16 Aug 2011 00:00:00 +0800</pubDate><description>&lt;ul&gt;&lt;li&gt;&lt;a href='http://monty-says.blogspot.com/2011/08/what-is-happening-with-mysql-conference.html' title='link to ..'&gt;What is happening with the MySQL conference?&lt;/a&gt;&lt;br/&gt;&lt;div&gt;Shared by  orczhou 

Good news for community, bad news for Oracle.
What is happening with the MySQL conference?

I'm at the moment perplexed, confused and disappointed in what's going on around the traditional MySQL user conference. Percona yesterd..&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description><fs:burntype>mark day</fs:burntype><fs:srclink>http://monty-says.blogspot.com/2011/08/what-is-happening-with-mysql-conference.html</fs:srclink><fs:srcfeed>http://www.google.com/reader/public/atom/user/17790666245306540771/state/com.google/broadcast</fs:srcfeed><fs:itemid>feedsky/orczhou/~8092345/595001589/4031936</fs:itemid></item><item><title>orczhou@Google Reader [2011-07-30]</title><link>http://www.google.com/reader/shared/17790666245306540771#2011-07-30</link><guid>http://www.google.com/reader/shared/17790666245306540771#2011-07-30</guid><pubDate>Sat, 30 Jul 2011 00:00:00 +0800</pubDate><description>&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.mysqlperformanceblog.com/2011/07/29/intel-320-ssd-read-performance/' title='link to ..'&gt;Intel 320 SSD read performance&lt;/a&gt;&lt;br/&gt;&lt;div&gt;(this is cross-post from http://www.ssdperformanceblog.com/)
While PCI-e Flash cards show great performance, I am often asked about alternatives, as price for PCI-e cards is still significant and not acceptable for small companies and startups.
Int..&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description><fs:burntype>mark day</fs:burntype><fs:srclink>http://www.mysqlperformanceblog.com/2011/07/29/intel-320-ssd-read-performance/</fs:srclink><fs:srcfeed>http://www.google.com/reader/public/atom/user/17790666245306540771/state/com.google/broadcast</fs:srcfeed><fs:itemid>feedsky/orczhou/~8092345/595001590/4031936</fs:itemid></item></channel></rss>
