mysql事务

大纲:

  1. 事务特性
  2. 事务隔离级别
  3. 日志
  4. 事务隔离性实现

一、事务特性

  1. 原子性(Atomicity):对数据的修改要么全部执行成功,要么全部失败
  2. 一致性(Consistent):数据一致性,其他三点就是为了保证数据最终一一致性
  3. 隔离性(Isalotion):事务之间相互隔离,不受影响,这个与事务设置的隔离级别有密切的关系
  4. 持久性(Durable):一个事务提交后,这个事务的状态会被持久化到数据库中

二、事务隔离级别

  1. 读未提交(READ UNCOMMITTED):脏读,不可重复读,幻读
  2. 读已提交(READ COMMITTED):不可重复读,幻读
  3. 可重复读(REPEATABLE READ):幻读
  4. 串行化(SERIALIZABLE):无

以上是4种隔离级别与产生的问题,1、4生产中不会使用。2、3在innodb下也不会出现幻读问题(查询结果集中insert,delete问题),区别在与是否可重复读(同一条记录update问题)

三、日志

逻辑日志简单理解是update,insert语句,物理日志是数据页的改动

binlog

逻辑日志,mysql的server层记录,作用是主从同步和数据恢复,叠加记录

sync_binlog=1,事务提交后同步刷盘

undolog:

逻辑日志,innodb存储引擎层记录,作用是事务回滚和mvcc生成版本链

undolog为每一个写入操作记录一个逆向操作,由于insert操作仅对本事务可见,提交后可直接删除,delete update操作需要帮助其他事务mvcc,需要放入undolog链表,等待purge线程清除

purge线程线程2个,清除无用undolog,清除被delete的行

redolog:

物理日志,innodb存储引擎层记录,作用是数据持久化,当脏页数据成功写入磁盘双写缓冲区redolog可以清除

redolog先写在logbuffer区,事务提交后刷入磁盘

innodb_flush_log_at_trx_commit=1,事务提交后同步刷盘

四、锁

按性质分:共享锁(读锁),SELECT ...LOCK IN SHARE MODE,排他锁(写锁)UPDATE,DELETE,INSERT。写写互斥、读写互斥、读读相容

按粒度分:记录锁(行锁)、表锁、间隙锁、临键锁(记录锁+相邻2个间隙锁)

行锁-唯一索引写操作,where条件为单行且存在,会上行锁。

表锁-写操作不走索引,或者给表加索引、alter table操作。

间隙锁-以下记录产生6个间隙:(-∞,5](5,10](10,1where5](15,20](20,25](25,+supernum],RR级别默认开启

   -唯一索引等值查询:where id=5时行锁,where id = 6时间隙锁(5,10]

   -普通索引等值查询:where c=5时临键锁 (-∞,5](5,10]会产生行锁及相邻两个间隙锁,where c = 6时间隙锁(5,10]

   -范围查询-范围查询根据左右区间落到的范围增加间隙,再根据等值查询确定边界

id(主键)c(普通索引)d(无索引)
5 5 5
10 10 10
15 15 15
20 20 20
25 25 25

 

五、事务隔离性实现

LBCC(Lock-Based Concurrent Control):当前读

update,delete,insert写操作时候利用写锁解决并发控制,

 

MVCC(Multi-Version Concurremt Control):快照读

RC与RR两种隔离级别下,利用table view和undo log对select形成快照   

InnoDB行记录中维护了三个隐藏列rowid行号,trx_id事务id,每个事务一个唯一标识,表示事务先后顺序 ,db_roll_ptr回滚指针,回滚指针会指向undolog链表,找到该行的历史版本链

table view中保存四个数据:min_trx_id当前活跃事务的最小id,max_trx_id当前最大id,trx_ids为活跃事务id列表,creator_trx_id生成当前事务的id

根据table view判断版本链中那个版本可用过程:

  1. 数据中trx_id==creator_trx_id,当前版本修改的数据(可见)
  2. 数据中trx_id<min_trx_id,已经提交过的数据(可见)
  3. 数据中trx_id>max_trx_id,生成table view后开启的事务(不可见)
  4. min_trx_id<=数据中trx_id<=max_trx_id,如果在trx_ids中则未提交(不可见),如果不在其中则已提交(可见)
  5. 不可见的版本通过版本链找到上一个版本重复上面的过程
原文地址:https://www.cnblogs.com/liuboyuan/p/14826735.html