MySQL之更新是如何执行的--读书笔记

不想你离开。 提交于 2020-12-13 19:35:29

通过上一篇文章,对MySQL的内部结构以及一条查询语句是如何执行的有了一个大概的认识。下面对MySQL的更新以及两个日志文件进行总结。

如图:

以上是一张MySQL更新的执行示意图。这张图较好地解释了一条sql是如何执行的。下面先对图中比较陌生的元素redo logbinlog进行介绍。

redo log:

    翻译过来就是重做日志,是Innodb存储引擎特有的(Innodb原先是另外一家公司以插件形式加入到MySQL中),它是物理日志,只有Indobd能使用,记录的是“在某个数据页上做了什么修改”。它是一个环形,说明它是有固定大小的,从头写到末尾就要擦出一部分之后才能继续写。这边有一个WAL技术,后面再做详情介绍。

binlog:

    翻译过来就是归档日志,在MySQL的server层,所以是所有存储引擎都共有的,它是逻辑日志,可以给别的数据库,引擎使用,记录的是这个语句的原始逻辑,如“给id=1的这一行的某个字段+1”。它不是环形,它是一直追加写入的,不会覆盖以前的日志。

WAL技术:

    Wirte-Ahead logging,直译就是“先写日志”。为什么要先写日志呢?在MySQL中,我们的数据页有可能在内存中,也有可能在磁盘中,如果我们每次更新都去写磁盘,那么MySQL的更新操作的效率会很低。并且写日志时按照顺序写,可以以组的方式提交,因此比直接更新数据页到磁盘效率来的高。

MYSQL是更新的呢?下面我再引用陈晓斌老师的一张图

图中颜色较深的发生在MySQL的server层中,较浅的发生在Indodb引擎中。图中看到,写redo log有两个阶段,prepare和commit。这个就是“两阶段提交”。

这是为了让两份日志保持数据的一致性。试想,由于redo log和binlog是两个独立的逻辑,要么先写redo log,要么先写binlog,先写redo log再写binlog时,如果中间服务器crash掉,那么数据恢复的时候,binlog没有记录上,这是数据就不一致了;先写binlog 再写redo log,中间服务器crash掉,由于redo log没有写完,这个事务无效,而binlog中以后有了更新的日志,恢复的时候就多了一个事务,数据也会不一致。

到这应该对一条SQL时如何执行更新的,MySQL中重要的两个日志有了一个初步认识。后面还会继续总结。

记一下MySQL中经常用到的几个重要参数设置,

innodb_flush_log_at_trx_commit :这个参数设置成1,表示每次事务的redo log都直接持久化到磁盘,以保证MySQL异常重启之后数据不丢失。

sync_binlog:这个参数设置成1,保证MySQL异常重启之后binlog不丢失。

最后说一下我们的运维同学时如何恢复数据的呢?

通常我们的运维同学会定时把MySQL的数据库备份,然后定时清理binlog日志。当数据库被误删了之后,找到在误删之前的备库,和那个时间点开始的binlog日志,就可以恢复到你想要的时间点的日志了。

为什么不能用redo log恢复呢?

1.因为redo log是Innodb特有的,不一定每一张表都有redo log

2.redo log是循环写的,当redo log 写满之后会擦出一部分。

 

补充说明:两个日志文件的写入机制

binlog的写入机制

binlog先把日志写到binlog cache,事务提交的时候再把binlog cache写到binlog文件中。一个事务的binlog不能被拆开,因此无论这个事务多大,也要确保一次性写入。 系统给binlog chche分配了一片内存,每线程一个,参数binlog_cache_size用于控制每个线程内binlog cahce的内存的大小,超过暂存到磁盘。事务提交的时候,执行器把binlog cache里的完成事务写入到binlog file中,并清空binlog cache。每个线程都有自己的binlog cache,但是共用同一份binlog文件。fsync的时候才会把binlog写入到磁盘,这个时候才是会占IOPS。

 

redo log的写入机制

事务在执行过程中,生成的redo log要先写入到redo log buffer中,物理上这是在MySQL进程内存中。InnoDB有一个后台线程,每隔1秒,就会把redo log buffer中的日志,调用write写入到文件系统的page cache,然后调用fsync持久化到磁盘。这个过程是一直持续的,也就是说一个没有被提交的事务的redo log也可能已经持久化到磁盘了。

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!