1. 什么是数据库事务?

数据库事务是由一组不可分割的数据库操作序列组成的逻辑单元,确保操作要么全部成功(提交),要么全部失败(回滚),以维护数据的完整性和一致性。
事务是数据库管理系统(DBMS)中的最小工作单元,包含一个或多个SQL操作(如INSERT/UPDATE/DELETE)。

2. 二阶段提交 (2PC) 在 MySQL 中的实现?

MySQL 的 2PC 机制本质是协调 Redo Log 和 Binlog 的双写一致性,分两阶段实现:

  • 准备阶段:Redo Log 标记为 PREPARED(可回滚状态);
  • 提交阶段:Binlog 持久化后,Redo Log 标记为 COMMITTED。
    崩溃恢复时,根据 Redo Log 状态和 Binlog 存在性决定提交或回滚,确保数据安全。
    参数 innodb_flush_log_at_trx_commit 和 sync_binlog 可调整持久化策略,平衡性能与可靠性。

3. Write‑Ahead Logging(WAL)及其在 MySQL 中的应用

Write-Ahead Logging(WAL)是一种日志记录机制,确保在数据写入磁盘前先记录日志,以提高数据恢复能力和系统可靠性,在 MySQL 中通过 InnoDB 的重做日志实现。

4. redo log / undo log / binlog 各自作用?

  1. undo log:用于数据回滚,记录了数据修改前的数据库日志,当事务失败或者数据库崩溃重启后可以通过这个日志将数据库恢复到崩溃前的状态
  2. redo log:用于记录数据修改,在事务提交时会先将修改记录保存到日志中并进行持久化,即使崩溃也能恢复已提交的数据
  3. binlog:用于数据复制跟恢复,支持主从复制跟数据备份,会记录所有对数据库的修改操作并以事件形式存储

5. redo log 在一次 INSERT 中记录了什么?

是在一次INSERT操作中,redo log记录了数据页的物理修改信息,以便在系统崩溃后能够恢复数据。

6. MySQL 中的 MVCC 是什么?Read View 在 MVCC 中如何工作?如果没有 MVCC 会怎样?

  1. MVCC(多版本并发控制)是 MySQL InnoDB 存储引擎实现读 - 写不阻塞的核心机制,它为每行数据维护多个版本的快照,不同事务在访问数据时,能看到数据的不同版本,而非直接修改或锁定原始数据,以此平衡并发性能与数据一致性。
  2. Read View(读视图)是事务执行快照读时生成的可见性判断规则集,核心包含四个关键值:当前活跃事务 ID 集合、最小活跃事务 ID、最大事务 ID、创建读视图的事务 ID。
    • 事务读取数据时,会通过 Read View 检查数据行的版本事务 ID:
      • 若版本 ID 小于最小活跃 ID,说明该版本已提交,可见;
      • 若版本 ID 大于等于最大活跃 ID,或在活跃事务 ID 集合中,说明版本未提交,不可见,需回溯到历史版本;
      • 最终找到符合可见性的最新版本返回。
  3. 没有 MVCC 会怎样
    • 并发性能暴跌:读操作会阻塞写操作,写操作也会阻塞读操作(如行锁 / 表锁全程持有),高并发场景下大量事务排队等待;
    • 一致性难以保证:若放弃锁机制仅用 “读最新数据”,会出现脏读、不可重复读等问题;若强依赖锁,又会丧失并发能力;
    • 隔离级别无法灵活实现:InnoDB 的可重复读、读已提交隔离级别依赖 MVCC 实现,无 MVCC 则只能依赖加锁实现串行化,无法兼顾性能与隔离性。

7. 长事务可能带来哪些问题?

长事务可能导致锁定资源、占用大量系统资源、增加死锁风险和影响数据库性能。

8. 并发事务会产生哪些问题?

并发事务可能导致脏读、不可重复读、幻读和死锁等问题,影响数据一致性和系统性能。

9. 事务隔离级别有哪些?

事务隔离级别从低到高分别是:读未提交、读已提交、可重复读、串行化。

  • 读未提交 无锁会出现脏读问题(修改未提交,读取是修改之前的数据)
  • 读已提交 解决了脏读问题,出现了不可重复读(同一个事务两次读取结果不一致)
  • 可重复读 innodb默认级别,解决不可重复读问题,出现幻读(新增数据未读取到)
  • 串行化 加锁,强行一致

10. MySQL 默认隔离级别?为何选择它?

MySQL 的默认隔离级别是 REPEATABLE READ(可重复读),它在提供较高数据一致性的同时,利用 MVCC 技术有效地支持并发性能。

11. 隔离级别是怎样实现的?

隔离级别通过锁机制、MVCC(多版本并发控制)和事务管理来实现,确保数据一致性和并发性能。

  • READ UNCOMMITTED:最低隔离级别,允许脏读。
  • READ COMMITTED:通过行锁和版本控制,防止脏读。
  • REPEATABLE READ:通过行锁、间隙锁和 MVCC,防止不可重复读和幻读。
  • SERIALIZABLE:最高隔离级别,通过表锁和严格的事务管理,确保完全隔离。

12. 间隙锁(Gap Lock)是什么?

间隙锁(Gap Lock)是一种锁机制,用于锁定行之间的间隙,防止其他事务在该间隙中插入或删除数据,以避免幻读。

13. InnoDB 行级锁是如何实现的?

InnoDB 行级锁通过索引实现,锁定特定行以支持高并发访问,确保数据一致性和事务隔离。

14. 表级锁与行级锁的区别?

表级锁锁定整个表,适用于低并发场景,而行级锁锁定特定行,支持高并发访问,二者在锁定粒度和性能上存在显著区别。

  • 锁定粒度:表级锁锁定整个表,行级锁锁定特定行。
  • 并发性能:表级锁并发性能低,行级锁并发性能高。
  • 适用场景:表级锁适用于低并发,行级锁适用于高并发。
  • 实现方式:表级锁简单,行级锁复杂。
  • 优缺点:表级锁管理开销低,行级锁支持高并发。

15. 排它锁与共享锁有什么区别?

排它锁(X 锁)允许事务独占访问资源,阻止其他事务的读写,而共享锁(S 锁)允许多个事务同时读取资源,但阻止写操作。

  • 排它锁:独占访问,阻止其他读写。
  • 共享锁:允许并发读取,阻止写入。
  • 锁兼容性:排它锁不兼容其他锁,共享锁兼容其他共享锁。
  • 优缺点:排它锁确保一致性,共享锁提高读取性能。

16. 意向锁有什么作用?

意向锁是 InnoDB 为了支持表锁和行锁共存而设计的表级标记锁。
它的主要作用是: 当事务要对某行加锁时,先在表上标记意向,让其他事务在尝试加表锁时,能快速判断表里是否有行被加锁,避免逐行检查,提升加锁效率,同时保证多粒度锁之间的互斥与兼容。

17. 自增锁 (auto‑inc lock) 了解吗?

自增锁(auto-inc lock)是 MySQL 中用于管理自增列的锁机制,确保在并发插入时自增值的唯一性和连续性。

  • 自增锁的定义:用于保护自增列,确保唯一性和连续性。
  • 自增锁的工作原理:获取和释放自增锁以计算自增值。
  • 自增锁的类型:表级锁,锁定整个表。
  • 自增锁的优缺点:确保唯一性但可能影响并发性能。
  • 自增锁的优化:通过批量插入和配置调整提高效率。

18. MySQL 的锁类型有哪些?

  • 表级锁:锁定整个表,适用于低并发。
  • 行级锁:锁定特定行,支持高并发。
  • 意向锁:表明计划加锁,帮助判断锁冲突。
  • 共享锁:允许并发读取,阻止写入。
  • 排它锁:独占访问,阻止其他读写。
  • 自增锁:保护自增列,确保唯一性。

19. MySQL 是怎么加锁的?

  • 锁的类型:表级锁、行级锁、意向锁。
  • 加锁过程:锁请求、检查、授予。
  • 锁的兼容性:共享锁和排它锁。
  • 锁的管理:锁超时和死锁检测。
  • 性能优化:索引使用和锁策略调整。

20. 数据库在什么情况下会发生死锁?

  • 死锁的定义:事务相互等待对方持有的锁。
  • 死锁发生的条件:互斥、持有并等待、不可抢占、循环等待。
  • 死锁的常见场景:交叉锁定、资源竞争。
  • 死锁的检测与解决:检测等待图,回滚事务。
  • 避免死锁的策略:资源排序,减少锁持有时间。

21. MySQL 事务如何回滚?

MySQL 事务回滚核心分两种场景,基于 InnoDB 引擎回答:

  • 主动回滚:执行ROLLBACK语句,触发事务回滚,撤销事务内所有未提交的增删改操作,恢复数据到事务开始前状态;
  • 自动回滚:事务执行中遇错误(如主键冲突、锁等待超时、数据库崩溃),或手动执行SET autocommit=1(自动提交)时未显式COMMIT,InnoDB 会自动回滚事务,保证数据一致性;
  • 回滚依赖 undo 日志:事务执行时会记录数据修改前的快照到 undo 日志,回滚时通过 undo 日志反向恢复数据,且只回滚未提交事务,已COMMIT的事务无法回滚。

22. 事务可以嵌套吗?

MySQL 不支持真正的嵌套事务,但可以通过保存点(SAVEPOINT)实现部分嵌套事务的效果,允许在事务中回滚到特定的保存点。

23. 如何避免单点故障?

  • 冗余设计:增加冗余,确保系统稳定性。比如增加服务器节点,数据库的主从复制
  • 负载均衡:请求平均分配到每个服务器上,避免单个服务器承接大量请求过载
  • 故障转移:某台服务器故障时候能自动切换到备用服务器。
  • 定期备份:确保故障后数据可恢复。包括全量备份和增量备份
  • 监控和预警:通过监控系统实时监测组件状态,及时发现和处理故障。

24. 什么是主从同步?MySQL 如何实现?

主从同步指的是主节点和从节点数据同步,保证数据一致。mysql实现原理是通过binlog日志

  • 主节点将变更操作写入到binlog日志中
  • 从节点通过io线程解析binlog,并写入relaylog
  • 从节点通过sql线程读取relaylog日志进行数据复现同时写入自己的数据中

25. 主从同步延迟如何处理?

处理主从同步延迟可以通过优化网络、调整配置、使用半同步复制和监控延迟等方法来提高同步效率和数据一致性。

26. 如何实现读写分离?

MySQL 读写分离核心是将读操作(SELECT)路由到从库,写操作(INSERT/UPDATE/DELETE)路由到主库,依托主从同步保证数据一致性,实现方式分三层:

  • 应用层实现:代码中区分读写操作,写请求直连主库,读请求分发到从库(可结合配置中心管理主从地址),简单易实现,适合中小系统;
  • 中间件层实现(主流):通过 MyCat、Sharding-JDBC、ProxySQL 等中间件,中间件统一接收所有请求,自动解析 SQL 类型并路由到主 / 从库,无需修改业务代码,适配高并发场景;
  • 数据库代理层:借助 MySQL Proxy 等代理工具,代理层屏蔽主从差异,应用只对接代理地址,由代理完成读写路由,运维成本低但性能略逊于中间件。

27. 什么是分库分表?有哪些策略?

分库分表是将单个数据库、单张大数据表拆分成多个库、多个表,以此缓解数据量和并发压力,提高系统性能与扩展性。

  • 垂直分库:按照不同业务模块,将表分到不同数据库,比如用户库、订单库、商品库分开。
  • 垂直分表:将一张表的不同字段拆分到多张表,比如把基础字段和大字段、冷字段拆开放。
  • 水平分库分表:表结构保持不变,把数据按行拆分到多个库、多个表中。
  • 水平拆分常用策略:按哈希取模拆分,数据分布均匀;按时间、ID 范围拆分,便于归档和查询。

28. 分库分表可能引发哪些问题?

分库分表后主要会带来这些问题:

  • 分布式事务问题,跨库跨表的事务难以保证原子性。
  • 跨库分页、排序、聚合查询复杂,不能像单表一样直接查询。
  • 分布式唯一 ID,自增 ID 无法使用,需要全局唯一 ID 方案。
  • 跨库关联查询困难,join 操作不能直接使用。
  • 数据迁移和扩容复杂,分表后扩容需要重新分片、迁移数据。
  • 运维成本变高,库表数量多,监控、备份、扩容都更复杂。

29. 数据冷热分离应如何设计?

数据冷热分离就是把高频访问的热数据和低频访问的冷数据分开存储,提高查询效率、降低存储成本。 设计思路一般这样:

  • 按时间、访问频率、业务状态划分冷热数据,比如近 3 个月订单是热数据,更早的是冷数据。
  • 热数据放在性能高的 MySQL 主表,保证快速查询;冷数据迁移到便宜、大容量的存储,如 MySQL 归档表、HDFS、对象存储。
  • 通过定时任务自动把过期数据从热库同步到冷库,同步后清理热库数据。
  • 业务层做查询路由,先查热库,不存在再查冷库,或提供分开的查询入口。
  • 支持冷热数据关联查询,但不做复杂 join,保证热库性能稳定。

30. MySQL 的 buffer pool 与缓存命中率如何监控?

监控 MySQL Buffer Pool 可查 innodb_buffer_pool 系列变量看配置 / 使用量,通过 SHOW ENGINE INNODB STATUS 看缓存页状态;缓存命中率用公式 1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests) 计算,理想值>99%,低命中率需调大 Buffer Pool 或优化 SQL。

31. 深度分页、读写分离、分库分表后 SQL 该如何优化?

  • 深度分页:用主键 / 索引做游标分页(替代 LIMIT offset),只查必要字段 + 覆盖索引,避免全表扫描;
  • 读写分离:实时读走主库、非实时读走从库,从库优化索引,控制主从同步延迟;
  • 分库分表:SQL 必带分片键(避免全库扫描),规避跨库 JOIN,聚合查询用中间表汇总。
    核心原则:减少无效扫描、适配分布式规则、降低数据库压力。