2010年4月14日星期三

[翻译]How to calculate a good InnoDB log file size

原文在这里

Peter之前写了一篇文章:'选择合适的InnoDB日志文件大小'。不是挑peter的刺儿,这篇文章其实讲了挺多东西,但就是没有告诉你怎么选择合适的日志文件大小!所以我想澄清这一点。

基本的一点是,你的日志文件大小应该满足InnoDB优化自己的IO的需要,但是太大的话崩溃恢复时间就会变得很长。这一点peter已经讲的很清楚。怎么确定这个大小呢?我这里有一个相当不错的经验。

在大多数情况下,当别人给你一个公式来选择一个配置的时候,你应该对它持怀疑的态度。但是在这种情况下,你可以计算出一个合理的值,信不信由你。在你服务器的高峰期运行下面这些查询:


  1. mysql> pager grep sequence

  2. PAGER SET TO 'grep sequence'

  3. mysql> SHOW engine innodb STATUS\G SELECT sleep(60)SHOW engine innodb STATUS\G

  4. Log sequence number 84 3836410803

  5. 1 row IN SET (0.06 sec)


  6. 1 row IN SET (1 min 0.00 sec)


  7. Log sequence number 84 3838334638
  8. 1 row IN SET (0.05 sec)
注意'log sequence number',这个是已经写到事务日志中总的字节数。所以,现在你可以看到每分钟有多少MB写到日志文件中。(这种方法对MySQL的所有版本都有效。在5.0以上的版本中,可以用SHOW GLOBAL STATUS来观察Innodb_os_log_written的变化即可。最后有这种方法的介绍)


  1. mysql> SELECT (3838334638 - 3836410803) / 1024 / 1024 AS MB_per_min;

  2. +------------+

  3. | MB_per_min |

  4. +------------+

  5. | 1.83471203 |


一个粗略的经验,你可以设置日志文件的大小,使它可以存放一个小时左右的日志。一小时的日志是足够应对InnoDB处理的大量数据,数据库就能在周期性的IO刷新和保存进度的过程中使用顺序写。以这样的速度,这个服务器会一共使用大约110MB的日志。为了好计算可以
把这个值约算到128M(2的倍数)。因为默认的日志文件有两个,所以除以二,你可以设置为:

 innodb_log_file_size=64M  

这个值是不是有点儿出乎你意料的小?可能吧,我经常看到这个参数设置上G的。但是大部分都是设置错了。我上面用来计算这个参数的数据库不是个玩具,是一个负载挺大的数据库。在生产环境中日志文件的大小当然不能用默认的5M,但是也往往没有你想象中的那么大。

如果你有一个写操作很繁忙的数据库(可能你会插入很多数据量很大的),根据这个经验计算你得到的日志文件应该为好几G。这种情况下你可能想让日志文件小一点儿,不用GB来做文件结尾。但你同时要意识到:恢复时间不只和日志文件的大小有关,也和日志文件包含的条目数有关系。如果你的日志中,每个条目都很大,但是条目数并不多,那么它的恢复比你预料中的大日志恢复要快很多。

但是在我用这种方法的大多数情况下,我最后都发现合适的日志大小都比当时数据库已经配置好的要小得多。一方面是因为InnoDB日志经过很好的压缩;另一个原因是通常对设置日志大小的建议是错误的:根据innodb_buffer_pool_size来设置它的大小。(就是my.cnf里面的"Set innodb_log_file_size to 25 %of innodb_buffer_pool_size")

最后一个要注意的:很大的缓冲池或者异常繁忙的数据库可能需要更大(或者更小!)的日志大小。这就是公式的分解,需要更多的判断和经验。但是这个'经验法则'是一个很好的开端。

-------------------
附:怎么用Innodb_os_log_written来计算日志文件的大小。
mysql> SHOW GLOBAL STATUS  like 'Innodb_os_log_written';select sleep(60);SHOW GLOBAL STATUS  like 'Innodb_os_log_written';
+-----------------------+--------------+
| Variable_name         | Value        |
+-----------------------+--------------+
| Innodb_os_log_written | 291899526656 |
+-----------------------+--------------+
1 row in set (0.00 sec)

+-----------+
| sleep(60) |
+-----------+
|         0 |
+-----------+
1 row in set (1 min 0.08 sec)

+-----------------------+--------------+
| Variable_name         | Value        |
+-----------------------+--------------+
| Innodb_os_log_written | 291905601536 |
+-----------------------+--------------+
1 row in set (0.00 sec)

没有评论: