zoukankan      html  css  js  c++  java
  • MySQL事务调优

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11429239.html

    数据库事务

    数据库事务是数据库系统执行过程中的一个逻辑处理单元,保证一个数据库操作要么成功,要么失败。

    数据库事务具有以下四个基本属性:

    • 原子性(Atomicity)
    • 一致性(Consistent)
    • 隔离性(Isolation)
    • 持久性(Durable)

    正是这些特性,才保证了数据库事务的安全性。而在MySQL中,鉴于MyISAM存储引擎不支持事务,MySQL的事务都是在InnoDB存储引擎的基础上进行的。

    事务隔离机制

    InnoDB实现了两种类型的锁机制:共享锁(S)和排他锁(X)。

    共享锁允许一个事务读数据,不允许修改数据,如果其他事务要再对该行加锁,只能加共享锁;

    排他锁是修改数据时加的锁,可以读取和修改数据,一旦一个事务对该行数据加锁,其他事务将不能再对该数据加任务锁。

    在操作数据的事务中,不同的锁机制会产生以下几种不同的事务隔离级别,不同的隔离级别分别可以解决并发事务产生的几个问题,对应如下:

    • 未提交读(Read Uncommitted):在事务A读取数据时,事务B读取和修改数据加了共享锁。这种隔离级别,会导致脏读、不可重复读以及幻读。
    • 已提交读(Read Committed):在事务A读取数据时增加了共享锁,一旦读取,立即释放锁,事务B读取修改数据时增加了行级排他锁,直到事务结束才释放锁。也就是说,事务A在读取数据时,事务B只能读取数据,不能修改。当事务A读取到数据后,事务B才能修改。这种隔离级别,可以避免脏读,但依然存在不可重复读以及幻读的问题。
    • 可重复读(Repeatable Read):在事务A读取数据时增加了共享锁,事务结束,才释放锁,事务B读取修改数据时增加了行级排他锁,直到事务结束才释放锁。也就是说,事务A在没有结束事务时,事务B只能读取数据,不能修改。当事务A结束事务,事务B才能修改。这种隔离级别,可以避免脏读、不可重复读,但依然存在幻读的问题。
    • 可序列化(Serializable):在事务A读取数据时增加了共享锁,事务结束,才释放锁,事务B读取修改数据时增加了表级排他锁,直到事务结束才释放锁。可序列化解决了脏读、不可重复读、幻读等问题,但隔离级别越来越高的同时,并发性会越来越低。

    InnoDB中的RC和RR隔离事务是基于多版本并发控制(MVCC)实现高性能事务。一旦数据被加上排他锁,其他事务将无法加入共享锁,且处于阻塞等待状态,如果一张表有大量的请求,这样的性能将是无法支持的。

    MVCC对普通的 Select 不加锁,如果读取的数据正在执行Delete或Update操作,这时读取操作不会等待排它锁的释放,而是直接利用MVCC读取该行的数据快照(数据快照是指在该行的之前版本的数据,而数据快照的版本是基于undo实现的,undo是用来做事务回滚的,记录了回滚的不同版本的行记录)。MVCC避免了对数据重复加锁的过程,大大提高了读操作的性能。

    锁具体实现算法

    InnoDB既实现了行锁,也实现了表锁。行锁是通过索引实现的,如果不通过索引条件检索数据,那么InnoDB将对表中所有的记录进行加锁,其实就是升级为表锁了。

    行锁的具体实现算法有三种:record lock、gap lock以及next-key lock。record lock是专门对索引项加锁;gap lock是对索引项之间的间隙加锁;next-key lock则是前面两种的组合,对索引项及其之间的间隙加锁。

    1. Record Lock:单个行记录上的锁。
    2. Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。GAP锁的目的,是为了防止同一事务的两次当前读,出现幻读的情况。
    3. Next-Key Lock:1+2,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。

    只在可重复读或以上隔离级别下的特定操作才会取得gap lock或next-key lock;

    在Select 、Update和Delete时,除了基于唯一索引的查询之外,其他索引查询时都会获取gap lock或next-key lock,即锁住其扫描的范围。

    优化高并发事务方案

    1. 结合业务场景,使用低级别事务隔离

    2. 避免行锁升级表锁

    在InnoDB中,行锁是通过索引实现的,如果不通过索引条件检索数据,行锁将会升级到表锁。表锁是会严重影响到整张表的操作性能的,所以应该避免它。

    3. 控制事务的大小,减少锁定的资源量和锁定时间长度

    Reference

    https://time.geekbang.org/column/article/114194

    https://www.cnblogs.com/zhoujinyi/p/3435982.html

  • 相关阅读:
    Find the capitals
    Area of a Circle
    SequenceSum
    使用Eclipse设定Android开发环境
    hdu 1290 竭诚为杭州电礼物50周年
    oracle connect by 说明
    CSS截取字符串,额外的文本显示以省略号
    动态规划——背包问题
    【MySQL笔记】mysql来源安装/配置步骤和支持中国gbk/gb2312编码配置
    博客搬到了http://xianglong.me
  • 原文地址:https://www.cnblogs.com/agilestyle/p/11429239.html
Copyright © 2011-2022 走看看