MySQL进阶之InnoDB引擎的锁处理

作者: 怀老师 | 来源:发表于2020-04-14 16:15 被阅读0次

事务

        InnoDB支持事务也就是ACID原子性,一致性,隔离性,持久性。

    并发事务

        优势:

            并发事务能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户。

        问题:

            更新丢失:当多个事务选择同一行,然后基于最初选定的值更新,后续事务会覆盖前面的更新。

            脏读:一个事务正在更改一条记录,在事务提交前,另一个事务读取了这个事务未提交的数据,并依赖这个数据做进一步和粗粒,就会产生未提交的数据依赖关系。

            不可重复读:一个事务在读取某些数据后一段时间再次读取,发现数据已经改变或者删除。

            幻读:一个事务按相同的查询条件重新读取以前检索过的数据,其他事务这时插入了满足查询条件的新数据,导致读取的数据不准确。(未提交的事务数据是不能产生依赖关系的,是脏数据。

        解决方案:读取数据前,对其加锁,防止其他事务对数据进行修改。

    事务隔离级别

        MVCC,通过一定机制生成一个数据请求时间点的一致性数据快照,并用这个快照来提供一定级别的一致性读取。关于MVCC的介绍详见:https://blog.dugwang.com/?p=373

        四种隔离级别:未提交读,已提交读,可重复读,可序列化。

InnoDB的锁

    InnoDB的行锁模式

        共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁(其他事务获得排它锁,意味着这个共享锁将失效)

        排它锁:允许获得排他锁的事务更新数据,,阻止其他事务取得相同数据集的共享锁和排他写锁。

        小结:共享锁的期间,其他事务也可以获取共享锁。排他锁期间,其他事务不能获取共享锁和排他锁,只可以做简单的查询。

    InnoDB的加锁方法

       1、对于增删改操作,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,不会加锁。

       2、可以通过以下语句给记录集加共享锁和排他锁

            2.1、共享锁:select * from table_name where ... LOCK IN SHARE MODE.

            2.2、排他锁:select * from table_name where ...FOR UPDATE.

            2.3、共享锁的问题?用LOCK IN SHARE MODE加锁,主要是用来确认数据是否存在,并确保没人对这个数据进行其他操作。但是如果当前事务也需要对该记录进行更新操作,则很可能造成死锁(其他事务此时也给该记录加了个共享锁,并且对该行进行更新,就会造成同时2个循环等待的锁,死锁退出)。

            2.4、如何处理?对于锁定行记录后需要进行更新操作的应用,应该使用select ... for update方式获得排他锁。

    InnoDB行锁的实现方式

        1、InnoDB行锁是通过给索引上的索引项加锁来实现的,所以只有通过索引条件检索数据,才使用行级锁,否则会用表锁。

        2、因为是使用索引加锁,所以虽然不是同一行记录,如果使用同一个索引键,还是会阻塞。

        3、可能造成全表扫描的问题?a表的name字段有索引,但是name是varchar类型的,如果where条件后不跟引号,会造成强制类型转换,执行全表扫描。

    间隙锁

        用范围查询或者查询一个不存在的数据并加锁时,InnoDB不仅会对已存在的数据加锁,也会对范围内的不存在的数据加间隙锁,这是为了避免幻读。所以,应尽量避免给范围查询加锁

    恢复和复制对InnoDB锁机制的影响

        1、MySQL通过binlog记录执行的sql语句,一般的恢复是SQL语句级别的,就是重新执行binlog中的sql语句。

        2、MySQL的binlog是按照事务提交的先后顺序记录的,恢复也是按照这个顺序执行。

        3、所以,MySQL的恢复要求事务在提交前不允许其他事务插入新数据,因为会影响到恢复是时数据的正确性。

    InnoDB 什么情况下使用表锁

        1、事务需要更新大部分或者全部数据,表又比较大。

        2、事务涉及多个表,比较复杂,可能引起死锁。

    如何尽量避免死锁

        1、尽量使用较低的隔离级别

        2、精心设计索引,使用索引访问数据

        3、选择合理的事务大小

        4、给记录集显式加锁时,最好一次申请足够级别的锁

        5、不同程序访问同一组表,尽量约定相同的顺序。

        6、尽量使用相等条件

        7、除非必须,查询时不要显式加锁

        8、特殊事务,用你表锁来提高处理速度和减少死锁的可能。

相关文章

  • 淘宝MySQL文档整理

    MySQL · 引擎特性 · InnoDB 事务锁系统简介 MySQL · 引擎特性 · Innodb 锁子系统浅...

  • MySQL进阶之InnoDB引擎的锁处理

    事务 InnoDB支持事务也就是ACID原子性,一致性,隔离性,持久性。 并发事务 优势: 并发事务能大大增加数...

  • Innodb的锁

    Innodb的锁是行级锁 mysql delete是否会锁表 MySQL的InnoDB存储引擎支持行级锁,Inno...

  • Mysql存储引擎Innodb小结

    innodb是mysql支持事务的存储引擎,也是当前mysql默认的存储引擎。innodb支持行级别锁,对并发性事...

  • InnoDB介绍

    InnoDB介绍 InnoDB是事务安全的mysql存储引擎,也是mysql的默认存储引擎,特点是行锁设计、支持M...

  • mysql规范

    一、基础规范【强制】使用InnoDB存储引擎解读:InnoDB存储引擎是MySQL默认存储引擎,支持事务和行级锁,...

  • 【原创】因酷数据库开发规范

    基本规范 所有表必须使用Innodb存储引擎Innodb存储引擎是Mysql5.6以后默认引擎支持事务,行级锁,更...

  • mysql实战(七)行锁、死锁

    MySQL的行锁是在引擎层实现的,MySQL原生引擎MyISAM不具备行锁,这也是被InnoDB替换它的原因。 两...

  • MySQL会发生死锁吗?

    MySQL的InnoDB引擎事务有4种隔离级别,主要是为了保证数据的一致性。 InnoDB引擎提供了行级锁,表锁。...

  • InnoDB存储引擎和MyISAM存储引擎

    InnoDB存储引擎 InnoDB是MySQL的默认事务型引擎,它被设计用来处理大量的短期(short-lived...

网友评论

    本文标题:MySQL进阶之InnoDB引擎的锁处理

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