简介:mysql
数据库的东西,每每一个参数就牵涉N多知识点。因此简单的说一下。你们都知道innodb是支持事务的存储引擎。事务的四个特性ACID即原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability)。其中原子性,一致性,持久性经过redo log 和 undo来实现。redo log称为重作日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。 当事务提交时,必须先将该事务的全部日志写入到重作日志文件(redo log)进行持久化(固然先写到日志缓冲区,而不是直接写文件,关于何时刷新到磁盘文件,是一个比较复杂的问题,同窗们自行查阅资料),待事务提交操做才算完成。innodb的redo log是顺序I/O,因此设置合适的值可以大大提升数据库性能。那么是否是设置的越大越好呢?sql
设置的过小:当一个日志文件写满后,innodb会自动切换到另一个日志文件,并且会触发数据库的检查点(Checkpoint),这会致使innodb缓存脏页的小批量刷新,会明显下降innodb的性能。数据库
设置的太大:设置很大之后减小了checkpoint,而且因为redo log是顺序I/O,大大提升了I/O性能。可是若是数据库意外出现了问题,好比意外宕机,那么须要重放日志而且恢复已经提交的事务,若是日志很大,那么将会致使恢复时间很长。甚至到咱们不能接受的程度。缓存
那么咱们如何估算log file该设置为多大?一般咱们能够经过观察show status中innodb_os_log_written状态变量来查看innodb对日志文件写出了多少数据。一个好用的经验是,查看10-100秒间隔的数字,而后记录峰值。能够用这个判断日志缓冲是否设置的正好。例如,若看到峰值是每秒写100kb数据到日志,那么1MB的日志缓冲已经足够了。也可使用这个衡量标准来决定日志文件设置多大会比较好。若是峰值是100KB/s,那么256M的日志文件足够存储至少2560秒的日志记录。通常来讲,日志文件的所有大小,应该足够容纳服务器一个小时的活动内容。服务器
下面看实际的测试(因为是虚拟机,因此使用sysbench模拟据量写入,生产环境选择数据库最繁忙的时候测试):socket
[root@yayun-mysql-server ~]# sysbench --test=oltp --oltp-table-size=100000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=180 --mysql-user=root --mysql-socket=/tmp/mysqld.sock --mysql-password=123456 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare
1.首先计算innodb每分钟产生的日志量:性能
(root@yayun-mysql-server) [(none)]>pager grep sequence PAGER set to 'grep sequence' (root@yayun-mysql-server) [(none)]>show engine innodb status\G select sleep(60); show engine innodb status\G Log sequence number 6377275259 1 row in set (0.00 sec) 1 row in set (1 min 0.00 sec) Log sequence number 6403945555 1 row in set (0.00 sec) (root@yayun-mysql-server) [(none)]>nopager PAGER set to stdout (root@yayun-mysql-server) [(none)]>select (6403945555 - 6377275259) / 1024 / 1024 as MB_per_min; +-------------+ | MB_per_min | +-------------+ | 25.43477631 | +-------------+ 1 row in set (0.02 sec) (root@yayun-mysql-server) [(none)]>
注意Log sequence number,这是写入事务日志的总字节数。因此,如今你能够看到每分钟有多少MB日志写入(这里的技术适用于全部版本的MySQL,在5.0及更高版本,你能够从SHOW GLOBAL STATUS的输出看Innodb_os_log_written的值) 。测试
经过计算后获得每分钟有25M的日志写入。atom
根据经验法则。一般咱们设置redo log size足够大,可以容纳1个小时的日志写入量。spa
1小时日志写入量=25M * 60=1500M,大约等于1.5G。因为默认有两个日志重作日志文件ib_logfile0和ib_logfile1。在日志组中的每一个重作日志文件的大小一致,并以循环的方式写入。innodb存储引擎先写重作日志文件0,当达到文件的最后时,会切换到重作日志1,并checkpoint。以此循环。
因此咱们能够大约设置innodb_log_file_size=800M。注意:在innodb1.2.x版本以前,重作日志文件总的大小不得大于等于4G,而1.2.x版本将该限制扩大到了521G。
innodb_log_file_size = 800M
[root@yayun-mysql-server mysql]# du -sh ib_logfile* 801M ib_logfile0 801M ib_logfile1 [root@yayun-mysql-server mysql]#
对于innodb 1.2.x版本以前若是设置大于4G则报错
[root@yayun-mysql-server mysql]# tail -n 10 yayun-mysql-server.err 140511 1:01:15 InnoDB: Completed initialization of buffer pool 140511 1:01:15 InnoDB: Error: combined size of log files must be < 4 GB 140511 1:01:15 [ERROR] Plugin 'InnoDB' init function returned error. 140511 1:01:15 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed. 140511 1:01:15 [ERROR] Failed to initialize plugins. 140511 1:01:15 [ERROR] Aborting 140511 1:01:15 [Note] /usr/local/mysql/bin/mysqld: Shutdown complete 140511 01:01:15 mysqld_safe mysqld from pid file /data/mysql/yayun-mysql-server.pid ended [root@yayun-mysql-server mysql]#
而innodb 1.2.x之后版本则不会:
[root@yayun-mysql-server mysql5.6]# tail -f yayun-mysql-server.err 2014-05-11 01:06:47 5205 [Note] InnoDB: Using Linux native AIO 2014-05-11 01:06:47 5205 [Note] InnoDB: Initializing buffer pool, size = 128.0M 2014-05-11 01:06:47 5205 [Note] InnoDB: Completed initialization of buffer pool 2014-05-11 01:06:47 5205 [Note] InnoDB: Highest supported file format is Barracuda. 2014-05-11 01:06:47 5205 [Warning] InnoDB: Resizing redo log from 2*3072 to 2*327680 pages, LSN=1085681253 2014-05-11 01:06:47 5205 [Warning] InnoDB: Starting to delete and rewrite log files. 2014-05-11 01:06:47 5205 [Note] InnoDB: Setting log file ./ib_logfile101 size to 5120 MB InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100 2014-05-11 01:12:40 5205 [Note] InnoDB: Setting log file ./ib_logfile1 size to 5120 MB InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100
参考资料
http://www.mysqlperformanceblog.com/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/