件。
总的来说,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
innodb_flush_log_at_trx_commit = 0,Innodb 中的Log Thread 每隔1 秒钟会将log buffer中的数据写入到文件,同时还会通知文件系统进行文件同步的flush 操作,保证数据确实已经写入到磁盘上面的物理文件。但是,每次事务的结束(commit 或者是rollback)并不会触发Log Thread 将log buffer 中的数据写入文件。所以,当设置为0 的时候,当MySQL Crash 和OS Crash 或者主机断电之后,最极端的情况是丢失1 秒时间的数据变更。
innodb_flush_log_at_trx_commit = 1,这也是Innodb 的默认设置。我们每次事务的结束都会触发Log Thread 将log buffer 中的数据写入文件并通知文件系统同步文件。这个设置是最安全的设置,能够保证不论是MySQL Crash 还是OS Crash 或者是主机断电都不会丢失任何已经提交的数据。
innodb_flush_log_at_trx_commit = 2,当我们设置为2 的时候,Log Thread 会在我们每次事务结束的时候将数据写入事务日志,但是这里的写入仅仅是调用了文件系统的文件写入操作。而我们的文件系统都是有缓存机制的,所以Log Thread 的这个写入并不能保证内容真的已经写入到物理磁盘上面完成持久化的动作。文件系统什么时候会将缓存中的这个数据同步到物理磁盘文件Log Thread 就完全不知道了。所以,当设置为2 的时候,MySQL Crash 并不会造成数据的丢失,但是OS Crash 或者是主机断电后可能丢失的数据量就完全控制在文件系统上了。
从上面的分析我们可以看出,当innodb_flush_log_at_trx_commit 设置为1 的时候是最安全的,但是由于所做的IO 同步操作也最多,所以性能也是三种设置中最差的一种。如果设置为0,则每秒有一次同步,性能相对高一些。如果设置为2,可能性能是三这种最好的。但是也可能是出现Crash后丢失数据最多的。到底该如何设置设置,就要根据具体的场景来分析了。一般来说,如果完全不能接受数据的丢失,那么我们肯定会通过牺牲一定的性能来换取数据的安全性,选择设置为1。而如果我们可以丢失很少量的数据(比如说1 秒之内),那么我们可以设置为0。当然,如果大家觉得我们的OS 足够稳定,主机硬件设备,而且主机的供电系统也足够安全,我们也可以将innodb_flush_log_at_trx_commit 设置为2 让系统的整体性能尽可能的高。
transaction-isolation
对于高并发应用来说,为了尽可能保证数据的一致性,避免并发可能带来的数据不一致问题,自然是事务隔离级别越高越好。但是,对于Innodb 来说,所使用的事务隔离级别越高,实现复杂度自然就会更高,所需要做的事情也会更多,整体性能也就会更差。
所以,我们需要分析自己应用系统的逻辑,选择可以接受的最低事务隔离级别。以在保证数据安全一致性的同时达到最高的性能。
虽然Innodb 存储引擎默认的事务隔离级别是REPEATABLE READ,但实际上在我们大部分的应用场景下,都只需要READ COMMITED 的事务隔离级别就可以满足需求了。
sync_binlog
表示每次刷新binlog到磁盘的数目。
对于核心系统,我们需要采用双1模式,即:innodb_flush_log_at_trx_commit=1, sync_binlog=1,这样可以保证主备库数据一致,不会有数据丢失。