欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

事务性表的性能

程序员文章站 2022-06-11 13:11:39
...

MySQL 中的 Innodb 除了支持行锁定外,还支持事务,这往往也是使用 Innodb 的另一个原因。在一些特定的应用中,程序依赖于数据库提供的事务操作(如 rollback 或者 commit),这给应用程序带来了不少方便。

 

当然,如果你并没有在应用程序中使用事务操作的打算,而只是看中了 Innodb 的其它特性,比如行锁定、外键以及易于修复等,你仍然可以使用它。虽然人们一提到 Innodb 就会联想到事务,但是大多数的站点使用 Innodb 都不是冲着事务,而是为了理想中的性能,事实上大多数的站点都不需要事务级别的保障。

 

也许行锁定正符合你的站点应用类型,而且由于行锁定带来的其它问题你都可以统统搞定,那么,对于一个事务性表,我们需要注意哪些呢?

 

预写日志方式(WAL),这也是 Innodb 实现事务的方法。当有事务提交时,Innodb 首先将它写到内存中的事务日志缓冲区,随后当事务日志写入磁盘时, Innodb 才更新实际数据和索引。这里有一个关键点,那就是事务日志何时写入磁盘。

 

为此,MySQL 提供了一个配置选项,它有3个可选的值:

innodb_flush_log_at_trx_commit = 1

表示事务提交时立即将事务日志写入磁盘,同时数据和索引也立即更新。这符合事务的持久性原则。

innodb_flush_log_at_trx_commit = 0

表示事务提交时不立即将事务日志写入磁盘,而是每隔1秒写入磁盘文件一次,并且刷新到磁盘,同时更新数据和索引。这样一来,如果 mysqld 奔溃,那么在内存中事务日志缓存区最近 1 秒的数据将会丢失,这些更新将永远无法恢复。

innodb_flush_log_at_trx_commit = 2

表示事务提交时立即写入磁盘文件,但是不立即刷新到磁盘,而是每隔1秒刷新到磁盘一次,同时更新数据和索引。在这种情况下,即使 mysqld 奔溃后,位于内核缓冲区的事务日志仍然不会丢失,只有当操作系统奔溃的时候才会丢失最后 1 秒的数据。

 

上面提到的“写入磁盘文件”和“刷新到磁盘”,它们的区别在于前者只是将数据写入位于物理内存中的内核缓冲区,而后者是将内核缓冲区中的数据真正写入磁盘。

显然,将 innodb_flush_log_at_trx_commit 设置为 0 可以获得最佳性能,同时它的数据丢失可能性也最大。

 

另一个重要的配置选项是 Innodb 数据和索引的内存缓冲池大小,MySQL 提供了 innodb_buffer_pool_size 选项来设置这个数值,如果你在 MySQL 中大量使用 Innodb 类型表,则可以将缓冲池大小设置为物理内存的 80%,并持续关注它的使用率。

 

另外,可以这样设置 innodb_flush_method 选项:

innodb_flush_method = O_DIRECT

这样一来,innodb 将可以跳过文件系统缓冲区,提高 I/O 性能,同时凭借自身的缓冲池更加高效地工作。