第一部份:日志
1. 错误日志
记录 mysqld 启动/停止以及运行过程中的严重错误。默认开启。
SHOW VARIABLES LIKE 'log_error';
默认存放:/var/log/mysqld.log
2. 二进制日志(Binlog)
记录所有 DDL 和 DML 语句(SELECT/SHOW 除外)。用于 数据恢复 和 主从复制 。MySQL 8.0 默认开启。
2.1 相关参数
SHOW VARIABLES LIKE 'log_bin'; -- 是否开启
SHOW VARIABLES LIKE 'binlog_format'; -- 日志格式
SHOW MASTER STATUS; -- 查看当前 binlog 文件和位置
SHOW BINLOG EVENTS IN 'binlog.000001'; -- 查看事件
参数说明:
log_bin_basename:binlog 文件基础名(后跟编号 000001 起)
log_bin_index:binlog 索引文件,记录所有 binlog 文件列表
2.2 三种格式
|---------------|-----------------|-----------|---------------------|
| 格式 | 记录内容 | 优点 | 缺点 |
| STATEMENT | SQL 语句 | 日志量小 | 部分函数(UUID、NOW)导致不一致 |
| ROW(默认) | 每行数据变更 | 精确,推荐 | 日志量大 |
| MIXED | 混合,默认 STATEMENT | 折中 | |
| | 特殊情况自动切 ROW | | |
2.3 查看 binlog
# 因为二进制存储,需要用 mysqlbinlog 工具
mysqlbinlog -v binlog.000001 # 重构 SQL
mysqlbinlog -vv binlog.000001 # 重构 SQL + 注释
mysqlbinlog -d 数据库名 binlog.000001 # 只看指定库
2.4 删除 binlog
RESET MASTER; -- 删除全部,编号重置
PURGE MASTER LOGS TO 'binlog.000004'; -- 删除指定编号之前
PURGE MASTER LOGS BEFORE '2023-01-01 00:00:00'; -- 删除指定时间之前
自动清理(推荐):
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds'; -- 过期自动删除
2.5 Redo Log vs Binlog(面试高频)
|------|-------------|----------------|
| 维度 | Redo Log | Binlog |
| 所属 | InnoDB 引擎层 | MySQL Server 层 |
| 类型 | 物理日志(数据页修改) | 逻辑日志(SQL 或行变更) |
| 写入方式 | 循环写(固定空间) | 追加写(文件切换) |
| 用途 | 崩溃恢复(持久性) | 数据恢复 + 主从复制 |
两阶段提交:保证 redo log 和 binlog 的一致性。先写 redo log (prepare) → 写 binlog → redo log (commit)。
3. 查询日志(General Log)
记录所有客户端操作(含 SELECT),默认关闭。长时间开启文件会非常大。
# my.cnf
general_log = 1
general_log_file = mysql_query.log
4. 慢查询日志
记录执行时间超过 long_query_time 的 SQL。默认关闭。
4.1 配置
# my.cnf
slow_query_log = 1 # 开启
long_query_time = 2 # 阈值(秒,可精确到微秒)
额外配置:
log_slow_admin_statements = 1 # 记录慢管理语句
log_queries_not_using_indexes = 1 # 记录未使用索引的查询
min_examined_row_limit = 1000 # 扫描行数少于该值不记录
4.2 分析工具
# mysqldumpslow 常用
mysqldumpslow -s t -t 10 slow.log # 按时间排序前 10 条
mysqldumpslow -s c -t 10 slow.log # 按访问次数排序
mysqldumpslow -s r -t 10 slow.log # 按返回记录数排序
mysqldumpslow -g 'left join' slow.log # 正则匹配过滤
第二部份:主从复制
5. 主从复制
5.1 概述
将主库 DDL/DML 通过 Binlog 传到从库执行,使主从数据保持同步。
优点:
- 主库故障时快速切换到从库(高可用)
- 读写分离,降低主库压力
- 从库备份,不影响主库服务
5.2 原理(三个线程)
Master Slave
┌──────────┐ ┌──────────────┐
│ Binlog │──Dump Thread→│ I/O Thread │
│ │ │ ↓ │
│ │ │ Relay Log │
│ │ │ ↓ │
│ │ │ SQL Thread │
└──────────┘ └──────────────┘
- Master 事务提交时写入 Binlog
- Slave I/O 线程读取 Master Binlog → 写入 Relay Log
- Slave SQL 线程重放 Relay Log 中的事件
5.3 搭建
主库配置 (my.cnf):
server-id = 1
read-only = 0
-- 创建复制账号
CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
SHOW MASTER STATUS; -- 记下 File 和 Position
从库配置 (my.cnf):
server-id = 2
read-only = 1
-- 8.0.23+ 语法
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.200.200',
SOURCE_USER='slave',
SOURCE_PASSWORD='123456',
SOURCE_LOG_FILE='binlog.000004',
SOURCE_LOG_POS=663;
-- 8.0.23 之前语法
CHANGE MASTER TO
MASTER_HOST='192.168.200.200',
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='binlog.000004',
MASTER_LOG_POS=663;
START REPLICA; -- 或 START SLAVE;
SHOW REPLICA STATUS\G; -- IO_Running 和 SQL_Running 都是 Yes 即成功
5.4 复制模式
|----------------|-----------------------------------|
| 模式 | 说明 |
| 异步复制(默认) | Master 提交后直接返回,不管 Slave |
| 半同步复制 | Master 等待至少一个 Slave 收到 Binlog 再返回 |
| 全同步复制 | 所有 Slave 执行完再返回(性能差) |
| 并行复制(5.7+) | Slave 多线程回放,解决延迟 |
第三部份:分库分表与读写分离
6. 分库分表
6.1 问题分析
单数据库瓶颈:
- IO 瓶颈:热点数据多、缓存不足、网络带宽不够
- CPU 瓶颈:排序、分组、连接查询、聚合统计等
核心思想:将数据分散存储,降低单库/表单表数据量。
6.2 拆分策略
|----------|-------------|------------------|
| 策略 | 说明 | 场景 |
| 垂直分库 | 按业务拆不同库 | 微服务(用户库、订单库、商品库) |
| 垂直分表 | 拆大字段到扩展表 | 宽表拆分(基本信息 + 详情) |
| 水平分库 | 按分片键拆到不同库 | 数据量巨大 |
| 水平分表 | 按分片键拆到同库不同表 | 单表数据量大 |
水平拆分算法:
- 范围分片(按日期、按 ID 区间)
- Hash 取模(
id % N)
- 一致性 Hash(减少扩缩容数据迁移)
- 按日期(
order_202301, order_202302, ...)
中间件:
|---------------------|---------|----------------|
| 中间件 | 类型 | 特点 |
| ShardingSphere-JDBC | 客户端 SDK | 嵌入应用,无代理层,性能高 |
| MyCat | 代理 | 独立部署,跨语言 |
| Vitess | 代理 | 云原生,YouTube 开源 |
6.3 全局唯一 ID 方案
|---------------------|----------|---------|
| 方案 | 优点 | 缺点 |
| 雪花算法(Snowflake) | 高性能、趋势递增 | 依赖机器时钟 |
| UUID | 简单 | 无序、字符串长 |
| 数据库自增 | 简单 | 单点瓶颈 |
| Redis INCR | 快 | 持久化风险 |
| 号段模式(Leaf) | 高可用 | 实现复杂 |
7. 读写分离
基于主从复制实现:主库写,从库读。
实现方式
|------------------|-------------------------------|
| 方式 | 说明 |
| 代码层 AOP | 动态切换数据源(注解标记读写) |
| 中间件代理 | MyCat/ShardingSphere/ProxySQL |
| MySQL Router | 官方路由组件 |
主从延迟处理
|---------|--------------------|
| 方案 | 说明 |
| 并行复制 | 5.7+ 组提交并行回放 |
| 刚写后读走主库 | 写操作后的事务内/短时间内的读走主库 |
| 半同步复制 | 降低延迟 |
| 缓存层 | Redis 中转,写完同时更新缓存 |