内容简介:MySQL服务器异常处理是数据库运维的重要组成部分,直接影响数据库的可用性和数据的完整性。本文风哥教程参考MySQL官方文档MySQL Server Administration部分,详细介绍MySQL服务器常见异常类型、检测方法和恢复策略,帮助DBA快速定位和解决MySQL服务器异常。学习交流加群风哥QQ113257174
Part01-基础概念与理论知识
1.1 MySQL异常概述
MySQL服务器异常是指数据库在运行过程中出现的各种错误和异常情况,主要包括:
- 服务器崩溃:MySQL进程意外终止
- 数据损坏:数据库文件或索引损坏
- 性能异常:响应时间变慢、资源利用率异常
- 连接异常:连接数过多、连接超时等
- 磁盘空间不足:数据目录磁盘空间耗尽
- 网络异常:网络连接中断或不稳定
1.2 MySQL异常类型
MySQL异常可以分为以下几类:
- 致命异常:导致服务器崩溃或无法启动的严重错误
- 非致命异常:影响部分功能但不导致服务器崩溃的错误
- 性能异常:不导致功能错误但影响性能的异常
- 安全异常:涉及安全问题的异常
Part02-生产环境规划与建议
2.1 异常预防规划
异常预防是减少MySQL异常发生的重要措施:
- 硬件冗余:使用RAID、冗余电源等硬件冗余技术
- 软件冗余:部署主从复制、MGR等高可用架构
- 定期备份:建立完善的备份策略,定期进行备份
- 补丁升级:及时安装MySQL补丁和安全更新
- 监控告警:建立全面的监控和告警机制
2.2 异常检测规划
异常检测是及时发现MySQL异常的关键:
- 性能监控:监控CPU、内存、磁盘、网络等资源使用情况
- 数据库监控:监控连接数、QPS、慢查询、错误日志等
- 磁盘监控:监控磁盘空间使用情况,设置告警阈值
- 日志分析:定期分析错误日志、慢查询日志等
2.3 异常恢复规划
异常恢复是在MySQL异常发生后快速恢复服务的保障:
- 恢复流程:制定详细的异常恢复流程和操作手册
- 恢复工具:准备必要的恢复工具,如mysqlbinlog、innodb_force_recovery等
- 测试恢复:定期测试恢复流程,确保其有效性
- 容灾切换:准备容灾切换方案,在主库异常时快速切换到备库
Part03-生产环境项目实施方案
3.1 错误日志分析
错误日志是分析MySQL异常的重要依据。
mysql> SHOW GLOBAL VARIABLES LIKE ‘log_error’;
+—————+——————-+
| Variable_name | Value |
+—————+——————-+
| log_error | /mysql/logs/error.log |
+—————+——————-+
1 row in set (0.00 sec)
# 查看最新的错误日志
# tail -n 50 /mysql/logs/error.log
2026-04-02T16:00:00.123456Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: ‘8.4.0’ socket: ‘/var/lib/mysql/mysql.sock’ port: 3306 MySQL Community Server – GPL.
2026-04-02T16:10:00.123456Z 10 [Warning] [MY-012145] [InnoDB] Tablespace has been discarded for table fgedudb.fgedu_users.
2026-04-02T16:15:00.123456Z 15 [ERROR] [MY-011866] [InnoDB] Table fgedudb.fgedu_orders contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in MySQL.
2026-04-02T16:20:00.123456Z 0 [ERROR] [MY-012681] [InnoDB] mmap(134217728 bytes) failed; errno 12
2026-04-02T16:20:00.123456Z 0 [ERROR] [MY-012960] [InnoDB] Cannot allocate memory for the buffer pool
2026-04-02T16:20:00.123456Z 0 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Generic error.
2026-04-02T16:20:00.123456Z 0 [ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine
2026-04-02T16:20:00.123456Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
2026-04-02T16:20:00.123456Z 0 [ERROR] [MY-010119] [Server] Aborting
3.2 异常检测方法
使用多种方法检测MySQL异常。
mysql> SHOW GLOBAL STATUS LIKE ‘Aborted_connects’;
+——————+——-+
| Variable_name | Value |
+——————+——-+
| Aborted_connects | 10 |
+——————+——-+
1 row in set (0.00 sec)
mysql> SHOW GLOBAL STATUS LIKE ‘Aborted_clients’;
+—————–+——-+
| Variable_name | Value |
+—————–+——-+
| Aborted_clients | 5 |
+—————–+——-+
1 row in set (0.00 sec)
mysql> SHOW GLOBAL STATUS LIKE ‘Uptime’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| Uptime | 3600 |
+—————+——-+
1 row in set (0.00 sec)
# 2. 使用系统命令检测
# ps aux | grep mysqld
mysql 12345 0.5 5.0 1234567 204800 ? Sl 16:00 0:02 /usr/sbin/mysqld
# netstat -tlnp | grep mysql
tcp6 0 0 :::3306 :::* LISTEN 12345/mysqld
tcp6 0 0 :::33060 :::* LISTEN 12345/mysqld
# 3. 检查磁盘空间
# df -h /mysql
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 10G 8.5G 1.5G 85% /mysql
# 4. 检查内存使用
# free -m
total used free shared buff/cache available
Mem: 8192 4096 2048 128 2048 3840
Swap: 4096 512 3584
3.3 异常恢复方案
根据不同的异常类型,采取相应的恢复方案。
# 查看内存使用情况
# free -m
total used free shared buff/cache available
Mem: 8192 7680 128 128 384 128
# 调整innodb_buffer_pool_size参数
# vi /etc/my.cnf
innodb_buffer_pool_size = 2G # 原来设置为6G,减少内存使用
# 重启MySQL
# systemctl restart mysqld
# 2. 表损坏导致的异常恢复
# 使用mysqlcheck修复表
# mysqlcheck -u root -p –repair fgedudb fgedu_orders
Enter password:
fgedudb.fgedu_orders OK
# 3. 磁盘空间不足导致的异常恢复
# 清理日志文件
# rm /mysql/logs/binlog.000001 /mysql/logs/binlog.000002
# 重新启动MySQL
# systemctl restart mysqld
# 4. 使用innodb_force_recovery恢复
# vi /etc/my.cnf
[mysqld]
innodb_force_recovery = 1 # 1-6,从低到高尝试
# 启动MySQL
# systemctl start mysqld
# 导出数据
# mysqldump -u root -p fgedudb > fgedudb_backup.sql
# 关闭MySQL
# systemctl stop mysqld
# 删除force recovery参数
# vi /etc/my.cnf
# innodb_force_recovery = 1
# 重建数据库
# rm -rf /mysql/data/*
# mysqld –initialize –user=mysql
# systemctl start mysqld
# mysql -u root -p < fgedudb_backup.sql
Part04-生产案例与实战讲解
4.1 服务器崩溃恢复
处理MySQL服务器崩溃的实战案例。
问题描述:服务器意外断电,导致MySQL崩溃,无法正常启动
解决方法:使用InnoDB的自动恢复功能,必要时使用innodb_force_recovery
# systemctl start mysqld
Job for mysqld.service failed because the control process exited with error code. See “systemctl status mysqld.service” and “journalctl -xe” for details.
# 查看错误日志
# tail -n 50 /mysql/logs/error.log
2026-04-02T17:00:00.123456Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.0) starting as process 12345
2026-04-02T17:00:00.123456Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2026-04-02T17:00:00.123456Z 1 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Corrupt database page.
2026-04-02T17:00:00.123456Z 1 [ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine
2026-04-02T17:00:00.123456Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
2026-04-02T17:00:00.123456Z 0 [ERROR] [MY-010119] [Server] Aborting
# 尝试使用innodb_force_recovery=1启动
# vi /etc/my.cnf
[mysqld]
innodb_force_recovery = 1
# 启动MySQL
# systemctl start mysqld
# 检查MySQL状态
# systemctl status mysqld
● mysqld.service – MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2026-04-02 17:05:00 CST; 1min ago
# 导出数据
# mysqldump -u root -p –all-databases > all_databases.sql
# 关闭MySQL
# systemctl stop mysqld
# 清理数据目录
# rm -rf /mysql/data/*
# 重新初始化MySQL
# mysqld –initialize –user=mysql
# 启动MySQL
# systemctl start mysqld
# 导入数据
# mysql -u root -p < all_databases.sql
# 验证数据
# mysql -u root -p -e "SHOW DATABASES;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| fgedudb |
+--------------------+
5 rows in set (0.00 sec)
4.2 数据损坏恢复
处理MySQL数据损坏的实战案例。
问题描述:执行查询时提示”Table ‘./fgedudb/fgedu_orders’ is marked as crashed and last (automatic?) repair failed”
解决方法:使用mysqlcheck或myisamchk修复表
mysql> SELECT * FROM fgedudb.fgedu_orders WHERE id = 1;
ERROR 145 (HY000): Table ‘./fgedudb/fgedu_orders’ is marked as crashed and last (automatic?) repair failed
# 检查表状态
mysql> CHECK TABLE fgedudb.fgedu_orders;
+———————+——-+———-+————————————————————————+
| Table | Op | Msg_type | Msg_text |
+———————+——-+———-+————————————————————————+
| fgedudb.fgedu_orders | check | error | Table ‘./fgedudb/fgedu_orders’ is marked as crashed |
| fgedudb.fgedu_orders | check | error | Found 23456 rows instead of 23450 |
| fgedudb.fgedu_orders | check | error | Corrupt |
+———————+——-+———-+————————————————————————+
3 rows in set (0.01 sec)
# 使用mysqlcheck修复表
# mysqlcheck -u root -p –repair fgedudb fgedu_orders
Enter password:
fgedudb.fgedu_orders OK
# 验证修复结果
mysql> CHECK TABLE fgedudb.fgedu_orders;
+———————+——-+———-+———-+
| Table | Op | Msg_type | Msg_text |
+———————+——-+———-+———-+
| fgedudb.fgedu_orders | check | status | OK |
+———————+——-+———-+———-+
1 row in set (0.01 sec)
# 执行查询验证
mysql> SELECT * FROM fgedudb.fgedu_orders WHERE id = 1;
+—-+———+——–+————+
| id | user_id | amount | order_date |
+—-+———+——–+————+
| 1 | 1 | 1000 | 2026-01-01 |
+—-+———+——–+————+
1 row in set (0.00 sec)
4.3 性能异常处理
处理MySQL性能异常的实战案例。
问题描述:服务器CPU使用率突然升高到90%以上,响应时间变慢
解决方法:定位高负载进程,分析慢查询,优化SQL或参数
# top
%Cpu(s): 90.0 us, 5.0 sy, 0.0 ni, 5.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8192000 total, 204800 free, 7680000 used, 307200 buff/cache
KiB Swap: 4096000 total, 3584000 free, 512000 used. 128000 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
12345 mysql 20 0 1234567 204800 36800 S 85.0 5.0 0:30.00 mysqld
# 查看MySQL进程列表
mysql> SHOW PROCESSLIST;
+—–+——+—————–+———+———+——+———-+———————————————-+
| Id | User | Host | db | Command | Time | State | Info |
+—–+——+—————–+———+———+——+———-+———————————————-+
| 10 | root | localhost | NULL | Sleep | 100 | | NULL |
| 11 | user1| 192.168.1.100:54321 | fgedudb | Query | 30 | Sending data | SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10 |
| 12 | user1| 192.168.1.100:54322 | fgedudb | Query | 25 | Sending data | SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10 |
| 13 | user1| 192.168.1.100:54323 | fgedudb | Query | 20 | Sending data | SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10 |
+—–+——+—————–+———+———+——+———-+———————————————-+
# 分析慢查询日志
# tail -n 100 /mysql/logs/slow.log | grep -A 10 “SELECT * FROM fgedu_orders ORDER BY RAND()”
# Time: 2026-04-02T17:15:00.123456Z
# User@Host: user1[user1] @ 192.168.1.100 [192.168.1.100]
# Query_time: 30.000000 Lock_time: 0.000000 Rows_sent: 10 Rows_examined: 100000
use fgedudb;
SET timestamp=1750000000;
SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10;
# 优化SQL语句
# 原SQL:
SELECT * FROM fgedu_orders ORDER BY RAND() LIMIT 10;
# 优化后SQL:
SELECT * FROM fgedu_orders WHERE id >= (SELECT FLOOR(MAX(id) * RAND()) FROM fgedu_orders) LIMIT 10;
# 验证优化效果
mysql> SELECT * FROM fgedu_orders WHERE id >= (SELECT FLOOR(MAX(id) * RAND()) FROM fgedu_orders) LIMIT 10;
+——-+———+——–+————+
| id | user_id | amount | order_date |
+——-+———+——–+————+
| 12345 | 123 | 500 | 2026-03-01 |
| 12346 | 123 | 800 | 2026-03-02 |
| 12347 | 124 | 300 | 2026-03-03 |
…
10 rows in set (0.01 sec)
# 监控系统负载
# top
%Cpu(s): 10.0 us, 2.0 sy, 0.0 ni, 88.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8192000 total, 1024000 free, 6656000 used, 512000 buff/cache
KiB Swap: 4096000 total, 3584000 free, 512000 used. 768000 avail Mem
Part05-风哥经验总结与分享
5.1 异常预防最佳实践
- 硬件保障:使用高质量的服务器硬件,包括CPU、内存、磁盘等
- 数据备份:建立完善的备份策略,包括全量备份、增量备份和日志备份
- 高可用架构:部署主从复制、MGR等高可用架构,确保服务连续性
- 定期维护:定期进行数据库优化、索引重建、统计信息更新等维护操作
- 安全防护:加强数据库安全防护,包括访问控制、加密、审计等
5.2 异常检测最佳实践
- 监控指标:监控CPU、内存、磁盘、网络等系统指标,以及连接数、QPS、慢查询等数据库指标
- 告警阈值:设置合理的告警阈值,避免误报和漏报
- 日志分析:定期分析错误日志、慢查询日志、二进制日志等
- 自动化检测:使用自动化工具如Prometheus、Zabbix等进行监控
- 定期检查:定期进行手动检查,验证监控系统的有效性
5.3 异常恢复最佳实践
- 恢复流程:制定详细的恢复流程和操作手册,确保恢复过程规范化
- 恢复测试:定期进行恢复测试,验证备份的有效性和恢复流程的正确性
- 数据验证:恢复后进行数据验证,确保数据的完整性和一致性
- 性能验证:恢复后进行性能测试,确保系统性能满足要求
- 事后总结:异常恢复后进行总结,分析异常原因,完善预防措施
from MySQL:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
