innodb_buffer_pool_size
innodb_buffer_pool_size 参数用来设置Innodb 最主要的Buffer(Innodb_Buffer_Pool)的大小,也就是缓存用户表及索引数据的最主要缓存空间,对Innodb 整体性能影响也最大。
对于一台单独给MySQL 使用的主机,并假设只使用innodb引擎,一般建议该参数为物理内存的75%左右。
当系统上线之后,我们可以通过Innodb 存储引擎提供给我们的关于Buffer Pool 的实时状态信息作出进一步分析,来确定系统中Innodb 的Buffer Pool 使用情况是否正常高效:
mysql> show status like 'Innodb_buffer_pool_%';
+-----------------------------------------+---------------+
| Variable_name | Value |
+-----------------------------------------+---------------+
| Innodb_buffer_pool_pages_data | 999020 |
| Innodb_buffer_pool_pages_dirty | 47643 |
| Innodb_buffer_pool_pages_flushed | 474668167 |
| Innodb_buffer_pool_pages_LRU_flushed | 365125 |
| Innodb_buffer_pool_pages_free | 0 |
| Innodb_buffer_pool_pages_made_not_young | 0 |
| Innodb_buffer_pool_pages_made_young | 203410903 |
| Innodb_buffer_pool_pages_misc | 49552 |
| Innodb_buffer_pool_pages_old | 368697 |
| Innodb_buffer_pool_pages_total | 1048572 |
| Innodb_buffer_pool_read_ahead_rnd | 0 |
| Innodb_buffer_pool_read_ahead | 66348855 |
| Innodb_buffer_pool_read_ahead_evicted | 3716819 |
| Innodb_buffer_pool_read_requests | 3215992991498 |
| Innodb_buffer_pool_reads | 65634998 |
| Innodb_buffer_pool_wait_free | 651 |
| Innodb_buffer_pool_write_requests | 21900970785 |
+-----------------------------------------+---------------+
从上面的值我们可以看出总共1048572个 pages,其中放数据的有999020个 pages,且已没有free状态的page。
innodb_buffer_pool_instances
该参数将innodb_buffer_pool划分为不同的instance,每个instance独立的LRU、FLUSH、FREE、独立的mutex控制。
对于比较大的innodb_buffer_pool_size,建议设置多个instances,避免内存锁的争用。
innodb_log_file_size
设置innodb redo log file的大小,从性能角度来看,日志文件越大越好,可以减少buffer pool checkpoint的频率,但是在MySQL的官方版本中,iinnodb_log_file_size*innodb_log_files_in_group不能超过4G。
日志文件越大,也意味着MySQL实例crash之后恢复的时间越长,不过一般生成系统都会配置主从库,因此这个因素可以忽略不考虑。
一般来说,在我个人维护的环境中,比较偏向于将事务日志设置为3 组,每个日志设置为256MB 大小,整体效果还算不错。
innodb_log_buffer_size
顾名思义,这个参数就是用来设置Innodb 的Log Buffer 大小的,系统默认值为1MB。Log Buffer的主要作用就是缓冲Log 数据,提高写Log 的IO 性能。一般来说,如果你的系统不是“写负载非常高且以大事务居多”的话,8MB 以内的大小就完全足够了。
我们也可以通过系统状态参数提供的性能统计数据来分析Log 的使用情况:
mysql> show status like 'innodb_log%';
+---------------------------+------------+
| Variable_name | Value |
+---------------------------+------------+
| Innodb_log_waits | 0 |
| Innodb_log_write_requests | 3486920147 |
| Innodb_log_writes | 352577360 |
+---------------------------+------------+
如果Innodb_log_waits不等于0的话,表示出现过Log Buffer的写等待,表示innodb_log_buffer_size有可能过小。
innodb_thread_concurrency
该参数表示innodb最大线程并发量,官方推荐设为0,表示由innodb自己控制,但实践证明,当并发过大时,innodb自己会控制不当,可能导致MySQL hang死,所以一般建议为CPU核心数(不含超线程)
innodb_io_capacity
表示每秒钟IO设备处理数据页的上限,如果硬盘性能比较好,可以设大一些(如1000)。
innodb_max_dirty_pages_pct
表示innodb从buffer中刷新脏页的比例不超过这个值,每次checkpoint的脏页刷新为:innodb_max_dirty_pages_pct*innodb_io_capacity
Innodb_flush_method
用来设置Innodb 打开和同步数据文件以及日志文件的方式,不过只有在Linux & Unix 系统上面有效。当我们设置为O_DSYNC,则系统以O_SYNC 方式打开和刷新日志文件, 通过fsync() 来打开和刷新数据文件。而设置为O_DIRECT 的时候, 则通过O_DIRECT(Solaris 上为directio())打开数据文件,同时以fsync()来刷新数据和日志文件。
总的来说,innodb_flush_method 的不同设置主要影响的是Innodb 在不同运行平台下进行IO 操作的时候所调用的操作系统IO 借口的区别。而不同的IO 操作接口对数据的处理方式会有一定的区别,所以处理性能也会有一定的差异。一般来说,如果我们的磁盘是通过RAID 卡做了硬件级别的RAID,建议可以使用O_DIRECT,可以一定程度上提高IO 性能,但如果RAID Cache 不够的话,还是需要谨慎对待。
innodb_file_per_table
一般建议开启,因为不同的表空间可以灵活设置数据目录的地址,避免共享表空间产生的IO竞争。
innodb_flush_log_at_trx_commit
transaction-isolation
对于高并发应用来说,为了尽可能保证数据的一致性,避免并发可能带来的数据不一致问题,自然是事务隔离级别越高越好。但是,对于Innodb 来说,所使用的事务隔离级别越高,实现复杂度自然就会更高,所需要做的事情也会更多,整体性能也就会更差。
所以,我们需要分析自己应用系统的逻辑,选择可以接受的最低事务隔离级别。以在保证数据安全一致性的同时达到最高的性能。
虽然Innodb 存储引擎默认的事务隔离级别是REPEATABLE READ,但实际上在我们大部分的应用场景下,都只需要READ COMMITED 的事务隔离级别就可以满足需求了。
sync_binlog
表示每次刷新binlog到磁盘的数目。
对于核心系统,我们需要采用双1模式,即:innodb_flush_log_at_trx_commit=1, sync_binlog=1,这样可以保证主备库数据一致,不会有数据丢失。