﻿<?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>P.Linux Laboratory &#187; InnoDB</title>
	<atom:link href="http://www.penglixun.com/tag/innodb/feed" rel="self" type="application/rss+xml" />
	<link>http://www.penglixun.com</link>
	<description>MySQL DBA &#38; Linux SA</description>
	<lastBuildDate>Sun, 22 Jan 2012 16:34:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>一个InnoDB性能超过Oracle的调优Case</title>
		<link>http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html</link>
		<comments>http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html#comments</comments>
		<pubDate>Sun, 22 Jan 2012 16:00:59 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[AIO]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[Kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Percona]]></category>
		<category><![CDATA[XtraDB]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1232</guid>
		<description><![CDATA[年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试，本想把MySQL调优到接近Oracle的性能即可，但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助（排名不分先后，仅按第一次... ]]></description>
			<content:encoded><![CDATA[<p>年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试，本想把MySQL调优到接近Oracle的性能即可，但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助（排名不分先后，仅按第一次为此CASE而骚扰的时间排序），不断修正方案，最终获得了比Oracle更好的性能，虽然是个特殊场景，但是我觉得意义是很广泛的，值得参考，遂记录于此。<br />
所有涉及表结构和具体业务模型的部分全部略去，也请勿咨询，不能透露，敬请谅解。</p>
<h2>一、测试模型：</h2>
<p>包含12张业务表，每个事务包含12个<acronym title="Structured Query Language">SQL</acronym>，每个<acronym title="Structured Query Language">SQL</acronym>向一张表做INSERT，做完12个<acronym title="Structured Query Language">SQL</acronym>即完成一个事务。</p>
<p>用一个C <acronym title="Application Programming Interface">API</acronym>编写的程序连接MySQL，不断执行如下操作</p>
<blockquote><p>开始事务：START TRANSACTION;<br />
每张表插入一行：INSERT INTO xxx VALUES (val1,val2,…); #一共12次<br />
提交事务：COMMIT;</p></blockquote>
<p>通过一个Shell脚本来启动32个测试程序并发测试</p>
<h2>二、测试环境：</h2>
<h3>1. 机型：</h3>
<p>R510<br />
CPU：Intel(R) Xeon(R) CPU E5645 @ 2.40GHz 双路24线程<br />
内存：6 * 8G 48G<br />
存储：FusionIO 320G MLC</p>
<p>R910<br />
CPU：Intel(R) Xeon(R) CPU E7530 @ 1.87GHz 四路48线程<br />
内存：32* 4G 128G<br />
存储：FusionIO 640G MLC</p>
<h3>2. Linux配置：</h3>
<p>单实例启动数据库：/boot/grub/menu.lst修改kernel启动参数增加numa=off<br />
多实例启动数据库：numactl &#8211;cpunodebind=$BIND_NO &#8211;localalloc $MYSQLD</p>
<p>RHEL 5.4 with 2.6.18内置内核<br />
RHEL 6.1 with 2.6.32淘宝版内核</p>
<p>fs.aio-max-nr = 1048576 #调整系统允许的最大异步IO队列长度<br />
vm.nr_hugepages = 18000 #大页页数<br />
vm.hugetlb_shm_group = 601 #允许使用大页的用户id，即mysql用户<br />
vm.swappiness = 0 #不倾向使用SWAP</p>
<h3>3. FusionIO配置：</h3>
<p>启动配置：<br />
/etc/modprobe.d/iomemory-vsl.conf<br />
options iomemory-vsl use_workqueue=0 # 忽略Linux IO调度<br />
options iomemory-vsl disable-msi=0 # 开启MSI中断<br />
options iomemory-vsl use_large_pcie_rx_buffer=1 # 打开PCIE缓冲<br />
options iomemory-vsl preallocate_memory=SN号 # 预分配管理内存</p>
<p>格式化配置：<br />
fio-format -b 4K /dev/fct0 # 格式化设备为4K匹配NAND芯片页大小<br />
mkfs.xfs -f -i attr=2 -l lazy-count=1,sectsize=4096 -b size=4096 -d sectsize=4096 -L data /dev/fioa # 调整XFS与FusionIO 4K页匹配，比较激进，需要更多稳定性测试认为这组参数充分安全</p>
<p>mount配置：<br />
/dev/fioa on /data type xfs (rw,noatime,nodiratime,noikeep,nobarrier,allocsize=100M,attr2,largeio,inode64,swalloc) # FusionIO的逻辑Block是100M，所以设为100M的预扩展</p>
<h3>4. MySQL版本和通用配置：</h3>
<p>Percona 5.1.60-13.1 原版<br />
Percona 5.1.60-13.1 修改版<br />
* 允许自定义InnoDB AIO队列申请长度 (5.5_change_aio_io_limit.patch)<br />
Percona 5.5.19-24.0 原版<br />
* 允许innodb_flush_neighbor_pages=2来合并真正相邻的脏页合并<br />
* Group Commit<br />
Percona 5.5.18-23.0 修改版<br />
* 允许自定义InnoDB AIO队列申请长度 (5.5_change_aio_io_limit.patch)<br />
* 允许预先扩展数据文件 (5.5_innodb_extent_tablespace.patch，@淘宝丁奇 贡献)<br />
* Group Cimmit</p>
<p>innodb_buffer_pool_size=20G<br />
sync_binlog=1<br />
innodb_flush_log_at_trx_commit=1</p>
<p>测试并发：32</p>
<h3>5. 修改补丁</h3>
<p>#cat 5.5_change_aio_io_limit.patch</p>

<div class="wp_codebox"><table><tr id="p12323"><td class="code" id="p1232code3"><pre class="cpp" style="font-family:monospace;"><span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">:</span><span style="color: #0000dd;">13</span><span style="color: #008080;">:</span><span style="color:#800080;">41.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">146</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">146</span>,<span style="color: #0000dd;">7</span> @@
 <span style="color: #0000ff;">static</span> ulong innobase_commit_concurrency <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">static</span> ulong innobase_read_io_threads<span style="color: #008080;">;</span>
 <span style="color: #0000ff;">static</span> ulong innobase_write_io_threads<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span><span style="color: #0000ff;">static</span> ulong innobase_aio_pending_ios_per_thread<span style="color: #008080;">;</span> <span style="color: #666666;">// Change AIO io_limit By P.Linux</span>
 <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">long</span> innobase_buffer_pool_instances <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #0000ff;">static</span> ulong innobase_page_size<span style="color: #008080;">;</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">2870</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">2871</span>,<span style="color: #0000dd;">7</span> @@
 	srv_n_file_io_threads <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_file_io_threads<span style="color: #008080;">;</span>
 	srv_n_read_io_threads <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_read_io_threads<span style="color: #008080;">;</span>
 	srv_n_write_io_threads <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_write_io_threads<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>	srv_n_aio_pending_ios_per_thread <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_aio_pending_ios_per_thread<span style="color: #008080;">;</span>
&nbsp;
 	srv_read_ahead <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span>
 	srv_adaptive_flushing_method <span style="color: #000040;">%</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">12282</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">12284</span>,<span style="color: #0000dd;">11</span> @@
   <span style="color: #FF0000;">&quot;Number of background write I/O threads in InnoDB.&quot;</span>,
   <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000dd;">4</span>, <span style="color: #0000dd;">1</span>, <span style="color: #0000dd;">64</span>, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #000040;">+</span><span style="color: #0000ff;">static</span> MYSQL_SYSVAR_ULONG<span style="color: #008000;">&#40;</span>aio_pending_ios_per_thread, innobase_aio_pending_ios_per_thread,
<span style="color: #000040;">+</span>  PLUGIN_VAR_RQCMDARG <span style="color: #000040;">|</span> PLUGIN_VAR_READONLY,
<span style="color: #000040;">+</span>  <span style="color: #FF0000;">&quot;Number of AIO pending IOS per-thread in InnoDB.&quot;</span>,
<span style="color: #000040;">+</span>  <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000dd;">4</span>, <span style="color: #0000dd;">32</span>, <span style="color: #0000dd;">4096</span>, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>
 <span style="color: #0000ff;">static</span> MYSQL_SYSVAR_LONG<span style="color: #008000;">&#40;</span>force_recovery, innobase_force_recovery,
   PLUGIN_VAR_RQCMDARG <span style="color: #000040;">|</span> PLUGIN_VAR_READONLY,
   <span style="color: #FF0000;">&quot;Helps to save your data in case the disk image of the database becomes corrupt.&quot;</span>,
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0srv.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0srv.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">:</span><span style="color: #0000dd;">23</span><span style="color: #008080;">:</span><span style="color:#800080;">35.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">242</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">242</span>,<span style="color: #0000dd;">7</span> @@
 UNIV_INTERN ulint	srv_n_file_io_threads	<span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span>
 UNIV_INTERN ulint	srv_n_read_io_threads	<span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span>
 UNIV_INTERN ulint	srv_n_write_io_threads	<span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>UNIV_INTERN ulint   srv_n_aio_pending_ios_per_thread <span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span> <span style="color: #666666;">// Change AIO io_limit By P.Linux</span>
&nbsp;
 <span style="color: #ff0000; font-style: italic;">/* Switch to enable random read ahead. */</span>
 UNIV_INTERN my_bool	srv_random_read_ahead	<span style="color: #000080;">=</span> FALSE<span style="color: #008080;">;</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0start.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0start.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">:</span><span style="color: #0000dd;">25</span><span style="color: #008080;">:</span><span style="color:#800080;">12.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">1475</span>,<span style="color: #0000dd;">14</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">1475</span>,<span style="color: #0000dd;">16</span> @@
&nbsp;
 	ut_a<span style="color: #008000;">&#40;</span>srv_n_file_io_threads</pre></td></tr></table></div>

<p>#cat 5.5_innodb_extent_tablespace.patch</p>

<div class="wp_codebox"><table><tr id="p12324"><td class="code" id="p1232code4"><pre class="cpp" style="font-family:monospace;"><span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>sql_yacc.<span style="color: #007788;">yy</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>sql_yacc.<span style="color: #007788;">yy</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">45</span><span style="color: #008080;">:</span><span style="color:#800080;">47.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">3878</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">3878</span>,<span style="color: #0000dd;">14</span> @@
           <span style="color: #008000;">&#123;</span> 
             Lex<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>alter_tablespace_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ts_alter_tablespace_type<span style="color: #000080;">=</span> ALTER_TABLESPACE_DROP_FILE<span style="color: #008080;">;</span> 
           <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>        <span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>        <span style="color: #000040;">|</span> tablespace_name
<span style="color: #000040;">+</span>          SET
<span style="color: #000040;">+</span>          opt_ts_extent_size
<span style="color: #000040;">+</span>          <span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>            Lex<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>alter_tablespace_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ts_alter_tablespace_type<span style="color: #000080;">=</span> ALTER_TABLESPACE_ALTER_FILE<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>          <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>        <span style="color: #ff0000; font-style: italic;">/* End */</span>
         <span style="color: #008080;">;</span>
&nbsp;
 logfile_group_info<span style="color: #008080;">:</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>handler.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>handler.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">29</span><span style="color: #008080;">:</span><span style="color:#800080;">17.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">501</span>,<span style="color: #0000dd;">7</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">501</span>,<span style="color: #0000dd;">8</span> @@
 <span style="color: #008000;">&#123;</span>
   TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED <span style="color: #000080;">=</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>,
   ALTER_TABLESPACE_ADD_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span>,
<span style="color: #000040;">-</span>  ALTER_TABLESPACE_DROP_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span>
<span style="color: #000040;">+</span>  ALTER_TABLESPACE_DROP_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span>,
<span style="color: #000040;">+</span>  ALTER_TABLESPACE_ALTER_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span> <span style="color: #666666;">// innodb_extent_tablespace By P.Linux</span>
 <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #0000ff;">enum</span> tablespace_access_mode
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>fil<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>fil<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">31</span><span style="color: #008080;">:</span><span style="color:#800080;">40.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">368</span>,<span style="color: #0000dd;">7</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">368</span>,<span style="color: #0000dd;">8</span> @@
 Checks <span style="color: #0000ff;">if</span> a single<span style="color: #000040;">-</span>table tablespace <span style="color: #0000ff;">for</span> a given table name exists in the
 tablespace memory cache.
 @<span style="color: #0000ff;">return</span>	space id, ULINT_UNDEFINED <span style="color: #0000ff;">if</span> not found <span style="color: #000040;">*/</span>
<span style="color: #000040;">-</span><span style="color: #0000ff;">static</span>
<span style="color: #000040;">+</span><span style="color: #666666;">//static</span>
<span style="color: #000040;">+</span>UNIV_INTERN <span style="color: #666666;">// innodb_extent_tablespace By P.Linux</span>
 ulint
 fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>
 <span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">4676</span>,<span style="color: #0000dd;">7</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">4677</span>,<span style="color: #0000dd;">8</span> @@
 Checks <span style="color: #0000ff;">if</span> a single<span style="color: #000040;">-</span>table tablespace <span style="color: #0000ff;">for</span> a given table name exists in the
 tablespace memory cache.
 @<span style="color: #0000ff;">return</span>	space id, ULINT_UNDEFINED <span style="color: #0000ff;">if</span> not found <span style="color: #000040;">*/</span>
<span style="color: #000040;">-</span><span style="color: #0000ff;">static</span>
<span style="color: #000040;">+</span><span style="color: #666666;">//static</span>
<span style="color: #000040;">+</span>UNIV_INTERN <span style="color: #666666;">// innodb_extent_tablespace By P.Linux</span>
 ulint
 fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>
 <span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">37</span><span style="color: #008080;">:</span><span style="color:#800080;">49.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">433</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">434</span>,<span style="color: #0000dd;">12</span> @@
 <span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
 	uint	flags<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/****************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
+Alter tablespace supported in an InnoDB table. Allow setting extent space. */</span>
<span style="color: #000040;">+</span><span style="color: #0000ff;">int</span> innobase_alter_tablespace<span style="color: #008000;">&#40;</span>handlerton <span style="color: #000040;">*</span>hton,
<span style="color: #000040;">+</span>                                THD<span style="color: #000040;">*</span> thd, st_alter_tablespace <span style="color: #000040;">*</span>alter_info<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>
 <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> innobase_hton_name<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;InnoDB&quot;</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #ff0000; font-style: italic;">/*************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
@@ -2489,6 +2496,7 @@
         innobase_hton-&amp;gt;flags=HTON_NO_FLAGS;
         innobase_hton-&amp;gt;release_temporary_latches=innobase_release_temporary_latches;
 	innobase_hton-&amp;gt;alter_table_flags = innobase_alter_table_flags;
+	innobase_hton-&amp;gt;alter_tablespace= innobase_alter_tablespace; // innodb_extent_tablespace By P.Linux
&nbsp;
 	ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
&nbsp;
@@ -3146,6 +3155,33 @@
 		| HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);
 }
&nbsp;
+/****************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
+Alter tablespace supported in an InnoDB table. Allow setting extent space. */</span>
<span style="color: #000040;">+</span><span style="color: #0000ff;">int</span> innobase_alter_tablespace<span style="color: #008000;">&#40;</span>handlerton <span style="color: #000040;">*</span>hton,
<span style="color: #000040;">+</span>                                THD<span style="color: #000040;">*</span> thd, st_alter_tablespace <span style="color: #000040;">*</span>alter_info<span style="color: #008000;">&#41;</span>
<span style="color: #000040;">+</span><span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ts_alter_tablespace_type <span style="color: #000040;">!</span><span style="color: #000080;">=</span> ALTER_TABLESPACE_ALTER_FILE<span style="color: #008000;">&#41;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>               <span style="color: #0000ff;">return</span> HA_ADMIN_NOT_IMPLEMENTED<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       ulint table_space<span style="color: #000080;">=</span> fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>tablespace_name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>table_space <span style="color: #000080;">==</span> ULINT_UNDEFINED<span style="color: #008000;">&#41;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>               my_error<span style="color: #008000;">&#40;</span>ER_WRONG_TABLE_NAME, MYF<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>, alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>tablespace_name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>               <span style="color: #0000ff;">return</span> EE_FILENOTFOUND<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       ulint extent_size<span style="color: #000080;">=</span> alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>extent_size<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       
<span style="color: #000040;">+</span>       ulint actual_size<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       fil_extend_space_to_desired_size<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>actual_size, table_space, extent_size<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span><span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>
 <span style="color: #ff0000; font-style: italic;">/*****************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
 Commits a transaction in an InnoDB database. */</span>
 <span style="color: #0000ff;">static</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>include<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>include<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">39</span><span style="color: #008080;">:</span><span style="color:#800080;">20.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">744</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">744</span>,<span style="color: #0000dd;">18</span> @@
 <span style="color: #ff0000; font-style: italic;">/*============================*/</span>
 	ulint		id<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>	<span style="color: #ff0000; font-style: italic;">/*!&amp;lt; in: space id */</span>
&nbsp;
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/*******************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
+Checks if a single-table tablespace for a given table name exists in the
+tablespace memory cache.
+@return        space id, ULINT_UNDEFINED if not found */</span>
<span style="color: #000040;">+</span>UNIV_INTERN
<span style="color: #000040;">+</span>ulint
<span style="color: #000040;">+</span>fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span>     name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>  <span style="color: #ff0000; font-style: italic;">/*!&amp;lt; in: table name in the standard
+                               'databasename/tablename' format */</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>
 <span style="color: #ff0000; font-style: italic;">/*************************************************************************
 Return local hash table informations. */</span></pre></td></tr></table></div>

<h2>三、测试结果：</h2>
<h3>1. R910 Oracle单实例</h3>
<p>测试人：童家旺，支付宝<br />
TPS：稳定值2000,峰值2600 （我没参与测试，也没有报告，无法确定详情）<br />
我的补充：Oracle已经是调优的过的，请相信我们的Oracle <acronym title="Database Administrator">DBA</acronym>不是吃素的。我把听Oracle <acronym title="Database Administrator">DBA</acronym>描述的只言碎语随便写下，Oracle跑到后面TPS也是有所下降，不是能一直100%稳定，最后CPU已经吃尽了，所以基本上再怎么优化提升的幅度会比较小。</p>
<h3>2. R910 MySQL单实例 Percona 5.1.59 原版</h3>
<p>测试人：帝俊，支付宝<br />
TPS：峰值1500，无法稳定（具体不祥）<br />
测试人描述：<br />
目前的测试数据显示，由于MySQL在checkpoint上处理跟不上，不足以持续支持1.5K/s的事务数，10MB/s的redo量下的交易创建。该负载下，FIO的写出速度为160～190MB/s，写IOPS为2～2.3k，测试FIO的写吞吐量可以到600MB/s，写IOPS有8K+，需要进一步研究如何进一步提升系统的吞吐量。</p>
<h3>3. R910 MySQL多实例 Percona 5.1.60-13.1原版</h3>
<p>测试人：彭立勋，B2B<br />
TPS：峰值500*4（无法稳定），谷值100，均值450＊4<br />
重要配置：<br />
innodb_page_size=4K # 修改数据页大小与FusionIO匹配<br />
innodb_log_block_size=4K # 修改日志页大小于FusionIO匹配<br />
innodb_log_file_size=1G<br />
innodb_log_files_in_group=3<br />
innodb_buffer_pool_size=20G<br />
innodb_max_dirty_pages_pct=75<br />
innodb_flush_method=ALL_O_DIRECT # 修改文件写入方式全部为O_DIRECT<br />
innodb_read_io_threads=2<br />
innodb_write_io_threads=10<br />
innodb_io_capacity=20000<br />
innodb_extra_rsegments=16<br />
innodb_use_purge_thread=4<br />
innodb_adaptive_flushing_method=3 # 采用Keep_average刷新方式<br />
innodb_flush_neighbor_pages=0 # 不为了凑顺序IO刷相邻未修改的页<br />
测试人描述：<br />
每颗物理CPU绑定一个MySQL实例，四个实例同时接受测试。可以看到在测试过程中，IOPS抖动很大，在4K～17K之间抖动，可以判定，是Checkpoint机制不完善导致刷新间歇性繁忙，在IO闲置的时候不能充分发挥性能。但多实例可以提升整体TPS接近Oracle的均值，说明MySQL内部可能某些常量设置不合理，或者锁定力度太粗导致单实例不能充分发挥单机性能。</p>
<h3>4. R910 MySQL多实例 Percona 5.1.60-13.1 修改版</h3>
<p>测试人：彭立勋，B2B<br />
TPS：峰值1200*4，谷值0，均值950*4<br />
重要配置：（在测试3的基础上）<br />
innodb_aio_pending_ios_per_thread=1024<br />
测试人描述：<br />
经过对测试3的分析，可以发现，InnoDB已经标记了很多Page到Flush_list，但是并没有被即时的回写，可以在INNODB_BUFFER_POOL_PAGES系统表中发现很页flush_type=2，即在Flush_list中。<br />
经过review代码，发现InnoDB申请的AIO队列的长度只有256，由常量OS_AIO_N_PENDING_IOS_PER_THREAD（os0file.h）定义。将此常量修改为InnoDB的参数后，重新测试，可以使FusionIO的IOPS达到7K～18K，IO利用率得以提升，整体性能已经超越Oracle，但存在严重的低谷，大约每10s一次。</p>
<h3>5.R510 MySQL单实例 Percona 5.5.18-23.0 修改版</h3>
<p>测试人：彭立勋,B2B<br />
TPS：峰值2800，谷值2300，均值2500<br />
重要配置：（在测试3的基础上）<br />
innodb_aio_pending_ios_per_thread=512<br />
alter tablespace `trade/xxx` set extent_size=5000000; # 预先扩展数据文件<br />
测试人描述：<br />
根据测试4的结果进行分析，需要解决的主要问题就是抖动，抖动可能是两个原因导致的，一个是Checkpoint机制不完善，一个是数据文件扩展。Checkpoint机制不完善这个暂时无法改进，只能先解决数据文件扩展上的问题，采用淘宝丁奇的方法，对MySQL增加预先扩展文件的功能，在测试前先将文件扩展至测试写满需要的大小，使测试过程中无需扩展文件。<br />
实例测试中发现非常有效，抖动范围在2300～2800之间，可以接受。但是Buffer Pool一旦脏页写满，为了控制脏页量InnoDB就会加大刷新量，影响到TPS。实际上在脏页未满的时候，IOPS就没有用完，但是InnoDB计算刷新量并没有考虑操作系统反馈的影响信息，只是根据自己的redo产生量计算。<br />
<a href="http://www.yupoo.com/photos/plinux/84222190/" title="R510_1"><img src="http://pic.yupoo.com/plinux/BGH3jg5X/medish.jpg" alt="R510_1" width="533" height="462" border="0" /></a><br />
同时观察CPU还发现，2.6.18内核会将所有软中断发送到Core0上处理，这可能也是瓶颈之一。（当时忘记拷贝状态，这是后来确认内核问题看得，可以看这篇文章，一样的，<a href="http://dbahacker.com/linux/cpu%E8%BD%AF%E4%B8%AD%E6%96%AD%E5%AE%9E%E8%B7%B5%E4%B8%80" title="CPU软中断实践" target="_blank">CPU软中断实践</a>）<br />
03:05:17 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s<br />
03:05:18 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 1014.00<br />
03:05:18 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 1000.00</p>
<h3>6. R510 MySQL单实例 Percona 5.5.19-24.0 原版</h3>
<p>测试人：彭立勋，B2B<br />
TPS：峰值3100，谷值2400，均值2700<br />
重要配置：（在测试3的基础上）<br />
替换内核版本为2.6.32淘宝版，使用IO中断负载均衡。<br />
innodb_adaptive_flushing_method = 2<br />
innodb_flush_neighbor_pages = cont<br />
测试人描述：<br />
采用淘宝版内核后，可以发现每个CPU都被用的比较满：(部分)<br />
06:27:26 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle<br />
06:27:27 PM  all   69.80    0.00   18.68    0.51    0.00    0.17    0.00    0.00   10.84<br />
06:27:27 PM    0   74.75    0.00   17.17    0.00    0.00    0.00    0.00    0.00    8.08<br />
06:27:27 PM    1   73.96    0.00   16.67    1.04    0.00    0.00    0.00    0.00    8.33<br />
06:27:27 PM    2   73.20    0.00   17.53    1.03    0.00    0.00    0.00    0.00    8.25<br />
06:27:27 PM    3   71.72    0.00   19.19    1.01    0.00    0.00    0.00    0.00    8.08<br />
06:27:27 PM    4   71.43    0.00   18.37    1.02    0.00    0.00    0.00    0.00    9.18<br />
06:27:27 PM    5   70.71    0.00   19.19    1.01    0.00    0.00    0.00    0.00    9.09</p>
<p>这是个好现象，说明CPU被充分用起来了，在脏页未满之前，TPS可以比较稳定的维持在3000以上。但还是老问题，脏页一满，速度就下降，到测试结束时下降为2400。<br />
<a href="http://www.yupoo.com/photos/plinux/84222191/" title="R510_2"><img src="http://pic.yupoo.com/plinux/BGH3jipn/q6QVk.jpg" alt="R510_2" width="530" height="372" border="0" /></a></p>
<h2>四、测试结论：</h2>
<p>MySQL的调优与操作系统结合非常紧密，需要整体联动才能获得好的效果，InnoDB琐粒度较粗的缺陷，在代码实现简单的情况下，实际上对并发的影响不是很明显。<br />
目前MySQL对高速硬件的利用主要缺陷是，不少常量写死，Checkpoint机制不完善，Checkpoint刷新脏页&#8211;&gt;InnoDB AIO队列&#8211;&gt;操作系统IO队列&#8211;&gt;存储设备，中间任何一环存在问题，都可能导致性能下降。<br />
InnoDB AIO队列可以通过补丁开放参数设置，这个瓶颈已经消除。<br />
操作系统IO队列可以通过淘宝的内核补丁将中断分散到每个核上处理来解决。<br />
目前存在最大的问题就是Checkpoint刷新脏页的机制，仅仅依赖redo产生的速度，其实硬件IO还有很多余量，但InnoDB并不知道。<br />
如果能限定一种机型，限定一种操作系统，在MySQL内获取操作系统报告的硬件状态，自适应的决策自己的行为，这样可以充分利用系统资源，例如IO util%并不高的时候，即使脏页还没到阈值，也可以加大刷新量，充分利用IO，这样可能系统根本就达不到脏页阈值，可以一直保持搞TPS，至少可以延缓TPS下降的趋势。<br />
抖动问题则是Oracle和MySQL都存在的问题，扩展数据文件的瞬间必然导致TPS下降，淘宝丁奇的方法可以完美解决，Oracle也是类似的方法通过预先分配表空间文件解决。</p>
<h2>五、测试缺陷：</h2>
<p>测试CASE不全，没有在R910上测试5.5（虽然已经超了Oracle，但R910上应该还能猛一点），没有测试5.5多实例下可以获得何种性能，没有测试5.1在2.6.32内核下的表现，没有测试不同的页大小对InnoDB的影响。<br />
没有稳定性测试，原版+多实例 属于稳定方案，其他改动是否100%不影响稳定，尚需测试。<br />
在R910上的测试没有监控系统，也就没有图，坑爹了。</p>
<h2>六、后续Action</h2>
<p>在InnoDB控制刷赃页量的地方加入对系统diskstat的监控，当系统IO util%<80%的时候，增加(IO_CAPACITY-当前系统IO数-redo计算的刷新量)个页的刷新，在系统不忙的时候提前加大刷新量，期望保持TPS稳定。</p>
<h2>七、随意补充</h2>
<p>为什么读为主的应用不用担心IO用不完？因为读操作是同步IO，一旦请求就被发送到磁盘，所以只要并发够多，总能把IO压爆。但是写为了加速，几乎所有数据库都是先写到内存，再异步写到磁盘，当然你要是搞最大保护模式，应该也是有数据库可以直接同步写磁盘的，但是对大部分数据库都是先写内存，再异步到磁盘，所以如果异步IO这里存在设计上的瓶颈，不管加多少并发，都是徒劳，内存一旦写满，链接线程就都堵住了，要等异步IO消化完才能继续，所以对于写为主的应用，这个CASE都是很有参考价值的。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2010年12月6日 -- <a href="http://www.penglixun.com/tech/database/percona_vs_mysql.html" title="Percona对MySQL标准版本的改进">Percona对MySQL标准版本的改进</a> (3)</li><li>2010年01月14日 -- <a href="http://www.penglixun.com/tech/database/xtradb_compile_error.html" title="XtraDB 1.0.6-9编译错误的解决">XtraDB 1.0.6-9编译错误的解决</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>在Server层实现Kill Idle Transaction</title>
		<link>http://www.penglixun.com/tech/database/server_kill_idle_transaction.html</link>
		<comments>http://www.penglixun.com/tech/database/server_kill_idle_transaction.html#comments</comments>
		<pubDate>Fri, 23 Dec 2011 12:43:22 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[kill_idle_transaction]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[Percona]]></category>
		<category><![CDATA[XtraDB]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1230</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/server_kill_idle_transaction.html 在上一篇文章里我们写了如... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/server_kill_idle_transaction.html </p>
<p></span>在上一篇文章里我们写了如何针对InnoDB清理空闲事务《<a title="如何杀掉空闲事务" href="http://www.penglixun.com/tech/database/how_to_kill_idle_trx.html" target="_blank">如何杀掉空闲事务</a>》，在@sleebin9 的提示下，这个功能不仅可以针对InnoDB，也可以用于所有MySQL的事务引擎。</p>
<p>如何在Server层实现呢，sql/sql_parse.cc的do_command()函数是个好函数，连接线程会循环调用do_command()来读取并执行命令，在do_command()函数中，会调用my_net_set_read_timeout(net, thd->variables.net_wait_timeout)来设置线程socket连接超时时间，于是在这里可以下手。<br />
主要代码：</p>

<div class="wp_codebox"><table><tr id="p12307"><td class="code" id="p1230code7"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000dd;">830</span>   <span style="color: #ff0000; font-style: italic;">/*
 831     This thread will do a blocking read from the client which
 832     will be interrupted when the next command is received from
 833     the client, the connection is closed or &quot;net_wait_timeout&quot;
 834     number of seconds has passed
 835   */</span>
 <span style="color: #0000dd;">836</span>   <span style="color: #ff0000; font-style: italic;">/* Add For Kill Idle Transaction By P.Linux */</span>
 <span style="color: #0000dd;">837</span>   <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>active_transaction<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
 <span style="color: #0000dd;">838</span>   <span style="color: #008000;">&#123;</span>
 <span style="color: #0000dd;">839</span>     <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">trx_idle_timeout</span> <span style="color: #000080;">&gt;</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
 <span style="color: #0000dd;">840</span>     <span style="color: #008000;">&#123;</span>
 <span style="color: #0000dd;">841</span>       my_net_set_read_timeout<span style="color: #008000;">&#40;</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">trx_idle_timeout</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000dd;">842</span>     <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">trx_readonly_idle_timeout</span> <span style="color: #000080;">&gt;</span> <span style="color: #0000dd;">0</span> <span style="color: #000040;">&amp;&amp;</span> thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>is_readonly_trx<span style="color: #008000;">&#41;</span>
 <span style="color: #0000dd;">843</span>     <span style="color: #008000;">&#123;</span>
 <span style="color: #0000dd;">844</span>       my_net_set_read_timeout<span style="color: #008000;">&#40;</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">trx_readonly_idle_timeout</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000dd;">845</span>     <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">trx_changes_idle_timeout</span> <span style="color: #000080;">&gt;</span> <span style="color: #0000dd;">0</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">!</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>is_readonly_trx<span style="color: #008000;">&#41;</span>
 <span style="color: #0000dd;">846</span>     <span style="color: #008000;">&#123;</span>
 <span style="color: #0000dd;">847</span>       my_net_set_read_timeout<span style="color: #008000;">&#40;</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">trx_changes_idle_timeout</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000dd;">848</span>     <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
 <span style="color: #0000dd;">849</span>       my_net_set_read_timeout<span style="color: #008000;">&#40;</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">net_wait_timeout</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000dd;">850</span>     <span style="color: #008000;">&#125;</span>
 <span style="color: #0000dd;">851</span>   <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
 <span style="color: #0000dd;">852</span>     my_net_set_read_timeout<span style="color: #008000;">&#40;</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>variables.<span style="color: #007788;">net_wait_timeout</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000dd;">853</span>   <span style="color: #008000;">&#125;</span>
 <span style="color: #0000dd;">854</span>   <span style="color: #ff0000; font-style: italic;">/* End */</span></pre></td></tr></table></div>

<p>大家看明白了吗？其实这是偷梁换柱，本来在这里是要设置wait_timeout的，先判断线程是不是在事务里，就可以转而实现空闲事务的超时。</p>
<blockquote><p>    trx_idle_timeout 控制所有事务的超时，优先级最高<br />
    trx_changes_idle_timeout 控制非只读事务的超时<br />
    trx_readonly_idle_timeout 控制只读事务的超时</p></blockquote>
<p>效果：</p>

<div class="wp_codebox"><table><tr id="p12308"><td class="code" id="p1230code8"><pre class="sql" style="font-family:monospace;">root@localhost : <span style="color: #66cc66;">&#40;</span>none<span style="color: #66cc66;">&#41;</span> 08:<span style="color: #cc66cc;">39</span>:<span style="color: #cc66cc;">49</span><span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">set</span> autocommit <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span> ;
Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
root@localhost : <span style="color: #66cc66;">&#40;</span>none<span style="color: #66cc66;">&#41;</span> 08:<span style="color: #cc66cc;">39</span>:<span style="color: #cc66cc;">56</span><span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">set</span> trx_idle_timeout <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">5</span>;
Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
root@localhost : <span style="color: #66cc66;">&#40;</span>none<span style="color: #66cc66;">&#41;</span> 08:<span style="color: #cc66cc;">40</span>:<span style="color: #cc66cc;">17</span><span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">use</span> perf 
<span style="color: #993333; font-weight: bold;">Database</span> changed
root@localhost : perf 08:<span style="color: #cc66cc;">40</span>:<span style="color: #cc66cc;">19</span><span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">insert</span> <span style="color: #993333; font-weight: bold;">into</span> perf <span style="color: #66cc66;">&#40;</span>info <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">values</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'11'</span><span style="color: #66cc66;">&#41;</span>;
Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span> row affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
root@localhost : perf 08:<span style="color: #cc66cc;">40</span>:<span style="color: #cc66cc;">26</span><span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">select</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">from</span> perf;
ERROR <span style="color: #cc66cc;">2006</span> <span style="color: #66cc66;">&#40;</span>HY000<span style="color: #66cc66;">&#41;</span>: MySQL server has gone away
No connection<span style="color: #66cc66;">.</span> Trying <span style="color: #993333; font-weight: bold;">to</span> reconnect<span style="color: #66cc66;">...</span>
Connection id:    <span style="color: #cc66cc;">6</span>
Current <span style="color: #993333; font-weight: bold;">database</span>: perf
&nbsp;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+</span>
<span style="color: #66cc66;">|</span> id <span style="color: #66cc66;">|</span> info <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+</span>
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">7</span> <span style="color: #66cc66;">|</span> aaaa <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">9</span> <span style="color: #66cc66;">|</span> aaaa <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">|</span> aaaa <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+</span>
<span style="color: #cc66cc;">3</span> rows <span style="color: #993333; font-weight: bold;">in</span> <span style="color: #993333; font-weight: bold;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>完整的patch这里下载：<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年12月6日 -- <a href="http://www.penglixun.com/tech/database/percona_vs_mysql.html" title="Percona对MySQL标准版本的改进">Percona对MySQL标准版本的改进</a> (3)</li><li>2010年01月14日 -- <a href="http://www.penglixun.com/tech/database/xtradb_compile_error.html" title="XtraDB 1.0.6-9编译错误的解决">XtraDB 1.0.6-9编译错误的解决</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/server_kill_idle_transaction.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性</title>
		<link>http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html</link>
		<comments>http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html#comments</comments>
		<pubDate>Thu, 27 Jan 2011 07:57:30 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1191</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html 原文地址：http://blogs... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html </p>
<p></span>原文地址：<a href="http://blogs.innodb.com/wp/2009/03/plug-in-for-performance-and-scalability/">http://blogs.innodb.com/wp/2009/03/plug-in-for-performance-and-scalability/</a></p>
<p>Why should you care about             the latest “early adopter” release of the InnoDB Plugin,             version 1.0.3?   One word: <strong>performance!</strong> The release             introduces these features:<br />
<strong>为什么你应该关注最近的InnoDB Plugin 1.0.3版？一个词：性能！这个版本包括了这些特性</strong></p>
<ul>
<li>Enhanced concurrency               &amp; scalability: the “Google SMP patch” using atomic               instructions for mutexing</li>
<li><strong>增强的并发可可伸缩性：”Google                 多处理机 补丁” 为Mutext锁操作使用原子操作</strong></li>
<li>More efficient memory               allocation: ability to use more scalable platform memory               allocator</li>
<li><strong>更有效的内存分配：可以使用更多的可扩展内存                 分配器（例如tcmalloc）</strong></li>
<li>Improved out-of-the-box               scalability: unlimited concurrent thread execution by               default</li>
<li><strong>改进的即装即用扩展性：默认无限制的线程并发</strong></li>
<li>Dynamic tuning: at               run-time, enable or disable insert buffering and adaptive               hash indexing</li>
<li><strong>动态优化调整：在运行时，打开或者关闭插入缓                 存和自适应哈希索引</strong></li>
</ul>
<p>These new performance             features can yield <strong>up               to twice the throughput</strong> or more, depending             on your workload, platform and other tuning considerations.             In another post, we explore some details about these             changes, but first, what do these enhancements mean for             performance and scalability?<br />
<strong>这些新的性能特新可以提升多大两倍甚至更多的的吞吐量，这依赖于你的负载，平台和其他调整事项。在另一篇文章中，我们会探               讨这些改变的一些细节，但首先，我们现探讨这些性能和可扩展性的增强是什么意思，包括哪些内容</strong></p>
<p>In brief, we’ve tested             three different workloads (joins, DBT2 OLTP and a modified             sysbench) using a memory-resident database. In all cases,             the InnoDB Plugin scales significantly better than the             built-in InnoDB in MySQL 5.1. And in some cases, the             absolute level of performance is dramatically higher too!             The charts below illustrate the kinds of performance gains             we’ve measured with release 1.0.3 of the InnoDB Plugin. Your             mileage may vary, of course. See the <a href="http://www.innodb.com/wp/innodb_plugin/plugin-performance">InnoDB website</a> for all the details             on these tests.<br />
<strong>总之，我们已经使用内存驻留数据库（所有数据都载入在内存中）测试了三种不同的工作负载（关联，DBT2               OLTP和修改过的sysbench）。在所有的情况下，InnoDB Plugin的伸缩性明显优于MySQL               5.1内置的InnoDB。在一些场景中，性能提升的水平高的惊人。下面的图说明了InnoDB Plugin               1.0.3的性能提升。你的测试结果可能不同，当然可以在InnoDB网站看到所有测试的细节。</strong></p>
<p>This release of the InnoDB             Plugin incorporates a <a href="http://code.google.com/p/google-mysql-tools/wiki/SmpPerformance" target="new">patch               made by Ben Handy and Mark Callaghan at Google</a> to improve             multi-core scalability by using more efficient             synchronization methods (mutexing and rw-locks) to reduce             cpu utilization and contention. We’re grateful for this             contribution, and you will be too!<br />
<strong>这个InnoDB Plugin版本包含了Google的Ben Handy和Mark               Callaghan的补丁来提升多处理机扩展性，包括使用了更有效的同步机制（Mutexing和RW-Locks）来减少CPU利用和竞争。我们非常感               谢这个补丁的贡献，相信你也是。</strong></p>
<p>Now to our test results …<br />
<strong>现在来看我们的测试结果</strong>&#8230;</p>
<p><strong>Joins: </strong>The             following chart shows the performance gains in performing             joins, comparing the built-in InnoDB in MySQL (in blue) with the             InnoDB Plugin 1.0.3 (in red).<br />
<strong>关联：下图展示了执行Join操作时的性能提升，内置InnoDB（蓝）和InnoDB Plugin               1.0.3（红）的比较。</strong></p>
<div><a href="http://www.penglixun.com/wp-content/uploads/2011/01/1.png"><img class="alignnone size-full wp-image-1192" title="Case 1" src="http://www.penglixun.com/wp-content/uploads/2011/01/1.png" alt="" width="450" height="320" /></a></div>
<p>As you can see from the             blue bars in the above chart, with MySQL 5.1 using the             built-in InnoDB, the total number of joins the system can             execute declines as the number of concurrent users             increases. In contrast, the InnoDB Plugin slightly improves             performance even with one user, and maintains performance as             the number of users rises. This performance improvement is             due in large part to the use of atomics for mutexing in the             InnoDB Plugin.<br />
<strong>正如你在上面蓝柱上看到的，MySQL               5.1的内置InnoDB，随着并发数的增加系统的执行速度反而下降了。与此相反，InnoDB               Plugin随着并发的提升处理速度甚至略有提高，并且随着用户的增长保持着这种性能。这个性能改善很大程度上是因为对Mutexing使用了原子操作。</strong></p>
<p><strong>Transaction               Processing (DBT2):</strong> The following chart             illustrates a scalability improvement using the OLTP             read/write DBT2 benchmark, again comparing the performance             of the built-in               InnoDB in MySQL with             the performance of InnoDB Plugin               1.0.3.<br />
<strong>事务处理（DBT2）：下入展示了用DBT2测试OLTP读写性能的提升，再次比较了内置InnoDB和InnoDB               Plugin 1.0.3的性能。</strong></p>
<div><a href="http://www.penglixun.com/wp-content/uploads/2011/01/2.png"><img class="alignnone size-full wp-image-1193" title="2" src="http://www.penglixun.com/wp-content/uploads/2011/01/2.png" alt="" width="606" height="320" /></a></div>
<p>Here, the InnoDB Plugin             scales better than the built-in InnoDB from 16 to 32 users             and produces about 12% more throughput with 64 concurrent             users, as other bottlenecks are encountered or system             capacity is reached. This improvement is likewise due             primarily to the changes in mutexing.<br />
<strong>这里，InnoDB               Plugin伸缩性在16增加到32线程时表现更好，产生比64线程多大约12%的吞吐量。由于其他性能瓶颈或系统容量达到基线。这个提升依然主要依赖于               Mutexing的改变。</strong></p>
<p><strong>Modified Sysbench:</strong> This test uses a             version of the well-known sysbench workload, modified to             include queries based on a secondary index, <a href="http://mysqlha.blogspot.com/2009/02/update-for-sysbench.html">as suggested</a> by Mark Callaghan of             Google.<br />
<strong>修改过的sysbench：这个测试使用了著名的sysbench，修改包括基于非主键索引的查询，由Google的               Mark Callaghan建议。</strong></p>
<div><a href="http://www.penglixun.com/wp-content/uploads/2011/01/3.png"><img class="alignnone size-full wp-image-1194" title="3" src="http://www.penglixun.com/wp-content/uploads/2011/01/3.png" alt="" width="450" height="320" /></a></div>
<p>This time, the InnoDB             Plugin shows significantly better scalability from 8 to 64             users than the built-in InnoDB in MySQL, yielding as much as             60% more throughput at 64 users. Like the previous examples,             this improvement is largely due to the use of atomics for             mutexing.<br />
<strong>这次，InnoDB               Plugin在8~64线程都展示了明显优于内置InnoDB的可伸缩性。在64并发时多大60%的性能提升！像前一个例子，这个提升依然主要靠               Mutexing的原子性。</strong></p>
<p><strong>Modified Sysbench               with tcmalloc:</strong> This             test uses the same modified sysbench workload, but shows the             difference between the built-in InnoDB (which uses the             internal InnoDB memory allocator) and the InnoDB Plugin when             using a more scalable memory allocator, in this case <a href="http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html">tcmalloc</a>.<br />
<strong>使用tcmalloc的修改过的sysbench：这种测试使用相同的sysbench场景，但是不同于内置InnoDB               的是InnoDB Plugin使用了tcmalloc作为内存分配器。</strong></p>
<div><a href="http://www.penglixun.com/wp-content/uploads/2011/01/4.png"><img class="alignnone size-full wp-image-1195" title="4" src="http://www.penglixun.com/wp-content/uploads/2011/01/4.png" alt="" width="450" height="320" /></a></div>
<p>When the new configuration             parameter <code>innodb_use_sys_malloc</code> is set to enable use             of the memory allocator tcmalloc, the InnoDB Plugin really             shines! Transaction throughput continues to scale, and the             actual throughput with 64 users has nearly doubled!<br />
<strong>当设置innodb_user_sys_malloc变量为tcmalloc作为内存分配器时，InnoDB               Plugin依然是亮点！事务吞吐量继续扩展，在64并发时吞吐量提升接近1倍（相对没有tcmalloc的）。</strong></p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2011年01月19日 -- <a href="http://www.penglixun.com/tech/database/mysql_some_tips_part_1.html" title="MySQL小技巧问答(一)">MySQL小技巧问答(一)</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL小技巧问答(一)</title>
		<link>http://www.penglixun.com/tech/database/mysql_some_tips_part_1.html</link>
		<comments>http://www.penglixun.com/tech/database/mysql_some_tips_part_1.html#comments</comments>
		<pubDate>Tue, 18 Jan 2011 21:01:02 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1189</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/mysql_some_tips_part_1.html 抽空总结一下自己操作MySQL的一些... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/mysql_some_tips_part_1.html </p>
<p></span>抽空总结一下自己操作MySQL的一些心得体会，做成MySQL小技巧问答系列，给大家作为一些案例参考，也为我自己做一些记录：</p>
<p><strong>1. 在基于ROW的双Master复制下，如何快速大批量订正？</strong><br />
在A&lt;-&gt;B的双Master结构下，假设只有一台提供服务，这是我们常用的架构，需要大批量订正数据，如何做最快？用存储过程一批批提交？这有很多的限制，有时候并不可以把一条或多条<acronym title="Structured Query Language">SQL</acronym>拆成几段，怎么办呢？binlog不是很好的工具嘛?! ROW格式的binlog，Slave在应用时是直接使用Handler <acronym title="Application Programming Interface">API</acronym>，并没有走<acronym title="Structured Query Language">SQL</acronym>解析，速度非常快，基本上是IO操作了，那么我们可以在备库上直接执行订正<acronym title="Structured Query Language">SQL</acronym>，产生的ROW binlog传到主机，就会很快订正完，基本上都比写存储过程快。</p>
<p><strong>2. ROW格式Replication如何实现不带库名的replicate-do-db？</strong><br />
虽然MySQL有replicate-do-db这个参数，但是在ROW格式的binlog下必须使用”db.table”的方式才能生效，USE对ROW格式是无效的。现在我有一个Instance，只需要复制Master的某几个库，但是是ROW格式，<acronym title="Structured Query Language">SQL</acronym>都没有使用db前缀，怎么办？可以这么做，把主库需要的库导出来，不需要的库导出结构即可，在Slave导入这些数据及结构，配置skip-slave-errors=all，这样Master复制过来的binlog，只要发现有库有表结构，就不会报找不到表，就不会阻塞复制，但是UPDATE/DELETE过来没有数据也会被跳过错误，间接的实现了replicate-do-db。</p>
<p><strong>3. 大批量乱序数据导入InnoDB很慢如何解决？</strong><br />
InnoDB因为主键聚集索引的关系，如果没有主键或者主键非序列的情况下，导入会越来越慢，如何快速的迁移数据到InnoDB？借助MyISAM的力量是很靠谱的，先关闭InnoDB的Buffer Pool，把内存空出来，建一张没有任何索引的MyISAM表，然后只管插入吧，concurrent_insert=2，在文件末尾并发插入，速度刚刚的，插入完成后，ALTER TABLE把索引加上，记得还有ENGINE=InnoDB，就把MyISAM转到InnoDB了，这样的速度远比直接往InnoDB里插乱序数据来得快。</p>
<p><strong>4. A&lt;&#8211;&gt;B&#8211;&gt;C&#8211;&gt;D结构切换到A&lt;&#8211;&gt;B, C&lt;&#8211;&gt;D结构出现Slave_lag一直增常如何避免？</strong><br />
这种情况常见与一个双Master集群分离出一套双Master集群，例如从原集群分离一部分库。过快的切换B&#8211;&gt;C到C&lt;&#8211;&gt;D容易导致主备出现slave_lag，并且一直增长，原因在于A&lt;&#8211;&gt;B集群产生的<acronym title="Structured Query Language">SQL</acronym>，随同server_id带到了C&#8211;&gt;D这个M-S中，当A,B产生的<acronym title="Structured Query Language">SQL</acronym>在C,D还没消化完成就CHANGE MASTER为C&lt;&#8211;&gt;D时，会导致这写<acronym title="Structured Query Language">SQL</acronym>在C,D之间来回传输，因为C,D都认为这个<acronym title="Structured Query Language">SQL</acronym>不是自己产生的，因而不销毁，自己执行后写入binlog，于是Slave_Lag就一直增长。<br />
避免的方法很简单，部分写切到C后，先断开B&#8211;&gt;C的复制，等一会，看D上已经没有Slave_Lag了，再CHANGE MASTER为C&lt;&#8211;&gt;D，这样A,B传过来的<acronym title="Structured Query Language">SQL</acronym>都消化完了。</p>
<p><strong>5. 表中存在很多重复数据时，如何删除这些重复数据最快？</strong><br />
在需要给表中某些字段加唯一索引时，而字段中又存在需要重复清理数据的问题，不少<acronym title="Database Administrator">DBA</acronym>都应该遇到过。一般在处理时总是想在数据库中只保留一条，其他的删除，但是这样的<acronym title="Structured Query Language">SQL</acronym>写出来总是效率不高，怎么办？其实可以转换思路，把重复的都选出一条出来，存到一张临时表，然后删除原表中所有存在重复的，再把临时表的数据库全部插入原库，这是比较通用并且高效的做法。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2011年01月27日 -- <a href="http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html" title="[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性">[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/mysql_some_tips_part_1.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PostgreSQL和MySQL的对比，第1部分：表组织</title>
		<link>http://www.penglixun.com/tech/database/mysql-vs-postgresql-part-1-table-organization.html</link>
		<comments>http://www.penglixun.com/tech/database/mysql-vs-postgresql-part-1-table-organization.html#comments</comments>
		<pubDate>Mon, 27 Dec 2010 12:36:04 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1181</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/mysql-vs-postgresql-part-1-table-organization.html 翻译自：http://bl... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/mysql-vs-postgresql-part-1-table-organization.html </p>
<p></span>翻译自：http://blogs.enterprisedb.com/2010/11/29/mysql-vs-postgresql-part-1-table-organization/<br />
翻译不正确之处请指正。</p>
<p>I&#8217;m going to be starting an occasional series of blog postings comparing MySQL&#8217;s architecture to PostgreSQL&#8217;s architecture.  Regular readers of this blog will already be aware that I know PostgreSQL far better than MySQL, having last used MySQL a very long time ago when both products were far less mature than they are today.  So, my discussion of how PostgreSQL works will be based on first-hand knowledge, but discussion of how MySQL works will be based on research and – insofar as I&#8217;m can make it happen – discussion with people who know it better than I do.  (Note: If you&#8217;re a person who knows MySQL better than I do and would like to help me avoid making stupid mistakes, drop me an email.)<br />
我将要开始一个比较MySQL和PostgreSQL架构系列的博客。本博客的长期读者都已经知道，我最后一次使用MySQL是在很久很久以前两款产品都远不如今天的时候，所以我认为PostgreSQL远好于MySQL。因此，我讨论PostgreSQL如何工作是基于第一手资料，而对于MySQL则是基于很久以前的情况，看博客的同学有很多比我更了解MySQL。如果你是一个比我更了解MySQL的人，发现了我愚蠢的错误请给我一个邮件。</p>
<p>In writing these posts, I&#8217;m going to try to avoid making value judgments about which system is “better”, and instead focus on describing how the architecture differs, and maybe a bit about the advantages of each architecture.  I can&#8217;t promise that it will be entirely unbiased (after all, I am a PostgreSQL committer, not a MySQL committer!) but I&#8217;m going to try to make it as unbiased as I can.  Also, bearing in mind what I&#8217;ve recently been told by Baron Schwartz and Rob Wultsch, I&#8217;m going to focus completely on InnoDB and ignore MyISAM and all other storage engines.  Finally, I&#8217;m going to focus on architectural differences.  People might choose to use PostgreSQL because they hate Oracle, or MySQL because it&#8217;s easier to find hosting, or either product because they know it better, and that&#8217;s totally legitimate and perhaps worth talking about, but – partly in the interests of harmony among communities that ought to be allies – it&#8217;s not what I&#8217;m going to talk about here.<br />
写这些文章，我要尽量避免作出哪个系统更好的判断，而是侧重于介绍他们架构的不同，也许是一些各种架构的优势。我不能保证这些观点是完全不带偏见的（毕竟，我是一个PostgreSQL代码的提交者，而不是MySQL的提交者），但是我会尽量做到不偏重某一个。此外，考虑到我最近已经跟Baron Schwartz和Rob Wultsch说的内容，我将完全忽略MyISAM和所有其他存储引擎，而重点关注InnoDB。最后，我将专注于架构的差异。人们有时选择使用PostgreSQL是因为他们恨甲骨文，或者选择MySQL因为它更容易找到托管服务，或其他一些产品因为他们知道它更好，并且这是完全符合授权的。这些但这不是我想要谈的。（译者注：最后一段话太绕口，翻译不了，只翻译大意）</p>
<p>So, all that having been said, what I&#8217;d like to talk about in this post is the way that MySQL and PostgreSQL store tables and indexes on disk.  In PostgreSQL, table data and index data are stored in completely separate structures.  When a new row is inserted, or when an existing row is updated, the new row is stored in any convenient place in the table.  In the case of an update, we try to store the new row on the same page as the old row if there&#8217;s room; if there isn&#8217;t room or if it&#8217;s an insert, we pick a page that has adequate free space and use that, or failing all else extend the table by one page and add the new row there.  Once the table row is added, we cycle through all the indexes defined for the table and add an index entry to each one pointing at the physical position of the table row.  One index may happen to be the primary key, but that&#8217;s a fairly nominal distinction – all indexes are basically the same.<br />
因此，我将说的内容是，MySQL和PostgreSQL的表和索引存储在磁盘上的方式。在 PostgreSQL，表数据和索引数据是完全分开存储的。当新行插入，或现有的行被更新，新行是表中的任何方便保存的地方保存。在更新的场景下，我们尝试在页内还有空间的情况下存储新行与旧行在同一个页上。如果没有空间，或者如果它是一个插入操作，我们将选择一个有足够空闲空间的页，使用它，或者扩展一个新页把新行放入。我们轮训表上定义的所有索引，并添加一个索引项指针指向表中新行的物理位置。这个索引也许是主键，也许是一般的索引，但是所有的所有索引都是基于一样的操作。</p>
<p>Under MySQL&#8217;s InnoDB, the table data and the primary key index are stored in the same data structure.  As I understand it, this is what Oracle calls an index-organized table.  Any additional (”secondary”) indexes refer to the primary key value of the tuple to which they point, not the physical position, which can change as leaf pages in the primary key index are split.  Since this architecture requires every table to have a primary key, an internal row ID field is used as the primary key if no explicit primary key is specified.<br />
在InnoDB中，表数据和主键索引是存在同样的数据结构中（译者注：主键聚集索引）。据我的理解，这就像Oracle的索引组织表（译者注：还是有一些区别，索引组织表完全按索引排序，但是InnoDB只按主键排序）。任何非主键索引指向主键索引的位置，而不是物理位置，所以主键索引页的页节点分裂不会导致数据改变。由于这种架构要求每个表都有一个主键，所以如果没有定义主键内部将隐含定义一个主键（译者注，内部定义的主键为6字节）。</p>
<p>Since Oracle supports both options, they are probably both useful.  An index-organized table seems particularly likely to be useful when most lookups are by primary key, and most of the data in each row is part of the primary key anyway, either because the primary key columns are long compared with the remaining columns, or because the rows, overall, are short.  Storing the whole row in the index avoids storing the same data twice (once in the index and once in the table), and the gain will be larger when the primary key is a substantial percentage of the total data.  Furthermore, in this situation, the index page still holds as many, or almost as many, keys as it would if only a pointer were stored in lieu of the whole row, so one fewer random I/Os will be needed to access a given row.<br />
由于Oracle支持两种选择（索引组织表和堆表），他们可能都非常有用。一个索引组织表似乎在多数<acronym title="Structured Query Language">SQL</acronym>是通过主键查找，以及每行的大部分数据是主键的一部分的时候非常有用。要么因为主键列比其余的列长，或因为行总体而言是比较短的。存储整行数据在索引上避免了同样的数据存两分（一份在索引，一份在表中），但是如果主键占数据行的比例较大时，数据增益（译者注：数据+表的重复数据量）将更大。此外，在这种情况下，索引页将保存很多或几乎一样多的数据，访问数据时在索引页中就可能得到整行需要的列，所以这可以减少随机IO（译者注：覆盖索引扫描，Index Scan）。</p>
<p>When accessing an index-organized table via a secondary index, it may be necessary to traverse both the B-tree in the secondary-index, and the B-tree in the primary index.  As a result, queries involving secondary indexes might be slower.  However, since MySQL has index-only scans ( PostgreSQL does not ), it can sometimes avoid traversing the secondary index.  So in MySQL, adding additional columns to an index might very well make it run faster, if it causes the index to function as a covering index for the query being executed.  But in PostgreSQL, we frequently find ourselves telling users to pare down the columns in the index to the minimum set that is absolutely necessary, often resulting in dramatic performance gains.  This is an interesting example of how the tuning that is right for one database may be completely wrong for another database.<br />
当通过非主键索引访问一个索引组织表，可能需要遍历非主键索引的B树和主键索引的B树。因此，查询涉及非主键索引可能会变慢。然而，由于MySQL有Index-Scan方式（译者注：访问索引即可获得数据） 而PostgreSQL没有，它有时访问非主键索引就能拿到数据。因此，在MySQL中，添加额外的列索引如果带来覆盖索引的查询计划，则很可能使<acronym title="Structured Query Language">SQL</acronym>运行得更快（译者注：这个不完全对，索引多的话索引页分裂时的物理IO操作还是比较多的，推荐满足需求的情况下减少索引，除非你能保证覆盖索引经常被用到）。但是在PostgreSQL里，我们经常发现自己告诉用户减少索引到满足要求的最低限度时往往能带来巨大的性能提升。这是一个有趣的例子，如何调整数据库在不同的数据库中是完全相反的方法。</p>
<p>I&#8217;ve recently learned that neither InnoDB nor PostgreSQL supports traversing an index in physical order, only in key order.  For InnoDB, this means that ALL scans are performed in key order, since the table itself is, in essence, also an index.  As I understand it, this can make a large sequential scan quite slow, by defeating the operating system&#8217;s prefetch logic.  In PostgreSQL, however, because tables are not index-organized, sequential scans are always performed in physical order, and don&#8217;t require looking at the indexes at all; this also means we can skip any I/O or CPU cost associated with examining non-leaf index pages.  Traversing in physical order is apparently difficult from a locking perspective, although it must be possible, because Oracle supports it.  It would be very useful to see this support in MySQL, and once PostgreSQL has index-only scans, it would be a useful improvement for PostgreSQL, too.<br />
我最近获悉，PostgreSQL跟InnoDB一样也支持通过主键索引顺序遍历（译者注：InnoDB访问全表返回数据按主键顺序排列）。对于 InnoDB，这意味着所有的全表扫描是在扫描主键索引，主键索引本身就是表。据我了解，这可能导致大的顺序扫描慢很多（译者注：这个比较扯淡，在数据静止的情况下，PostgreSQL一样要通过block的指针访问下一个block，InnoDB通过页的指针访问下一个页）。在PostgreSQL，因为表不是按（主键）索引组织，顺序扫描总是按物理顺序进行，并且完全不需要访问索引，这也意味着我们可以跳过任何访问索引非叶子节点的IO或CPU开销（译者注：这位兄台应该忘记了什么是B+树）。显然按物理顺序访问是很困难的，但是肯定可以实现，因为Oracle支持。这是MySQL一个非常有用的功能，PostgreSQL一旦有了覆盖索引扫描功能，对PostgreSQL也将是非常有用的提升。</p>
<p>One final difficulty with an index-organized table is that you can&#8217;t add, drop, or change the primary key definition without a full-table rewrite.  In PostgreSQL, on the other hand, this can be done – even while allow concurrent read and write activity.  This is a fairly nominal advantage for most use cases since the primary key of a table rarely changes – I think it&#8217;s happened to me only once or twice in the last ten years – but it is useful when it does comes up.<br />
使用索引组织表的最后一个问题是不能在不重建全表的情况下添加，删除或变更主键索引定义。反而在PostgreSQL里，这是可以做到的——即使当允许并发读写活动时。在大多数情况下（InnoDB）具有优势，因为在大多数场景下一旦定义主键不太可能更改 。在我最近十年内这只碰到一次或两次——但是它真的发生时，（PostgreSQL）还是很有用的。</p>
<p>I hope that the above is a fair and accurate summary of the topic, but I&#8217;m sure I&#8217;ve missed a few things and covered others incompletely or in less detail than might be helpful.  Please feel free to respond with a comment below or a blog post of your own if I&#8217;ve missed something.<br />
我希望以上是这个专题比较公正和准确的总结，但我敢肯定，我已经错过了一些东西，或者覆盖一些内容不完全，缺少一些可能会有所帮助的细节。请随时反馈在下面的评论中评论您对我遗漏的一些内容的看法。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2011年01月27日 -- <a href="http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html" title="[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性">[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/mysql-vs-postgresql-part-1-table-organization.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>InnoDB的Master Thread调度流程</title>
		<link>http://www.penglixun.com/tech/database/innodb_master_thread.html</link>
		<comments>http://www.penglixun.com/tech/database/innodb_master_thread.html#comments</comments>
		<pubDate>Tue, 14 Dec 2010 17:22:03 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[Master Thread]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[XtraDB]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1180</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/innodb_master_thread.html InnoDB的主要IO操作都是在Master Thread... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/innodb_master_thread.html </p>
<p></span>InnoDB的主要IO操作都是在<strong>Master Thread</strong>（srv0srv.c）中完成的，所以分析InnoDB的IO调度，就一定要分析Master Thread线程。</p>
<p>下面是我画的一张流程图，标识了整个Master Thread的调度流程。红色部分是InnoDB Plugin/XtraDB对原有InnoDB引擎的改进。<br />
每个Process文字中最下面的括号是进行这个操作的具体函数，可以参照源代码阅读本图。</p>
<p>顺便解释一下“<strong>插入缓冲</strong>”（Insert Buffer）：InnoDB为了避免更新数据时更新索引损失太多性能，使用了这种称为Insert Buffer的方法来缓冲索引更新，对于非聚集索引（主键索引）、唯一索引的修改，不是每次都直接插入索引页，而是先判断要更新的这一页在不在内存中，如果不在则存入Insert Buffer，按照Master Thread的调度规则来合并非唯一索引和索引页中的叶子结点，这样经常能减少更新索引的代价。<strong>为什么要求是非唯一索引</strong>（排除主键索引和唯一索引）呢？因为唯一索引要检查记录是不是存在，所以必须把修改的记录影响的索引页读出来才知道是不是唯一，这样Insert Buffer就没意义了，反正要读出来，所以只对非唯一索引有效。<br />
show innodb status中的“INSERT BUFFER AND ADAPITIVE HASH INDEX”里面显示了Insert Buffer的效果。</p>
<p><strong>更正一部分，发现在刷新100个赃页后，InnoDB认为刷新耗时已经超过一秒了，无需等待，设置skip_sleep=TRUE，直接跳过os_pthread_sleep，进行下一次判断。</strong></p>
<p><img src="http://file.penglixun.com/InnoDB_Master_Thread.png" alt="InnoDB Master Thread" /></p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2010年12月6日 -- <a href="http://www.penglixun.com/tech/database/percona_vs_mysql.html" title="Percona对MySQL标准版本的改进">Percona对MySQL标准版本的改进</a> (3)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/innodb_master_thread.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Percona对MySQL标准版本的改进</title>
		<link>http://www.penglixun.com/tech/database/percona_vs_mysql.html</link>
		<comments>http://www.penglixun.com/tech/database/percona_vs_mysql.html#comments</comments>
		<pubDate>Mon, 06 Dec 2010 08:08:41 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Percona]]></category>
		<category><![CDATA[XtraDB]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1176</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/percona_vs_mysql.html 周末有空读了下Percona XtraDB对MySQL InnoDB... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/percona_vs_mysql.html </p>
<p></span>周末有空读了下Percona XtraDB对MySQL InnoDB的改进点，这里给大家分享下。</p>
<p><strong>一、对可扩展性的改进： </strong><br />
1. 提升Buffer Pool的扩展性<br />
InnoDB Buffer Pool一个众所周知的问题是大并发查询执行的争用，XtraDB将Buffer Pool的全局Mutex拆成了多个Mutex以减少争用。</p>
<p>2. 提高InnoDB IO扩展性<br />
XtraDB增加了许多变量去调整IO到最佳状态，包括调整checkpoint、后台读写数据文件线程数等等的参数。</p>
<p>3. 多个回滚段<br />
为提供一直读，InnoDB将事务修改的数据写到回滚段。回滚段被一个独立的Mutex保护，这直接导致了写密集型的工作并发不高。在 XtraDB可以改变回滚段的数目（innodb_extra_rsegments），在写密集型操作中可以大幅度提高性能。</p>
<p>4. 可以更高的并发数<br />
InnoDB在回滚段只提供了1024个回滚槽（春哥就遇到过这个瓶颈），如果回滚槽用完，新的事务将不能开始，直到有回滚槽被释放。</p>
<p><strong>二、性能上的提升 </strong><br />
1. 专用的Purge线程<br />
在InnoDB一个事务修改的数据被写到共享表空间的undo space，所以InnoDB能提供读一致。到一个事务结束了，undo space的相应区域被释放。但是如果有很多事务，Purge线程清理空间不够快，共享表空间将急剧增长（BRMMS共享表空间巨大应该是这个原因）。这 将导致性能严重下降，甚至可能用完所有的磁盘空间。XtraDB使用了一个专用的线程来清理undo space，这对undo space的清理速度可以提升很多。尽管这可能使整体的性能降低，但是可以大大提高稳定性，因而整体性能略微降低是值得的。</p>
<p>2. 可配置的Doublewrite缓冲<br />
InnoDB使用了double write功能来防止数据损坏，double write的意思是，是写数据到文件前，先顺序写到到共享表空间。如果遇到一个损坏的写，InnoDB将使用这个buffer去恢复数据。尽管数据被写了 两次但对性能影响通常较小，但是在一些高负载环境，doublewrite就成了瓶颈。XtraDB提供了一个选项将doublewrite buffer放在一个独立的磁盘来提升并发性能。</p>
<p>3. Query Cache增强<br />
Percona提供了额外的参数来配置Query Cache，例如忽略<acronym title="Structured Query Language">SQL</acronym>中的注释性语句来检查是否可以命中。</p>
<p>4. Fast InnoDB Checksum<br />
InnoDB可以checksum所有从磁盘上读取的页，以提供防止数据损坏的额外安全保障。在XtraDB中，Percona改进算了 checksum算法，可以提供更好的性能。</p>
<p>5. 删除过多的函数调用<br />
当MySQL从socket读数据时，将产生很多fcntl（针对描述符提供控制的函数）调用，导致并发性能下降。Percona移出了多于 的调用。</p>
<p>6. 减少了Buffer Pool Mutex竞争<br />
在InnoDB内核操作时减少了Buffer Pool之间的Mutex争用（拆分Mutex变量）</p>
<p><strong>三、灵活性改进 </strong><br />
1. 支持多种页大小<br />
尽管InnoDB支持多种页大小，但是默认的页大小16K无法在不重新编译的情况下改变。XtraDB提供一个系统变量 （innodb_page_size）来改变这个值。更小的页大小可以提升大多数OLTP系统的工作性能，更大的页通常可以提供更好的 OLAP性能。</p>
<p>2. 禁止Replication警告<br />
默认的基于Statement的复制，例如NOW(),RAND()，call存储过程/函数等一些语句，或者UPDATE没有ORDER BY而使用LIMIT，可能是不安全的。在这种情况下，MySQL会发出1592警告（声明语句在Statement日志下是不安全的）。不 幸的是，MySQL 5.1的一个Bug导致Server发出这个警告在一些安全的情况下。索然他不会导致任何与复制相关的问题，但是这会导致Error Log里面存在没必要的报警。这个改进可以避免这些警告。</p>
<p>3. 处理BLOB中的行结束符<br />
Percona(5.1.x-12.x开始，5.1.x-11.x不支持)为MySQL客户端提供一个新的选项（no-remove- eol-carret）来处理Blob字段含\r字符的情况。</p>
<p>4. 复制停止恢复<br />
当使用sql_slave_skip_counter参数时，如果一个事件组的中间某条出错了，slave将跳过所有剩余的时间操作直到这个 事件组结束。表述比较困难，直接看Percona给的使用例子就明白了。<br />
<a href="http://www.percona.com/docs/wiki/percona-server:features:replication_skip_single_statement" target="_blank">http://www.percona.com/docs/wiki/percona-server:features:replication_skip_single_statement</a></p>
<p>5. 可固定的预读区<br />
在InnoDB中，预读（read-ahead区域）的大小是动态计算的，但是它经常是一个同样的值。XtraDB(5.1.x-12.x开 始，5.1.x-11.x不支持)可以让这个这个区域的大小固定，避免无用的计算。<br />
这是Facebook放出的补丁：<a href="http://bazaar.launchpad.net/~mysqlatfacebook/mysqlatfacebook/5.1/revision/3538">http://bazaar.launchpad.net/~mysqlatfacebook/mysqlatfacebook/5.1/revision/3538</a></p>
<p><strong>四、可靠性的改进</strong><br />
1. Crash后同步日志<br />
在InnoDB中，slave复制状态存储在两个不同步的文件中(relay.index和relay.info)。如果slave因为错误 状态而停止，文件将不同步，最后的事务将重新执行。Percona在XtraDB事务日志中增加了复制状态：当重启事务时，slave可以使 用这个信息来实现一致性。<br />
来自Google的补丁：<a href="http://code.google.com/p/google-mysql-tools/wiki/TransactionalReplication">http://code.google.com/p/google-mysql-tools/wiki/TransactionalReplication</a><br />
这个缺陷可能导致的Bug：<a href="http://bugs.mysql.com/bug.php?id=34058" target="_blank">http://bugs.mysql.com/bug.php?id=34058</a></p>
<p>2. Too Many Connections的警告<br />
Percona将“Too Many Connections”这个警告写入Server端的error_log，而不只是客户端报这个错。</p>
<p>3. 错误代码的兼容性<br />
Percona(5.1.x-12.x开始，5.1.x-11.x不支持)提供与MySQL 5.5错误代码的兼容性，避免因为升级到5.5而带来错误码不一样的问题。</p>
<p>4. 文件句柄损坏的表（InnoDB）<br />
MySQL在InnoDB有表损坏之后，所有的InnoDB表都不可用。XtraDB改进了这一点，只是disable损坏的表，数据库依然 可以使用其他的表，损坏的表被锁定。</p>
<p><strong>五、可管理性的提升</strong><br />
1. Fast InnoDB Recovery<br />
InnoDB一直以来有个很麻烦的事情，在crash后回复InnoDB的表非常的缓慢。Percona/XtraDB因为是基于 InnoDB Plugin 1.0.8+的，也具备InnoDB Plugin快速恢复的功能。（早期的Percona版本也能看到XtraDB恢复速度比InnoDB快很多，因为XtraDB早期使用了自己开发的 Fast Revcovery）<br />
一些测试：<a href="http://www.mysqlperformanceblog.com/2009/07/07/improving-innodb-recovery-time/">http://www.mysqlperformanceblog.com/2009/07/07/improving-innodb-recovery-time/</a></p>
<p>2. InnoDB 数据字段大小限制<br />
InnoDB在自己的表缓存（Table Cache）中分配存储表定义（Table Definitions）的内存称为数据字典。默认情况下，一旦打开表，字典中表示它的内部对象将一直保存在内存中，直到表被删除或者服务器重启。如果存 在很多表（例如 10万张或更多，Dubbo就有这种情况，logstat库），可能导致消耗巨大的内存有时可能达到G级别。Percona修改了这种策略，可以设置参数 （innodb_dict_size_limit）来限制数据字典的大小，使InnoDB使用LRU算法来限制数据字典大小，而不是一直存在 内存中，避免因为表太多而内存耗尽。</p>
<p>3. 展开表导入<br />
InnoDB不像MyISAM那样可以在服务器之间拷贝单表定义文件。如果配合Xtrabackup导出，一张表可以在另一个XtraDB导 入。</p>
<p>4. Buffer Pool使用共享内存<br />
当Buffer Pool非常大时，重启后Warn up需要大量磁盘读写，这会消耗很多时间。通过将Buffer Pool存储在Shared Memory中，这些非是耗时的IO将会节省掉。主机重启就没办法了，得用下面的功能。</p>
<p>5. 导出/恢复Buffer Pool<br />
对于使用了很大Buffer Pool的InnoDB，重启数据库很痛苦。通常需要InnoDB Buffer Pool先Warn Up再提供服务，这可能需要很久。XtraDB(5.1.x-12.x开始，5.1.x-11.x不支持)提供了命令可以把Buffer Pool的内容导入或导出，从而可以提高重启提供服务的速度。<br />
使用方法：<a href="http://www.percona.com/docs/wiki/percona-server:features:innodb_lru_dump_restore?redirect=1">http://www.percona.com/docs/wiki/percona-server:features:innodb_lru_dump_restore?redirect=1</a></p>
<p>6. Fast Index Creation<br />
快速索引创建是InnoDB Plugin的功能，只要不是主键变动，修改索引的速度比之前快很多。但是在一些场景下，这可能导致损坏。XtraDB提供参数 （innodb_fast_index_creation）来选择Fast Index Creation功能是否启用，如果关闭，则使用原来的创建方法。</p>
<p>7. Fast Index Renaming<br />
XtraDB（(5.1.x-12.x开始，5.1.x-11.x不支持)）扩展了ALTER TABLE命令，提供在线重命名索引功能，这样不会导致重建索引。（这对我们调整不规范索引名称非常有用）</p>
<p>8. 防止缓存Flashcache<br />
Flashcache通过在SSD上缓存数据来提升性能。它工作时应该让更热的数据缓存才能能提高更好的性能，XtraDB提供了注释提示来 忽略不必缓存的数据。</p>
<p><strong>六、诊断问题方面的提升</strong><br />
1. 额外的INFORMATION_SCHEMA表<br />
Percona/XtraDB提供额外的INFORMATION_SCHEMA表以获得数据库内部更详尽的信息，例如内部缓冲池的内容或统计 信息。</p>
<p>2. 慢查日志扩展<br />
Percona提供了额外的统计数据，可以通过参数启用。它可以帮助我们捕捉需要的事件尽可能详细的信息，简化了慢查分析的难度。</p>
<p>3. InnoDB状态显示<br />
XtraDB整理了InnoDB Status的显示量，提供更好的可读性，状态由24个上升到48个，并且打印了被内部哈希表使用的内存量。通过新的参数可以配置的输出。</p>
<p>4. 计算InnoDB死锁数<br />
当运行一饿事务性的应用程序，总会不同程度的出现死锁，只要不经常出现这并不是大的问题。InnoDB中Show InnoDB Status命令只给出了最后一次死锁额信息，当我们需要知道总的死锁数或一个单位时间的死锁量这里并不能给出。XtraDB增加了一个保存死锁量的状态 变量，通过这个变量可以更好的了解我们数据库上发生的死锁。</p>
<p>5. 可以记录所有Server端命令（syslog）<br />
Percona可以在syslog中记录所有运行在Server端的命令。</p>
<p>6. 响应时间分布<br />
Percona提供了一份报告表明在一定间隔内在服务器上执行Query数。这个信息可以用于监控数据库性能是否稳定。</p>
<p>7. Show Storage Engines<br />
Percona改变了Show Storage Egnines的输出，以表名XtraDB是不是启用。（以前XtraDB也使用InnoDB的名称输出）</p>
<p>8. Query Cache Mutex状态<br />
Query Cache可能导致一些很难被检测出来的问题，Percona修改了show processlist命令，可以输出“Waiting on query cache mutex”状态。</p>
<p>9. 显示锁名称<br />
“show mutex status”命令可以显示当前发生的锁定名称和os_wait值。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2010年01月14日 -- <a href="http://www.penglixun.com/tech/database/xtradb_compile_error.html" title="XtraDB 1.0.6-9编译错误的解决">XtraDB 1.0.6-9编译错误的解决</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/percona_vs_mysql.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MySQL索引与存储方式对性能的影响</title>
		<link>http://www.penglixun.com/tech/database/mysql_index_store_perfomance_effect.html</link>
		<comments>http://www.penglixun.com/tech/database/mysql_index_store_perfomance_effect.html#comments</comments>
		<pubDate>Sat, 20 Mar 2010 09:27:13 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[myisam]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1077</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/mysql_index_store_perfomance_effect.html 本文配图来自《高性能M... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/mysql_index_store_perfomance_effect.html </p>
<p></span>本文配图来自《高性能MySQL(第二版)》。</p>
<p>在数据库中，对性能影响最大的几个策略包括数据库的锁策略、缓存策略、索引策略、存储策略、执行计划优化策略。<br />
索引策略决定数据库快速定位数据的效率，存储策略决定数据持久化的效率。<br />
MySQL中两大主要存储引擎MyISAM和InnoDB采用了不同的索引和存储策略，本文将分析它们的异同和性能。</p>
<p>MySQL主要提供2种方式的索引：B-Tree（包括B+Tree）索引，Hash索引。<br />
B树索引具有范围查找和前缀查找的能力，对于N节点的B树，检索一条记录的复杂度为O(LogN)。<br />
哈希索引只能做等于查找，但是无论多大的Hash表，查找复杂度都是O(1)。<br />
显然，如果值的差异性大，并且以等于查找为主，Hash索引是更高效的选择，它有O(1)的查找复杂度。如果值的差异性相对较差，并且以范围查找为主，B树是更好的选择，它支持范围查找。</p>
<p><span id="more-1077"></span><br />
Hash索引各种引擎大同小异，没有太多可探讨性，本文主要讨论不同形式的B树索引。</p>
<p>B树属于二叉平衡树，平衡树就是任何一个节点的左右节点高度差距不能超过1的树，这才是绝对平衡的树。<br />
平衡树比较好的算法是AVL，它通过左旋、右旋及其组合的操作可以保证树绝对平衡。<br />
下面是AVL算法中的全部旋转操作：<br />
<a title="Flickr 上 P.Linux 的 AVL二叉平衡树" href="http://www.flickr.com/photos/penglixun/4446760301/"><img src="http://farm5.static.flickr.com/4024/4446760301_da13d53506_o.jpg" alt="AVL二叉平衡树" width="435" height="727" /></a><br />
平衡树处在任何一个左边的不平衡状态都可以通过相应的旋转操作转移到右边的平衡状态。</p>
<p>数据库采用的B树只在叶子节点记录信息，非叶子节点记录的是范围信息，这是与一般搜索树不同的地方（一般搜索树非叶子节点也记录信息）。<br />
这是一个B+树的结构，InnoDB的索引都采取了这种形式，它在B-树的基础上为每个叶子节点加了一个指针指向下一个叶子节点，这样可以快速的进行范围查找。<br />
MyISAM是否也是B+树我还不能确定，但是B-树我没有想到可以快速进行范围查找的方法，应该也是B+树。<br />
<a title="Flickr 上 P.Linux 的 B+树索引" href="http://www.flickr.com/photos/penglixun/4445202603/"><img src="http://farm5.static.flickr.com/4029/4445202603_eb376f2d2b_o.png" alt="B+树索引" width="544" height="355" /></a></p>
<p>例如这个B+树的例子：<br />
<a title="Flickr 上 P.Linux 的 B+树索引的例子" href="http://www.flickr.com/photos/penglixun/4445202745/"><img src="http://farm5.static.flickr.com/4007/4445202745_f95863b2b4_o.png" alt="B+树索引的例子" width="543" height="368" /></a><br />
如果我要查找名字以A开头的全部信息，我只要获取第一个叶子节点，然后顺序沿着指向下一个叶子的指针，直到发现当年叶子节点已经不是以A开头则中止，这样只要搜索到第一个叶子节点(O(LogN))再沿着指针检索(O(N))，就可以获取全部索引，如果N个节点的表扫描M个连续值，就是O(LogN)+O(M)，如果B-树则需要回溯到上层节点，这样最差的效率是O(LogN)*M。</p>
<p>对于InnoDB，使用了一种改进的B+树索引，称为聚集索引（Clustered Index），它的不同之处在于索引上不仅有索引值的信息，还有整个索引值所在行的信息，免去了一次通过索引值上的位置去取整行的操作。<br />
<a title="Flickr 上 P.Linux 的 聚集索引" href="http://www.flickr.com/photos/penglixun/4445976712/"><img src="http://farm3.static.flickr.com/2789/4445976712_08522430fe_o.png" alt="聚集索引" width="546" height="398" /></a></p>
<p>假设我们有个表有(col1,col2)列，col1是主键，col2也建立索引。那么在MyISAM引擎中，文件会被这样记录，因为MyISAM是按插入顺序把数据写入文件。如果有删除则空出位置，再次插入如果可以放下则会填充空白，对于不定长的行，存储引擎都会在分页中预留位置，以供更新更长的值（一般是VARCHAR），放不下则会添加到文件结尾，并从原位置删除。所以有时候会有空间浪费，需要Optimize Table来优化。<br />
因此：<span style="color: #ff0000;">定长的行比不定长的行效率高！把定长数据和不定长数据分开存储，很多时候可以提高效率。</span><br />
<a title="Flickr 上 P.Linux 的 MyISAM的文件组织" href="http://www.flickr.com/photos/penglixun/4445976822/"><img src="http://farm5.static.flickr.com/4026/4445976822_5d91f2511e_o.png" alt="MyISAM的文件组织" width="206" height="176" /></a></p>
<p>再来看MyISAM的主键索引，索引Key是主键值，索引Value是行的文件位置，通过这个位置可以直接读取行。从这个图上来看，MyISAM也是采用B+树。<br />
<a title="Flickr 上 P.Linux 的 MyISAM主键索引结构" href="http://www.flickr.com/photos/penglixun/4445203107/"><img src="http://farm3.static.flickr.com/2716/4445203107_3c3fac95a5_o.png" alt="MyISAM主键索引结构" width="535" height="198" /></a></p>
<p>MyISAM的非主键索引，跟逐渐索引没有不同，也是索引行的文件位置。<br />
<a title="Flickr 上 P.Linux 的 MyISAM普通列索引结构" href="http://www.flickr.com/photos/penglixun/4445203165/"><img src="http://farm3.static.flickr.com/2771/4445203165_5c03c4f603_o.png" alt="MyISAM普通列索引结构" width="540" height="201" /></a></p>
<p>再看InnoDB的主键索引，索引Key是主键值，索引Value是整行的数据。<br />
<a title="Flickr 上 P.Linux 的 InnoDB主键索引结构" href="http://www.flickr.com/photos/penglixun/4445203293/"><img src="http://farm5.static.flickr.com/4072/4445203293_8e9210300b_o.png" alt="InnoDB主键索引结构" width="544" height="251" /></a></p>
<p>InnoDB的非主键索引，索引Key是列值，索引Value是主键值。<br />
<a title="Flickr 上 P.Linux 的 InnoDB普通列索引结构" href="http://www.flickr.com/photos/penglixun/4445977156/"><img src="http://farm3.static.flickr.com/2679/4445977156_3e858ec65e_o.png" alt="InnoDB普通列索引结构" width="543" height="203" /></a></p>
<p>对比MyISAM和InnoDB的索引策略：<br />
<a title="Flickr 上 P.Linux 的 聚集索引和非聚集索引对比" href="http://www.flickr.com/photos/penglixun/4445977248/"><img src="http://farm5.static.flickr.com/4060/4445977248_2e51afe688_o.png" alt="聚集索引和非聚集索引对比" width="544" height="463" /></a><br />
可以发现MyISAM所有列的索引都是一样，索引Key是列值，索引Value是行的文件位置。<br />
InnoDB的主键索引包含了行的全部信息，索引Key是主键值，索引Value是整行的值。而非主键索引索引Key是列值，索引Value是主键值，取数据时到主键索引中取。</p>
<p>并且在InnoDB中，一个聚集索引是必须的，如果没有定义主键，InnoDB也会自己隐含的建立一个聚集索引作为主键，因为InnoDB的主键索引还有个重要的功能就是行锁，这在我的<a href="http://www.penglixun.com/work/database/innodb_next_key_locking.html">另一篇文章</a>中分析过。</p>
<p>再来看看我们插入值时会发生什么：<br />
<a title="Flickr 上 P.Linux 的 插入连续值到聚集索引" href="http://www.flickr.com/photos/penglixun/4445203565/"><img src="http://farm5.static.flickr.com/4006/4445203565_08b3ff0b6c_o.png" alt="插入连续值到聚集索引" width="545" height="164" /></a><br />
InnoDB会按主键索引顺序组织文件，如果按主键顺序插入，可以直接在最尾部加入。并且只填充页面的15/16，这样可以预留部分空间以供行修改，这样组织的数据是非常紧凑的。</p>
<p>如果主键不是顺序的，我们来看看会发生什么，因为要按主键顺序存放，数据会被不断地移动，调整页面。<br />
<a title="Flickr 上 P.Linux 的 插入非连续值到聚集索引" href="http://www.flickr.com/photos/penglixun/4445977554/"><img src="http://farm5.static.flickr.com/4045/4445977554_94e9bef209_o.png" alt="插入非连续值到聚集索引" width="540" height="386" /></a><br />
所以：<span style="color: #ff0000;">InnoDB引擎按主键顺序插入记录是非常必要的，否则性能将会面临很大风险。</span></p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年09月30日 -- <a href="http://www.penglixun.com/tech/database/mysql_parameter_tuning.html" title="MySQL参数调优">MySQL参数调优</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/mysql_index_store_perfomance_effect.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>InnoDB行锁的实现分析</title>
		<link>http://www.penglixun.com/tech/database/innodb_next_key_locking.html</link>
		<comments>http://www.penglixun.com/tech/database/innodb_next_key_locking.html#comments</comments>
		<pubDate>Thu, 11 Feb 2010 08:27:35 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[行锁]]></category>
		<category><![CDATA[锁机制]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=968</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/innodb_next_key_locking.html 感谢Fenng的提醒，已删除锁粒度... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/innodb_next_key_locking.html </p>
<p></span><strong>感谢Fenng的提醒，已删除锁粒度和死锁的关系，专门撰文写了<a href="http://www.penglixun.com/work/database/lock_granularity_deadlock_probability.html">锁的粒度与死锁的关系</a>。</strong></p>
<p>InnoDB与MyISAM不同，它实现的是一个行级锁，而非MyISAM的表锁。锁的粒度越大，则<del datetime="2010-02-12T15:16:00+00:00">发生死锁的概率越小、</del>锁机制开销越小，但并发能力会越低。如果锁的粒度变细，则<del datetime="2010-02-12T15:16:00+00:00">发生死锁的概率也会增大，</del>锁机制的开销会更大，但是并发能力能提高。表锁是如何实现的呢，以MyISAM为例，是在每个表的结构中加入一个互斥变量记录锁状态，像：<br />
struct Table {<br />
    Row     rows[MAXROWS];<br />
    pthread_mutex_t lock;//表锁<br />
};<br />
这样做的好处就是锁非常简单，当操作表的时候，直接锁住整个表就行，锁机制的开销非常小。但是问题也很明显，并发量上不去，因为无论多小的操作，都必须锁整个表，这可能带来其他操作的阻塞。<br />
行锁又是如何实现的呢，Oracle是直接在每个行的block上做标记，而InnoDB则是靠索引来做。InnoDB的主键索引跟一般的索引不太一样，Key后面还跟上了整行的数据，互斥变量也是加载主键索引上的，像<br />
struct PK_Idx {<br />
    Row     row;<br />
    pthread_mutex_t lock;//行锁<br />
};<br />
multimap<int, PK_Idx> pk_idx;<br />
这样的形式。<br />
这样做的好处是锁的粒度小，只锁住需要的数据不被更改，但是问题也很明显，锁的开销很大，每个主键索引上都要加上一个标记，<del datetime="2010-02-12T15:16:00+00:00">因为锁的粒度很小</del>，可能两个不同的操作各锁住一部分行等待对方释放形成死锁，不过这个是有办法解决的，把上锁的操作封装成原子操作就行，不过并发量会受些影响。</p>
<p>下面是类似InnoDB的Next-Key locking算法的演示:<br />
编译需要加-lpthread参数，例如g++ inno.cpp -lpthread -o inno<br />
<span id="more-968"></span></p>

<div class="wp_codebox"><table><tr id="p96810"><td class="code" id="p968code10"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;cstdio&gt;</span>
<span style="color: #339900;">#include &lt;cstdlib&gt;</span>
<span style="color: #339900;">#include &lt;string&gt;</span>
<span style="color: #339900;">#include &lt;map&gt;</span>
<span style="color: #339900;">#include &lt;unistd.h&gt;</span>
<span style="color: #339900;">#include &lt;time.h&gt;</span>
<span style="color: #339900;">#include &lt;pthread.h&gt;</span>
<span style="color: #339900;">#include &lt;windows.h&gt;</span>
&nbsp;
<span style="color: #339900;">#define LOCK pthread_mutex_lock(&amp;lock)</span>
<span style="color: #339900;">#define UNLOCK pthread_mutex_unlock(&amp;lock)</span>
<span style="color: #339900;">#define PRINT(STR, ...) LOCK;fprintf(stderr, STR,  __VA_ARGS__);UNLOCK</span>
&nbsp;
<span style="color: #339900;">#define MAXROWS 100</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/* 行结构 */</span>
<span style="color: #0000ff;">struct</span> Row <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span>     num<span style="color: #008080;">;</span>
    string  info<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/* 主键索引结构 */</span>
<span style="color: #0000ff;">struct</span> PK_Idx <span style="color: #008000;">&#123;</span>
    Row     row<span style="color: #008080;">;</span>
    pthread_mutex_t lock<span style="color: #008080;">;</span><span style="color: #666666;">//行锁</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/* 表结构 */</span>
<span style="color: #0000ff;">struct</span> Table <span style="color: #008000;">&#123;</span>
    multimap<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span>, PK_Idx<span style="color: #000080;">&gt;</span> pk_idx<span style="color: #008080;">;</span>
    multimap<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span>, <span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span>      num_idx<span style="color: #008080;">;</span>
    multimap<span style="color: #000080;">&lt;</span>string, <span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span>   info_idx<span style="color: #008080;">;</span>
    Row     rows<span style="color: #008000;">&#91;</span>MAXROWS<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    pthread_mutex_t lock<span style="color: #008080;">;</span><span style="color: #666666;">//表锁</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
Table table<span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> pid<span style="color: #008080;">;</span>
<span style="color: #666666;">//全局锁</span>
pthread_mutex_t lock <span style="color: #000080;">=</span> PTHREAD_MUTEX_INITIALIZER<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/* 随机字符 */</span>
<span style="color: #0000ff;">char</span> randChar<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color:#800080;">26</span><span style="color: #000040;">+</span><span style="color: #FF0000;">'A'</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/* 随机字符串 */</span>
<span style="color: #0000ff;">void</span> randString<span style="color: #008000;">&#40;</span>string <span style="color: #000040;">&amp;</span>col, <span style="color: #0000ff;">int</span> len<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    col <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>len<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        col <span style="color: #000040;">+</span><span style="color: #000080;">=</span> randChar<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/* 初始化数据 */</span>
<span style="color: #0000ff;">void</span> init<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    pid <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    PK_Idx pk<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">srand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">time</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">//初始化表数据</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>MAXROWS<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        pk.<span style="color: #007788;">row</span>.<span style="color: #007788;">num</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span>MAXROWS<span style="color: #008080;">;</span>
        randString<span style="color: #008000;">&#40;</span>pk.<span style="color: #007788;">row</span>.<span style="color: #007788;">info</span>, <span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color:#800080;">10</span><span style="color: #000040;">+</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #666666;">//初始化行锁</span>
        pk.<span style="color: #007788;">lock</span> <span style="color: #000080;">=</span> PTHREAD_MUTEX_INITIALIZER<span style="color: #008080;">;</span>
        <span style="color: #666666;">//写入表数据</span>
        table.<span style="color: #007788;">rows</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">num</span> <span style="color: #000080;">=</span> pk.<span style="color: #007788;">row</span>.<span style="color: #007788;">num</span><span style="color: #008080;">;</span>
        table.<span style="color: #007788;">rows</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">info</span> <span style="color: #000080;">=</span> pk.<span style="color: #007788;">row</span>.<span style="color: #007788;">info</span><span style="color: #008080;">;</span>
        <span style="color: #666666;">//写入索引</span>
        table.<span style="color: #007788;">pk_idx</span>.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span>pair<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span>, PK_Idx<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>i, pk<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        table.<span style="color: #007788;">num_idx</span>.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span>pair<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span>, <span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>pk.<span style="color: #007788;">row</span>.<span style="color: #007788;">num</span>, i<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        table.<span style="color: #007788;">info_idx</span>.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span>pair<span style="color: #000080;">&lt;</span>string, <span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>pk.<span style="color: #007788;">row</span>.<span style="color: #007788;">info</span>, i<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #666666;">//初始化表锁</span>
    table.<span style="color: #007788;">lock</span> <span style="color: #000080;">=</span> PTHREAD_MUTEX_INITIALIZER<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/*获取范围数据*/</span>
<span style="color: #0000ff;">void</span> select_num<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> begin, <span style="color: #0000ff;">int</span> end<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> id<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> cur_pid<span style="color: #008080;">;</span>
    multimap<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span>,<span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it, itlow, itup<span style="color: #008080;">;</span>
    PK_Idx <span style="color: #000040;">*</span>pk<span style="color: #008080;">;</span>
    <span style="color: #ff0000; font-style: italic;">/* 按字段范围查找ID */</span>
    itlow <span style="color: #000080;">=</span> table.<span style="color: #007788;">num_idx</span>.<span style="color: #007788;">lower_bound</span> <span style="color: #008000;">&#40;</span>begin<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    itup <span style="color: #000080;">=</span> table.<span style="color: #007788;">num_idx</span>.<span style="color: #007788;">upper_bound</span> <span style="color: #008000;">&#40;</span>end<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    LOCK<span style="color: #008080;">;</span>
    cur_pid <span style="color: #000080;">=</span> pid<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
    UNLOCK<span style="color: #008080;">;</span>
    PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : * Start Select:%d,%d *<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid, begin, end<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>it<span style="color: #000080;">=</span>itlow<span style="color: #008080;">;</span> it<span style="color: #000040;">!</span><span style="color: #000080;">=</span>itup<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        id <span style="color: #000080;">=</span> it<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008080;">;</span>
        pk <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>table.<span style="color: #007788;">pk_idx</span>.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>id<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><span style="color: #666666;">//根据ID去查主键索引</span>
        pthread_mutex_lock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>lock<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><span style="color: #666666;">//在主键索引上加锁</span>
        PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : LOCK Row %d: %d<span style="color: #000099; font-weight: bold;">\t</span>%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid, id, pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>row.<span style="color: #007788;">num</span>, pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>row.<span style="color: #007788;">info</span>.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        Sleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">500</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>it<span style="color: #000080;">=</span>itlow<span style="color: #008080;">;</span> it<span style="color: #000040;">!</span><span style="color: #000080;">=</span>itup<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        id <span style="color: #000080;">=</span> it<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008080;">;</span>
        pk <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>table.<span style="color: #007788;">pk_idx</span>.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>id<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : UNLOCK Row %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid, id<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        pthread_mutex_unlock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>lock<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><span style="color: #666666;">//使用完毕依次释放锁</span>
    <span style="color: #008000;">&#125;</span>
    PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : * Select Finished! *<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/*修改范围数据*/</span>
<span style="color: #0000ff;">void</span> update_num<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> begin, <span style="color: #0000ff;">int</span> end<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> id<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> cur_pid<span style="color: #008080;">;</span>
    multimap<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span>,<span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it, itlow, itup<span style="color: #008080;">;</span>
    PK_Idx <span style="color: #000040;">*</span>pk<span style="color: #008080;">;</span>
&nbsp;
    itlow <span style="color: #000080;">=</span> table.<span style="color: #007788;">num_idx</span>.<span style="color: #007788;">lower_bound</span> <span style="color: #008000;">&#40;</span>begin<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    itup <span style="color: #000080;">=</span> table.<span style="color: #007788;">num_idx</span>.<span style="color: #007788;">upper_bound</span> <span style="color: #008000;">&#40;</span>end<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    LOCK<span style="color: #008080;">;</span>
    cur_pid <span style="color: #000080;">=</span> pid<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
    UNLOCK<span style="color: #008080;">;</span>
    PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : * Start Update:%d,%d *<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid, begin, end<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>it<span style="color: #000080;">=</span>itlow<span style="color: #008080;">;</span> it<span style="color: #000040;">!</span><span style="color: #000080;">=</span>itup<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        id <span style="color: #000080;">=</span> it<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008080;">;</span>
        pk <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>table.<span style="color: #007788;">pk_idx</span>.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>id<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        pthread_mutex_lock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>lock<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : LOCK Row %d: %d<span style="color: #000099; font-weight: bold;">\t</span>%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid, id, pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>row.<span style="color: #007788;">num</span>, pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>row.<span style="color: #007788;">info</span>.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        Sleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">500</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>it<span style="color: #000080;">=</span>itlow<span style="color: #008080;">;</span> it<span style="color: #000040;">!</span><span style="color: #000080;">=</span>itup<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        id <span style="color: #000080;">=</span> it<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008080;">;</span>
        pk <span style="color: #000080;">=</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>table.<span style="color: #007788;">pk_idx</span>.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>id<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : UNLOCK Row %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid, id<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        pthread_mutex_unlock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#40;</span>pk<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>lock<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d : * Update Finished! *<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, cur_pid<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">void</span><span style="color: #000040;">*</span> test_select<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> begin, end<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">srand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">time</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        begin <span style="color: #000080;">=</span> <span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color: #008000;">&#40;</span>MAXROWS<span style="color: #000040;">/</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        end <span style="color: #000080;">=</span> begin<span style="color: #000040;">+</span><span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color: #008000;">&#40;</span>MAXROWS<span style="color: #000040;">/</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        select_num<span style="color: #008000;">&#40;</span>begin, end<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        Sleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">500</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span><span style="color: #000040;">*</span> test_update<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> begin, end<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">srand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">time</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        begin <span style="color: #000080;">=</span> <span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color: #008000;">&#40;</span>MAXROWS<span style="color: #000040;">/</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        end <span style="color: #000080;">=</span> begin<span style="color: #000040;">+</span><span style="color: #0000dd;">rand</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">%</span><span style="color: #008000;">&#40;</span>MAXROWS<span style="color: #000040;">/</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        update_num<span style="color: #008000;">&#40;</span>begin, end<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        Sleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">500</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> test<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    pthread_t id<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>pthread_create<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>id<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span>, <span style="color: #0000ff;">NULL</span>, test_select, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%s&quot;</span>, <span style="color: #FF0000;">&quot;Create Thread Error!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>pthread_create<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>id<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span>, <span style="color: #0000ff;">NULL</span>, test_update, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        PRINT<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%s&quot;</span>, <span style="color: #FF0000;">&quot;Create Thread Error!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
		Sleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">500</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    init<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    test<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>
<h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2011年01月27日 -- <a href="http://www.penglixun.com/tech/database/plug-in-for-performance-and-scalability.html" title="[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性">[译]InnoDB官方博客：InnoDB Plugin的性能和可伸缩性</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/innodb_next_key_locking.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>XtraDB 1.0.6-9编译错误的解决</title>
		<link>http://www.penglixun.com/tech/database/xtradb_compile_error.html</link>
		<comments>http://www.penglixun.com/tech/database/xtradb_compile_error.html#comments</comments>
		<pubDate>Thu, 14 Jan 2010 09:18:38 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Percona]]></category>
		<category><![CDATA[XtraDB]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=884</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/xtradb_compile_error.html 今天 XtraDB Release 9 发布了，不过，... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/xtradb_compile_error.html </p>
<p></span>今天 XtraDB Release 9 发布了，不过，竟然有编译错误，真是个杯具哇，不过还好，不是什么难解决的错误。</p>
<p>我下载的是 MySQL 5.1.42 和 XtraDB 1.0.6-9，把xtradb的解压文件覆盖mysql的storage/innobase，很Happy的去编译，想很快就能完成，结果一个Error让我郁闷了：<br />
<span style="color: #ff0000;">handler/i_s.cc: In function ‘int i_s_innodb_admin_command_fill(THD*,<br />
TABLE_LIST*, COND*)’:<br />
handler/i_s.cc:2995: warning: deprecated conversion from string<br />
constant to ‘char*’<br />
handler/i_s.cc:2991: warning: unused variable ‘cs’<br />
handler/i_s.cc: At global scope:<br />
handler/i_s.cc:2984: warning: unused parameter ‘cond’<br />
make[2]: *** [libinnobase_a-i_s.o] Error 1<br />
make[2]: Leaving directory `/home/plx/Downloads/mysql-5.1.42/storage/<br />
innobase&#8217;<br />
make[1]: *** [all-recursive] Error 1<br />
make[1]: Leaving directory `/home/plx/Downloads/mysql-5.1.42/storage&#8217;<br />
make: *** [all-recursive] Error 1<span id="more-884"></span></span></p>
<p>我还以为我的GCC参数设置错了，去掉参数直接configure，还是一样的错误。<br />
于是怀疑是不是xtradb本来的问题了，用我的GCC参数编译原版，一切正常，肯定就是xtradb的问题。<br />
Google之无结果，百度之也无结果~</p>
<p>只能自己动手丰衣足食了，先到percona-discus讨论组提问，等待回答。<br />
然后仔细看编译错误发现 真正的Error所在：<br />
<span style="color: #ff0000;">handler/i_s.cc: In function ‘int i_s_innodb_buffer_pool_pages_index_fill(THD*, TABLE_LIST*, COND*)’:<br />
handler/i_s.cc:801: error: invalid conversion from ‘const char*’ to ‘char*’</span></p>
<p>查看了这一行代码：<br />
<span style="color: #0000ff;">if((p = strchr(index-&gt;table_name, &#8216;/&#8217;)))</span></p>
<p>于是去查看strchr的函数原型，得到：<br />
<span style="color: #0000ff;">extern char *strchr(char *s,char c);</span></p>
<p>那就判定是index-&gt;table_name是const char * 导致的。<br />
于是很简单的加上const_cast，801行改为：<br />
<span style="color: #0000ff;">if((p = strchr(const_cast(index-&gt;table_name), &#8216;/&#8217;)))</span></p>
<p>再次编译，成功。</p>
<p>然后看到邮件组里XtraDB的开发人员Aleksandr Kuzminsky也回复我了，确认这是个BUG，然后修正方法跟我也差不多。<br />
不过Aleksandr Kuzminsky也说了，这个问题会导致mysql-test无法通过。</p>
<p>这个版本的XtraDB算比较失败了，期待下一个版本。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2010年12月6日 -- <a href="http://www.penglixun.com/tech/database/percona_vs_mysql.html" title="Percona对MySQL标准版本的改进">Percona对MySQL标准版本的改进</a> (3)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/xtradb_compile_error.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL参数调优</title>
		<link>http://www.penglixun.com/tech/database/mysql_parameter_tuning.html</link>
		<comments>http://www.penglixun.com/tech/database/mysql_parameter_tuning.html#comments</comments>
		<pubDate>Wed, 30 Sep 2009 08:41:06 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[myisam]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[参数]]></category>
		<category><![CDATA[调优]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=346</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/mysql_parameter_tuning.html      l 通用类： key_buffer_size 含... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/mysql_parameter_tuning.html </p>
<p></span>
<div>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"> </span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 14pt; font-family: 'Wingdings';">l </span><span style="font-weight: bold; font-size: 14pt; font-family: '黑体';">通用类：</span><span style="font-weight: bold; font-size: 14pt; font-family: '黑体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: 'Arial';">key_buffer_size</span><span style="font-weight: bold; font-style: italic; font-size: 14pt; font-family: 'Arial';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：用于索引块的缓冲区大小，增加它可得到更好处理的索引（对所有读和多重写）。</span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：对于<span style="font-family: Times New Roman;">MyISAM</span><span style="font-family: 宋体;">表的影响不是很大，</span><span style="font-family: Times New Roman;">MyISAM</span><span style="font-family: 宋体;">会使用系统的缓存来存储数据，所以大量使用</span><span style="font-family: Times New Roman;">MyISAM</span><span style="font-family: 宋体;">表的机器内存很快就会耗尽。但是，如果你将该值设得过大</span></span><span style="font-size: 10.5pt; font-family: '宋体';">（</span><span style="font-size: 10.5pt; font-family: '宋体';">例如，大于总内存的<span style="font-family: Times New Roman;">50%</span></span><span style="font-size: 10.5pt; font-family: '宋体';">）</span><span style="font-size: 10.5pt; font-family: '宋体';">，系统将转换为页并变得极慢。<span style="font-family: Times New Roman;">MySQL</span><span style="font-family: 宋体;">依赖操作系统来执行数据读取时的文件系统缓存，因此你必须为文件系统缓存留一些空间。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：先设置为内存的<span style="font-family: Times New Roman;">25%</span><span style="font-family: 宋体;">，观察性能变化。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">table_open_cache</span><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">为所有线程打开表的数量。</span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">增加该值能增加<span style="font-family: Times New Roman;">mysqld</span><span style="font-family: 宋体;">要求的文件描述符的数量。可以避免频繁的打开数据表产生的开销</span></span><span style="font-size: 10.5pt; font-family: '宋体';">。打开一个表的开销可能很大，因为<span style="font-family: Times New Roman;">MyISAM</span><span style="font-family: 宋体;">会把</span><span style="font-family: Times New Roman;">MYI</span><span style="font-family: 宋体;">文件的文件头标识为正在使用，所以在内存中做这个操作比较好。，因为每个线程都需要打开表，连接数越大这个值要越大。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：我们有<span style="font-family: Times New Roman;">300</span><span style="font-family: 宋体;">多个表的话，大约</span><span style="font-family: Times New Roman;">2048</span><span style="font-family: 宋体;">差不多了。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';"> <span id="more-346"></span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">thread_cache_size</span><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：缓存可重用的线程数。</span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：这个参数设置线程的缓存，线程的创建和销毁的开销可能很大，因为每个线程的连接<span style="font-family: Times New Roman;">/</span><span style="font-family: 宋体;">断开都需要。如果应用程序中有大量的跳跃并发连接并且线程较多的话，就要加大它的值。它的目的是在通常的操作中无需创建新线程。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：通常至少设置为<span style="font-family: Times New Roman;">16</span><span style="font-family: 宋体;">。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">query_cache_size</span><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：指定<span style="font-family: Times New Roman;">MySQL</span><span style="font-family: 宋体;">查询结果缓冲区的大小。</span></span><span style="font-size: 10.5pt; font-family: '宋体';"> </span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：如果应用程序有大量读，而且没有应用程序级别的缓存，那么这很有用。不过不要设置太大，因为维护它也需要不少开销，这会导致<span style="font-family: Times New Roman;">MySQL</span><span style="font-family: 宋体;">变慢。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: '宋体';">通常设置为 <span style="font-family: Times New Roman;">32-512Mb</span><span style="font-family: 宋体;">。设置完之后最好是跟踪一段时间，查看是否运行良好。在一定的负载压力下，如果缓存命中率太低了，就启用它，如果命中率已经不错了，就可以把他调小一点。</span></span><span style="font-size: 10.5pt; font-family: '宋体';">对于<span style="font-family: Times New Roman;">2G</span><span style="font-family: 宋体;">的内存，先从</span><span style="font-family: Times New Roman;">16M</span><span style="font-family: 宋体;">开始，一倍一倍的增加，直到命中率比较稳定为止。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">query_cache_limit</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：缓存单条<span style="font-family: Times New Roman;"><acronym title="Structured Query Language">SQL</acronym></span><span style="font-family: 宋体;">的结果集上限。默认</span><span style="font-family: Times New Roman;">4KB</span><span style="font-family: 宋体;">。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：当一条<span style="font-family: Times New Roman;"><acronym title="Structured Query Language">SQL</acronym></span><span style="font-family: 宋体;">返回的结果集大于这个限制的时候，将不被</span><span style="font-family: Times New Roman;">MySQL</span><span style="font-family: 宋体;">缓存。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：设置为<span style="font-family: Times New Roman;">1M</span><span style="font-family: 宋体;">即可。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">query_cache_min_res_unit</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：缓存为每个数据集存放的最小内存大小，默认<span style="font-family: Times New Roman;">4KB</span><span style="font-family: 宋体;">。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：如果太小的话，将会导致<span style="font-family: Times New Roman;">MySQL</span><span style="font-family: 宋体;">经常访问内存块去获取信息，如果设置太大则浪费内存。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：如果<span style="font-family: Times New Roman;"><acronym title="Structured Query Language">SQL</acronym></span><span style="font-family: 宋体;">返回的结果集都很小的话，参数也可以调小一点，避免内存浪费。如果结果集大部分都大于</span><span style="font-family: Times New Roman;">4KB</span><span style="font-family: 宋体;">的话，则考虑加大参数。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">back_log</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：在<span style="font-family: Times New Roman;">MySQL</span><span style="font-family: 宋体;">的连接请求等待队列中允许存放的最大连接请求数。系统默认值为</span><span style="font-family: Times New Roman;">50</span><span style="font-family: 宋体;">。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：如果系统在一个短时间内有很多连接，则需要增大该参数的值，该参数值指定到来的<span style="font-family: Times New Roman;">TCP/<acronym title="Internet Protocol">IP</acronym></span><span style="font-family: 宋体;">连接的侦听队列的大小。不同的操作系统在这个队列大小上有它自 己的限制。试图设定</span><span style="font-family: Times New Roman;">back_log</span><span style="font-family: 宋体;">高于你的操作系统的限制将是无效的。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：对于<span style="font-family: Times New Roman;">Linux</span><span style="font-family: 宋体;">系统推荐设置为小于</span><span style="font-family: Times New Roman;">512</span><span style="font-family: 宋体;">的整数。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">sort_buffer_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：为</span><span style="font-size: 10.5pt; font-family: '宋体';">每个需要进行排序的线程分配该大小的一个缓冲区。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: '宋体';">增加这值加速<span style="font-family: Times New Roman;">ORDER BY</span><span style="font-family: 宋体;">或</span><span style="font-family: Times New Roman;">GROUP BY</span><span style="font-family: 宋体;">操作。不过该参数对应的分配内存是每连接独占的，如果有</span><span style="font-family: Times New Roman;">100</span><span style="font-family: 宋体;">个连接，那么实际分配的总共排序缓冲区大小为</span><span style="font-family: Times New Roman;">100</span><span style="font-family: 宋体;">×</span><span style="font-family: Times New Roman;">sort_buffer_size</span><span style="font-family: 宋体;">。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: '宋体';">一般设置为<span style="font-family: Times New Roman;">2M</span></span><span style="font-size: 10.5pt; font-family: '宋体';">观察变化再调整</span><span style="font-size: 10.5pt; font-family: '宋体';">。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">read_buffer_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：顺序</span><span style="font-size: 10.5pt; font-family: '宋体';">查询操作所能使用的缓冲区大小。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: '宋体';">和<span style="font-family: Times New Roman;">sort_buffer_size</span><span style="font-family: 宋体;">一样，该参数对应的分配内存也是每连接独享。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: '宋体';">一般设置为<span style="font-family: Times New Roman;">2M</span></span><span style="font-size: 10.5pt; font-family: '宋体';">再观察变化</span><span style="font-size: 10.5pt; font-family: '宋体';">。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">read_rnd_buffer_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：随机查询操作所能使用的缓冲区大小。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：每个线程独享。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: '宋体';">一般设置为<span style="font-family: Times New Roman;">2M</span></span><span style="font-size: 10.5pt; font-family: '宋体';">再观察变化</span><span style="font-size: 10.5pt; font-family: '宋体';">。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: 'Arial';">query_cache_type</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">含义</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">查询缓冲</span><span style="font-size: 10.5pt; font-family: '宋体';">类型。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">影响</span><span style="font-size: 10.5pt; font-family: '宋体';">：</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">为<span style="font-family: Times New Roman;">1</span><span style="font-family: 宋体;">是使用缓冲，</span><span style="font-family: Times New Roman;">2</span><span style="font-family: 宋体;">是除非使用</span><span style="font-family: Times New Roman;">SQL_CACHE</span><span style="font-family: 宋体;">才进行缓冲</span></span><span style="font-size: 10.5pt; font-family: '宋体';">。对于缓冲而言，数据并不是实时的，有一定的延时。但是对于实时性要求不高的查询短时间内多次执行，是不划算的，这个时候就需要缓存。并且缓存中是区分空格和大小写的，如果大小写不一致和空格不一致，也会认为是不同的<span style="font-family: Times New Roman;"><acronym title="Structured Query Language">SQL</acronym></span><span style="font-family: 宋体;">，不会利用到缓存。虽然不设置查询缓冲，有时可能带来性能上的损失，但有一些</span><span style="font-family: Times New Roman;"><acronym title="Structured Query Language">SQL</acronym></span><span style="font-family: 宋体;">语句需要实时地查询数据，或并不经常使用</span><span style="font-family: Times New Roman;">(</span><span style="font-family: 宋体;">可能一天就执行一两次</span><span style="font-family: Times New Roman;">)</span><span style="font-family: 宋体;">，这样就需要把缓冲关了，可以采用临时关闭的方法</span></span><span style="font-size: 10.5pt; font-family: 'Verdana';">SELECT SQL_NO_CACHE</span><span style="font-size: 10.5pt; font-family: '宋体';">。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 10.5pt; font-family: '宋体';">建议</span><span style="font-size: 10.5pt; font-family: '宋体';">：一般设置为<span style="font-family: Times New Roman;">1</span><span style="font-family: 宋体;">。</span></span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"><br />
</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 14pt; font-family: 'Wingdings';">l </span><span style="font-weight: bold; font-size: 14pt; font-family: '黑体';">MyISAM类：</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">myisam_sort_buffer_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">MyISAM<span style="font-family: 宋体;">表发生变化时重新排序所需的缓冲。一般</span><span style="font-family: Times New Roman;">64M</span><span style="font-family: 宋体;">足矣。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-left: 21pt; text-indent: -21pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 14pt; font-family: 'Wingdings';">l </span><span style="font-weight: bold; font-size: 14pt; font-family: '黑体';">InnoDB类：</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">innodb_buffer_pool_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">对<span style="font-family: Times New Roman;">InnoDB</span><span style="font-family: 宋体;">的效率影响很大。因为</span><span style="font-family: Times New Roman;">InnoDB</span><span style="font-family: 宋体;">会把尽可能多的数据和索引缓存在缓冲区，这个类似与</span><span style="font-family: Times New Roman;">Oracle</span><span style="font-family: 宋体;">的</span><span style="font-family: Times New Roman;">Buffer Pool</span><span style="font-family: 宋体;">：如果只采用</span><span style="font-family: Times New Roman;">InnoDB</span><span style="font-family: 宋体;">，可以把这个参数调大一点，大约内存的</span><span style="font-family: Times New Roman;">70%</span><span style="font-family: 宋体;">左右。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">当然，如果数据量不会暴增并且不是特别大，这个参数还是不要太大了，浪费空间。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">innodb_additional_pool_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">对数据库性能影响不是很大，至少内存足够的机器上不会有什么影响。</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">innodb_log_file_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">在高写入负载尤其是数据集很大的时候，这个值非常重要，值越高性能越好，不过可能会增加数据恢复的时候。我设置为<span style="font-family: Times New Roman;">128M</span><span style="font-family: 宋体;">。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">innodb_log_buffer_size</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">默认的设置在中等强度的写入负载及短事物处理时，性能还可以。但是存在大量更新操作或者负载较大时，就要慢慢增加这个参数的值了。不过不要设置太大，会浪费内存。它每秒都会刷新一次，所以不用设置超过<span style="font-family: Times New Roman;">1s</span><span style="font-family: 宋体;">所需的内存空间，</span><span style="font-family: Times New Roman;">16M</span><span style="font-family: 宋体;">足够了。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-style: italic; font-size: 12pt; font-family: '宋体';">innodb_flush_logs_at_trx_commit</span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">这个参数对<span style="font-family: Times New Roman;">InnoDB</span><span style="font-family: 宋体;">及其重要，设置不好的话会比</span><span style="font-family: Times New Roman;">MyISAM</span><span style="font-family: 宋体;">慢</span><span style="font-family: Times New Roman;">1000</span><span style="font-family: 宋体;">倍！默认是</span><span style="font-family: Times New Roman;">1</span><span style="font-family: 宋体;">，这就是说每次更新事务都会被提交到磁盘，这是非常消耗资源的，硬盘和内存的速度是明显数量级的差距。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">设置为<span style="font-family: Times New Roman;">0</span><span style="font-family: 宋体;">是最快的，但是很不安全，全部在缓存中，一掉电全没了。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">设置为<span style="font-family: Times New Roman;">1</span><span style="font-family: 宋体;">很不好，每次都去写硬盘，没有必要。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';">设置为<span style="font-family: Times New Roman;">2</span><span style="font-family: 宋体;">是比较好的，日志不刷新到磁盘上，只刷新到操作系统缓存上。然后每秒钟写缓存。相对于现在数据库每秒</span><span style="font-family: Times New Roman;">4K</span><span style="font-family: 宋体;">条左右的</span><span style="font-family: Times New Roman;"><acronym title="Structured Query Language">SQL</acronym></span><span style="font-family: 宋体;">，性能已经可以提高不少。</span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"><span style="font-family: 宋体;"> </span></span></p>
<p style="margin-bottom: 0pt; margin-top: 0pt;">
<p style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10.5pt; font-family: '宋体';"><br />
</span></p>
</div><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2010年03月20日 -- <a href="http://www.penglixun.com/tech/database/mysql_index_store_perfomance_effect.html" title="MySQL索引与存储方式对性能的影响">MySQL索引与存储方式对性能的影响</a> (2)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/mysql_parameter_tuning.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

