MySQL update正在执行中突然断电,数据是否更改成功?

时间:2022-11-05 11:55:50

         今天有个朋友突然问到我这个问题,当我们的update语句执行过程中,服务器突然断电了会发生什么?其实这个问题主要在于对mysql update生命周期的理解,以及了解mysql 的redolog和binlog这两个日志的作用。

        上一篇文章讲到mysql update的执行过程,MySQL update生命周期 。执行过程主要分为server层和存储引擎层两步操作,server层主要是创建连接和SQL的解析优化,存储引擎层主要是事务的执行和提交的操作。这里就不细讲了可以查看之前的文章或者其他论坛文章。

redolog

       redolog 也叫预写式日志WAL(write-ahead logging),它是innoDB存储引擎层特有的一种日志。redolog 空间大小固定,可循环写。

       redolog的结构包含四部分信息:

       type redo日志的类型(mlog_1byte、mlog_2byte、mlog_4byte、mlog_8byte、mlog_write_string);

       space ID表空间ID;

       page number 页号;

       offset 数据修改的位置;

       data 该条日志得具体数据内容,redolog是物理日志所以data里记录的是物理操作(例如:某个事务ID将哪张表空间的第几页中的哪个数据做了什么样的修改)。

       redolog的写入过程

        redolog最终也是写入在磁盘中的,它写入在磁盘中是顺序IO因此它的性能是非常高的。

        写入log buffer

        redo log在写入时也不是直接写入磁盘中的,它是被写入到 一个大小为512字节的 redo log block页中。它先写入到 redo 日志缓冲区 (log buffer) 的内存区域中,该区域在MySQL启动时就会向操作系统申请,这片区域被划分为若干个连续的 block,可以通过启动选项 innodb_log_buffer_size 指定 log buffer 的大小。

        redo日志刷盘

        写入到log buffer内存后,需要将数据刷到磁盘中刷盘的策略主要有:1.当log buffer空间不足;2.当前的事务完整提交;3. 固定每秒刷盘一次;4.正常关闭服务器;

binlog

        binlog也叫做归档日志,它是mysql  server层的日志。不区分存储引擎,所有存储引擎都可以使用。binlog 日志是逻辑日志,记录的是sql语句的原始逻辑,binlog日志是以追加的方式写入在文件中并不会覆盖之前的日志。

        binlog日志的使用场景

        1. mysql主从时做数据复制同步使用,binlog日志是二进制的文件所以它的复制性能会高。

        2. 做容灾的数据恢复。

        binlog的写入过程

         写入binglog cache

        mysql服务器系统给每个线程分配一个binlog cache的内存块,当事务在执行的过程中,会把操作的日志写到binlog cache中,同一个事务的binlog日志不会被分开写入都是一次性写入到binlog cache中。如果是支持事务的存储引擎,必须要事务提交后才会写入日志。

         binlog日志刷盘

         binlog日志刷盘取决于sync_binlog参数的设置,表示每sync_binlog次事务提交则将日志刷新到磁盘。如果设置为0,则完全由文件系统去控制它缓存的刷新。因此未保证数据的完整性最好将sync_binlog设置为1,每次事务提交都刷新,但会对性能有所影响。

如果在update执行过程中突然断电会发生什么?

        1. 如果在断电时 redolog 还没有写入,那么重启后将没有任何的数据变化。

        2. 如果redolog 已经写入了但状态还在prepare时,binlog日志还没有写入,那么重启后会将事务进行回滚,数据也没有任何变化。

        3. 如果redolog 已经写入了,binlog也写入了,但redolog日志还没commit, 那么重启后会检查binlog是否完整,如果完整则提交事务,数据发生变化,如果不完整则回滚事务,数据也不发生变化。