2010年05月12日

案例:一个引号带来的查询性能提升

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注:译者和出处,并且不能用于商业用途,违者必究.
今天看了一个优化案例觉的挺有代表性,这里记录下来做一个标记,来纪念一下随便的字段定义的问题。

回忆一下,在表的设计中很多人习惯的把表的结构设计成Varchar(64),Varchar(255)之类的,虽然大多数情况只存了5-15个字节.那么我看一下下面这个案例.
查询语句:

	SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_id, channel;

该表(client_id,channel)是一个组合索引.
利用explain,看一下执行计划,对于索引使用上看上非常完美

mysql> explain SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_id, channel;
+----+-------------+-------------+-------+--------------------+--------------------+---------+------+----------+--------------------------+
| id | select_type | table       | type  | possible_keys      | key                | key_len | ref  | rows     | Extra                    |
+----+-------------+-------------+-------+--------------------+--------------------+---------+------+----------+--------------------------+
|  1 | SIMPLE      | xxx_sources | index | idx_client_channel | idx_client_channel | 1032    | NULL | 20207319 | Using where; Using index |
+----+-------------+-------------+-------+--------------------+--------------------+---------+------+----------+--------------------------+
1 row in set (0.00 sec)

看一下实际执行:

mysql> SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = 1301 GROUP BY client_id, channel;
+---------+----------+
| channel | visitors |
+---------+----------+
| NULL    |        0 |
+---------+----------+
1 row in set (11.69 sec)

实际执行的情况非常的糟糕.传通的想法,这个执行从索引上执行计划上看非常完美了,好象和MySQL没什么关系了. 在去看一下表的设计会发现client_id也是设计成了
varchar(255).看到这里不防可以使用下面的方法试一下:

mysql> explain SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = '1301' GROUP BY client_id, channel;
+----+-------------+-------------+------+--------------------+--------------------+---------+-------+--------+--------------------------+
| id | select_type | table       | type | possible_keys      | key                | key_len | ref   | rows   | Extra                    |
+----+-------------+-------------+------+--------------------+--------------------+---------+-------+--------+--------------------------+
|  1 | SIMPLE      | xxx_sources | ref  | idx_client_channel | idx_client_channel | 258     | const | 457184 | Using where; Using index |
+----+-------------+-------------+------+--------------------+--------------------+---------+-------+--------+--------------------------+
1 row in set (0.00 sec)

从执行计划上来看,差不多,但实际差多了.具体上来看key_len从1032降到了258,执行计划变成了const基于等于的查找,行数从原来千万级到了十万级了.不算也能明白IO
节省了很多.
再来看实际执行:

mysql> SELECT SQL_NO_CACHE channel, COUNT(channel) AS visitors FROM xxx_sources WHERE client_id = '1301' GROUP BY client_id, channel;
+---------+----------+
| channel | visitors |
+---------+----------+
| NULL    |        0 |
+---------+----------+
1 row in set (0.25 sec)

哇,从11.69秒变成了0.25秒,这是什么概念,优化了多少倍,算一下吧.

看到这里在想什么呢,记住这个案例,嗯,不错,以后还可以加引号优化一下.那为什么不问一下,能不能在优化了,为什么会这样呢?
我们先来看一下第一个问题:
能不能在优化了?
答案是当然可以了.从索引的长度上来看258还是一个非常大的数据,对于client_id这个字段从名字上来看,也只会存数据型的值,那为什么不用的一个int unsigned去存呢,
索引的长度马上会从258降到4。这样不是又节省了很多吗?
接下来看一下第二个问题,为什么会这样呢?
原因有两点,同时基于一个原则,基于成本的优化器。对于client_id在表的定义时定义成了字符型的值,在查询时传入了数值型的值,需要经过一个数值转换,悲剧的开始,最终
导致MySQL选择了一个完成的索引去扫描。

从这个案例上,我们需要注意什么呢?
合理的选择数据类型,基本工太重要了,就这叫赢在起跑线,一切都不能随便了,别把一个表定义成了降了主建外其它全是Varchar(255)。对数据库的double/float这种字
段做索引时一定要小心。

待思考:
为什么加一个引号后索引长度执行计划变成了258,为什么是258呢,不是别的呢。

2010年04月8日

Linux运维Tips(-)

        作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注:译者和出处,并且不能用于商业用途,违者必究.

       对于一个Linux运维团队,在管理一些机器时,难免会出现一些尴嘎的事情,A同事在操作的时间,B同事也上去操作了;本来工作时间上去时,如果看一下磁盘使用状态,也许就必免了假日收到了短信报警。对于这些问题怎么处理呢?

      聪明的朋友说,登录到系统后运行一下w 和df -h不就行了。是的,这是一个很好的解决方法。但人总是懒惰的。要不,也不会出那么事了。

        这里提供一个自动化每一个用户登录上去,自动把df  -h 和w的结果输出到终端。实现方法: 编辑~/.profile 或是 ~/.bashrc (提倡改.profile)在最后添加:

echo "============================="
 
df -h
 
echo "============================="
 
w

       然后再登录到系统中时就会自动显示:

=============================
 
Filesystem            Size  Used Avail Use% Mounted on
 
/dev/sda2             3.9G  2.4G  1.4G  65% /
 
/dev/sda1             122M   12M  104M  11% /boot
 
tmpfs                 250M     0  250M   0% /dev/shm
 
/dev/sdb1           11G  1.9G  9.1G  17% /data
 
=============================
 
 09:15:00 up 28 days, 20 min,  1 user,  load average: 0.00, 0.00, 0.00
 
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
wubx     pts/0    10.10.15.72      09:15    0.00s  0.02s  0.02s -bash

2010年03月31日

利用tcpflow抓取SQL

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注:译者和出处,并且不能用于商业用途,违者必究.

以前介绍过利用tcpdump抓取相关的SQL,但是在识别方面并不友好,只是能看到相关的SQL。今天推荐一个强劲的工具:tcpflow加一些牛人们开发的工具从而实现友好的显示相关的SQL。
相关工具下载,功先欲其事,必先利其器:
Tcpflow 下载:http://www.circlemud.org/~jelson/software/tcpflow/
extract_queries.: http://mysqldump.azundris.com/uploads/extract_queries.c
使用方法:
#mkdir flow
#cd flow
#tcpflow –i eth0 dst MasterIP and port 3306
等待一会 Ctrl+c

#cd ..
# find flow –print0 |xargs -0 extract_queries –u >slow
#mysqldumpslow -s c slow >stats

不足之处:
不能真正把SQL的执行时间记录下来,因为这个只是网络IO的流量抓取,同时这个也不能把真正的连接数据库的用户抓下来。
原文地址:http://mysqldump.azundris.com/archives/85-Getting-SQL-from-a-SPAN-port.html

2010年03月19日

FaceBook开始关注MySQL5.1了

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注:译者和出处,并且不能用于商业用途,违者必究.

FaceBook开始关注MySQL5.1了 ,说明MySQL5.1开始靠谱了。

MySQL-5.1面世将近一年多的时间了,在2009年大家对MySQL-5.1试用,放弃,最终的无耐。但MySQL总的还是在进步的,差不多到MySQL-5.1.41基本上处于稳定阶段了。到了MySQL-5.1.44好象更是稳定了,本人觉的可以试着用到生产环境了。在Mail列表中,看到好多人对MySQL5-1.44和MySQL-5.1.45有了很高的信心。

FaceBook的关注毕将会把自已对MySQL的改善也会加入到他使用的版本,Facebook将会使用MySQL-5.1.44做会一个基本版本进行Patch。项目网址:https://launchpad.net/mysqlatfacebook/51

如果对MySQL5.1比较关注,也请保持对这个项目关注。

2010年03月17日

MySQL不同分支版本的压力测试

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注:译者和出处,并且不能用于商业用途,违者必究.

压力测试的目的:
通过压力测试了解一下不同发行版本的性能区别。
MySQL不的版本测试,MySQL同样的配置
具体版本如下:
MySQL-5.1.42企业版+innodb-plugin
MySQL-5.1.42企业版+默认的innodb
MySQL-5.1.43开源版+ innodb-plugin
MySQL-5.1.43 Percona
操作系统:
Redhat Enterprise 5.4
硬件: Dell R710,RAM:48G,硬盘:6块SAS做Radid10

压力设置
创建一个1kw的Innodb表,使用16个并发去进行读取写入更新事务方面的操作.
测试工具:
Sysbench
测试方法:
创建数据:

time sysbench --mysql-user=root --mysql-host=localhost --test=oltp --oltp-test-mode=complex --mysql-table-engine=innodb --oltp-table-size=10000000 --mysql-db=test --oltp-table-name=innodb_1kw --num-threads=16 --max-requests=500000 preware

测试:

time sysbench --mysql-user=root --mysql-host=localhost --test=oltp --oltp-test-mode=complex --mysql-table-engine=innodb --oltp-table-size=10000000 --mysql-db=test --oltp-table-name=innodb_1kw --num-threads=16 --max-requests=500000 run

MySQL的基本配置

innodb_buffer_pool_size = 30G
innodb_data_file_path = ibdata1:1G:autoextend
transaction_isolation = READ-COMMITTED
innodb_thread_concurrency = 16
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 8M
innodb_log_file_size = 256M
innodb_log_files_in_group = 3
innodb_log_group_home_dir=/u1/mysqlp/logs/
innodb_max_dirty_pages_pct = 75
innodb_flush_method=O_DIRECT
innodb_lock_wait_timeout = 20
innodb_file_per_table = 1
启用innodb-plugin,innodb-plugin的版本号为:1.0.6

测试结果
分别测试三次,取平均值:

版本 事务/秒 写入读取/秒 其它操作/秒
MySQL企业版Innodb 1882.32 35764.1 3764.64
MySQL企业版Innodb-plugin 2395.073 45506.45 4790.15
MySQL开源版innodb-plugin 2288.09 43473.72 4576.18
Precona-MySQL 2754.24 52330.52 5508.48

1kw 写入的速度

版本 写入1kw数据总时间 用户 系统
MySQL企业版Innodb 3m25.318s 0m1.953s 0m0.177s
MySQL企业版Innodb-plugin 3m0.077s 0m1.783s 0m0.081s
MySQL开源版Innodb-plugin 3m0.169s 0m1.882s 0m0.125s
Precona-MySQL 3m0.030s 0m1.979s 0m0.192s

结果分析
事务对比:
transcation
写入读取对比:
readwrite
其它操作对比:
other
MySQL的开源版和企业版的Innodb性能相差不大,所以这里不在单独比较。总的来看Precona的MySQL性能表现良好。针对Innodb-plugin的的比较MySQL的企业版少表现比较好一点。从数据上来看选择不同的版本性能上最大的区别基本接近2倍。

2010年02月2日

Linux 安装pptp vpn client

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注:译者和出处,并且不能用于商业用途,违者必究.

    Linux使用pptp vpn client 其实很简单的,只是相对文档较少或是落后造成很多Linuxer报怨。下面我简单的列一下操作步骤。

背景:
    系统使用Redhat Enterprise 5.4(CentOS也支持)
    该文档应该能适应不同的Linux。
    基于命令行的操作。我的开发机器上没装图形界面。

需要软件:
     pptp 该软件可以从:
     http://pptpclient.sourceforge.net/#download
     pppd 一般系统自带。

安装:
      下载pptp,下载相应的pptp的RPM包即可。
      rpm -ivh pptp-*.rpm
      这样基本上完成了50%的工作了。
配置:   
     pptp安装后有一个配置命令:pptpsetup

# pptpsetup –help

pptpsetup –create <TUNNEL> –server <SERVER> [--domain <DOMAIN>]

          –username <USERNAME> [--password <PASSWORD>]

          [--encrypt] [--start]

 

pptpsetup –delete <TUNNEL>

Options:
* <TUNNEL>  配置文件的名称,可以根据不同的连接用不同的名字,自已指定,我这里有vpn.
* <SERVER>  PPTP SERVER的IP。
* <DOMAIN> 所在的域,可以省略,一般不用。
* <USERNAME>  VPN 上认证用的用户名,VPN用户
* <PASSWORD>  VPN上用户认证用的密码
* –encrypt 启用加密
*           当没使用–encrypt 连接时出现下面的错误时,表示使用了加密,这点也可以和VPN的管理员联系确认一下,遇到下面的*           情况可以加上该参数。
*                    CHAP authentication succeeded
*                          LCP terminated by peer (ZM-76-^@<M-Mt^@^@^BM-f
*                            
* –start  直接连接,第一次使用。

创建配置文件

假设VPN的用户名和密码都是wubx,IP是:xxx.xxx.xxx.xx

#pptpsetup –create vpn –server XXX.XXX.XXX.XX  –username wubx –password wubx –encrypt –start

         运气好了,就可以看到连接成功的信息了。
    如:

Using interface ppp0

Connect: ppp0 <–> /dev/pts/2

CHAP authentication succeeded

MPPE 128-bit stateless compression enabled

local  IP address 192.168.111.103

remote IP address 192.168.111.100

以后的启动可以使用:

pppd call vpn

相应的LOG也可以在/var/log/message中查看。

然后可以利用route命令添加相应的路由:
如我这边VPN的机器所在网段是192.168.110.0/24 那么我就可以使用:

#route add -net  192.168.110.0 netmask 255.255.255.0  gw 192.168.112.100 device ppp0

添加完路由就可以使用了。

备注:

建立连接:    

对于以后VPN的启动可以写一个ppp-on 放到/usr/local/bin内容:
#!/bin/bash

exec /usr/sbin/pppd call vpn

关闭连接:

可以写一个ppp-off放到/usr/local/bin/下,内容如下:

#!/bin/bash

if [ "$1" = "" ]; then

        DEVICE=ppp0

else

        DEVICE=$1

fi

if [ -r /var/run/$DEVICE.pid ]; then

        kill -INT `cat /var/run/$DEVICE.pid`

        if [ !"$?" = "0" ]; then

                rm -rf /var/run/$DEVICE.pid

                echo “ERROR: Removed stale pid file”

                exit 1

        fi

echo “PPP link to $DEVICE terminated.”

exit 0

fi

echo “ERROR: PPP link is not active on $DEVICE”

exit 1

路由添加:

         可以写到/etc/ppp/ip-up中:

         在exit 0前添加:

route add -net  192.168.110.0 netmask 255.255.255.0  gw 192.168.112.100 device ppp0

具体参考:
  PPP-HOWTO  http://man.chinaunix.net/linux/how/PPP-HOWTO.html#toc15

2010年01月20日

Innodb 表和索引结构

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

表的结构:

对于MySQL把有的存储引擎都是把表结构的定义存放到.frm文件中。但对于Innodb表同时有一个内部的字典存放到表空间中。所以对于Innodb表不能单纯的移动.frm在不同的MySQL事例下。对于Innodb引擎的表,如果MySQL 删除相应的表或数据库,同时会删除相应的.frm及在表空间的相应的字典信息。在.frm文件只是用来定义表的结构,Innodb把数据和索引都存放到了表空间中。

聚集索引和次要索引:

每一个Innodb表都有一个聚集索引,这个聚信索引和行数据存在一起。

可以用来做聚集索引的列:

  • 如果有声明了主建(primary key),则这个列可以做为表的主建。
  • 如果没有声明主建,MySQL会用一个唯一索引(UNIQUE)而且是不为空的列做为主建,成为该表的聚信索引。
  • 如果没声明主建,同时也没合适的唯一的索引,Innodb内部会产生一个隐藏的聚集索引:RowID。这个RowID在Innodb的多版本中曾提到过。这个RowID是在插入时产生,并且是自增的增加。所以也是按顺序增长存放。

由于聚集索引和行数据存放一起(在同一个数据页中),所以利用聚集索引访问数据行时,非常的快,同一个数据页在访问索引时,已经把页加载到Buffer中,在访问数据时,等于了一个顺序IO的访问(内存中完成)。大多数情况下索引和数据都不在一块(MyISAM,数据和索引存到不同的文件中),而聚集索引是有结构的通常是按顺序存放,同时和数据存放在一起,利用索引索引访问大表的数据可以节省许多IO。

对于Innodb次要的索引会包含聚信索引,查询在使用次要索引时,找到聚集索引信息,然后利用聚集索引信息访问行。所以,如果聚集索引过长,会造成空间浪费严重。另外,如果对表或是区间进行Count操作的话,大多数情况较短的次要索引比基于聚集索引快。对于Innodb的聚集索引选择,尽量选择比较短的列做为聚集索引列,是一个好的设计习惯。

索引的物理结构:

Innodb的索引以B-tree的形式存到各个叶点上。索引叶点页的大小默认为16K,当有什么的索引插入叶点时,该叶点至少会保留1/16的空闲空间,用于将来该叶点的索引更新或是插入。

对于顺序写入的索引(无论是递增或是递减,顺序的就行),索引叶点可以达到15/16满。如果是随机的索引写入行为,叶点只会达到1/2到15/16满。当叶点填充在1/2以下满,或是被删除到1/2下满时,Innodb会缩短索引树,试图释放该叶点,该叶点可以被继续写入数据。

设计中的Tips:

因为Innodb表的数据是依赖于聚集索引顺序存放,同时聚集索引和数据一块存储,普通索引也需要存放一份聚集索引。所以对于聚集索引的设计尽量按顺序写入,必免数据分页,行迁移等对性能影响的现象。另外聚集索引要设计的尽可能短。从设计上必须锁的时间,大量随机IO的出现。
如对于监控(或是股票类的信息)可以利用时间和类型构成聚集索引,让相关性高的数据尽可能位到一块。以便读取时可以利用顺序IO读取到相应的数据。最好的情况,相关性高的数据在一个Page上,这样读取的效果更好。基于Innodb聚集索引的特性,在设计上也需要考虑利用一下优势,必免其不好的一方面从而达到最佳性能。

2010年01月11日

MegaCli 学习 及R710 可选Raid卡分类

    作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

MegaCli常用参数介绍
MegaCli -adpCount 【显示适配器个数】
MegaCli -AdpGetTime –aALL 【显示适配器时间】
MegaCli -AdpAllInfo -aAll     【显示所有适配器信息】
MegaCli -LDInfo -LALL -aAll    【显示所有逻辑磁盘组信息】
MegaCli -PDList -aAll    【显示所有的物理信息】
MegaCli -AdpBbuCmd -GetBbuStatus -aALL |grep ‘Charger Status’ 【查看充电状态】
MegaCli -AdpBbuCmd -GetBbuStatus -aALL【显示BBU状态信息】
MegaCli -AdpBbuCmd -GetBbuCapacityInfo -aALL【显示BBU容量信息】
MegaCli -AdpBbuCmd -GetBbuDesignInfo -aALL    【显示BBU设计参数】
MegaCli -AdpBbuCmd -GetBbuProperties -aALL    【显示当前BBU属性】
MegaCli -cfgdsply -aALL    【显示Raid卡型号,Raid设置,Disk相关信息】
MegaCli -cfgdsply -aALL |grep Policy      【查看Cache 策略设置】
MegaCli -AdpBbuCmd -GetBbuStatus -aALL |grep ‘Relative State of Charge’【查看充电进度百分比】
磁带状态的变化,从拔盘,到插盘的过程中。
Device         |Normal|Damage|Rebuild|Normal
Virtual Drive     |Optimal|Degraded|Degraded|Optimal
Physical Drive     |Online|Failed –> Unconfigured|Rebuild|Online

R710 可选Raid卡分类

内部:
PERC H200(6 Gb/秒)
PERC H700(6 Gb/秒),配备512 MB电池后备高速缓存
SAS 6/iR
PERC 6/i,配备256 MB电池后备高速缓存
PERC S100(基于软件)
PERC S300(基于软件)
外部:
PERC H800(6 Gb/秒),配备512 MB电池后备高速缓存
PERC 6/E,配备256 MB或512 MB电池后备高速缓存
外部HBA(非RAID):
SAS 5/E HBA
LSI2032 PCIe SCSI HBA

2010年01月8日

小心对待query_cache_size

        作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

       对于使用MySQL的用户,对于这个变量大家一定不会陌生。前几年的MyISAM引擎优化中,这个参数也是一个重要的优化参数。但随着发展,这个参数也爆露出来一些问题。

       机器的内存越来越大,人们也都习惯性的把以前有用的参数分配的值越来越大。这个参数加大后也引发了一系列问题。我们首先分析一下query_cache_size的工作原理:

       一个SELECT查询在DB中工作后,DB会把该语句缓存下来,当同样的一个SQL再次来到DB里调用时,DB在该表没发生变化的情况下把结果从缓存中返回给Client。

   这里有一个关建点,就是DB在利用Query_cache工作时,要求该语句涉及的表在这段时间内没有发生变更。那如果该表在发生变更时,Query_cache里的数据又怎么处理呢?首先要把Query_cache和该表相关的语句全部置为失效,然后在写入更新。那么如果Query_cache非常大,该表的查询结构又比较多,查询语句失效也慢,一个更新或是Insert就会很慢,这样看到的就是Update或是Insert怎么这么慢了。

   所以在数据库写入量或是更新量也比较大的系统,该参数不适合分配过大。而且在高并发,写入量大的系统,建系把该功能禁掉。

 

2010年01月5日

Innodb 多版本实现

    作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究

     Innodb是一个多版本的存储引擎,它可以把旧的行信息存到表空间中。这些旧的行信息存储到Innodb称为的回滚段的表空间中。

     Innodb为实现多版本,Innodb在每一行添加了三个列。一个6字节的DB_TRX_ID字段用来表示事务的Insert或是Update操作,对于Delete操作实际上也并不在直接删除,只是用一个Bit位去标识行被删除。另外,每行包括7字节的DB_ROLL_PTR字段,称为回滚指针(roll pointer)。这个回滚指针指向回滚段(undo segment)中的回滚记录。如果行被更新,那么回滚段中记录的信息足以使update操作加到update操作之间。最后还有一个6字节的DB_ROW_ID字段,该字段包含新行的Row Id,这个字段只在Insert操作时单纯的增加。DB_ROW_ID是需要一个互诉锁的才能产生。Innodb产生的clustered index包括Row ID.从另一方面来说,除了Clustered Index索引外,其它的索引不会包含Row Id.

     Innodb利用回滚段保存的信息完成事务的回滚。同样是为了读取早的版本行信息,通过回滚段中的信息达到一致性读。

       回滚段中的回滚日值可以区分为insert和update日值。Insert的回滚日值只需要一个事务回的信息,记录Insert的操作的事务就行,该回滚信息在事务提交后被丢弃。Update的回滚日值不但用来撤销事务,同时也为一致性读服务。在事务操作中,别的Session可以通过Update的回滚段信息达构建早期的版本,从来达到一致性读。

       对于Innodb的多版本是为达到一致性读,我们在使用Innodb时要养成一个习惯:要规律的提交我们的事务。另一方面,对于Innodb的回滚段中Update的回滚日值不能随着事务的提交而被丢弃,所以回滚段有可能增长很大,填满所有的表空间。

       回滚段的需求的物理大小通常比Insert和Update的行小的多,所以我们可以根据Insert,Update行的并发量来估算分配回滚段的大小。

    在Innodb的多版本设计中,Delete语句并不是直接物理的从数据中立即删除相应的行,只是做一个Bit位的标识。另外当Innodb删除相应的原行和行的索引信息时,回滚段中此行的Update回滚日值才会被清除。对于Delete操作的的删除我们称为静化(purge),这个操作是很快速的,正常情况下静化在SQL语句后按一定的顺序去执行删除操作。

    假设一个场景:当一个用户用小的批量插入和删除行操作在一个表,它有可能会造成静化操作的进程落后,从而造成表的增长的很大很大,使的磁盘的工作效率比较低了。这样就会出现恶劣的情况既使表只有该表只有10M的数据,也有可能使表空间增长到10G,当然里面有很多是即将过静化掉的行(dead row).基于这个原因,静化进程会造成新的行操作和分配资源的性能瓶颈。所以也要关注一下innodb_max_purge_lag这个参数的设定是不是合适。