Skip to content

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 进行监控的步骤:

  1. 确保 Performance Schema 已启用(默认启用)
  2. 配置需要监控的消费者
  3. 查询相关的 Performance Schema 表
  4. 分析监控数据
  5. 根据分析结果进行优化

示例:

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 慢查询日志的步骤:

  1. 启用慢查询日志:
    sql
    SET GLOBAL slow_query_log = ON;
  2. 设置慢查询阈值:
    sql
    SET GLOBAL long_query_time = 1; -- 1 秒
  3. 设置慢查询日志文件:
    sql
    SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow-query.log';
  4. 可选:记录未使用索引的查询:
    sql
    SET GLOBAL log_queries_not_using_indexes = ON;
  5. 永久生效需修改配置文件:
    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 的运行状态和性能,及时发现和解决问题,确保数据库的稳定运行。数据库管理员应该根据实际情况,选择合适的监控方法和工具,建立完善的监控体系。