MqSQL事务、锁

事务特性(ACID)
  • 原子性
  • 一致性
  • 隔离性
  • 持久性
 
日志(innodb)
  • binlog日志
    binlog记录了数据库表结构和表数据变更,它存储了每条变更的sql。binlog主要用来复制和恢复数据,例如在主从复制中,以及数据库崩溃恢复。
  • redo日志
    事务提交后,需要把数据保存到磁盘,如果每次都刷盘,会影响效率。所以将修改行为先写到redo日志中,再定期将日志刷到磁盘中,redolog记载的是物理变化(xxxx页做了xxx修改)。

 

  • undo日志
         事务未提交时,会将修改前的旧版本存放到undo日志,事务回滚时,利用undo日志,撤销未提交事务对数据的影响。
    存储undo的地方就是回滚段。
insert操作,undo直接存数据的pk(row_id),回滚直接删除
delete/update,记录旧数据row,回滚直接恢复
 

binlog和redo log 区别

  • binlog记载的是update/delete/insert这样的SQL语句,而redo log记载的是物理修改的内容(xxxx页修改了xxx)。
  • redo log的作用是为持久化而生的。写完内存,如果数据库挂了,那我们可以通过redo log来恢复内存还没来得及刷到磁盘的数据,将redo log加载到内存里边,那内存就能恢复到挂掉之前的数据了。

binlog的作用是复制和恢复而生的。

mysql操作数据,会先写入redo log再写入 binlog,如果其中任何一个失败,就会回滚

 

隔离性
  • 脏读。事务T1修改某条数据,事务T2读取该值,T1由于某种原因导致回滚,导致T2所读的数据是无效数据。
  • 不可重复读。一个事务范围内,两个相同的查询却返回不同的值。由于在事务范围内,有其它事物修改了数据导致。
  • 幻读。与不可重复读非常类似,指一个事务范围内,两次相同的查询,第二次比第一次少或多数据。
  •  
 
    InnoDB四种事务隔离级别实现原理
  • read uncommitted
        select语句不加锁,并发最高,一致性最差。
  • read commotted
        普通读是快照读
        加锁的select, update, delete等语句,除了在外键约束检查(foreign-key constraint checking)以及重复键检查(duplicate-key checking)时会封锁区间,其他时刻都只使用记录锁;此时,其他事务的插入依然可以执行,就可能导致,读取到幻影记录。
  • repeatable read
        InnoDB行锁是通过给索引上的索引项加锁的,InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则InnoDB将使用表锁。另外,无论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁;
     如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁而不是行锁。
         范围查询条件,会使用间隙锁与临键锁,锁住索引记录之间的范围。
  • serializable
        所有select语句都会被隐式的转化为select ... in share mode,如果有事务正在修改该行,那么读会阻塞,这是并发最低,一致性最好的
 
  • 乐观锁
    具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。之所以叫乐观,因为这个模式没有从数据库加锁,等到更新的时候再判断是否可以更新。
  • 悲观锁
    悲观锁则是直接加锁。
小知识:
innodb只有通过索引检索数据,才会使用行锁,否则使用表锁。
 
 
innodb锁
  • 自增锁
        自增锁是一种特殊的表级别锁,专门正对插入包含自增的列,如果一个事务正在插入数据,那么其它事务的插入必须等待。
  • 共享/排它锁(行级别)
        读锁(S锁),写锁(X锁)。写锁是排它锁。读读可以并行,写写、读写是互斥。
  • 意向锁(行级别)
        意向锁是指,在某个时刻,事务可能要加共享/排它锁,先提前声明一个意向。意向锁分为意向共享锁(IS);意向排它锁(IX),意向锁之间不互斥。
          S          X
IS      兼容      互斥
IX      互斥      互斥
  • 插入意向锁
        上面提到插入有自增列的数据,有自增锁,如果插入没有自增列的数据,则是插入意向锁,它是间隙锁的一种,实施在索引上,专门正对insert操作。
  • 记录锁
        封锁索引记录,例如select * from user where id = 1 for update;
  • 间隙锁
        封锁第一条索引之后或者最后一条索引之前的数据。
        例如:select * from user where id between 1 and 10 for update; 会锁定id 1-10的所有行,防治出现幻影数据,假如插入了一条id=5的记录,那么执行相同的sql会发现多了一条记录,出现幻影数据,所以这么做防治了不可重复读。
  • 临键锁
        临键锁,是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。临键锁会封锁索引记录本身,以及索引记录之前的区间。避免幻读。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值