开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11 天
大家好,我是小冷。 上一篇写了CRM系统基础模块和异常处理,拦截 ,具体地址请点击
这一篇介绍下MySQL5.7新特性
获取InnoDB行级锁的竞争情况
对于InnoDB所使用的行级锁定,系统中是通过另一组更为详细的状态来记录的,查看命令如下:
show status like '%innodb_row_lock %'
InnoDB的行级锁定状态不仅记录了锁定等待次数,还记录了锁定总时间长、每次平均时长以及最大的时长,各个状态变量的说明如下。 (1)Innodb_row_lock_current_waits:当前正在等待锁定的数量。 (2)Innodb_row_lock_time:从系统启动到现在锁定的总时间长度。 (3)Innodb_row_lock_time_avg:每次等待锁 花费的平均时间。 (4)Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花费的时间。 (5)Innodb_row_lock_waits:系统启动后到现在总共等待的次数。
根据Innodb提供的这些系统状态的分析制定相应的优化计划,尤其是当等待次数比较多,而且每次等待时间也比较长的时候,就需要分析系统出现这种情况的原因。
Mysql 里面的事务,满足 ACID 特性,所以在我看来,Mysql 的事务 实现原理,就是 InnoDB 是如何保证 ACID 特性的。首先,A 表示 Atomic 原子性,也就是需要保证多个 DML 操作是原子的,要么都成功,要么都失败。那么,失败就意味着要对原本执行成功的数据进行回滚,所以 InnoDB 设计了一个 UNDO_LOG 表,在事务执行的过程中,把修改之前的数据快照保存到UNDO_LOG 里面,一旦出现错误,就直接从 UNDO_LOG 里面读取数据执行反向操作就行了。其次,C 表示一致性,表示数据的完整性约束没有被破坏,这个更多是依赖于业务层面的保证,数据库本身也提供了一些,比如主键的唯一余数,字段长度和类型的保证等等。接着,I 表示事物的隔离性,也就是多个并行事务对同一个数据进行操作的时候,如何避免多个事务的干扰导致数据混乱的问题。
InnoDB行级锁的实现方法
InnoDB行级锁是通过给索引上的索引项加锁来实现的,InnoDB行级锁只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。
在不同的隔离级别下,InnoDB处理SQL语句时所采用的一致性和需要的锁是不同的。
对于SQL语句而言,隔离级别越高,InnoDB存储引擎给记录添加的锁就越严格,产生锁冲突的可能性就越高,对并发的性能影响就越大。因此,应该尽量使用较低的隔离级别,以降低并发中锁争用的概率。
锁优化
InnoDB存储引擎由于实现了行级锁,很显然,在锁定方面,行级锁的颗粒更小,实现更为复杂,所带来的性能损耗也比表级锁更高,但是InnoDB行级锁在并发性能上要远远高于表级锁,当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比优势就比较明显了,所以在选择使用哪种锁的时候,应该考虑到应用是否有很大的并发量,想要合理使用InnoDB行级锁,应该做到扬长避短,尽量做到以下几点:
(1)尽量控制事务的大小,减少锁定的资源量和锁定时间长度。 (2)尽可能让所有的数据检索都通过索引来完成,从而避免因为无法通过索引加锁而升级为表级锁。 (3)尽可能减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的记录。