我打开了innodb_flush_log_at_trx_commit = 2,并获得了非常快的写入速度。但是可以安全地用于生产网站吗?

#1 楼

您最多可能损失一秒钟的交易价值。默认值为1,这有助于保持InnoDB ACID兼容。

根据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中使用
innodb_flush_log_at_trx_commit = 1和sync_binlog = 1。 cnf文件。

注意事项

许多操作系统和某些磁盘硬件使“从磁盘刷新到磁盘”操作变得愚蠢。他们可能会告诉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


如果您不介意可能的数据丢失(最长1秒),则可以在0或2处使用如果值得的话(更快的写入速度),您自己承担风险。

评论


罗兰多:+1为最后几行sync_binlog = 1 ...

–阿卜杜勒·玛纳夫(Abdul Manaf)
2012年2月10日5:58



@AbdulManaf,始终追求数据完整性而不是速度。如果您想牺牲数据完整性的速度,则会发现自己在处理数据问题上浪费了更多时间。

–起搏器
2015年4月9日在11:20

@RolandoMySQLDBA,通过“失去一秒钟的交易价值”,您是说成功提交实际上可能会丢失吗?

–起搏器
2015年4月9日在11:21

起搏器,是的。仅保证将数据“刷新到磁盘”后才将其写入磁盘。在此之前,它可能只在RAM内存中。

–埃米尔·维克斯特伦(EmilVikström)
16年4月18日在13:20

@RolandoMySQLDBA,你是认真的人。如果您不做全职的mysql咨询工作,则可能应该改变自己的职业道路。

– sjas
17年6月10日在9:45

#2 楼

innodb_flush_log_at_trx_commit的用途是..

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

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

值为2时,每次提交时会将日志缓冲区写出到文件中,但不对其执行刷新到磁盘操作。但是,当值是2时,也会每秒对日志文件进行一次刷新。
请注意,由于进程调度问题,每秒刷新一次不能保证100%每秒进行一次。 br />
要完全符合ACID,必须使用默认值1。您可以通过将值设置为1来获得更好的性能,但是在崩溃中您可能会损失高达一秒钟的事务价值。值为0时,任何mysqld进程崩溃都可以擦除事务的最后一秒。值为2时,只有操作系统崩溃或断电才能清除事务的最后一秒。 InnoDB的崩溃恢复不管值如何都起作用。

我认为将innodb_flush_log_at_trx_commit设置为2应该不是问题。但是使用1是最安全的。

评论


我只是注意到您在我之后仅18秒就回答了基本相同的答案。 +1 !!!

– RolandoMySQLDBA
2012年4月24日在18:16

#3 楼

我的看法与其他人不同。
innodb_flush_log_at_trx_commit = 0,如果:
它是我的开发计算机或家用小型数据库,其中没有敏感数据。 >这是博客/统计/电子商务(每天约有100多家商店)等。

innodb_flush_log_at_trx_commit = 1,如果:
您有很多客户或需要与之合作像银行这样的货币交易。因此,这次您应该将数据流分配到多个服务器之间以提高速度和安全性。

我更喜欢2,因为它的写入速度快约75倍,并且只有在硬件出现故障时才会失败。

无论如何,您应该知道您需要更多的写入速度或最多1秒的信息吗?

评论


+1可使写入速度提高75倍,并且只有在硬件出现故障时才会失败。

– Naman Gala
15年3月26日在5:40

快75倍?需要引用。

–起搏器
2015年4月9日在11:22



我自己的基准测试:使用innodb_flush_log_at_trx_commit = 1:179秒进行5000 UPDATE。与innodb_flush_log_at_trx_commit = 2:1.12秒。在我的情况下,写入速度要快160倍。

–凯文
15年11月20日在12:16

好答案。要考虑的一件事是-如果您的计算机在成功完成事务后崩溃,则可能没有使用innodb_flush_log_at_trx_commit = 2将事务写入磁盘的机会,但仍向您的应用程序指示成功(即mysqld设法发送一个网络数据包,指示事务已成功完成给您应用程序中的驱动程序),机会很小

–弗拉迪斯拉夫·维恩特鲁布(Vladislav Vaintroub)
17年2月17日在0:01



您可以通过指定崩溃的含义来改善答案吗?

– shareef
18 Mar 20 '18在6:57

#4 楼

我正在尝试回答,innodb_flush_log_at_trx_commit?的用途是什么?InnoDB在内存(InnoDB Buffer Pool)上执行其大部分操作。 Al将修改后的数据写入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秒的数据。刷新和事务提交操作。

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





/>在某些情况下无法修改,例如如果您具有复制多az:



#5 楼

如果您的硬件出现故障,则可以丢失所有数据,因此我使用param = 2时没有任何后顾之忧。无论如何,您可以在2个数据库服务器之间分配敏感数据(订单,虚拟货币等)和常规数据(统计数据,购物车等),以确保其安全快速。对于数据库之间的事务,可以使用http://dev.mysql.com/doc/refman/5.7/en/xa.html

评论


“丢失所有数据”,或者您表示过去几秒钟左右正在查询的交易?

– NiCk Newman
16 Mar 10 '16 at 7:17

硬件故障可能意味着丢失整个硬盘驱动器,从而“丢失所有数据”。因此,除非您有复制设置,否则您的数据将受到备份频率的支配,因此,此答案的意思是,相比较而言,丢失一两秒钟的数据无需担心

–胸骨
16年4月27日在17:09