外观
MySQL 状态检查命令与脚本
基本状态检查命令
1. MySQL 服务状态检查
检查 MySQL 服务是否运行
- 命令:bash
# systemd 系统 systemctl status mysqld # SysV init 系统 service mysqld status # 或使用 mysqladmin mysqladmin -u root -p ping - 输出示例:
mysqladmin: [Warning] Using a password on the command line interface can be insecure. mysqld is alive - 说明:
- 检查 MySQL 服务是否正在运行
mysqladmin ping返回 "mysqld is alive" 表示服务正常- 适合用于脚本自动化检查
- 命令:
获取 MySQL 版本信息
- 命令:bash
mysql -V # 或登录后查看 mysql -u root -p -e "SELECT VERSION();" - 输出示例:
mysql Ver 8.0.36 for Linux on x86_64 (MySQL Community Server - GPL) - 说明:
- 查看 MySQL 客户端和服务器版本
- 用于确认 MySQL 版本,排查版本兼容性问题
- 命令:
2. 连接状态检查
查看当前连接数
- 命令:sql
SHOW STATUS LIKE 'Threads%'; -- 或使用 mysqladmin mysqladmin -u root -p status - 输出示例:sql
-- 连接数状态示例 SHOW STATUS LIKE 'Threads%'; -- 输出格式(中文说明) -- +-------------------+-------+ -- | 变量名称 | 值 | -- +-------------------+-------+ -- | 缓存的线程数 | 5 | -- | 当前连接数 | 23 | -- | 创建的线程总数 | 100 | -- | 运行中的线程数 | 2 | -- +-------------------+-------+ - 说明:
- Threads_connected:当前连接数
- Threads_running:当前运行的线程数
- Threads_cached:缓存的线程数
- 用于监控连接使用情况,避免连接耗尽
- 命令:
查看连接详细信息
- 命令:sql
SHOW PROCESSLIST; -- 或查看完整信息 SHOW FULL PROCESSLIST; -- 或使用 mysqladmin mysqladmin -u root -p processlist - 输出示例:sql
-- 连接详细信息示例 SHOW PROCESSLIST; -- 输出格式(中文说明) -- +----+------+-----------+--------+---------+------+----------+------------------+ -- | ID | 用户 | 主机 | 数据库 | 命令 | 时间 | 状态 | 执行的SQL | -- +----+------+-----------+--------+---------+------+----------+------------------+ -- | 1 | root | localhost | test | Query | 0 | starting | SHOW PROCESSLIST | -- | 2 | app | 10.0.0.1 | app_db | Sleep | 10 | | NULL | -- +----+------+-----------+--------+---------+------+----------+------------------+ - 说明:
- 查看所有当前连接的详细信息
- 包括用户、主机、数据库、命令、运行时间和执行的 SQL
- 用于排查长时间运行的查询和异常连接
- 命令:
3. 性能状态检查
查看全局状态变量
- 命令:sql
-- 查看所有状态变量 SHOW GLOBAL STATUS; -- 查看特定状态变量 SHOW GLOBAL STATUS LIKE 'Innodb%'; SHOW GLOBAL STATUS LIKE 'Com_%'; -- 或使用 mysqladmin mysqladmin -u root -p extended-status - 常用状态变量:
Com_select:SELECT 查询次数Com_insert:INSERT 查询次数Com_update:UPDATE 查询次数Com_delete:DELETE 查询次数Innodb_buffer_pool_reads:从磁盘读取的页数Innodb_buffer_pool_read_requests:从缓冲池读取的请求数
- 说明:
- 查看 MySQL 各种性能指标
- 用于性能分析和优化
- 命令:
查看全局变量配置
- 命令:sql
-- 查看所有全局变量 SHOW GLOBAL VARIABLES; -- 查看特定全局变量 SHOW GLOBAL VARIABLES LIKE 'max_connections'; SHOW GLOBAL VARIABLES LIKE 'innodb%'; -- 或使用 mysqladmin mysqladmin -u root -p variables - 常用全局变量:
max_connections:最大连接数innodb_buffer_pool_size:InnoDB 缓冲池大小innodb_log_file_size:InnoDB 日志文件大小wait_timeout:连接超时时间
- 说明:
- 查看和验证 MySQL 配置
- 用于确认配置是否生效
- 命令:
存储引擎状态检查
1. InnoDB 状态检查
查看 InnoDB 详细状态
- 命令:sql
SHOW ENGINE INNODB STATUS\G - 关键信息:
- BUFFER POOL AND MEMORY:缓冲池使用情况
- ROW OPERATIONS:行操作统计
- TRANSACTIONS:当前事务信息
- SEMAPHORES:锁和等待情况
- LOG:日志写入情况
- 说明:
- 查看 InnoDB 存储引擎的详细状态
- 用于排查 InnoDB 相关问题,如死锁、缓冲池使用情况等
- 命令:
查看 InnoDB 缓冲池状态
- 命令:sql
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%'; - 关键指标:
Innodb_buffer_pool_reads:从磁盘读取的页数Innodb_buffer_pool_read_requests:从缓冲池读取的请求数Innodb_buffer_pool_hit_rate:缓冲池命中率Innodb_buffer_pool_pages_free:空闲页数Innodb_buffer_pool_pages_data:包含数据的页数
- 说明:
- 监控 InnoDB 缓冲池的使用情况
- 计算缓冲池命中率:
Hit Rate = (1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests)) * 100% - 命中率一般应保持在 99% 以上
- 命令:
2. 其他存储引擎状态检查
查看 MyISAM 状态
- 命令:sql
SHOW ENGINE MYISAM STATUS\G - 关键信息:
- Keybuffer:键缓冲使用情况
- Data:数据文件使用情况
- Indexes:索引使用情况
- 说明:
- 查看 MyISAM 存储引擎的状态
- 用于排查 MyISAM 相关问题
- 命令:
查看存储引擎状态
- 命令:sql
SHOW ENGINES; - 输出示例:sql
-- 存储引擎状态示例 SHOW ENGINES; -- 输出格式(中文说明) -- +--------------------+---------+----------------------------------+ -- | 引擎名称 | 支持状态| 说明 | -- +--------------------+---------+----------------------------------+ -- | InnoDB | DEFAULT | 支持事务... | -- | MRG_MYISAM | YES | 相同MyISAM表的集合... | -- | MEMORY | YES | 基于哈希,存储在内存中... | -- | BLACKHOLE | YES | /dev/null存储引擎... | -- | MyISAM | YES | MyISAM存储引擎 | -- +--------------------+---------+----------------------------------+ - 说明:
- 查看所有支持的存储引擎
- 确认默认存储引擎
- 命令:
监控脚本与工具
1. 简单监控脚本
连接数监控脚本
- 脚本内容:bash
#!/bin/bash # MySQL 连接数监控脚本 USER="root" PASSWORD="password" HOST="localhost" # 获取当前连接数 CONNECTIONS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';" | grep Threads_connected | awk '{print $2}') # 获取最大连接数 MAX_CONNECTIONS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL VARIABLES LIKE 'max_connections';" | grep max_connections | awk '{print $2}') # 计算连接使用率 USAGE=$(echo "scale=2; $CONNECTIONS / $MAX_CONNECTIONS * 100" | bc) echo "当前连接数: $CONNECTIONS" echo "最大连接数: $MAX_CONNECTIONS" echo "连接使用率: $USAGE%" # 如果连接使用率超过 80%,发送告警 if (( $(echo "$USAGE > 80" | bc -l) )); then echo "警告: 连接使用率超过 80%" # 可以添加发送邮件或短信告警的代码 fi - 使用方法:bash
chmod +x connection_monitor.sh ./connection_monitor.sh - 说明:
- 监控 MySQL 连接数和使用率
- 当连接使用率超过 80% 时发出警告
- 可以添加告警通知功能
- 脚本内容:
InnoDB 缓冲池监控脚本
- 脚本内容:bash
#!/bin/bash # InnoDB 缓冲池监控脚本 USER="root" PASSWORD="password" # 获取缓冲池相关状态 STATUS=$(mysql -u $USER -p$PASSWORD -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%';") # 提取关键指标 READS=$(echo "$STATUS" | grep Innodb_buffer_pool_reads | awk '{print $2}') READ_REQUESTS=$(echo "$STATUS" | grep Innodb_buffer_pool_read_requests | awk '{print $2}') PAGES_DATA=$(echo "$STATUS" | grep Innodb_buffer_pool_pages_data | awk '{print $2}') PAGES_FREE=$(echo "$STATUS" | grep Innodb_buffer_pool_pages_free | awk '{print $2}') PAGES_TOTAL=$(echo "$STATUS" | grep Innodb_buffer_pool_pages_total | awk '{print $2}') # 计算命中率 if [ $READ_REQUESTS -gt 0 ]; then HIT_RATE=$(echo "scale=4; (1 - ($READS / $READ_REQUESTS)) * 100" | bc) else HIT_RATE=0 fi # 计算使用率 USAGE=$(echo "scale=4; ($PAGES_DATA / $PAGES_TOTAL) * 100" | bc) echo "InnoDB 缓冲池状态:" echo "-------------------" echo "读取请求总数: $READ_REQUESTS" echo "从磁盘读取次数: $READS" echo "缓冲池命中率: $HIT_RATE%" echo "数据页数: $PAGES_DATA" echo "空闲页数: $PAGES_FREE" echo "总页数: $PAGES_TOTAL" echo "缓冲池使用率: $USAGE%" # 输出完整状态 echo "\n完整状态:" echo "$STATUS" - 使用方法:bash
chmod +x innodb_buffer_pool_monitor.sh ./innodb_buffer_pool_monitor.sh - 说明:
- 监控 InnoDB 缓冲池的使用情况
- 计算命中率和使用率
- 输出详细的缓冲池状态
- 脚本内容:
2. 定时监控脚本
- 使用 crontab 定时执行监控
- 配置方法:bash
# 编辑 crontab crontab -e # 添加定时任务 # 每 5 分钟执行连接数监控 */5 * * * * /path/to/connection_monitor.sh >> /var/log/mysql/connection_monitor.log 2>&1 # 每小时执行 InnoDB 缓冲池监控 0 * * * * /path/to/innodb_buffer_pool_monitor.sh >> /var/log/mysql/innodb_monitor.log 2>&1 # 每天凌晨执行完整状态检查 0 0 * * * /path/to/full_status_check.sh >> /var/log/mysql/daily_status.log 2>&1 - 说明:
- 使用 crontab 定时执行监控脚本
- 将输出重定向到日志文件,便于后续分析
- 可以根据需要调整执行频率
- 配置方法:
3. 第三方监控工具
Percona Monitoring and Management (PMM)
- 特点:
- 开源监控平台,专为 MySQL 和其他数据库设计
- 提供丰富的监控指标和可视化图表
- 支持告警和报告功能
- 安装方法:bash
# 安装 PMM Server docker pull percona/pmm-server:2 docker create --volume pmm-data:/srv --name pmm-server -p 80:80 -p 443:443 --restart always percona/pmm-server:2 docker start pmm-server # 安装 PMM Client wget https://downloads.percona.com/downloads/pmm2/2.37.0/binary/debian/bullseye/x86_64/pmm2-client_2.37.0-1.bullseye_amd64.deb dpkg -i pmm2-client_2.37.0-1.bullseye_amd64.deb # 连接到 PMM Server pmm-admin config --server-insecure-tls --server-url=https://admin:admin@localhost:443 # 添加 MySQL 实例 pmm-admin add mysql --username=root --password=password --query-source=perfschema mysql_instance - 说明:
- 功能强大的企业级监控工具
- 适合大规模 MySQL 部署
- 提供详细的性能分析和故障诊断
- 特点:
Prometheus + Grafana
- 特点:
- 开源监控和可视化平台
- 支持多种数据源
- 高度可定制的仪表板
- 配置方法:bash
# 安装 Prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.42.0/prometheus-2.42.0.linux-amd64.tar.gz tar xvfz prometheus-*.tar.gz cd prometheus-* ./prometheus --config.file=prometheus.yml # 安装 Grafana wget https://dl.grafana.com/oss/release/grafana_10.0.3_amd64.deb dpkg -i grafana_10.0.3_amd64.deb systemctl start grafana-server # 安装 mysqld_exporter wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz tar xvfz mysqld_exporter-*.tar.gz cd mysqld_exporter-* # 创建 MySQL 用户 mysql -u root -p -e "CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password' WITH MAX_USER_CONNECTIONS 3;" mysql -u root -p -e "GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';" # 创建配置文件 echo "[client]" > .my.cnf echo "user=exporter" >> .my.cnf echo "password=password" >> .my.cnf # 启动 mysqld_exporter ./mysqld_exporter --config.my-cnf=.my.cnf - 说明:
- 灵活的监控解决方案
- 丰富的可视化选项
- 支持自定义告警规则
- 特点:
性能分析命令
1. 查询性能分析
查看慢查询日志配置
- 命令:sql
SHOW GLOBAL VARIABLES LIKE '%slow%'; - 输出示例:sql
-- 慢查询日志配置示例 SHOW GLOBAL VARIABLES LIKE '%slow%'; -- 输出格式(中文说明) -- +---------------------------+----------------------------------+ -- | 变量名称 | 值 | -- +---------------------------+----------------------------------+ -- | 记录慢管理语句 | OFF | -- | 记录慢查询额外信息 | ON | -- | 记录慢副本语句 | OFF | -- | 记录慢从库语句 | OFF | -- | 慢启动时间 | 2 | -- | 慢查询日志 | ON | -- | 慢查询日志文件 | /var/lib/mysql/slow-query.log | -- | 慢查询阈值 | 1.000000 | -- +---------------------------+----------------------------------+ - 说明:
- 查看慢查询日志配置
- 确认慢查询日志是否启用
- 查看慢查询阈值(long_query_time)
- 命令:
使用 EXPLAIN 分析查询
- 命令:sql
EXPLAIN SELECT * FROM users WHERE age > 30 ORDER BY created_at DESC; -- 或使用 EXPLAIN ANALYZE(MySQL 8.0+) EXPLAIN ANALYZE SELECT * FROM users WHERE age > 30 ORDER BY created_at DESC; - 输出示例:sql
-- EXPLAIN 分析查询示例 EXPLAIN SELECT * FROM users WHERE age > 30 ORDER BY created_at DESC; -- 输出格式(中文说明) -- +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+ -- | id | 查询类型 | 表名 | 分区 | 类型 | 可能使用的索引| 索引 | 索引长度| 引用 | 行数 | 过滤比例 | 额外信息 | -- +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+ -- | 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 33.33 | Using filesort | -- +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+ - 说明:
- 分析查询执行计划
- 查看查询使用的索引
- 估算扫描的行数
- EXPLAIN ANALYZE 提供实际执行时间和行数
- 命令:
2. 索引使用分析
查看索引使用情况
- 命令:sql
-- 查看索引使用统计 SHOW GLOBAL STATUS LIKE 'Handler_read%'; -- 或查看表的索引使用情况 SHOW INDEX FROM table_name; -- 或使用 Performance Schema(MySQL 5.7+) SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE table_schema = 'test' AND index_name IS NOT NULL ORDER BY count_star DESC; - 关键指标:
Handler_read_first:索引第一行的读取次数Handler_read_key:通过索引读取行的次数Handler_read_next:索引顺序读取下一行的次数Handler_read_prev:索引顺序读取前一行的次数Handler_read_rnd:随机读取行的次数Handler_read_rnd_next:数据文件中随机读取下一行的次数
- 说明:
- 监控索引的使用情况
- 识别未使用的索引
- 分析索引效率
- 命令:
识别未使用的索引
- 命令:sql
-- 使用 Performance Schema SELECT OBJECT_SCHEMA as database_name, OBJECT_NAME as table_name, INDEX_NAME as index_name, COUNT_STAR as access_count FROM performance_schema.table_io_waits_summary_by_index_usage WHERE OBJECT_SCHEMA NOT IN ('mysql', 'sys', 'performance_schema', 'information_schema') AND INDEX_NAME IS NOT NULL AND COUNT_STAR = 0 ORDER BY OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME; - 说明:
- 查找未使用的索引
- 可以考虑删除未使用的索引,减少维护开销
- 需要足够的监控时间,确保索引确实未被使用
- 命令:
健康检查脚本
1. 数据库健康检查脚本
- 完整健康检查脚本
- 脚本内容:bash
#!/bin/bash # MySQL 健康检查脚本 USER="root" PASSWORD="password" HOST="localhost" LOG_FILE="/var/log/mysql/health_check.log" echo "==================== MySQL 健康检查报告 ====================" >> $LOG_FILE echo "检查时间: $(date '+%Y-%m-%d %H:%M:%S')" >> $LOG_FILE echo "=======================================================" >> $LOG_FILE # 1. 检查 MySQL 服务是否运行 echo "\n1. 检查 MySQL 服务状态:" >> $LOG_FILE if mysqladmin -u $USER -p$PASSWORD -h $HOST ping > /dev/null 2>&1; then echo " ✓ MySQL 服务正在运行" >> $LOG_FILE else echo " ✗ MySQL 服务未运行" >> $LOG_FILE exit 1 fi # 2. 检查连接数 echo "\n2. 连接数状态:" >> $LOG_FILE CONNECTIONS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';" | grep Threads_connected | awk '{print $2}') MAX_CONNECTIONS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL VARIABLES LIKE 'max_connections';" | grep max_connections | awk '{print $2}') USAGE=$(echo "scale=2; $CONNECTIONS / $MAX_CONNECTIONS * 100" | bc) echo " 当前连接数: $CONNECTIONS" >> $LOG_FILE echo " 最大连接数: $MAX_CONNECTIONS" >> $LOG_FILE echo " 连接使用率: $USAGE%" >> $LOG_FILE if (( $(echo "$USAGE > 80" | bc -l) )); then echo " ⚠ 警告: 连接使用率超过 80%" >> $LOG_FILE fi # 3. 检查 InnoDB 缓冲池状态 echo "\n3. InnoDB 缓冲池状态:" >> $LOG_FILE READS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';" | grep Innodb_buffer_pool_reads | awk '{print $2}') READ_REQUESTS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';" | grep Innodb_buffer_pool_read_requests | awk '{print $2}') if [ $READ_REQUESTS -gt 0 ]; then HIT_RATE=$(echo "scale=4; (1 - ($READS / $READ_REQUESTS)) * 100" | bc) else HIT_RATE=0 fi echo " 缓冲池命中率: $HIT_RATE%" >> $LOG_FILE if (( $(echo "$HIT_RATE < 95" | bc -l) )); then echo " ⚠ 警告: 缓冲池命中率低于 95%" >> $LOG_FILE fi # 4. 检查慢查询 echo "\n4. 慢查询状态:" >> $LOG_FILE SLOW_QUERIES=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW GLOBAL STATUS LIKE 'Slow_queries';" | grep Slow_queries | awk '{print $2}') echo " 慢查询数量: $SLOW_QUERIES" >> $LOG_FILE # 5. 检查 replication 状态(如果是从库) echo "\n5. 复制状态:" >> $LOG_FILE SLAVE_STATUS=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SHOW SLAVE STATUS\G" 2>/dev/null) if [ $? -eq 0 ] && [ -n "$SLAVE_STATUS" ]; then SLAVE_IO_RUNNING=$(echo "$SLAVE_STATUS" | grep Slave_IO_Running | awk '{print $2}') SLAVE_SQL_RUNNING=$(echo "$SLAVE_STATUS" | grep Slave_SQL_Running | awk '{print $2}') SECONDS_BEHIND_MASTER=$(echo "$SLAVE_STATUS" | grep Seconds_Behind_Master | awk '{print $2}') echo " IO 线程状态: $SLAVE_IO_RUNNING" >> $LOG_FILE echo " SQL 线程状态: $SLAVE_SQL_RUNNING" >> $LOG_FILE echo " 延迟秒数: $SECONDS_BEHIND_MASTER" >> $LOG_FILE if [ "$SLAVE_IO_RUNNING" != "Yes" ] || [ "$SLAVE_SQL_RUNNING" != "Yes" ]; then echo " ⚠ 警告: 复制线程未正常运行" >> $LOG_FILE fi if [ "$SECONDS_BEHIND_MASTER" -gt 60 ]; then echo " ⚠ 警告: 复制延迟超过 60 秒" >> $LOG_FILE fi else echo " 未配置复制" >> $LOG_FILE fi # 6. 检查数据库大小 echo "\n6. 数据库大小:" >> $LOG_FILE DB_SIZES=$(mysql -u $USER -p$PASSWORD -h $HOST -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema;") echo " $DB_SIZES" >> $LOG_FILE echo "\n=======================================================" >> $LOG_FILE echo "健康检查完成" >> $LOG_FILE echo "=======================================================" >> $LOG_FILE # 输出摘要到控制台 echo "MySQL 健康检查完成,报告已写入 $LOG_FILE" echo "连接数: $CONNECTIONS/$MAX_CONNECTIONS ($USAGE%)" echo "缓冲池命中率: $HIT_RATE%" echo "慢查询数量: $SLOW_QUERIES" - 使用方法:bash
chmod +x mysql_health_check.sh ./mysql_health_check.sh - 说明:
- 完整的 MySQL 健康检查脚本
- 检查服务状态、连接数、缓冲池、慢查询、复制状态和数据库大小
- 将结果写入日志文件
- 输出摘要到控制台
- 可以根据需要扩展检查项目
- 脚本内容:
2. 磁盘空间检查脚本
- MySQL 磁盘空间检查脚本
- 脚本内容:bash
#!/bin/bash # MySQL 磁盘空间检查脚本 USER="root" PASSWORD="password" # 获取 MySQL 数据目录 DATA_DIR=$(mysql -u $USER -p$PASSWORD -e "SHOW GLOBAL VARIABLES LIKE 'datadir';" | grep datadir | awk '{print $2}') # 获取日志目录 LOG_DIR=$(mysql -u $USER -p$PASSWORD -e "SHOW GLOBAL VARIABLES LIKE 'log_error';" | grep log_error | awk '{print $2}' | xargs dirname) echo "MySQL 磁盘空间检查:" echo "====================" # 检查数据目录空间 echo "\n1. 数据目录 ($DATA_DIR):" df -h $DATA_DIR # 检查日志目录空间 echo "\n2. 日志目录 ($LOG_DIR):" df -h $LOG_DIR # 检查临时目录空间 TMP_DIR=$(mysql -u $USER -p$PASSWORD -e "SHOW GLOBAL VARIABLES LIKE 'tmpdir';" | grep tmpdir | awk '{print $2}') echo "\n3. 临时目录 ($TMP_DIR):" df -h $TMP_DIR # 检查最大的数据库 echo "\n4. 最大的 5 个数据库:" mysql -u $USER -p$PASSWORD -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length + index_length) DESC LIMIT 5;" # 检查最大的表 echo "\n5. 最大的 5 个表:" mysql -u $USER -p$PASSWORD -e "SELECT table_schema AS 'Database', table_name AS 'Table', ROUND((data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables ORDER BY (data_length + index_length) DESC LIMIT 5;" # 检查二进制日志大小(如果启用) BINLOG_ENABLED=$(mysql -u $USER -p$PASSWORD -e "SHOW GLOBAL VARIABLES LIKE 'log_bin';" | grep log_bin | awk '{print $2}') if [ "$BINLOG_ENABLED" = "ON" ]; then BINLOG_DIR=$(mysql -u $USER -p$PASSWORD -e "SHOW GLOBAL VARIABLES LIKE 'log_bin_basename';" | grep log_bin_basename | awk '{print $2}' | xargs dirname) echo "\n6. 二进制日志目录 ($BINLOG_DIR):" du -sh $BINLOG_DIR/* | sort -rh | head -10 fi - 使用方法:bash
chmod +x mysql_disk_space_check.sh ./mysql_disk_space_check.sh - 说明:
- 检查 MySQL 相关目录的磁盘空间
- 列出最大的数据库和表
- 检查二进制日志大小(如果启用)
- 用于监控磁盘空间使用情况,避免磁盘空间不足
- 脚本内容:
不同 MySQL 版本的差异
MySQL 5.7 vs 8.0
状态检查命令差异
- MySQL 8.0 新增了更多状态变量和性能指标
- MySQL 8.0 增强了 EXPLAIN 输出,支持 EXPLAIN ANALYZE
- MySQL 8.0 改进了 Performance Schema,提供更详细的性能数据
监控工具差异
- MySQL 8.0 内置了更多的监控功能
- MySQL 8.0 支持更多的 Performance Schema 消费者
- MySQL 8.0 改进了 InnoDB 监控指标
脚本兼容性
- 大部分基本命令在两个版本中兼容
- 某些新功能和状态变量仅在 MySQL 8.0 中可用
- 编写脚本时需要考虑版本兼容性
MySQL 8.0 小版本差异
性能 Schema 改进
- 后续版本持续增强了 Performance Schema 的功能
- 新增了更多的监控指标和消费者
InnoDB 监控增强
- 新增了更多的 InnoDB 状态变量
- 改进了 InnoDB 状态输出格式
监控工具支持
- 第三方监控工具对新版本的支持可能有延迟
- 需要确保监控工具版本与 MySQL 版本兼容
常见问题(FAQ)
Q1: 如何监控 MySQL 的实时性能?
A1: 监控 MySQL 实时性能的方法:
- 使用 SHOW GLOBAL STATUS 查看实时状态变量
- 使用 SHOW PROCESSLIST 查看当前连接和查询
- 使用 SHOW ENGINE INNODB STATUS 查看 InnoDB 实时状态
- 使用第三方工具如 PMM、Prometheus+Grafana 进行实时监控
- 编写自定义脚本定期收集和分析性能数据
Q2: 如何判断 MySQL 性能是否正常?
A2: 判断 MySQL 性能是否正常的指标:
- 连接使用率:建议低于 80%
- InnoDB 缓冲池命中率:建议高于 99%
- 慢查询数量:建议保持在较低水平
- 查询响应时间:根据业务需求确定
- 复制延迟:建议低于 60 秒
Q3: 如何排查 MySQL 连接数过高的问题?
A3: 排查 MySQL 连接数过高的方法:
- 使用 SHOW PROCESSLIST 查看当前连接
- 分析连接来源和执行的 SQL
- 检查是否存在连接泄漏
- 检查应用连接池配置
- 考虑调整 max_connections 参数
- 优化查询,减少连接占用时间
Q4: 如何优化 InnoDB 缓冲池命中率?
A4: 优化 InnoDB 缓冲池命中率的方法:
- 增加 innodb_buffer_pool_size 参数
- 优化查询,减少全表扫描
- 合理设计索引,提高索引使用率
- 考虑使用覆盖索引
- 监控缓冲池使用情况,及时调整
Q5: 如何使用 Performance Schema 进行监控?
A5: 使用 Performance Schema 进行监控的步骤:
- 确保 Performance Schema 已启用(默认启用)
- 配置需要监控的消费者
- 查询相关的 Performance Schema 表
- 分析监控数据
- 根据分析结果进行优化
示例:
sql
-- 启用 statement 消费者
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%statement%';
-- 查询最慢的查询
SELECT * FROM performance_schema.events_statements_summary_by_digest ORDER BY avg_timer_wait DESC LIMIT 10;Q6: 如何设置 MySQL 慢查询日志?
A6: 设置 MySQL 慢查询日志的步骤:
- 启用慢查询日志:sql
SET GLOBAL slow_query_log = ON; - 设置慢查询阈值:sql
SET GLOBAL long_query_time = 1; -- 1 秒 - 设置慢查询日志文件:sql
SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow-query.log'; - 可选:记录未使用索引的查询:sql
SET GLOBAL log_queries_not_using_indexes = ON; - 永久生效需修改配置文件:ini
[mysqld] slow_query_log = ON long_query_time = 1 slow_query_log_file = /var/lib/mysql/slow-query.log log_queries_not_using_indexes = ON
Q7: 如何分析慢查询日志?
A7: 分析慢查询日志的方法:
- 使用 mysqldumpslow 工具:bash
mysqldumpslow slow-query.log - 使用 pt-query-digest 工具:bash
pt-query-digest slow-query.log > slow_query_analysis.txt - 使用 MySQL Workbench 等图形工具
- 编写自定义脚本分析
Q8: 如何监控 MySQL 复制状态?
A8: 监控 MySQL 复制状态的方法:
- 使用 SHOW SLAVE STATUS 查看复制状态
- 监控 Slave_IO_Running 和 Slave_SQL_Running 线程状态
- 监控 Seconds_Behind_Master 延迟时间
- 使用第三方监控工具设置复制告警
- 编写自定义脚本定期检查复制状态
Q9: 如何检查 MySQL 数据目录的大小?
A9: 检查 MySQL 数据目录大小的方法:
- 使用 du 命令:bash
du -sh /var/lib/mysql - 使用 SQL 查询:sql
SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema; - 使用 mysqlcheck 命令:bash
mysqlcheck -u root -p --check-upgrade --all-databases
Q10: 如何自动化 MySQL 状态检查?
A10: 自动化 MySQL 状态检查的方法:
- 使用 crontab 定时执行监控脚本
- 使用系统监控工具如 Nagios、Zabbix
- 使用云服务商提供的监控服务
- 使用容器编排平台的健康检查功能
- 编写自定义脚本,结合告警系统发送通知
最佳实践建议
1. 监控策略建议
分层监控
- 基础监控:服务状态、连接数、磁盘空间
- 性能监控:缓冲池、查询性能、慢查询
- 高级监控:锁等待、死锁、复制状态
监控频率
- 关键指标:5-15 分钟
- 非关键指标:1-24 小时
- 完整健康检查:每天
告警策略
- 设置多级告警阈值(警告、严重、紧急)
- 避免告警风暴
- 确保告警能够及时送达
- 定期测试告警系统
2. 脚本编写建议
安全性
- 避免在脚本中硬编码密码
- 使用环境变量或配置文件存储敏感信息
- 限制脚本的执行权限
可维护性
- 代码模块化,便于扩展
- 添加详细的注释
- 使用有意义的变量名
- 遵循一致的代码风格
可靠性
- 添加错误处理
- 检查命令执行结果
- 确保脚本在不同环境下兼容
- 测试脚本的各种情况
3. 性能优化建议
定期分析
- 定期分析慢查询日志
- 定期检查索引使用情况
- 定期分析缓冲池使用情况
- 定期检查连接使用情况
持续优化
- 根据监控数据进行针对性优化
- 优化查询和索引
- 调整配置参数
- 升级硬件资源
预防为主
- 设计阶段考虑性能
- 开发阶段进行性能测试
- 部署前进行性能评估
- 定期进行性能基准测试
通过合理使用状态检查命令和脚本,可以有效监控 MySQL 的运行状态和性能,及时发现和解决问题,确保数据库的稳定运行。数据库管理员应该根据实际情况,选择合适的监控方法和工具,建立完善的监控体系。
