Mysql 面试要点

数据库事务的实现原理

  • 数据库不同的存储引擎可能会有一些区别。这里拿常用的 InnerDB 存储引擎举例

原子性实现原理

  • 通过数据库 Undo Log 实现的。

  • 事务中在操作任何数据之前,首先将原数据备份到 Undo Log 然后进行数据的修改。

  • 如果事务中有任意操作发生异常或用户执行了 Rollback 语句,那么数据库就会使用 Undo Log 中的备份将数据恢复到事务开始之前的状态。

一致性实现原理

  • 与原子性实现原理一样也是利用 Undo Log

持久化实现原理

  • 通过数据库 Redo Log 实现的

  • Redo Log 与 Undo Log 相反,Redo Log 记录的是新数据的备份,事务提交之前,会把数据备份到 Redo Log 中并持久化。

  • 当系统崩溃时,虽然数据没有持久化到数据库中,但是 Redo Log 已经持久化。系统可以根据 Redo Log 的内容,将所有数据恢复到最新的

隔离性实现原理

  • 隔离性的实现原理比较特殊,是通过数据库锁的机制实现

  • 隔离性分四个级别:

    • 读未提交(Read uncommitted)

      • 读未提交:一个事务可以读到另外一个事务未提交的数据。脏读

      • 实现:事务在读数据的时候并未对数据进行加锁。事务在发生更新数据的瞬间,必须先对其加 行级共享锁,直到事务结束才释放。举例:事务 A 读取某行记录时(没有加锁),事务 2 也能对这行记录进行读取、更新。当事务 B 对该记录进行更新时,事务 A 读取该记录,能读到事务 B 对该记录的修改版本,即使该修改尚未被提交。事务 A 更新某行记录时,事务 B 不能对这行记录做更新,直到事务 A 结束。

    • 读已提交(Read committed)

      • 读已提交:一个事务可以读到另外一个事务提交的数据。不可重复读

      • 实现:事务对当前被读取的数据加 行级共享锁(当读到时才加锁),一旦读完该行,立即释放该行级共享锁;事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级排他锁,直到事务结束才释放。原理:事务 A 读取某行记录时,事务 B 也能对这行记录进行读取、更新;当事务 B 对该记录进行更新时,事务 A 再次读取该记录,读到的只能是事务 B 对其更新前的版本,或者事务 B 提交后的版本。事务 A 更新某行记录时,事务 B 不能对这行记录做更新,直到事务 1 结束。流程描述:事务 A 读操作会加上共享锁,事务 B 写操作时会加上排他锁,当事务 B 正在写操作时,事务 A 要读操作,发现有排他锁,事务 A 就会阻塞,等待排他锁释放(事务 B 写操作提交才会释放),才能进行读操作。

    • 可重复读(Repeatable reads)

      • 实现:事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加 行级共享锁,直到事务结束才释放;事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级排他锁,直到事务结束才释放。举例:事务 A 读取某行记录时,事务 B 也能对这行记录进行读取、更新;当事务 B 对该记录进行更新时,事务 A 再次读取该记录,读到的仍然是第一次读取的那个版本。事务 A 更新某行记录时,事务 B 不能对这行记录做更新,直到事务 1 结束。

    • 可序列化(Serializable)

      • 可序列化(Serializable) 写操作串联执行

      • 实现:事务在读取数据时,必须先对其加 表级共享锁 ,直到事务结束才释放;事务在更新数据时,必须先对其加 表级排他锁 ,直到事务结束才释放。举例:事务 A 正在读取 A 表中的记录时,则事务 B 也能读取 A 表,但不能对 A 表做更新、新增、删除,直到事务 A 结束。事务 A 正在更新 A 表中的记录时,则事务 B 不能读取 A 表的任意记录,更不可能对 A 表做更新、新增、删除,直到事务 A 结束。原理:在读操作时,加表级共享锁,事务结束时释放;写操作时候,加表级独占锁,事务结束时释放。

  • MySQL 的默认隔离级别就是 Repeatable,Oracle 默认 Read committed

MYSQL存储结构

SQL聚合查询语法

MYSQL存储结构,主键索引和非主键索引在MYSQL中是如何存储、查找的

ACID的涵义,MYSQL是如何保证的

b-tree和b+-tree的区别,INNODB为什么用b+-tree

Last updated

Was this helpful?