首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MySQL中,数据究竟是如何从查询流向磁盘的?

问在MySQL中,数据究竟是如何从查询流向磁盘的?
EN

Database Administration用户
提问于 2016-06-25 06:12:46
回答 3查看 2.3K关注 0票数 6

我想弄清楚从触发查询到进入磁盘之前数据到底是如何流动的。(我大致知道它会转到缓冲区,然后重做日志,然后重做磁盘文件),但是使用bin_log_cache怎么样?

我在谷歌上搜索过这个,但在这个话题上找不到多少。我希望在这个社区的人与人之间有一些解释。

EN

回答 3

Database Administration用户

发布于 2016-06-25 06:51:22

谷歌的“彼得·扎伊采夫”文件系统缓冲双写提供了几个很好的参考资料(Peter为Percona工作,他是MySQL世界的大杀手。

其中,我选择了4个特别感兴趣的[1,2,3.,4.]。

在第一次引用中,Zaitsev给出了可能发生部分页面写入的各种原因(标题为“现在让我们谈谈部分页面写入”一节)。

Zaitsev接着介绍了double write是如何工作的,但我认为在参考文献2中可以找到更好的解释--特别是这个部分:

如果数据文件中发生了部分页面写入,则InnoDB / XtraDB将检查数据文件中页的校验和与双写缓冲区中页的校验和是否不同,从而知道该页是否损坏。如果损坏,恢复过程将使用存储在双写缓冲区中的页来恢复正确的数据。如果在双写缓冲区中发生了部分写入,则原始页不受影响,可以与重做日志一起使用以恢复数据。

基本上,这种行为由一个名为诺姆b_同花顺_日志_在…_trx_提交的系统参数控制。本节太大了,不能在这里全部引用,我只引用默认值的部分:(我强烈建议您阅读全文以获得一个好的概述)。

◾默认值1是完全符合ACID要求的。使用此值,在每次事务提交时将InnoDB日志缓冲区的内容写入日志文件,并将日志文件刷新到磁盘。

然而,手册的这一节也指出:

控制对commit操作严格的ACID遵从性和当与提交相关的I/O操作被重新安排和批量执行时可能具有的更高性能之间的平衡。您可以通过更改默认值来获得更好的性能,但是在崩溃时,您可能会损失多达一秒的事务。

在通俗易懂的英语中,这意味着“你得到了你所付出的”--也就是说,在数据完整性和性能之间有一个平衡。然而,尽管搜索得很高,但我还是找不到比这更详细的内容--除非你想翻查代码(恐怕超出了我的工资等级:-)。

您可以关闭参数诺姆b_双写,然后这将导致另一个系统参数诺姆b_同花顺_方法 --这也是关于性能与数据完整性的问题。我的参考文献3和4详细介绍了这一点--基本上,这两种引用中的争论在于,如果您有事务文件系统,关闭双写是否是个好主意。

大家的共识似乎是,如果您使用的是ZFS (以及其他可能是深奥的文件系统/设备),那么您就可以安全地关闭双写操作--假设RAID具有电池驱动的磁盘缓存。参考文献4 IMHO建议,关于ext4是否安全的争论仍然没有定论--也见这里。

下图很好地概述了MySQL的InnoDB体系结构。

票数 3
EN

Database Administration用户

发布于 2016-06-26 02:05:51

严格地查看二进制日志,您可以遵循以下流程

请注意MySQL文档对联木_缓存_大小的说明:

在事务处理期间保存对二进制日志更改的缓存的大小。如果服务器支持任何事务存储引擎,如果服务器启用了二进制日志(- log选项),则为每个客户机分配二进制日志缓存。如果经常使用大型事务,则可以增加缓存大小以获得更好的性能。Binlog_cache_use和Binlog_cache_disk_use状态变量对于调整该变量的大小非常有用。见5.4.4节,“二进制日志”。

由于此设置影响事务的使用,因此在事务生命周期中写入二进制日志的时间点是存在的。您的问题是“二进制日志何时在InnoDB管道中起作用?”

作为Verace已经展示了InnoDB的图像表示.,您可以看到没有提到二进制日志。MySQL文档实际上提到了二进制日志在事务中交互的时间。

请注意它在The Binary Log来自MySQL文档中说的话:

二进制日志记录是在语句或事务完成后,但在释放任何锁或完成任何提交之前立即完成的。这确保日志按提交顺序登录。

另一段内容如下:

在未提交的事务中,所有更改事务性表(如InnoDB表)的更新(UPDATE、DELETE或INSERT)都被缓存,直到服务器收到COMMIT语句。此时,mysqld在执行提交之前将整个事务写入二进制日志。

另一段介绍了关于绑定日志的缓冲区缓存的如下内容:

当处理事务的线程启动时,它会将binlog_cache_size缓冲区分配给缓冲区语句。如果语句大于此,则线程将打开一个临时文件来存储事务。线程结束时删除临时文件。

摘要

  • 如果有太多流到binlog缓存中,则使用语句/事务加载binlog缓存,或者将其分页到磁盘。
  • 除非binlog文件事先接收一个或多个语句/事务,否则任何提交都不会到达磁盘(重做日志、双写缓冲区和InnoDB管道的其余部分)。
  • 您可能可以通过更改两件事( )来调整这种交互。
票数 1
EN

Database Administration用户

发布于 2018-02-07 13:25:59

你说:如果是的话,那么在这个过程中万一停电的话,会不会是数据丢失?

我说:这取决于您的tx是否已完全写入红色日志文件。

现在,如果您的事务已经完全写入重做日志文件中,那么它将被刷新到磁盘(我的意思是现在保存了iblogfile ),从而达到数据files.Hence没有数据丢失,即使由于您的数据现在被提交到重做日志中而发生了电源故障)。

如果服务器崩溃并没有在重做日志中完全写入txn,那么在mysql重新启动时它将被回滚。您可以在错误日志文件中选中“崩溃和mysql服务器重新启动”后的.Here,MySQL以崩溃恢复模式出现,并尝试将重做日志、数据文件、二进制日志相互同步。

因此,正如您已经提到的,数据进入缓冲池,然后进入日志缓冲区,并且根据“trx提交时的now刷新日志和超时时的now刷新日志”的值,数据将到达重做日志(iblog01文件),然后刷新到磁盘,然后到达数据文件。

所以,这就是事务流。我在我的博客中以解释性的方式提到了同样的问题。你可以参考我的博客。

https://jinglespreparatorycom.wordpress.com/

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/142224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档