Mysql 事务隔离

2022-12-17  本文已影响0人  蓝调_4f2b

一. 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性能极差。

上一篇下一篇

猜你喜欢

热点阅读