内容简介:MySQL查询日志记录了数据库服务器接收到的所有SQL查询,是数据库诊断、性能分析和安全审计的重要工具。本文风哥教程参考MySQL官方文档MySQL Server Administration部分,详细介绍MySQL查询日志的配置、管理、分析和使用方法,帮助DBA高效管理MySQL查询日志系统。学习交流加群风哥QQ113257174
Part01-基础概念与理论知识
1.1 MySQL查询日志概述
MySQL查询日志用于记录数据库服务器接收到的所有SQL查询语句,包括:
- 客户端连接和断开信息
- 所有SQL查询语句(包括SELECT、INSERT、UPDATE、DELETE等)
- 系统命令和管理语句
- 查询执行结果状态
1.2 查询日志类型与区别
MySQL提供多种查询日志类型,主要包括:
- 通用查询日志(General Query Log):记录所有客户端的连接和查询操作
- 慢查询日志(Slow Query Log):记录执行时间超过阈值的SQL语句
- 审计日志(Audit Log):企业版功能,提供更详细的审计信息
– 通用查询日志:记录所有查询,详细但性能影响大
– 慢查询日志:仅记录慢查询,性能影响小,适合长期开启
– 审计日志:功能强大但需要企业版,适合安全要求高的环境
Part02-生产环境规划与建议
2.1 查询日志存储规划
在生产环境中,查询日志的存储需要仔细规划:
- 独立存储:将查询日志存储在与数据文件不同的磁盘上,避免I/O竞争
- 高性能存储:使用高速磁盘存储查询日志,减少对数据库性能的影响
- 空间管理:为查询日志预留足够的存储空间,配置自动清理机制
- 安全保护:设置适当的文件权限,确保查询日志的安全性
2.2 查询日志性能影响
查询日志会对数据库性能产生一定影响,需要合理配置:
- 通用查询日志:会产生大量日志,对性能影响较大,建议仅在诊断问题时开启
- 慢查询日志:性能影响较小,可以长期开启,但需要合理设置阈值
- 日志格式:使用FILE格式比TABLE格式性能更好
- 日志轮转:定期轮转日志,避免单个日志文件过大
Part03-生产环境项目实施方案
3.1 通用查询日志配置
通用查询日志记录所有客户端的连接和查询操作,是最详细的查询日志。
mysql> SHOW GLOBAL VARIABLES LIKE ‘general_log%’;
+——————+——————————–+——————-+
| Variable_name | Value | Variable_source |
+——————+——————————–+——————-+
| general_log | OFF | my.cnf |
| general_log_file | /mysql/data/fgedu.net.cn.log | compiled in |
+——————+——————————–+——————-+
# 查看日志输出格式
mysql> SHOW GLOBAL VARIABLES LIKE ‘log_output’;
+—————+——-+——————-+
| Variable_name | Value | Variable_source |
+—————+——-+——————-+
| log_output | FILE | my.cnf |
+—————+——-+——————-+
# vi /etc/my.cnf
[mysqld]
# 通用查询日志默认关闭
# general_log = OFF
# 通用查询日志文件路径
general_log_file = /mysql/logs/general.log
# 日志输出格式(FILE或TABLE)
log_output = FILE
mysql> SET GLOBAL general_log = ON;
Query OK, 0 rows affected (0.00 sec)
# 动态设置通用查询日志文件
mysql> SET GLOBAL general_log_file = ‘/mysql/logs/general_current.log’;
Query OK, 0 rows affected (0.00 sec)
# 动态修改日志输出格式
mysql> SET GLOBAL log_output = ‘FILE,TABLE’;
Query OK, 0 rows affected (0.00 sec)
3.2 审计日志配置
审计日志是MySQL企业版的功能,提供更详细的审计信息。
mysql> SHOW PLUGINS LIKE ‘audit%’;
+—————————–+———-+——————–+———————-+———+
| Name | Status | Type | Library | License |
+—————————–+———-+——————–+———————-+———+
| audit_log | ACTIVE | AUDIT | audit_log.so | PROPRIETARY |
+—————————–+———-+——————–+———————-+———+
# 查看审计日志配置
mysql> SHOW GLOBAL VARIABLES LIKE ‘audit_log%’;
+—————————–+——————————–+——————-+
| Variable_name | Value | Variable_source |
+—————————–+——————————–+——————-+
| audit_log_buffer_size | 1048576 | compiled in |
| audit_log_file | /mysql/logs/audit.log | my.cnf |
| audit_log_flush | OFF | compiled in |
| audit_log_format | JSON | my.cnf |
| audit_log_policy | ALL | my.cnf |
| audit_log_rotate_on_size | 1073741824 | my.cnf |
| audit_log_rotations | 10 | my.cnf |
| audit_log_strategy | ASYNCHRONOUS | my.cnf |
+—————————–+——————————–+——————-+
# vi /etc/my.cnf
[mysqld]
# 审计日志文件路径
audit_log_file = /mysql/logs/audit.log
# 审计日志格式(JSON或NEW)
audit_log_format = JSON
# 审计策略(ALL, LOGINS, QUERIES, NONE)
audit_log_policy = ALL
# 审计日志大小限制(字节)
audit_log_rotate_on_size = 1073741824
# 审计日志保留数量
audit_log_rotations = 10
# 审计日志策略(SYNCHRONOUS或ASYNCHRONOUS)
audit_log_strategy = ASYNCHRONOUS
3.3 查询日志查看与分析
查询日志的查看和分析是数据库诊断和性能优化的重要工作。
# tail -n 20 /mysql/logs/general.log
2026-04-02T11:00:00.123456+08:00 1234 Connect root@localhost on fgedudb using Socket
2026-04-02T11:00:05.123456+08:00 1234 Query SHOW GLOBAL VARIABLES LIKE ‘general_log%’
2026-04-02T11:00:10.123456+08:00 1234 Query SELECT * FROM fgedu_student WHERE id = 1
2026-04-02T11:00:15.123456+08:00 1234 Query INSERT INTO fgedu_student (name, age, enroll_date) VALUES (‘李四’, 21, ‘2026-04-02’)
2026-04-02T11:00:20.123456+08:00 1234 Query UPDATE fgedu_student SET age = 22 WHERE id = 1
2026-04-02T11:00:25.123456+08:00 1234 Query DELETE FROM fgedu_student WHERE id = 1000
2026-04-02T11:00:30.123456+08:00 1234 Quit
2026-04-02T11:01:00.123456+08:00 5678 Connect fgedu_user@192.168.1.100 on fgedudb using TCP/IP
2026-04-02T11:01:05.123456+08:00 5678 Query SELECT * FROM fgedu_orders WHERE customer_id = 100 AND status = ‘completed’
2026-04-02T11:01:10.123456+08:00 5678 Quit
mysql> USE mysql;
Database changed
mysql> SELECT * FROM general_log ORDER BY event_time DESC LIMIT 10;
+—————————-+—————————+———–+———–+————-+———————————————————————————————————–+
| event_time | user_host | thread_id | server_id | command_type | argument |
+—————————-+—————————+———–+———–+————-+———————————————————————————————————–+
| 2026-04-02 11:01:10.123456 | fgedu_user[192.168.1.100] | 5678 | 1 | Quit | NULL |
| 2026-04-02 11:01:05.123456 | fgedu_user[192.168.1.100] | 5678 | 1 | Query | SELECT * FROM fgedu_orders WHERE customer_id = 100 AND status = ‘completed’ |
| 2026-04-02 11:01:00.123456 | fgedu_user[192.168.1.100] | 5678 | 1 | Connect | fgedu_user@192.168.1.100 on fgedudb using TCP/IP |
| 2026-04-02 11:00:30.123456 | root[localhost] | 1234 | 1 | Quit | NULL |
| 2026-04-02 11:00:25.123456 | root[localhost] | 1234 | 1 | Query | DELETE FROM fgedu_student WHERE id = 1000 |
| 2026-04-02 11:00:20.123456 | root[localhost] | 1234 | 1 | Query | UPDATE fgedu_student SET age = 22 WHERE id = 1 |
| 2026-04-02 11:00:15.123456 | root[localhost] | 1234 | 1 | Query | INSERT INTO fgedu_student (name, age, enroll_date) VALUES (‘李四’, 21, ‘2026-04-02’) |
| 2026-04-02 11:00:10.123456 | root[localhost] | 1234 | 1 | Query | SELECT * FROM fgedu_student WHERE id = 1 |
| 2026-04-02 11:00:05.123456 | root[localhost] | 1234 | 1 | Query | SHOW GLOBAL VARIABLES LIKE ‘general_log%’ |
| 2026-04-02 11:00:00.123456 | root[localhost] | 1234 | 1 | Connect | root@localhost on fgedudb using Socket |
+—————————-+—————————+———–+———–+————-+———————————————————————————————————–+
10 rows in set (0.01 sec)
Part04-生产案例与实战讲解
4.1 查询日志诊断案例
使用通用查询日志诊断数据库问题。
问题描述:应用程序报告数据库连接频繁断开,需要诊断原因
解决方法:临时开启通用查询日志,监控客户端连接和断开情况
mysql> SET GLOBAL general_log = ON;
Query OK, 0 rows affected (0.00 sec)
# 等待一段时间后查看日志
# grep -E “Connect|Quit|Aborted” /mysql/logs/general.log | tail -n 30
2026-04-02T11:05:00.123456+08:00 7890 Connect app_user@192.168.1.200 on fgedudb using TCP/IP
2026-04-02T11:05:01.123456+08:00 7890 Query SELECT * FROM fgedu_products WHERE id = 1
2026-04-02T11:05:01.123456+08:00 7890 Quit
2026-04-02T11:05:02.123456+08:00 7891 Connect app_user@192.168.1.200 on fgedudb using TCP/IP
2026-04-02T11:05:03.123456+08:00 7891 Query SELECT * FROM fgedu_products WHERE id = 2
2026-04-02T11:05:03.123456+08:00 7891 Quit
2026-04-02T11:05:04.123456+08:00 7892 Connect app_user@192.168.1.200 on fgedudb using TCP/IP
2026-04-02T11:05:05.123456+08:00 7892 Query SELECT * FROM fgedu_products WHERE id = 3
2026-04-02T11:05:05.123456+08:00 7892 Quit
2026-04-02T11:05:06.123456+08:00 7893 Connect app_user@192.168.1.200 on fgedudb using TCP/IP
2026-04-02T11:05:07.123456+08:00 7893 Query SELECT * FROM fgedu_products WHERE id = 4
2026-04-02T11:05:07.123456+08:00 7893 Quit
# 查看错误日志中的连接问题
# grep “Aborted connection” /mysql/logs/error.log | tail -n 10
2026-04-02T11:06:00.123456+08:00 7894 [Warning] Aborted connection 7894 to db: ‘fgedudb’ user: ‘app_user’ host: ‘192.168.1.200’ (Got an error reading communication packets)
2026-04-02T11:06:02.123456+08:00 7895 [Warning] Aborted connection 7895 to db: ‘fgedudb’ user: ‘app_user’ host: ‘192.168.1.200’ (Got an error reading communication packets)
分析结果:应用程序每次查询都创建新连接,没有使用连接池,导致连接频繁断开。需要修改应用程序配置,使用连接池管理数据库连接。更多学习教程公众号风哥教程itpux_com
4.2 查询日志安全审计
使用审计日志进行安全审计,监控数据库访问。
# tail -n 10 /mysql/logs/audit.log
{
“timestamp”: “2026-04-02 11:10:00”,
“id”: “12345678-1234-1234-1234-1234567890ab”,
“class”: “connection”,
“server_id”: 1,
“connection_id”: 9012,
“event_time”: “2026-04-02T11:10:00.123456+08:00”,
“command_class”: “connect”,
“user”: “admin”,
“host”: “localhost”,
“os_user”: null,
“ip”: null,
“db”: “fgedudb”
}
{
“timestamp”: “2026-04-02 11:10:05”,
“id”: “12345678-1234-1234-1234-1234567890ac”,
“class”: “general”,
“server_id”: 1,
“connection_id”: 9012,
“event_time”: “2026-04-02T11:10:05.123456+08:00”,
“command_class”: “query”,
“user”: “admin”,
“host”: “localhost”,
“os_user”: null,
“ip”: null,
“db”: “fgedudb”,
“sql_text”: “DROP TABLE fgedu_critical_data”
}
{
“timestamp”: “2026-04-02 11:10:10”,
“id”: “12345678-1234-1234-1234-1234567890ad”,
“class”: “connection”,
“server_id”: 1,
“connection_id”: 9012,
“event_time”: “2026-04-02T11:10:10.123456+08:00”,
“command_class”: “quit”,
“user”: “admin”,
“host”: “localhost”,
“os_user”: null,
“ip”: null,
“db”: “fgedudb”
}
4.3 查询日志清理与归档
定期清理和归档查询日志,避免占用过多磁盘空间。
# query_log_cleanup.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
LOG_DIR=”/mysql/logs”
ARCHIVE_DIR=”/mysql/logs/archive”
RETENTION_DAYS=7
# 创建归档目录
mkdir -p $ARCHIVE_DIR
# 清理通用查询日志
clean_general_log() {
echo “清理通用查询日志…”
if [ -f “$LOG_DIR/general.log” ]; then
# 压缩并归档旧日志
timestamp=$(date +%Y%m%d%H%M%S)
gzip -c $LOG_DIR/general.log > $ARCHIVE_DIR/general_$timestamp.log.gz
# 清空当前日志文件
> $LOG_DIR/general.log
echo “通用查询日志已归档至 $ARCHIVE_DIR/general_$timestamp.log.gz”
fi
# 删除超过保留期限的归档文件
find $ARCHIVE_DIR -name “general_*.log.gz” -mtime +$RETENTION_DAYS -delete
}
# 清理审计日志 from MySQL:www.itpux.com 本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
sql_clean_audit_log() {
echo “清理审计日志表…”
# 连接MySQL执行清理操作
mysql -u root -p”password” <
# chmod +x /mysql/scripts/query_log_cleanup.sh
# /mysql/scripts/query_log_cleanup.sh
查询日志清理脚本执行开始: Tue Apr 2 11:15:00 2026
清理通用查询日志…
通用查询日志已归档至 /mysql/logs/archive/general_20260402111500.log.gz
清理审计日志表…
审计日志表已清理
查询日志清理脚本执行完成: Tue Apr 2 11:15:00 2026
Part05-风哥经验总结与分享
5.1 查询日志管理最佳实践
5.2 查询日志使用技巧
