1:undo_log redo_log binlog (先了解)
1:如果是提交失败可以通过undo日志里面的数据恢复 BufferPool里面的缓存数据
2:如果事务提交成功 buffer pook里的数据还没来得及写入磁盘 此时系统宕机了
可以使用redo日志里面的数据恢复 buffer pool 里面的缓存数据
3:binlog主要是用来恢复数据库磁盘里的数据
2:执行器
原值HSJ
将要修改的值 hesuijin
执行sql:
update tableName set name = 'hesujin' where id =1
1:从磁盘文件 加载到 缓存池(Buffer Pool)(里面是LRU算法 Least Recently Used)
加载缓存数据:
加载id为1的记录所在的整页数据
旧数据HSJ 加载到 缓存
2:写入更新数据的旧值从缓存中加载数据到undo日志(InnoDB独有)中
旧数据HSJ 加载到 undo日志文件
3:更新缓存数据
把旧数据HSJ 改成 新数据 hesuijin
4:写入Redo_Log Buffer (缓冲机制)
缓存机制存放 新数据hesuijin 后面批量的去写入磁盘
5:redo_log日志(InnoDB独有)写入磁盘
新数据 hesuijin写入到磁盘中
该redo_log的事务 prepare阶段 准备提交事务(二段提交 第一阶段)
6:bin_log日志(属于Server层 Myisam与InnoDB都有)写入磁盘
新数据 hesuijin写入到磁盘中
7:进行bin_log 与 redo_log 事务提交阶段
bin_log提交事务
写入commit标记 到 redo_bin日志文件里面
该redo_log的事务 处于commit(二段提交 第二阶段)
该标志保证事务提交后 redo 与binlog 数据一致
8:最终写入新数据真正写入磁盘
1:提交事务成功后
2:Buffer Pool 的新数据 进入 IO 线程
3:IO线程 随机写入磁盘(随机刷盘)
(注意之前是读出一页的数据 这里面也是写入一页的数据)
4:刷盘完成 磁盘中的数据才真正变成 新数据 hesuijin
3:问题
问题1:为什么一定要保证 bin_log和redo_log 必须写完后 再进行提交事务?
因为提交事务就已经认为数据库的数据已经进行了修改。
redo_log日志文件:提交事务之后还没刷盘 在数据库重启之后会,redo_log日志文件恢复
bin_log日志文章:是需要保障数据恢复的 不可以缺少任何一条写记录的日志
问题2:如果事务提交失败,会如何处理
特别注意:实际上事务真正意义上的提交是指:redo_log 和 bin_log的日志一起提交
1:redo_log 与 bin_log 也会进行回滚
2:会使用undo_log 来恢复Buffer Pool缓存池的数据
3:磁盘中的真正的数据还没继续修改 不需要处理
4:Mysql要设置这么一套复杂的机制来执行SQL了?
效率问题:内存肯定比硬盘快
数据库的增删改查都是直接操作Buffer Pool的,Buffer Pool一般设置为机器内存的60%左右
但日志文件也是写到磁盘里面的如何解释?
真正的答案是:磁盘的随机读写性能非常差 但磁盘顺序读写非常快 (相差2到3个数量级)
磁盘顺序IO的速度几乎可以与内存速度媲美
redo_log是环型刷新 bin_log是文件追加 而mysql磁盘数据文件不一定连贯
Msql存储数据的磁盘文件是在磁盘中随机读写
而redo_log 和 bin_log 是在磁盘中顺序读写
Mysql这套机制看起来复杂,但它可以保证每个更新请求都是更新内存BufferPool,
然后顺序写日志文件,同时还能保证各种异常情况下的数据一致性。
更新内存的性能是极高的,然后顺序写磁盘上的日志文件的性能也是非常高的,要远高于随机读写磁盘文件。
正是通过这套机制,才能让我们的MySQL数据库在较高配置的机器上每秒可以抗下几干的读写请求。
网友评论