MySql锁和MVCC

具体来说,MySQL中的锁实现方式主要涉及到两个层面:表级锁和行级锁。以下是更详细的说明:

一.表级锁:

  1. 共享锁(Shared Lock):

    • 实现方式:通过 READ 锁实现,多个事务可以同时持有相同的共享锁,用于读取操作。
    • 语法:LOCK TABLES table_name READ;
  2. 排他锁(Exclusive Lock):

    • 实现方式:通过 WRITE 锁实现,事务独占排他锁,其他事务无法同时持有任何锁,用于写入操作。
    • 语法:LOCK TABLES table_name WRITE;

二.行级锁(InnoDB存储引擎):

  1. 共享锁(Shared Lock):

    • 实现方式:通过 FOR SHARELOCK IN SHARE MODE 获取,用于读操作。允许多个事务同时持有相同的共享锁。
    • 语法:SELECT * FROM table_name WHERE ... FOR SHARE;
  2. 排他锁(Exclusive Lock):

    • 实现方式:通过 FOR UPDATE 获取,用于写操作。只有一个事务可以持有排他锁。
    • 语法:SELECT * FROM table_name WHERE ... FOR UPDATE;
  3. 两阶段锁协议:

    • InnoDB使用两阶段锁协议,确保在事务中获取的锁在整个事务期间都不会被释放。
  4. Next-Key Locks:

    • 用于防止幻读,包括行锁和间隙锁,保护范围查询,防止新插入的行被其他事务插入。

三.死锁处理:

  1. 死锁检测:

    • MySQL使用等待图和超时机制来检测死锁。
  2. 死锁解决:

    • 当检测到死锁时,MySQL会选择回滚其中一些事务,解除死锁。

四.隔离级别:

  1. 读未提交(Read Uncommitted):

    • 事务可以读取其他事务未提交的数据,不会加锁。
  2. 读提交(Read Committed):

    • 事务只能读取其他事务已提交的数据,避免脏读。使用共享锁,保护读取的数据。
  3. 可重复读(Repeatable Read):

    • 事务在整个过程中看到的数据保持一致,不会被其他事务的提交影响。使用事务级锁,包括共享锁和排他锁
    • 通过MVCC实现,每个事务读取数据时看到的是一个快照,事务之间相互不可见。
    • 通过在每行数据中保存版本信息,事务只看到在它开始时已经存在的数据版本,因此避免了幻读。
  4. 串行化(Serializable):

    • 事务串行执行,避免了脏读、不可重复读和幻读的问题,但牺牲了并发性能。
    • 通过MVCC实现,每个事务按顺序访问数据,确保事务之间不会产生任何交叉。

在应用中,合理选择锁的级别、类型以及事务的隔离级别是非常重要的,以确保数据一致性、并发性和性能的平衡。

五.为什么互联网公司用mysql的事务隔离级别读提交比较多

互联网公司在选择事务隔离级别时常使用读已提交(Read Committed)级别的主要原因是在此级别下,相较于更高级别的隔离,性能表现较好,同时也避免了一些并发问题。

以下是一些互联网公司选择读已提交隔离级别的原因:

  1. 性能: 较低的隔离级别通常伴随着更好的并发性能,而读已提交级别可以在一定程度上提供合理的并发性能,避免了更高级别可能带来的性能开销。

  2. 脏读问题的控制: 读已提交级别避免了脏读问题,即一个事务不能读取到另一个未提交事务的数据快照。这在互联网应用中是很重要的,因为数据的一致性对用户体验至关重要。

  3. 适应业务场景: 互联网应用通常有大量的读操作,而对一致性的要求相对较低。在这种情况下,读已提交级别提供了较好的平衡,既保证了一定的数据一致性,又提高了读操作的并发性能。

  4. 避免过度锁定: 更高级别的隔离可能需要更多的锁定操作,可能导致系统过度锁定,限制了并发性。读已提交级别通过对提交的数据进行读取,避免了对未提交数据的锁定,减小了锁的粒度。

六.mysql行锁和表锁在什么情况下会使用到 

MySQL中的行锁和表锁在不同的情况下会被使用,主要取决于事务对数据的读写操作以及隔离级别的设置。

行锁(Row Locking):

  1. 并发写入(Update):

    • 当多个事务同时试图更新同一行数据时,InnoDB会使用行锁以确保数据的一致性。这是因为如果两个事务同时修改同一行,可能会导致数据不一致。
  2. 事务中的SELECT ... FOR UPDATE:

    • 在事务中使用SELECT ... FOR UPDATE语句时,会对选中的行加上行锁。这通常用于在事务中选择某些数据,并确保在事务结束前其他事务不能对这些数据进行修改。
  3. INSERT INTO ... SELECT:

    • 当使用INSERT INTO ... SELECT语句时,从选中的数据行中复制并插入到目标表时,行锁也会被使用,以防止其他事务同时修改这些数据。

表锁(Table Locking):

  1. DDL操作:

    • 在执行某些DDL(Data Definition Language)操作时,例如ALTER TABLERENAME TABLE等,会对整个表进行表锁,确保在DDL操作执行期间不会有其他事务对表进行读或写。
  2. 显式加表锁:

    • 通过LOCK TABLES语句显式加表锁,可以在某些特定的场景下控制并发访问。
  3. 全表扫描:

    • 在某些情况下,当执行全表扫描的查询,例如SELECT * FROM table_name时,InnoDB可能会选择使用表锁而不是行锁,以优化性能。

需要注意的是,行锁和表锁的使用受到数据库的存储引擎和隔离级别的影响。InnoDB存储引擎支持行级锁,而MyISAM等引擎可能更倾向于使用表锁。选择行锁还是表锁应该根据具体的业务需求和性能优化来进行权衡。通常情况下,倾向于使用行级锁,以提高并发性。

七.mysql间隙锁 

MySQL的间隙锁(Gap Lock)是一种锁定范围而不是具体行的锁定方式。它用于锁定一个范围的索引,而不仅仅是锁定已存在的记录。间隙锁的主要目的是防止其他事务在锁定范围内插入新记录,从而确保查询的一致性。

下面是一些关于MySQL间隙锁的重要概念:

  1. 间隙锁的应用场景:

    • 典型的应用场景是在某个范围内执行SELECT ... FOR UPDATESELECT ... FOR SHARE语句时,MySQL会使用间隙锁来锁定范围内的所有索引。
  2. 防止幻读:

    • 间隙锁的一项主要功能是防止幻读(Phantom Read)。幻读是指在同一个事务中,由于其他事务插入了新的记录,导致同一查询的结果集变化。通过使用间隙锁,MySQL可以防止其他事务在查询范围内插入新的记录,确保查询的一致性。
  3. 间隙锁的获取方式:

    • 当执行SELECT ... FOR UPDATESELECT ... FOR SHARE语句时,MySQL会在查询条件所涉及的索引范围内获取间隙锁。
  4. 不同存储引擎的支持:

    • InnoDB存储引擎支持间隙锁,而MyISAM等一些其他存储引擎不支持。
  5. 性能开销:

    • 间隙锁可能引入一些性能开销,特别是在高并发写入的情况下。因此,需要谨慎使用,确保它的应用场景符合实际需求。

使用间隙锁的场景通常涉及到对范围内数据的修改或锁定,而不仅仅是对现有行的锁定。在设计和优化数据库查询时,需要考虑间隙锁的影响,并根据具体业务需求选择合适的锁定方式。

八.mysql MVCC的实现方式 

MVCC(Multi-Version Concurrency Control)是一种用于提供数据库事务并发性的机制,MySQL的InnoDB存储引擎通过MVCC来实现事务的隔离。以下是MySQL MVCC的主要实现方式:

  1. 版本号(Transaction ID):

    • 每个事务都有一个唯一的事务ID(Transaction ID),这个ID是在事务开始时分配的。事务ID是递增的。
  2. 数据行的版本号:

    • 对于每一行数据,InnoDB存储引擎会为其维护一个版本号(或者称为事务ID范围)。这个版本号表示数据行最后一次被修改的事务ID。
  3. Read View:

    • 当一个事务开始时,会创建一个Read View,它包含了事务启动时所有已提交事务的事务ID。Read View确定了在该事务中可以看到哪些版本的数据。
  4. Read View的创建和使用:

    • 当一个事务执行一个读操作时,它会使用Read View来确定所能看到的数据行版本。Read View的创建是基于当前系统中的已提交事务ID。这个Read View会在整个事务期间一直存在,直到事务结束。
  5. 事务的隔离级别实现:

    • MVCC通过检查事务的Read View和数据行的版本号来实现不同的隔离级别,例如读未提交、读已提交、可重复读等。
  6. Undo Log:

    • InnoDB使用Undo Log记录数据行的旧值,以便在事务回滚时能够恢复原始状态。Undo Log在MVCC中用于生成Read View,确保一个事务不会读取到自己未提交的修改。
  7. 删除操作的处理:

    • 删除操作并不实际删除数据行,而是在数据行上设置删除标记。已删除数据行的版本号被更新,以便在Read View中被忽略。

MVCC的实现使得不同事务可以并发地读取和修改数据库,而不会互相干扰。每个事务在其Read View内只能看到在其启动时间已提交的事务所做的修改,从而提供了一定程度的隔离性。这是InnoDB存储引擎实现事务隔离的关键机制之一。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值