五种分布式事务解决方案及适用场景。
二 PC 方案:依靠数据库实现,分准备、提交 / 回滚两阶段,事务协调者通知参与者开启事务并执行业务操作,未提交时全局堵塞,异常时统一回滚,缺点是全局堵塞影响性能。
三 PC 方案:在二 PC 基础上增加询问阶段,事务协调者先确认参与者可用性,参与者仅回复状态不执行业务,可避免参与者不可用时的资源浪费,但仍存在事务全局堵塞问题。
TCC 方案:通过 Try、Confirm、Cancel 三个代码方法实现,Try 阶段排除业务异常并准备资源,Confirm 阶段完成最终提交,Cancel 阶段异常时回滚,阻塞力度小但与业务代码强耦合。
Saga 方案:将长事务拆分为多步本地事务,正常时依次执行提交,异常时反向回滚操作,可减少长事务堵塞时间,但无法保证事务隔离性,高并发下可能出现超卖。
消息最终一致性:以 RocketMQ 为例,生产者先发送半消息,执行本地事务成功后通知 MQ 投递消息,消费者接收后执行业务,异常时生产者删除半消息或消费者重试,重试失败需人工干预,保证最终数据一致。
MySQL 索引优化的核心逻辑与慢查询解决的三层防御体系,以面试场景为例点明单列索引的陷阱。
单列索引陷阱:MySQL 单表查询多数仅能使用一个索引,若为订单查询的用户名、手机号、下单时间字段分别建单列索引,优化器会按字段基数选过滤性最优的索引,其余字段需在索引结果中二次过滤;若选错过滤性差的索引,可能扫出十万行数据,回表速度比全表扫描还慢。
第一层防御:理解索引选择底层逻辑,优化器依据字段基数预估过滤性来选索引,明确单查询仅用一个索引的规则。
第二层防御:用 explain 查看执行计划的 key、rows 等字段,开启 optimizer_trace 追踪优化器选索引的成本计算,开启慢查询日志捕获索引使用异常情况,精准定位问题。
第三层防御:用区分度从高到低排序的联合索引替代单列索引,若查询字段固定可建覆盖索引省去回表;优化器选索引错误时,可 forceindex 强制指定索引,同时配合监控、业务限制(如限定查近三个月订单)优化查询。
索引并非越多越好,需结合 MySQL 优化器逻辑精准使用。
MySQL 中回表与覆盖索引的底层逻辑及关联关系。
两类索引定义:InnoDB 引擎的主键索引(聚簇索引)叶子节点存整行数据,类比户口本;辅助索引(普通索引)叶子节点仅存主键值,类比身份证号。
回表流程解析:用名字(辅助索引)查完整用户信息时,先通过辅助索引获取主键值,再持主键值到主键索引查询整行数据,该二次查询过程即为回表,会增加磁盘 I/O 损耗。
覆盖索引说明:覆盖索引是一种查询状态,若查询所需信息已包含在辅助索引(如名字 + 年龄联合索引)中,数据库无需回表,直接从辅助索引获取数据,可提升查询速度。
后续内容预告:面试官后续可能追问最左前缀原则、联合索引工作原理等高频面试题,将在后续讲解。
以上内容可帮助面试者清晰回应 MySQL 回表与覆盖索引相关问题。
MVCC 仅适用于读已提交和可重复读两种隔离级别,且两者的 readview 创建时机存在本质区别。
隔离级别基础:视频先讲解 4 种事务隔离级别(读未提交、读已提交、可重复读、串行化),通过账户余额案例解释脏读、不可重复读、幻读问题,说明 MySQL 默认隔离级别为可重复读,Oracle 为读已提交。
MVCC 核心机制:以读已提交为例,拆解三大关键点:隐藏列(事务 ID、历史数据指针等)、undolog 存储历史版本数据、readview 通过四个条件定位可读取的历史数据。
MVCC 适用场景:读未提交不使用 MVCC,串行化依赖表锁;读已提交每次查询创建 readview,可重复读仅在事务首次查询创建一次 readview。
Java 后端面试中 MySQL 快速加索引的答题方法及相关背景。
面试背景说明:Java 后端开发者吐槽面试被问非本职的 MySQL 加索引问题,还需承担前端、运维、测试甚至客服等额外工作。
早期加索引方式:MySQL 早期用 copy 模式,需建新表、拷数据、替换旧表,全程锁表阻塞读写,处理 1 亿条数据耗时极长。
在线 DDL 模式:MySQL 引入 inplace 模式的 online DDL,直接在原表构建索引,无需拷贝数据,设置 LOCK=NONE 可不阻塞 DML 操作;通过 row log 记录增量变更,索引构建完成后应用日志保证一致性,仅最后阶段秒级锁表。
特殊场景方案:修改列类型等原生不支持的操作,可使用 PT-OSC、gh-ost、OSC 三类工具,或借助云数据库的无锁变更功能。
答题套路总结:面试时先讲 online DDL 原理,再补充工具方案,最后提及云数据库无锁变更,可体现原理与工程实践能力。
面试官详解用户点击下单到数据库落库全链路的高并发风险与应对方案。
接入层防护:险境为瞬间流量洪峰打垮后端,对策是用令牌桶、漏桶算法限流,网关每秒仅放行指定数量请求;当下游服务报错超阈值时,触发熔断器的关闭→开启→半开状态流转,执行降级逻辑防止故障蔓延。
业务层控并发:险境为商品超卖、用户重复下单,扣库存可在读多写少场景用乐观锁(带 stock>0 条件的 update 语句),写冲突高场景用悲观锁(select...for update),高性能场景用 Redis 预扣减再异步同步数据库;幂等性可通过订单表唯一索引,或分布式锁加订单状态机实现。
中间件削峰:险境为数据库连接池被打满、CPU 占比 100%,对策是引入消息队列,业务服务发消息后立即返回,消费者异步处理落库;同时需开启生产者确认、MQ 持久化、消费者手动 ACK 防消息丢失,消费者端做幂等性处理防重复消费,临时扩容消费者或转积压消息防消息积压。
存储层扩能:险境为单表数据过亿导致读写缓慢,对策是分库分表,按 user_id 哈希分片;用雪花算法生成全局唯一 ID,其由 1 位符号位 + 41 位时间戳 + 10 位工作机器 ID+12 位序列号组成;遇时钟回拨可等待时钟追上、预留序列号缓冲或切换机器 ID。
该面试题考察后端开发者对高并发、高可用、数据一致性的综合理解。