这一个图就是整个MySQL的模型;
客户端--->连接池--->解析器--->优化器--->执行器--->存储引擎[innodb]-->磁盘;
第一个问题: 怎么保证事务一致性的?
第二个问题: redo_log undo_log bin_log 都是干什么用到?
bin_log 属于server层 undo_log也是属于server层, binlog 做同步用,归档用
redo_log 用于事务, Mysql在5.7之前是不支持事务的,集成InnoDB, 就支持事务, 加入redo_log就是为了事务一致性.
记住: redo_log 和undo_log 是属于存储层的的 bin_log是属于server层的
还有一点注意:
1.redo_log 是保证数据的持久性的也就是一致性的,等到事务提交之后, redo_Log也就失去了作用.
2.bin_log 是主要用于主->从中间同步数据使用的;
3.undo_log 主要用于事务之间的回滚及MVCC多版本控制使用.
其实redo_log ---->redo_log_buffer---->fsync()----->每次提交或者每秒刷盘到磁盘上;
checkpoint 记录数据的修改; 出现宕机的情况下,checkpoint只需要恢复到已经提交之后
第三个问题: Mysql都有那些锁?
乐观锁--版本号实现写写问题
悲观锁--[共享锁 S 排它锁 X]
排它锁-> 行锁 间隙锁 next_key lock 实现排它锁.
第四个: MVCC 多版本控制是解决了了什么问题? 还会存在什么问题?
首先是MVCC是多版本控制器, 是通过快照读解决了脏读,不可重复,幻读的问题
是怎么解决的呢?---->
启动每个事物的时候都有一个版本号, 在行记录中隐式的存在三个字段
row_id 行ID
trx_id 这条记录被insert update 的ID ;
还有一个指针 ,指向之前修改的undo-log日志,
事务1 | 事务2 | 事务3 |
begin |
| |
事务id=5 进行中---- 未提交
事务1在查询, 此时虽然事务3已经提交,还是看不到 |
事务ID6 查询操作; |
事务ID=7 update一条数据 已经执行完了
|
分析这个结果:只分析事务2 就可以;
第一种情况: 事务2在事务3提交之后, 这个时候在select * from t 其实这个时候的事务ID是事务ID=7+1;
第一次查询的时候才会生成快照读,
第二种情况:事务2 刚上来就查询,此时生成了快照. 这个时候,事务3 提交了,也是看不到事务3提交的信息的;
分析: 为什么T1看不到?
快照读带来的问题?
1.更新丢失 两个快照都update同一条语句, 之前的update语句信息会被覆盖掉;
解决方案: MVCC+ 乐观锁 MVCC+ 悲观锁