MySQL日志

第一部份:日志


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 传到从库执行,使主从数据保持同步。

优点:

  1. 主库故障时快速切换到从库(高可用)
  1. 读写分离,降低主库压力
  1. 从库备份,不影响主库服务

5.2 原理(三个线程)

复制代码
Master                     Slave
┌──────────┐              ┌──────────────┐
│ Binlog   │──Dump Thread→│ I/O Thread   │
│          │              │   ↓          │
│          │              │ Relay Log    │
│          │              │   ↓          │
│          │              │ SQL Thread   │
└──────────┘              └──────────────┘
  1. Master 事务提交时写入 Binlog
  1. Slave I/O 线程读取 Master Binlog → 写入 Relay Log
  1. 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 中转,写完同时更新缓存 |

相关推荐
奇树谦1 小时前
朴素贝叶斯(Naive Bayes)详解
机器学习·1024程序员节
Liaiyang661 小时前
空圈容错·极限工程实战下篇——外部供给层怎么升维,内外层怎么联动
量子计算·脑机接口·1024程序员节·科学哲学·容错设计·系统思维·工程方法论
传奇开心果编程2 小时前
【Jetpack Compose娓娓道来】第26课:Repository模式与数据层设计——数据的唯一入口
android·移动开发·1024程序员节·jetpack compose·编程语言理论·编程框架·声明式ui
Lucis__2 小时前
Redis持久化机制解析
redis·缓存·操作系统·文件·非关系型数据库·1024程序员节
不脱发的程序猿2 小时前
纳指ETF量化策略
数据库·人工智能·1024程序员节
科创致远2 小时前
廊坊注塑配套企业SOP工位数字化是把信息变简单
1024程序员节
文慧的科技江湖2 小时前
贰号开源零碳园区管理平台
1024程序员节
hi冻鱼2 小时前
PCIe + DDR架构(一):实测——块长从4 KiB 换 1 MiB,带宽从133 MB/s 涨到 3179 MB/s
性能测试·fpga·pcie·mig·xdma·1024程序员节·ddr3
小白起 v2 小时前
容器云平台的技术与实战
1024程序员节