在innodb mysql中,脏数据库页在被刷新回磁盘之前通常在内存中停留多长时间?

xt0899hw  于 2021-06-15  发布在  Mysql
关注(0)|答案(1)|浏览(501)

我所说的数据库页面是指:
https://dev.mysql.com/doc/internals/en/innodb-page-structure.html
现在,当我们对这些页发出查询时,这些页被加载到内存中,并且只在那里被更改并被标记为dirty
我不确定这是否取决于o.s或数据库,但我的问题是这些页在内存中通常会保持多长时间?
假设我们有一个用于高负载web服务器的数据库,流量很大,缓冲区大小像1gb之类的(不确定数据库服务器通常有多少),现在这些1gb中有多少可能是脏页?
如果在没有备用电源的情况下断电,那么这些脏页的所有更改都会丢失,对吗(基本上,我想知道是否发生了断电,如果没有电源备份,并且发生了大量插入和查询,那么内存中丢失的脏数据的估计百分比是多少?)
例如,这些脏页是否有可能在繁忙的服务器上停留超过12或24小时?
编辑:我所说的脏页是指页面在内存中被修改,例如其中一行被更新或删除

velaa5lx

velaa5lx1#

这些页面在内存中通常会保持多长时间?
它是可变的。innodb有一个后台线程,可以将脏页刷新到磁盘。它刷新一定数量的页面,然后在1秒后再次刷新。
因此,如果你在短时间内做了大量的更新,你会使很多页面变脏。然后冲洗线程会逐渐将它们冲洗到磁盘上。这个想法是,这有助于随着时间的推移延长工作时间,所以突然的更新高峰不会淹没您的磁盘。
但这意味着“这些页面在内存中脏了多长时间”可能会有很大的不同。我想在典型的情况下,几分钟就能完成。
不同版本的mysql以不同的方式刷新。几年前,主后台线程每1秒刷新固定数量的页面。然后,他们提出了自适应冲洗,所以它会自动增加冲洗率,如果它检测到你正在做很多改变。然后,他们想出了一个专门的线程称为页面清理器。我认为甚至可以将mysql配置为运行多个页面清理线程,但对于大多数应用程序来说这不是必需的。
你可能还会对我对这些问题的回答感兴趣:
如何计算页面清理器线程每秒执行的工作量?
如何解决mysql警告:“innodb:page\u cleaner:1000ms预期循环花费 ms。设置可能不是最佳的”?
让我们说。。。缓冲区大小大约为1gb(不确定数据库服务器通常有多少缓冲区)
它真的不同,取决于应用程序。默认的innodb缓冲池开箱即用的大小是128mb,但是对于大多数应用程序来说这太小了,除非它是一个测试示例。
在我的公司,我们试图保持缓冲池的大小至少为磁盘上数据大小的10%。有些应用需要更多。我们最常见的大小是24gb,但最小的是1gb,最大的是200gb。我们管理超过4000个mysql生产示例。
这些1gb中有多少是脏页?
从理论上说,都是。mysql有一个配置变量调用 innodb_max_dirty_pages_pct 如果你有太多的脏页,你可能会认为它会阻塞更多的脏页。但事实并非如此。即使缓冲池比该变量更脏(按百分比),您仍然可以修改更多页。
这个变量真正的作用是,如果缓冲池中的脏页数超过该百分比,则刷新脏页的速率将增加(iirc,它将使每个周期刷新的页数增加一倍),直到该数目再次低于该百分比阈值。
如果在没有备用电源的情况下断电,那么这些脏页的所有更改都会丢失,对吗?
是的,但是您不会丢失更改,因为它们可以从innodb redo日志(这两个文件)重建 iblogfile_0 以及 iblogfile_1 您可能已经在数据目录中看到了。任何创建脏页的事务都必须在提交期间记录在重做日志中。
如果您断电(或mysqld进程的其他重启),innodb做的第一件事就是扫描redo日志,检查记录的每个更改是否在崩溃前刷新,否则,加载原始页面并重新应用日志中的更改,再次生成脏页。这就是innodb所说的崩溃恢复。
你可以看着这一切发生。跟踪mysql服务器测试示例上的错误日志,同时 kill -9 mysqld进程。mysqld\u safe将重新启动mysqld进程,在执行崩溃恢复时,该进程将向错误日志中输出大量信息。
如果只有少量脏页需要恢复,这将非常快,也许只有几秒钟。如果缓冲池很大并且有很多脏页,则需要更长的时间。在崩溃恢复完成之前,mysql服务器尚未完全启动,无法建立新的客户端连接。这引起了许多mysql数据库管理员在观看崩溃恢复进度时的几分钟焦虑。我们无法预测坠机后需要多长时间。
由于重做日志是崩溃恢复所必需的,如果重做日志已满,mysql必须刷新一些脏页。它不允许清除脏页,也不允许从重做日志中恢复脏页。如果发生这种情况,您将看到innodb暂停了写操作,直到它可以对最旧的脏页进行某种“紧急刷新”。这曾经是mysql的一个问题,但是通过自适应刷新和页面清理等改进,它可以更好地跟上变化的步伐。你必须有非常多的写操作,以及一个小的重做日志,才能在innodb执行同步刷新时遇到一个硬停止。
下面是一个关于法拉盛的好博客:https://www.percona.com/blog/2011/04/04/innodb-flushing-theory-and-solutions/
p、 答:对于针对myisam的强制bash,我将指出myisam没有重做日志,没有崩溃恢复,并且在写入数据文件期间依赖于主机os文件缓冲区。如果您的主机在文件缓冲区中有挂起的写入但尚未写入磁盘时发生电源故障,您将丢失这些写入。myisam对酸的耐用性没有任何真正的支持。
请回复您的意见:
当重做日志回收时,页面可能会被刷新。也就是说,如果您有2X48MB的重做日志文件(默认大小),并且您向其中写入了足够的事务,以便完全遍历该文件并从头开始,则需要刷新缓冲池中在此期间变脏的任何页面。如果重做日志中的相应事务被新事务覆盖,则页面不能在bp中保持脏。
据我所知,一个脏页在缓冲池中不被刷新12-24小时几乎是不可能保持脏的。
一个可能的例外,我只是猜测一下,就是给定的页面在刷新之前会被一次又一次地更新。因此,它在很长一段时间内都是最近的脏页。再说一次,我不确定这是否克服了重做日志回收时刷新页面的需要。
不管怎样,我认为可能性很小。
还有,我不知道你说的法医是什么意思。没有直接的方法来检查缓冲池中的页面版本。要从innodb获取有关最近更改的信息,您需要检查undo段以查找页面的早期版本,并将它们与redo日志条目关联起来。脏页及其以前的版本可以在缓冲池中,也可以在磁盘上。没有命令、api或任何数据结构来做任何关联。因此,您需要手动转储磁盘映像和内存映像,并手动跟踪指针。
跟踪数据更改的一种更简单的方法是检查二进制日志中的更改流。独立于innodb。

相关问题