mysql:理解innodb日志操作



当涉及到在innodb存储引擎中写入二进制日志的更改时,我正在尝试理解这3个变量

sync_binlog

innodb_flush_log_at_trx_commit

innodb_flush_log_at_timeout

在阅读了几次文档之后,我对这些变量的理解是

sync_binlog

0  -> Operating system decides when to write log to disk(whenever it has free time)
1  -> after every commit changes written to disk(safest)
N  -> after N commits changes written to disk

innodb_flush_log_at_trx_commit

0 -> written and flushed to disk once per second
1 -> written and flushed after every commit(safest)
2 -> written after every commit and flushed to disk once per second

innodb_flush_log_at_timeout

after N seconds of delay logs are written to file

因此,作为一个实验,这里是我想要获得

1( 在提交5个事务之前,不应将任何事务写入日志

2( 在提交了5个事务之后,我希望innodb等待10秒,然后将这些事务写入日志

所以我把变量的设置如下

SET @@GLOBAL.sync_binlog=5;                          #Don't write anything until 5 commits have been done?
SET @@GLOBAL.innodb_flush_log_at_trx_commit=0;       #Maybe? because logs are written every second regardless if they are commited or not?
SET @@GLOBAL.innodb_flush_log_at_timeout=10;         #After 5 commit's wait for 10 seconds before writing the transaction's to disk?

正如你所看到的,我到处打问号,因为我不知道自己在做什么。这些设置不起作用。每次提交后,我都会立即在日志中看到更新的更改

基本上我有一个测试台

CREATE TABLE Test(TestCol INT);

我发布5个事务的[自动提交开启]作为5个插入语句

INSERT INTO Test VALUES(1);
INSERT INTO Test VALUES(2);
INSERT INTO Test VALUES(3);
INSERT INTO Test VALUES(4);
INSERT INTO Test VALUES(5);

我想要的是,如果我插入值,比如说只有1到4,那么我不想在日志文件中看到任何更改,但一旦我插入了5,总共进行了5次事务,那么我想让innodb等待10秒,然后再将这些事务写入日志,这样我就有足够的时间打开我的文件资源管理器并运行

mysqlbinlog --verbose --base64-output=DECODE-ROWS binlog.000001

查看我的日志文件中的更改

但是,即使我只插入一个值并打开我的日志文件,我也会看到它立即插入其中。

我的目标可能吗?有人能解释一下这些变量是如何工作的吗?如果可能的话,还有一个解决我问题的替代方案吗?

如有任何澄清,将不胜感激

sync_binlog仅控制文件何时同步到磁盘。当您提交事务时,事务仍然会立即写入逻辑文件,它们只是由操作系统缓冲。如果您使用程序(例如mysqlbinlog(读取同一个文件,则会读取所有内容,包括操作系统缓冲区中的内容。操作系统会自动将缓冲区与磁盘上的内容合并。

我不知道有什么方法可以让MySQL在提交时延迟写入二进制日志。有一个binlog缓冲区,但它用于在提交事务之前累积更改。提交后,它应该立即写入binlog,因为其他会话可能也希望写入binlog中,并且提交应该按照提交时间的顺序写入。

同样,对innodb重做日志的写入也是连续的。当文件同步到磁盘时,仅名称控制的刷新选项。与此同时,对日志文件的写入仍在进行,但可能会被操作系统缓冲。操作系统可以选择在innodb强制同步之前刷新缓冲的I/O。

我不认为你能做你想做的事。我不知道你为什么要做,因为这会破坏耐久性。假设您可以让InnoDB在提交5个事务之前不将事务保存到重做日志中。如果您提交了其中的4个事务并突然崩溃,那么您将失去这4个事务。


回复您的评论:

https://bugs.mysql.com/bug.php?id=69309有更多解释:

N秒写入并刷新日志。innodb_flush_log_at_timeout在MySQL 5.6.6中引入。它允许在增加冲洗次数,以减少冲洗并避免冲击二进制日志组提交的性能。MySQL 5.6.6之前,刷新频率为每秒一次。的默认设置CCD_ 3也是每秒一次。

错误日志声称这个解释将被添加到文档中,但我想它从未出现过。

听起来这个选项是为了在事务处理率太高以至于同步日志文件成为瓶颈的情况下降低耐用性。看见https://dev.mysql.com/worklog/task/?id=5223

在我看来,如果您的事务处理率太高,以至于无法每秒同步一次,那么您需要考虑如何重新设计您的体系结构。即使你延长了fsyncs之间的间隔,也会给你的数据带来风险,而且你不能永远延长。您需要一个更好的策略来管理不断增长的交易率。通常这意味着将数据库分成";碎片";使得每个事务都写入多个服务器中的一个。

最新更新