美文网首页
Mysql 事务隔离

Mysql 事务隔离

作者: 蓝调_4f2b | 来源:发表于2022-12-17 22:50 被阅读0次

    一. ACID概念

    1. 原子性:事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
    2. 一致性:在事物开始和完成时,数据都必须保持一致,这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性。
    3. 隔离性:数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。事务处理过程中数据的中间态对外部不可见
    4. 持久性:事务完成后,其对数据的修改是永久性的,使出现系统故障也能够保持。

    二. 并发事务处理带来的问题

    1. 脏写问题:当两个或多个事务选择同一行,会发生丢失更新问题–最后的更新覆盖了由其他事务所做的更新。
    2. 脏读问题:事务A读取到了事务B已经修改但尚未提交的数据,还在这个数据基础上做了操作。此时,如果B事务回滚,A读取的数据无效,不符合一致性要求。
    3. 不可重复读:事务A内部的相同查询语句在不同时刻读出的结果不一致,不符合隔离性。
    4. 幻读:事务A读取到了事务B提交的新增数据,不符合隔离性
      相关现象:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。

    三. Mysql事务隔离级别

    1. 不同的事务隔离级别
      (1)读未提交:可以读取到其他事务未提交的数据,会出现脏读,不可重复读,幻读等问题。
      (2)读已提交:可以读取到其他事务已提交的数据,解决了事务的脏读问题,多次读取会出现不可重复读,幻读等问题
      (3)可重复读:使用了MVCC机制,在同一事务内多次读取同一行记录不会读取到不一致的值,但无法避免幻读问题
      (4)串行化方式:解决以上所有读取问题,但使得数据库中的事务无法并行
      注:Mysql默认为可重复读级别

    2. 查询事务隔离级别命令:show variables like "tx_isolation";
      设置隔离级别:set tx_isolation = 'Repeatable_read';

    四. 数据库中的锁分类

    数据库中的锁分类.png
    1. 乐观锁:使用version版本号实现锁机制,无需进行锁等待,尝试更新数据,不成功则采用其他逻辑重试
    2. 悲观锁:争抢锁资源时触发锁等待机制
      (1)读锁:对同一份数据,多个读操作可同时进行不受对方影响
      (2)写锁:当前写操作未完成前,阻断其他写锁及读锁
    3. 表锁:
      每次操作锁住整张表,开销小,加锁快。锁定粒度大,发生锁冲突的概率最高,并发度最低;一般用在整表数据迁移的场景。
      (1)手动增加表锁:lock table table_name read(write_锁种类)
      (2)查看表上加过的锁:show open tables;
      (3)删除表锁:unlock tables;
    4. 行锁:
      每次操作锁住一行数据。开销大,加锁慢;会出现死锁;
      锁定粒度最小,发生锁冲突的概率最低,并发度最高。
      补充:Innodb与MyIsam引擎区别
      (1)底层区别:聚集索引与非聚集索引
      (2)Innodb支持事务,MyIsam不支持事务
      (3)Innodb支持行锁,MyIsam仅支持到表锁
      (4)MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行update、insert、delete操作会自动给涉及的表加写锁。
      InnoDB在执行查询语句SELECT时(非串行隔离级别),
      不会加锁。但是update、insert、delete操作会加行锁。
    5. 间隙锁(gap lock)
      间隙锁,锁的就是两个值之间的空隙。间隙锁在某些情况下可以解决幻读问题。
      (1)临键锁(Next-key Locks)
      Next-Key Locks是行锁与间隙锁的组合。
    6. 其他
      (1)无索引行锁会升级为表锁
      锁主要是加在索引上,如果对非索引字段更新,行锁可能会变表锁
      (2)添加共享锁/排他锁
      select * from test_innodb_lock where a=2 for update(lock in share mode);

    五. 锁性能分析

    1. 检查InnoDB_row_lock状态变量分析系统上的行锁的争夺情况
    show status like 'innodb_row_lock%';
    

    其中重要的指标:
    (1)等待平均时长: Innodb_row_lock_time_avg
    (2)等待总次数:Innodb_row_lock_waits
    (3)等待总时长:Innodb_row_lock_time

    1. 查看INFORMATION_SCHEMA系统库锁相关数据表
      (1) 查看事务:select * from INFORMATION_SCHEMA.INNODB_TRX;
      (2) 查看锁:select * from
      INFORMATION_SCHEMA.INNODB_LOCKS;
      (3) 查看锁等待:select * from
      INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
      (4) 查看锁等待详细信息:
      show engine innodb status\G;
    2. 锁优化
      (1)尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
      (2)合理设计索引,尽量缩小锁的范围
      (3)尽可能减少检索条件范围,避免间隙锁
      (4)尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql尽量放在事务最后执行
      (5)尽可能低级别事务隔离

    六. MVCC隔离机制

    1. 原理(依靠undo日志与read_view机制共同完成)
      (1)undo日志:一行数据被多个事务依次修改后,Mysql保留修改前的undo数据
      (2)查询一致性视图read_view:
      事务开启后,执行任何查询SQL都会生成当前事务的一致性视图(read_view)该视图由执行查询时所有未提交事务id数组与已创建的最大事务id组成。
    2. 运行时规则
      MVCC视图存储原理


      MVCC运行原理.png

      read_view视图展示规则


      read_view视图展示.png

    七. 其他规则补充

    1. buffer pool机制
      (1)undo日志, redo日志,binlog日志


      buffer pool.png

      (2)备注
      为什么不能一次性写入磁盘中?性能考虑
      基于内存操作远快于磁盘操作,磁盘的顺序I/O效率基本等同于内存操作。
      磁盘插入数据时随机I/O性能极差。

    相关文章

      网友评论

          本文标题:Mysql 事务隔离

          本文链接:https://www.haomeiwen.com/subject/qqisqdtx.html