数据库MySQL之事务、锁和存储引擎

本文深入探讨MySQL的事务处理,包括事务的定义、特性、原子性、一致性和隔离性的保证,以及事务的隔离级别。此外,介绍了锁机制,如行锁、间隙锁、Next-Key锁、意向锁和自增锁的原理。最后,对比分析了InnoDB和MyISAM存储引擎的区别,以及如何解决事务中的幻读问题。
摘要由CSDN通过智能技术生成

1.事务

1.1 事务的定义和作用

  • MySQL事务主要用于处理操作量大和复杂度高的数据。
  • 在 MySQL中只有Innodb存储引擎的表才支持事务。
  • 事务用来管理insert,update,delete语句

1.2 事务的特性

  • 原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。因此如果事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
  • 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行而导致数据的不一致
  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

1.3 Mysql怎么保证原子性

  • 是利用undo log来实现。当事务回滚时能够撤销所有已经成功执行的sql语句。undo log 需要记录要回滚的相应信息,当事务执行失败或者调用rollback语句时,便可以利用undo log中的信息将数据回滚到之前的状态。

1.4 Mysql怎么保证一致性

  • 数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说,原子性、隔离性、持久性是数据库实现一致性的前提。例如,原子性无法保证,显然一致性也无法保证。
  • 应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据。

1.5 Mysql怎么保证隔离性

  • 利用的是实现。一个行数据有多个版本快照数据,这些快照数据存储在undo log中。如果一个事务读取的行正在做delete或者update操作,读取操作不会等待锁释放,而是读取该行的快照版本

1.6 Mysql怎么保证持久性

  • 利用redo log实现。和undo log相反,redo log记录的是新数据的备份。在事务提交前,只需要将redo log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是redo log已经持久化。系统可以根据redo log的内容,将所有数据恢复到最新的状态
  • innodb_flush_log_at_trx_commit的值:

1.7 事务的隔离级别

  • 读未提交:一个事务可以读取另一个未提交事务的数据。
  • 读已提交:一个事务要等另一个事务提交后才能读取数据。
  • 可重复读:并发执行的事务不会相互影响,其对数据库的影响和它们串行执行时一样。
  • 序列化:最高的事务隔离级别。在该级别下,事务顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较消耗数据库性能,一般不使用。
  • 值得一提的是:大多数数据库默认的事务隔离级别是读已提交,比如Sql Server , Oracle。Mysql的默认隔离级别是可重复读

1.8 脏读、不可重复读和幻读

  • 脏读:简单来说,就是一个事务在处理过程中读取另外一个事务未提交的数据。这种未提交的数据我们称之为脏数据,依据脏数据所做的操作是不正确的。
  • 不可重复读:指一个事务范围内,多次查询某个数据,却得到不同的结果
  • 幻读:是事务非独立执行时发生的一种现象。
  • 不同隔离级别产生不同的并发异常

2.锁机制

2.1 行锁之行锁、间隙锁和Next-Key锁

  • 行锁单个行数据上锁。
  • 间隙锁:锁定一个范围,但不包括记录本身,是为了防止幻读以及防止间隙内有新数据插入。
  • Next-Key锁:锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。InnoDB默认加锁方式是next-key锁。
  • 以上三种锁都是排它锁。

2.2 表锁之意向锁和自增锁

  • 意向锁:InnoDB存储引擎引入了意向锁,意向锁就是一种表锁,允许行锁与表锁共存。实际应用中,InnoDB使用的是意向锁。意向锁是指,未来的某个时刻,事务可能要加共享/排它锁,先提前声明一个意向。
  • 自增锁:如果存在自增字段,MySQL会维护一个自增锁,和自增锁相关的一个参数为innodb_autoinc_lock_mode,可以设定3个值0,1和2。

9.3 锁的具体实现之排它锁和共享锁

  • 排它锁:又称为写锁。允许获得排它锁的事务更新数据,但是阻止其它事务取得排它锁。例如,事务T对数据对象A加上排它锁,事务T可以对对象A进行修改,但是其它事务不能对A进行修改。
  • 共享锁:又称为读锁。允许一个事务读取一行,阻止其它事务进行修改。例如,事务T对数据对象A加上共享锁,其他事务只能对A再次加上共享锁而不能加排它锁,这保证其他事务可以读取A,但是T释放A的共享锁之前不允许对A做任何修改。

9.4 乐观锁和悲观锁

  • 悲观锁:当要对数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。悲观锁主要分为共享锁和排他锁
  • 乐观锁:乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测。如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。乐观锁适用于读操作多的场景,这样可以提高程序的吞吐量。

3.常见的存储引擎

3.1 INNODB存储引擎

  • InnoDB具有较强的事务处理能力及较好的事务安全性并且支持外键,给MySQL提供了事务提交、回滚、崩溃修复能力、还能够实现并发控制下的事务安全,在需要频繁的更新、删除操作并要求事务完整性的情况下应该选择InnoDB种存储引擎。但是这种引擎不足之处是读写效率稍差占用空间相对较大

3.2 MyISAM存储引擎

  • MyISAM存储引擎的表存储成三个文件。文件的名字与表名相同,扩展名包括frm、MYD 和MYI。其中,frm为文件存储表的结构;MYD为文件存储数据,其是MYData的缩写;MYI为文件存储索引,其是MYIndex的缩写。基于MyISAM存储引擎的数据库支持三种不同的存储格式:静态、动态和压缩。其中前两个(静态格式和动态格式)根据正在使用的列的类型来自动选择,第三个即已压缩格式,只能使用myisampack工具来创建。

3.3 MEMORY存储引擎

  • MEMORY存储引擎是MySQL中的一类特殊的存储引擎,它使用存储在内存中的内容来创建表,而且所有数据也放在内存中。其特点是访问速度快但安全上没有保障,适用应用中涉及数据比较小、需要进行快速访问的场合。每个基于MEMORY存储引擎的数据库实际对应一个磁盘文件,该文件的文件名与表名相同,类型为frm类型,该文件中只存储表的结构,而数据文件都是存储在内存中。这样有利于对数据的快速的处理,提高整个表的处理效率。值得注意的是,服务器需要有足够的内存来维持MEMORY存储引擎的表的使用。如果不需要使用可以释放这些内存,甚至可以删除不需要的表。

3.4 INNODB存储引擎和MyISAM存储引擎的区别

  • innodb支持事务和外键,而myisun不支持。
  • innodb支持行锁和表锁,而myisum只支持表锁。
  • 在mysql5.6版本之后,支持全文索引。
  • innodb的叶子节点直接存储数据本身,而myisum存储的是数据的地址。

4.事务相关面试题

1.如何在可重复读级别解决幻读

  • MVCC机制表面上可以解决幻读。
  • 如果从根本上解决幻读,可以使用以下方法:a.使用序列化的隔离级别;b.MVCC+next-key锁:next-key锁由record locks(行锁) 和 gap locks(间隙锁,每次锁住的不光是需要使用的数据,还会锁住这些数据附近的数据)组成。
  • 实际上很多的项目中是不会使用到上面的两种方法的,序列化的性能太差,而且其实幻读很多时候是我们完全可以接受的。

2.怎么实现一个日志的滚动输出?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值