共计 2373 个字符,预计需要花费 6 分钟才能阅读完成。
这篇文章主要介绍了如何解读 MySQL 的 InnoDB 引擎日志工作原理,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让丸趣 TV 小编带着大家一起了解一下。
当你使用 UPDATE, INSERT, DELETE 语句更新数据的时候,你就改变了两个地方的数据:log buffer 和 data buffers。Buffers 是固定长度的内存块,通常是 512 字节。
LOG BUFFER DATA BUFFER
================= ===============
= Log Record #1 = = Page Header =
= Log Record #2 = = Data Row =
= Log Record #3 = = Data Row =
= Log Record #4 = = Data Row =
================= =============== 例如:INSERT INTO JOBS VALUES(1,2,3) 语句执行之后,log buffer 将增加一个新的 log 记录,称为 Log Record #5,它包含一个 rowid 和新记录的内容。同时,data buffer 也将增加一个新行,但是,它会同时在页头标识:该页最新的 log 记录是 Log Record #5。在这个例子中 #5 是 Log Sequence Number(LSN),它对于接下来操作的时序安排是至关重要的。
[@more@]
下面是 data-change 的一些细节:
1. 一个 INSERT log 记录仅包含一个新数据,它对于在页上重做操作是足够的了,因此被称为一个 redo 条目。
2. LSN 不是 log 记录的一个域,它是文件中的一个绝对地址的相对偏移值。
在 InnoDB 改变了 log buffer 和 data buffer 之后,接下来就是写盘了。这就是复杂的地方。有多个线程在监控 buffer 的活动情况,有三种情况――overflow,checkpoint 和 commit――可以导致写盘操作。
Overflows 情况下发生了什么?
Overflow 是很少发生的情况,因为 InnoDB 采用 pro-active 措施来防止 buffers 被填满。但是我们还是来看看下面两种情况:
1. 如果 log buffer 满了,InnoDBInnoDB 在 buffer 的末尾写 log。那么情况向下面的图一样(log buffer 只有四条记录的空间,现在插入第五条记录):
LOG FILE(S) BEFORE WRITING LOG RECORD #5
=================
= Log Record #1 =
= Log Record #2 =
= Log Record #3 =
= Log Record #4 =
=================
LOG FILE(S) AFTER WRITING LOG RECORD #5
=================
= Log Record #5 =
= Log Record #2 =
= Log Record #3 =
= Log Record #4 =
=================logs 不可能永远增长。即使 InnoDB 使用了某些压缩算法,log 文件还是会由于太大而不能放到任何磁盘驱动器上。因此 InnoDB 采取循环写的办法,也就是说将会覆盖前面就的 log 记录。
2. 如果 data buffer 满了,InnoDB 将最近使用的 buffer 写入到数据库中,但是不可能足够的快。这种情况下,页头的 LSN 就起作用了。第一,InnoDB 检查它的 LSN 是否比 log 文件中最近的 log 记录的 LSN 大,只有当 log 赶上了 data 的时候,才会将数据写到磁盘。换句话说,数据页不会写盘,直到相应的 log 记录需要写盘的时候。这就是先写日志策略。
CheckPoints 的时候发生了什么?
前面说过 InnoDB 采取了一些 pro-active 措施来保证不发生 overflows,其中最重要的措施就是 checkpointing。有一个分离的线程,或者说从一组修改 buffers 的线程中分离出来的一个线程。在特定的时间间隔,checkpointer 将醒来,检查 buffer 的改变,并保证写盘操作已经发生了。
大部分 DBMS 在这个时候,将会把所有的 buffer 写盘,这样可以保证所有改变了但是没写盘的 buffer 都写盘。就是说 DBMS 将通过”Sharp Checkpoint”flush 所有”dirty”buffers。但是 InnoDB 只保证:(a)log 和 data buffers 不会超过某个限制点;(b)log 始终比 data 先写盘;(c)没有哪个 data buffer 的页头 LSN 等于被覆盖写的 log 记录。也就是说 InnoDB 是”Fuzzy Checkpoint”。
在 COMMIT 的时候,InnoDB 不会将 dirty data page 写盘。之所以强调这个是因为,很容易让人想到,提交改变就是将所有东西写到一个持久媒介上。其实,只有 log 记录需要写。写 dirty data page 只可能发生在 overflow 或 checkpoint 时刻,因为它们的内容是多余的。
Recovery
在 recovery 里面可以看到 log 是非常必要的:当数据库发生异常的时候,数据是可以恢复的。
对于不是损坏磁盘驱动器的异常,恢复是自动进行的。InnoDB 读取最新的 checkpoint 日志记录,检查 dirty pages 是否在异常发生前写到磁盘上了,如果没有,则读取影响该页的 log 记录并应用它们。这被称为”rolling forward”。因为有 LSN,所以 InnoDB 只需要比较这个数字就可以进行同步。
感谢你能够认真阅读完这篇文章,希望丸趣 TV 小编分享的“如何解读 MySQL 的 InnoDB 引擎日志工作原理”这篇文章对大家有帮助,同时也希望大家多多支持丸趣 TV,关注丸趣 TV 行业资讯频道,更多相关知识等着你来学习!