image.png
比如执行 update from xxx set name = “b” where id = “5”; name之前为a

  1. 查询数据,查出来id是5的数据
  2. 计算机修改任何东西都是从内存中修改的,数据页从磁盘读入内存,就是说所在的那个叶子节点读出来,然后遍历叶子节点的row,找出id是5的数据,切割之后在MySQL Server修改行数据
  3. 写undo log,写一个反的数据,之后更新内存中的数据页
  4. redo log写入内存,就是把修改行数据记录下,准备提交事务(一旦redo log刷入磁盘,磁盘的数据才更新完毕)

注意,redo log这个时候写入的是内存,不是磁盘,binlog也是写入内存里。有没有不妥当的地方?
如果redo log写入内存,机器断电了,数据就丢了

redo log刷盘

  • innodb_flush_log_at_trx_commit参数控制redo log刷盘
    • 0:异步每秒刷盘
    • 1:每1个事务刷盘
    • N:每N个事务刷盘
  • 建议设置为1,保证数据安全

    binlog刷盘

  • sync_binlog参数控制binlog刷盘

    • 0:自动控制刷盘
    • 1:每1个事务刷盘
    • N:每N个事务刷盘
  • 建议设置为1,保证数据安全

    持久化分析

  • redo log刷盘前系统崩溃:

    • 数据丢失
  • redo log刷盘后系统崩溃:

    • 重启时会对redo log进行重放、重写内存中数据页、重写binlog

      为什么redo log在binlog之前

  • redo log是系统关键点,相当于“决断点”

  • binlog一旦写入无法撤回,因为可能已经被传送至备库

    总结

  • MySQL日志主要有binlog、undo log、redo log

  • MySQL实行日志优先的策略,日志刷盘,数据就不会丢失