MySQL日志模块

1、MySQL重要日志模块:redo log(事务日志)

MySQL中有一个重要的技术叫WAL(Write-Ahead Logging),意思是写入数据之前先写日志。当有一条update语句需要执行的时候,InnoDB引擎会先把修改的记录写到redo log中,并将数据的变更写入内存中的Page Pool中,不用每次都把修改的数据写入磁盘。

InnoDB的后台线程会按照一定的规则将内存中的脏页写入磁盘,落盘后记录下来当前redo log中有多少update日志已经实际存储到磁盘数据文件中了。redo log的总的写入量叫LSN(Log Secquence Numer日志序列号),而redo log中update记录已经写入到磁盘文件中的数量叫checkpoint LSN,表示的是有多少变更已经写入到了磁盘中。 一旦数据库崩溃InnoDB开始恢复数据的时候,先读取checkpoint,然后从checkpoint所指示的LSN读取其之后的redo log进行数据恢复。所以,当DB重启恢复时,只需要恢复checkpoint之后的数据,这样就能大大缩短恢复时间。

2、MySQL重要日志模块:binlog(二进制日志)

binlog属于Server层,是逻辑日志,记录了某个更新或者插入语句的原始逻辑,例如"给表T的ID=1行的a子段加1"。binlog可以追加写入。
怎么使用binlog日志来恢复数据?
如果在某一天下午6点,发现中午12点有数据被误删了。那么,我们可以先找到最近的一次全量备份(可能就是昨天晚上做的全量备份)。然后从备份的时间点开始,将备份的binlog取出来,应用到备份数据上,一直应用到误删数据的那个时刻前。接下来,就可以把临时库的数据恢复到线上库。

3、redo log与binlog的区别

①redo log属于引擎层,是InnoDB特有的;binlog属于Server层,是所有引擎共用的。
②redo log是物理日志,记录了"在哪个数据页上做了什么修改";而binlog是逻辑日志,记录了执行语句的原始逻辑。

4、一条update语句怎么执行的?

①执行器找引擎取id=2这行。id是主键的情况下,可以直接通过索引找到这行。如果这一行所在的数据页已经存在于内存中,则可以直接返回;否则,从磁盘读入内存再返回。
②执行器对要更新的行对应的字段值作更新(比如加1),得到新的一行数据。
③引擎将这行新数据更新到内存中,同时将更新操作记录到redo log buffer中,此时redo log处于prepare状态。
④执行器将更新操作记录到binlog中。
⑤引擎把redo log状态改为commit,更新完成。

5、为什么对redo log和binlog要进行两阶段提交?

反证法证明:
如果不用两阶段提交,那么就变成两个日志先后分别提交一次的情况。
如果先写redo log后写binlog,那么当redo log已经写好后,写binlog的时候突然系统崩溃了。redo log写完提交之后的事务是不可以回滚的(如果回滚会覆盖掉别的事务的更新),因此主库必定存在新的数据行,而binlog是主库要传给备库作同步的,由于binlog中并没有记录这个更新操作,所以会出现主备不一致的情况。
如果先写binlog后写redo log,那么当binlog已经写完,写redo log的时候突然崩溃,重启后主库中并没有更新这一行,但是binlog中却记录下了,会导致备库多进行了操作,也会出现主备不一致的情况。

猜你喜欢

转载自blog.csdn.net/Longstar_L/article/details/106865455