Innodb事务实现

SQL执行逻辑

引自《极客时间 mysql45讲》
在这里插入图片描述

事务

  Innodb引擎引入事务,可以认为事务是一组SQL语句的序列,事务具有ACID特性。

ACID
  • 原子性
    一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分操作。
  • 持久性
    一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中。
  • 隔离性
    在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。
  • 一致性
    一个事务在执行之前和执行之后,数据库都必须处于一致性状态。
快照读

  InnoDB在每行数据都增加几个隐藏字段,一个记录创建的事务id,一个指针指向上个版本的数据,在不同的隔离级别下MVVC会在不同的事件发生来创建快照来保证事务的隔离性。

  • 默认快照读
SELECT * FROM t_record WHERE id = 2 
  • 非快照读
SELECT * FROM t_record WHERE id = 2  FOR UPDATE
隔离级别
  • 读已提交:读取到未提交的数据(脏读)
  • 读未提交:读SQL执行前的快照,所以在一个事务中可能读取到同个记录的不同值(不可重复读)
  • 可重复读:读事务执行前的快照,一个事务的两次查询一致,但是会读到其他事务新增的数据(幻读)
  • 串行化:SQL语句串行化执行
幻读的解决方式 (MVVC、锁)

  在可重复读级别下,如果事务A产生查询,如果包含唯一索引会产生行锁,不包含唯一索引会产生间隙锁,锁住当前记录和下一条记录中间的区域。

# table(id,value) id为主键索引 value非索引
INSERT INTO t_record VALUE (1,5)
INSERT INTO t_record VALUE (5,10)
SessionASessionB备注
SELECT * FROM t_record WHERE id = 2
INSERT INTO t_record VALUE(2,15)不会阻塞
SELECT * FROM t_record WHERE id = 2读不到数据
SELECT * FROM t_record WHERE value = 5
INSERT INTO t_record VALUE(3,6)不会阻塞
SELECT * FROM t_record WHERE value = 6读不到数据
SessionASessionB备注
SELECT * FROM t_record WHERE id = 2 FOR UPDATE
INSERT INTO t_record VALUE(2,15)阻塞
SELECT * FROM t_record WHERE value = 5 FOR UPDATE
INSERT INTO t_record VALUE(3,6)阻塞
commit;插入执行

  在快照读时,不会影响其他事务插入操作。FOR UPDATE 读取当前最新记录,会导致其他事务插入的阻塞。

  共享锁 (S):读锁允许其他事务读,不允许写
  排他锁 (X):写锁独占资源阻塞其他操作
  记录锁(行锁):唯一索引,单条记录上锁
  间隙锁:解决幻读问题,可重复读隔离级别下,在数据范围内上锁

undo log、redo log、binlog

  如果每次查库都进行一次磁盘寻址,效率会很低,因此数据库在很多地方使用了缓存,为了解决缓存和磁盘数据不一致的问题,一般采用日志预写方案(WAL)来保证事务的特性。

undo log 回滚日志

  保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),即非锁定读。

redo log 重做日志

  确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。

binlog

  用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步,或是用于数据库的基于时间点的还原。

区别
undo logredo logbinlog
实现innodbinnodbmysql
数据逆语句数据页SQL语句
作用原子性持久性主从同步 恢复数据
事务特性的保证
  • 原子性 undo log回滚
  • 持久性 redo log commit 写入磁盘
  • 隔离性 锁 MVVC
  • 一致性 回滚、恢复、并发隔离
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值