使用innodb_flush_log_at_trx_commit = 2是否安全?


54

我转身innodb_flush_log_at_trx_commit = 2得到了非常快的写入速度。但是可以安全地用于生产网站吗?

Answers:


57

您可能会损失高达一秒钟的交易价值。默认值为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.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

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


3
罗兰多:+1为最后几行sync_binlog = 1 ...
阿卜杜勒·马纳夫

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

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

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

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

25

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是最安全的。


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

24

我的看法与众不同。innodb_flush_log_at_trx_commit = 0,如果:这是我的开发计算机或家用小型数据库,其中没有敏感数据。

innodb_flush_log_at_trx_commit = 2,如果:它是博客/统计/电子商务(一天有约100多家商店),等等。

innodb_flush_log_at_trx_commit = 1如果:您有很多客户,或者需要处理银行等货币交易。因此,这次您应该将数据流分配到多个服务器之间,以确保速度和安全性。

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

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


1
+1代表75x faster write speed and it fails ONLY if hardware fails.
Naman Gala 2015年

3
快75倍? 需要引用。
Pacerier,2015年

5
我自己的基准:5000 UPDATEinnodb_flush_log_at_trx_commit = 1:179秒。搭配innodb_flush_log_at_trx_commit = 2:1.12秒。在我的情况下,写入速度要快160倍。
凯文

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

您可以通过指定docs的意思来crash
改善

2

我想回答,目的是什么 innodb_flush_log_at_trx_commit?

InnoDB在内存(InnoDB Buffer Pool)上执行其大部分操作。A1将修改后的数据写入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:

仅供参考,在某些情况下无法更改


1

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


“丢失所有数据”,或者您是说过去几秒钟左右正在查询的交易?
NiCk Newman'3

1
硬件故障可能意味着丢失整个硬盘驱动器,从而“丢失所有数据”。因此,除非您有复制设置,否则您的数据
受制于
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.