最近开始面试了,410面试了一家公司 针对自己薄弱的面试题库,深入了解下,也应付下面试。在这里先祝愿大家在现有公司好好沉淀,定位好自己的目标,在自己的领域上发光发热,在自己想要的领域上(技术管理、项目管理、业务管理等)越走越远!希望各位面试都能稳过,待遇都是杠杠的!
mysql基础问题可以查看:两篇博客会进行不定期更新,更新慢了请大家谅解,希望在下个月能读透所有的技术问题,并找到合适的一个公司:面试题之数据库相关-mysql篇-CSDN博客
1.如何设计一个支撑每秒10万写入的高并发MySQL系统
-
分布式架构核心原则
- 分布式架构原则:
- 分而治之:讲写入负载分散到多个节点中
- 异步处理:解耦即使相应与数据持久化
- 冗余扩展:所有组件无单点故障
- 典型架构拓扑
-
客户端 → 负载均衡 → 写入API层 → 消息队列 → 分库分表集群↓缓存集群↓数据分析层
- 分布式架构原则:
-
分库分表详细方案
- 分片策略设计
- 水平分库分表
- 分片路由策略
- 一致性哈希扩容流程:
-
新增物理节点注册到元数据中心
-
数据迁移工具扫描待迁移分片
-
双写新旧分片直至数据同步完成
-
流量切换至新分片
-
清理旧分片冗余数据
-
- 分片策略设计
-
写入链路优化
- 异步写入架构
-
1. 客户端请求 → 2. API服务验证 → 3. 写入Kafka → 4. 返回成功响应↓ 5. 消费者批量写入MySQL → 6. 更新Redis缓存
- 批量写入优化
- 消息队列配置:kafka生产配置
-
mysql极致优化
- 关键的innodb参数
- 连接与线程配置
-
高可用保障措施
- 多活数据中心:设置双主同步且都有备库,主库通过专线同步到热备主库,热备主库同步热备从库信息
- 故障自动转移机制
- 性能验证方法
- 压测工具
- 关键指标监控
-
指标 阈值 监控工具 QPS 单库<1万 Prometheus 主从延迟 <100ms pt-heartbeat 线程运行数 <max_connections×80% Grafana 磁盘IOPS <标称值70% iostat
-
典型解决方案
- 热点数据问题
-
动态分片:将热点分片进一步拆分
-
本地缓存:在应用层缓存热点分片路由
-
限流保护:对特定分片实施写入限流
-
-
分布式事务处理
-
本地写入消息队列
-
异步发送MQ(可靠消息服务保证)
-
- 热点数据问题
2.MySQL Group Replication vs MGR vs 传统主从复制?
- 核心架构差异
特性 | 传统主从复制 | MySQL Group Replication (MGR) |
---|---|---|
拓扑结构 | 主从星型拓扑 | 全对称P2P架构 |
数据同步方式 | 异步/半同步复制 | 基于Paxos协议的原子广播 |
组成员管理 | 手动配置 | 自动故障检测与成员管理 |
一致性级别 | 最终一致性 | 即时一致性(可配置) |
故障切换 | 需手动或借助工具 | 自动选举新Primary |
- 技术对比
- 传统同步
- 数据流:基于binlog的逻辑日志复制
- 模式:
- 异步复制(默认)
- 半同步复制(after_commit/after_sync)
- 局限:
- 脑裂风险
- 切换时可能丢数据
- 从库可能落后
- MGR架构
- 核心组件:
- group communication engine:基于paxos的xcom协议
- certification layer:冲突检测
- 工作流程
- 事务在本地执行
- 广播到组内所有节点
- 多数节点确认后提交
- 应用事务到所有节点
- 关键能力对比
- 核心组件:
- 传统同步
能力维度 | 传统复制 | MGR |
---|---|---|
自动故障转移 | ❌ 需要VIP/Proxy | ✅ 内置自动选举 |
多主写入 | ❌ 单主 | ✅ 支持多主(需配置) |
数据一致性 | 最终一致 | 强一致(多数节点确认) |
网络分区容忍 | ❌ 可能丢数据 | ✅ 遵循CP原则 |
节点扩展性 | 线性扩展读能力 | 建议3-9个节点 |
- 性能指标对比
指标 | 传统半同步复制 | MGR单主模式 | MGR多主模式 |
---|---|---|---|
写入TPS | 12,000 | 9,500 | 7,200 |
平均延迟(ms) | 8 | 15 | 22 |
故障切换时间(s) | 5-30(手动) | 1-3 | 1-3 |
网络带宽消耗 | 1X | 2.5X | 3X |
-
适用场景
-
传统复制适合:
-
读写分离的报表系统
-
异地灾备场景
-
对一致性要求不高的业务
-
已有成熟中间件管理的环境
-
-
MGR适合:
-
需要高可用的核心业务系统
-
金融级数据一致性要求的场景
-
云原生/K8s环境部署
-
希望减少外部依赖的架构
-
-
Q:MGR的Paxos协议如何保证数据一致性?
A:MySQL Group Replication (MGR) 通过改进的Paxos协议(具体实现为XCom)来保证分布式环境下的数据一致性
- 一致性保证核心步骤
- 事务准备阶段:
-
客户端事务在Primary节点执行
-
生成包含所有修改的写集(writeset)
-
写集通过认证层进行冲突检测
-
-
提案广播:
-
Primary节点作为Proposer将写集广播给所有节点
-
节点收到提案后:
-
检查自身状态是否正常
-
验证写集冲突
-
返回Promise应答
-
-
-
多数派确认(Accept/Accepted)
-
当收到多数节点(N/2+1)的Promise后
-
Primary发送Accept请求
-
各节点将事务写入relay log(内存+磁盘)
-
-
全局提交(Learn)
-
收到多数节点的Accepted响应后
-
Primary提交本地事务
-
广播Commit消息通知所有节点
-
所有节点应用该事务
-
- 事务准备阶段:
- 关键一致性保护机制
- 多数派原则(Quorum)
-
每个事务必须得到多数节点确认
-
3节点集群至少2个确认
-
5节点集群至少3个确认
-
公式:
W + R > N
(W写节点数, R读节点数, N总节点数)
-
- 冲突检测与解决
-
基于GTID的认证:检查冲突
-
版本向量:每个事务携带版本信息
-
视图同步
-
- 多数派原则(Quorum)
-
异常处理机制
-
节点故障处理
-
故障类型 处理方式 少数节点宕机 继续服务 多数节点宕机 停止服务 网络分区 多数派分区继续服务
-
-
脑裂预防
-
世代时钟(Epoch Number):每次视图变更递增
-
Fencing机制:旧Primary自动降级
-
-
恢复流程
-
故障节点重新加入
-
从最新节点拉取GTID集合
-
自动选择增量同步或全量同步
-
追平数据后重新加入组
-
-
-
与经典的paxos区别
-
特性 经典Paxos MGR-XCom 成员管理 静态 动态 消息传输 原始UDP TCP+流控 领导者角色 临时选举 稳定Primary 数据载体 任意值 事务写集 持久化点 多数接受 多数确认
-
-
性能优化
-
流水线化处理
-
批量认证:合并多个事务的写集检测,减少网络往返次数
-
流控机制
-
-
一致性级别配置
-
MGR支持两种模式:
-
单主模式:SET GLOBAL group_replication_single_primary_mode=ON;
-
所有写操作到primary
-
保证线程一致性
-
-
多主模式:SET GLOBAL group_replication_enforce_update_everywhere_checks=ON;
-
任何节点可写
-
保证因果一致性
-
-
-
3.数据误删后,如何快速恢复
- 紧急处理流程:
- A[发现误删] --> B[立即停止相关服务] --> C[评估影响范围] --> D[选择恢复方案] --> E[执行恢复] --> F[数据验证] --> G[恢复服务]
- 基于备份恢复流程
- 全量数据备份恢复:根据每日备份的数据进行dump恢复
- 根据时间点恢复:需要binlog有完整的日志
- 无备份恢复方案
-
使用binlog2sql工具
-
使用美团开源的myflash工具
-
-
innodb引擎特殊恢复
-
使用undrop-for-innodb工具适用场景:无备份且binlog不可用
-
数据库恢复服务:MySQL数据恢复专家、DiskInternals MySQL Recovery、Kroll Ontrack
-
-
不同操作的恢复策略
操作类型 | 恢复难度 | 推荐方案 |
---|---|---|
DELETE误删 | ★★☆ | binlog2sql闪回 |
DROP TABLE | ★★★ | 全备恢复+binlog |
TRUNCATE | ★★★☆ | 解析表空间文件 |
DROP DATABASE | ★★★★ | 全备恢复 |
磁盘损坏 | ★★★★★ | 专业恢复工具 |
- 预防措施
- 备份策略配置:每天进行数据备份
- 安全防护配置:设置延迟复制从库,启动回收站功能
- 操作审计措施:使用预生产环境测试更新功能并对DDL操作的语句进行审计后执行
- 关键恢复原则
-
立即停止写入:防止覆盖原有数据页
-
优先使用逻辑备份:比物理恢复更安全可控
-
测试恢复流程:定期验证备份有效性
-
保留多个副本:采用3-2-1备份策略(3份副本,2种介质,1份离线)
-
Q:基于binlog的闪回(Flashback)技术实现?
A:MySQL闪回技术是通过逆向解析binlog来恢复误操作数据的关键手段
- 闪回基础原理
- binlog记录机制
- ROW格式:记录行级别变更前镜像(before_image)和变更后镜像(after_image)
- 写入时机:事务提交时一次性写入整个事务的binlog
- 闪回核心思想:delete逆向操作原理
- binlog记录机制
- 主流的闪回技术
工具名称 | 开发方 | 语言 | 特点 | 适用场景 |
---|---|---|---|---|
binlog2sql | 大众点评 | Python | 纯SQL实现 | 精细恢复 |
MyFlash | 美团 | C | 二进制级别 | 高性能恢复 |
mysqlbinlog_flashback | 阿里 | C++ | 集成补丁 | 云环境 |
- binlog2sql实现深度解析
- 核心的处理流程:
- A[解析binlog] --> B[提取DML事件] --> C[构建行变更对象] --> D[生成逆向SQL] --> E[过滤与排序] --> F[输出恢复脚本]
- 关键实现代码:
- 逆向使用update操作
- 解析闪回sql,执行恢复
- 核心的处理流程:
4.主从延迟的根本原因即解决方案
5.InnoDB的自适应哈希索引(AHI)适用场景?
Q:为什么高频等值查询能加速?
6.MySQL的CPU利用率飙高,如何定位?
Q:通过performance_schema
分析热点SQL与锁争用?
7.如何优化一条SELECT COUNT(*) FROM big_table?
Q:为什么InnoDB不缓存总行数?替代方案?
8.如果让你设计一个分布式MySQL,你会考虑哪些问题?
Q:数据分片、一致性协议(Raft/Paxos)、分布式事务(XA/TCC)的选择?
9.MySQL 8.0相比5.7的核心改进?
Q:窗口函数、CTE、原子DDL、直方图统计?
10.为什么MySQL默认隔离级别是RR(可重复读)?
- mysql主从复制是通过binlog日志进行数据同步的,而早期的版本中binlog记录的是sql语句的原文。若此时binlog格式设置为statement时,mysql可能在从库执行的sql逻辑与主库不一致。
- 比如在删除某个区间数据时:delete from user where age >=13 and create_time <= '2025-4-15' limit 1;
- 为什么在sql执行结果不一致:
- 在主库执行这条sql的时候,用的是索引age;而在备库执行这条语句的时候,却使用了索引create_time.mysql执行优化器会进行采样预估,在不同的mysql库里面,采样计算出来的预估结果不一样,会影响优化器的判断,由于优化器会进行成本分析,可能最终选择索引不一致。这跟sql执行过程有一定关系。
- 而因为这条delete语句带了limit,所以查出来的记录很大可能不会是同一条数据,排序可能不一样,会导致准备数据不一致的情况。
- 另外使用RC或者RU的话,是不会添加GAP LOCK间隙锁,而主从复制过程中出现的事务乱序问题,更容易导致备库在SQL回滚后与主库内容不一致。所以mysql选择了RR隔离级别
- RR级别在更新数据时会增加记录锁和间隙锁,可以避免事务乱序导致的数据不一致问题。
Q:为啥ORACLE选择的默认级别是RC?
A:oracle目前支持三种事务隔离级别,RC(读已提交,默认),serializable(可串行化),read-only(只读);其中Read-only隔离级别类似于序列化隔离级别,但只读事务甚至不允许在事务中进行数据修改,显然只能选择RC
Q:为何大厂要改成RC?
A:出于性能、死锁和实时性高的需求
- 提高并发性,RC隔离级别下,锁粒度小,只锁住一行数据,提高了并发性,尤其读密集的应用下表现优异。行级锁,减少了锁冲突,提升了并发度。
- 减少死锁,RR级别下会增加GAP Lock和next-key lock,是的所得粒度变大,死锁的概率也增大。而RC隔离级别下不存在间隙锁,只需行锁即可,减少了死锁的发生概率。
- 满足实时性:RC每次读取数据都会获取最新的行版本,适合实时性要求高的应用,而RR读取的数据可能不会反应出其他事务对数据的更改,无法满足对实时性要求高的场景
- 简化主从同步,RC要求实行行式binlog,有助于减少主从同步时数据不一致问题
11.分库分表下如何实现精准分页?
- 全局排序发(推荐)
- 实现步骤:
- 统一排序字段,确保所有的分片使用相同的排序规则,如使用时间排序
-
-- 每个分片执行 SELECT * FROM table ORDER BY sort_field LIMIT (pageNo-1)*pageSize + pageSize
- 各分片查询,想所有分片发送相同的分页查询请求
- 内存归并,将分片返回的结果在内存中排序,然后截取制定页数据
- 性能优化:使用流式处理避免内存溢出
- 优点是结果绝对精确,缺点是随着页码增大性能会下降,出现深分页问题
- 二次查询法(优化深分页)
- 实现步骤
- 各分片查询排序字段值(不返回具体完整行数据)
-
SELECT id FROM table ORDER BY create_time LIMIT 10000, 10
- 获取最小/最大边界值
- 用边界值精确查询完整数据
-
SELECT * FROM table WHERE create_time BETWEEN ? AND ? ORDER BY create_time LIMIT 10
- 分片键连续分页法
- 适用场景:
- 分片键本身具有连续性,如时间范围分片
- 能预先确定分片键的分布情况
- 实现方式:
- 根据分片键确定数据所在分片
- 只向特定分片发起查询
- 在该分片内做常规分页
- 适用场景:
- 适用elasticSeach等搜索引擎
- 将分库分表数据同步到ES
- 利用ES的分布式分页能力
- 注意:
- ES的form+size方式也有深分页限制
- 可考虑使用search_after或者scroll api
- 业务层解决方案
- 禁止跳页
- 只提供下一页功能
- 每次携带最后一条记录的排序字段值
-
SELECT * FROM table WHERE create_time < ? ORDER BY create_time DESC LIMIT pageSize
- 禁止跳页
- 性能优化建议
- 避免深分页:产品设计上限制最大页码
- 使用覆盖索引:减少回表操作
- 缓冲热门页:对前几页结果进行缓冲
- 预计算:对静态数据可提前计算分页结果
- 分批获取:客户端分批加载数据(无线滚动)
- 技术选型
方案 | 精准度 | 性能 | 实现复杂度 | 适用场景 |
---|---|---|---|---|
全局排序 | 高 | 中/差 | 中 | 数据量中等,要求绝对准确 |
二次查询 | 高 | 较好 | 高 | 深分页场景 |
分片键连续 | 高 | 优 | 低 | 分片键分布规律明显 |
ES搜索 | 高 | 优 | 中 | 已使用ES的场景 |
禁止跳页 | 中 | 优 | 低 | 用户浏览行为 |
12.mysql如何同步ES?
分库分表的情况下,如果需要精确的查找数据,需要用elasticsearch的集成,此时如何同步ES,有四种方案,应用同步双写、MQ队列双写、基于SQL脚本同步、基于binlog同步组件
- 应用数据库同步双写
- 特点:应用在同步数据库的时候也同步给ES,保障了ES的实时性,实现起来相对简单,不需要引入额外的组件或者复杂的逻辑。但是每次写入mysql的同时写入ES可能会对两个系统的性能产生影响,在高并发的情况下会到值双写失败导致数据不一致等问题,且每次写入操作都需要双写逻辑,增加了业务逻辑的复杂性和维护难度
- 具体实现:
- 代码调整:每次数据库调整的时候,复制相同逻辑到elasticsearch
- 事务管理:使用数据库的事务确保操作的院子性,避免数据不一致
- 性能优化:尽量批量操作或者使用异步方式来处理,降低对性能的影响
- MQ队列异步双写
- 特点:利用MQ队列可以实现异步处理,通过异步方式,可以降低对数据库写入性能的影响,利用消息队列的持久化和重试机制,可以调数据的可靠性。但是由于异步处理会存在数据延迟问题,而且需要引入消息队列和额外的消费者逻辑,增加系统的复杂性。
- 具体实现:
- 消息队列集成:选择兵集成一个消息队列,如kafka或者RabbitMQ
- 业务逻辑修改:将数据写入Mysql后,将变更信息发送到消息队列
- 消费者开发:开发消费者服务,从消息队列中读取消息并异步写入到elasticsearch。
- 异步处理:为消息队列的消费这实现异步处理和重试逻辑
- 基于SQL抽取:
- 特点:通过定时任务,根据数据库的时间戳字段来抽取并同步数据到elasticsearch,同步哦该方式无序修改业务逻辑对原系统无感知,通过定时任务逻辑相对简单易于理解与维护。但是数据库同步存在延迟无法满足实时性要求,定时任务可能对数据库产生额外的查询压力。
- 具体实现:
- 时间戳字段添加,在对应的数据库表中添加时间戳,用于记录数据变更
- 定时任务配置:按照固定频率查询mysql中自上次同步后发生变化的数据。
- 数据抽取:定时任务将查询结果抽取出来,同步到elasticsearch。
- 数据同步:将抽取的数据写入到elasticsearch完成同步过程。
- 利用binlog进行同步
- 特点:利用binlog日志,通过消息队列或者直接消费binlog变化来同步数据库到ES中。不需要修改现有的业务代码,对现有系统无感知,可以利用binlog精确捕捉到数据库的所有变更,确保数据同步的完整性,binlog可以高效地处理数据变更,对源数据库性能营销较小,通常配合消息队列使用,在网络波动或者服务故障的情况下也能保证数据库最终一致性。但是需要搭建和维护binlog监听和消息对垒系统,增加了系统架构的复杂性,虽然基于实时同步,但是遇到消息队列积压,可能会出现数据延迟。
- 具体实现:
- binlog启用:确保mysql实例开启了binlog功能,并且binlog格式(row或者mixed)能够支持所需的数据库同步需求
- binlog监听配置:部署并配置binlog监听器(如debezium),监听制定的mysql实例和数据库
- 消息队列集成:将binlog监听器和消息队列(kafka等)集成,确保binlog变更能够转换成消息并发送到队列中
- 消息消费者开发:开发消息消费者服务,该服务从消息队列中读取binlog变更消息,将其转换成ES可以理解的格式
- 数据同步:消息消费者将转换的数据写入ES完成同步
- 异常处理:实现异常处理机制,确保数据在同步失败后能够进行重试或者日志记录一遍排障。