使用 innodb_flush_log_at_trx_commit = 2 是否安全

Bru*_*Dou 63 mysql innodb performance

我转身innodb_flush_log_at_trx_commit = 2获得了非常快的写入速度。但是在生产网站中使用它安全吗?

Rol*_*DBA 64

您最多可能会丢失一秒钟的交易。默认值为 1,这有助于保持 InnoDB ACID Compliant

根据innodb_flush_log_at_trx_commit上的 MySQL 文档

如果 innodb_flush_log_at_trx_commit 的值为 0,则日志缓冲区每秒写入日志文件一次,并对日志文件执行刷新到磁盘操作,但在事务提交时不执行任何操作。当值为 1(默认值)时,日志缓冲区会在每次事务提交时写入日志文件,并对日志文件执行刷新到磁盘操作。当值为 2 时,日志缓冲区会在每次提交时写入文件,但不会对其执行刷新到磁盘操作。但是,当值为 2 时,日志文件的刷新也会每秒发生一次。请注意,由于进程调度问题,每秒刷新一次并不能 100% 保证每秒发生一次。

完全符合 ACID 需要默认值 1。您可以通过将值设置为不为 1 来获得更好的性能,但是您可能会在崩溃中丢失多达一秒钟的事务。值为 0 时,任何 mysqld 进程崩溃都可以清除事务的最后一秒。值为 2 时,只有操作系统崩溃或断电才能擦除最后一秒的事务。无论值如何,InnoDB 的崩溃恢复都有效。

为了在使用 InnoDB 和事务的复制设置中获得最大可能的持久性和一致性,请在主服务器 my.cnf 文件中使用 innodb_flush_log_at_trx_commit=1 和 sync_binlog=1。

警告

许多操作系统和一些磁盘硬件欺骗了刷新到磁盘操作。他们可能会告诉 mysqld 刷新已经发生,即使它没有发生。那么即使设置为 1 也不能保证事务的持久性,在最坏的情况下,断电甚至会损坏 InnoDB 数据库。在 SCSI 磁盘控制器或磁盘本身中使用电池供电的磁盘缓存可加快文件刷新,并使操作更安全。您还可以尝试使用 Unix 命令 hdparm 禁用硬件缓存中磁盘写入的缓存,或使用特定于硬件供应商的其他一些命令。

基于此,1 以外的值会使 InnoDB 面临丢失 1 秒事务或事务提交数据的风险。

该文档还说使用sync_binlog=1.

根据sync_binlog上的 MySQL 文档

值 1 是最安全的选择,因为在发生崩溃的情况下,您最多会丢失二进制日志中的一个语句或事务。然而,它也是最慢的选择(除非磁盘有电池供电的缓存,这使得同步非常快)。

您最安全的选择是

[mysqld]
innodb_flush_log_at_trx_commit=1
sync_binlog=1
Run Code Online (Sandbox Code Playgroud)

如果您不介意可能的数据丢失(最多 1 秒的价值),那么如果回报(更快的写入速度)值得,您可以自担风险使用 0 或 2。


小智 30

我的意见与其他答案不同。

innodb_flush_log_at_trx_commit = 0只在没有敏感数据的开发计算机或家庭迷你数据库上使用。

我使用的innodb_flush_log_at_trx_commit = 2是博客/统计数据/电子商务数据库(一天有大约 100 倍的商店)等。

innodb_flush_log_at_trx_commit = 1如果您有很多客户或者您需要像银行一样进行货币交易,我会使用它。因此,这一次您应该在多个服务器之间拆分数据流以提高速度安全性。

我更喜欢 2,因为它的写入速度要快得多,而且只有在硬件出现故障时才会出现故障。

只能决定是否需要快速写入或有保证的数据一致性、完整性和持久性。


Abd*_*naf 28

innodb_flush_log_at_trx_commit用于与目的为..

如果 的值为innodb_flush_log_at_trx_commit 0,则每秒将日志缓冲区写入日志文件一次,并对日志文件执行刷新到磁盘操作,但在事务提交时不执行任何操作。

当值为 1(默认值)时,日志缓冲区会在每次事务提交时写入日志文件,并对日志文件执行刷新到磁盘操作。

当值为 2 时,日志缓冲区会在每次提交时写入文件,但不会对其执行刷新到磁盘操作。但是,当值为 2 时,日志文件的刷新也会每秒发生一次。请注意,由于进程调度问题,每秒刷新一次并不能 100% 保证每秒发生一次。

完全符合 ACID 需要默认值 1。您可以通过将值设置为不为 1 来获得更好的性能,但是您可能会在崩溃中丢失多达一秒钟的事务。值为 0 时,任何 mysqld 进程崩溃都可以清除事务的最后一秒。值为 2 时,只有操作系统崩溃或断电才能擦除最后一秒的事务。无论值如何,InnoDB 的崩溃恢复都有效。

在我看来,使用innodb_flush_log_at_trx_commit2 应该不是问题。但使用 1 是最安全的。


Rat*_*r B 5

我试图回答,目的是innodb_flush_log_at_trx_commit什么?

InnoDB 在内存 ( InnoDB Buffer Pool) 中执行大部分操作。所有修改过的数据都被写入InnoDB transaction log file,然后刷新(写入)到持久存储(硬盘)。

为了数据安全(Durability from ACID),InnoDB 必须将每个事务的修改数据存储到永久存储中。同时,为每个事务提交到磁盘是一个代价高昂的过程。

磁盘 I/O 是一个阻塞过程并且非常慢,如果磁盘慢,则会进一步减少InnoDB transaction per seconds(磁盘吞吐量)的数量。

InnoDB 提供了innodb_flush_log_at_trx_commit控制刷新操作频率的变量。根据该值,InnoDB 刷新操作的行为有所不同。

(已经在其他答案中解释了)

0 - 每秒写入日志文件并刷新到磁盘(数据在缓冲池中而不是写入日志文件 - 以提高性能)。1 - 事务提交时刷新到磁盘 - 默认(为了数据安全 - ACID 合规性) 2 - 写入每个事务的日志文件并每秒刷新到磁盘。(为了性能增益)

根据应用要求 ( Performance Vs data safety) ,您可以设置此变量。0 和 2 之间的差异 - 两者都会提高性能,值 2 将数据存储在事务文件中并且可以在崩溃或失败的情况下恢复,但不是 0。

在许多情况下,刷新到磁盘意味着数据是从 写入的InnoDB buffer pool (memory) to Operating systems cache,而不是实际写入存储磁盘(永久存储)。万一失败,在最坏的情况下,您可能会丢失长达一秒的数据)

性能提升取决于您的环境,您可以进行基准测试和识别。在复制环境中,为了数据安全和一致性,设置innodb_flush_log_trx_commit = 1sync_binlog=1.

如果性能是应用程序的主要目标,InnoDB 提供了一个变量来控制日志刷新的频率innodb_flush_log_at_timeout——它允许您设置日志刷新频率范围从1 to 2700 seconds,默认为 1。

请注意,当您将刷新间隔增加到 N 秒时,性能提升会损害高达 N 秒的数据安全性。例如 - 如果您设置每 5 秒刷新一次 - 吞吐量增益非常高,但在断电或系统崩溃的情况下,您将丢失 5 秒的数据。

本文讨论InnoDB 刷新和事务提交操作。

您可以在 aws rds 上执行模式 2 后进行更改:

在 aws 上执行模式 2 后可以更改

预览更改

在某些情况下不可修改,例如如果您有复制多 az:

仅供参考,在某些情况下不可修改