Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL数据库监控

MySQL中数据库监控核心要素与实施策略详解

作者:Wang's Blog

数据库监控是系统稳定性的基石,作为核心组件,数据库的稳定性直接决定系统可用性,因此监控至关重要,下面小编就和大家详细讲讲MySQL中数据库监控核心要素与实施策略吧

数据库监控的必要性与范畴

数据库监控是系统稳定性的基石,作为核心组件,数据库的稳定性直接决定系统可用性,因此监控至关重要。当前市场上存在多种监控工具(如 Nagios、Zabbix),支持通过插件或自定义脚本实现数据库监控,用户可根据习惯选择工具与脚本语言(如 Python、Shell)

监控核心内容:

1 ) 服务可用性监控:

仅检测进程或端口存活并不充分,需通过网络连接数据库并执行简单查询(如 SELECT 1)验证实际可用性

超越进程/端口检查:需建立真实数据库连接并执行基础查询

监控指标:连接成功率、响应延迟、简单查询执行状态

/* 基础健康检查SQL */
SELECT 1;  
/* 连接池状态检查 */
SHOW STATUS LIKE 'Threads_connected'; 

2 )性能监控:

QPS(每秒查询量)、TPS(每秒事务量)、并发线程数(注意:并发线程指同时处理的 SQL 请求数,通常远小于连接数)

并发线程数:活跃工作线程(非连接数)

/* 关键性能指标查询 */
SHOW GLOBAL STATUS WHERE Variable_name IN ('Queries','Com_commit','Com_rollback','Threads_running');

InnoDB阻塞监控:

/* 阻塞会话检测 */
SELECT 
  bl.trx_mysql_thread_id AS blocking_id,
  wt.trx_mysql_thread_id AS waiting_id,
  wt.trx_query AS waiting_query
FROM information_schema.innodb_lock_waits w 
JOIN information_schema.innodb_trx bl ON bl.trx_id = w.blocking_trx_id 
JOIN information_schema.innodb_trx wt ON wt.trx_id = w.requesting_trx_id;

简单真相:

/* 检测阻塞事务 */  
SELECT  
  waiting_trx_id,  
  blocking_trx_id,  
  waiting_query,  
  blocking_query  
FROM sys.innodb_lock_waits;  -- 依赖sys schema  

3 )主从复制监控:

链路状态、延迟检测及数据一致性验证

复制链路状态(IO/SQL线程运行状态)

主从延迟(Seconds_Behind_Master)

数据一致性校验

/* 主从状态检查 */
SHOW SLAVE STATUS\G
/* 延迟检测 */
SELECT NOW() - MAX(create_time) AS replication_delay 
FROM mysql.slave_relay_log_info;

/* 查看复制状态 */  
SHOW REPLICA STATUS\G  
/* 关键字段:Replica_IO_Running, Replica_SQL_Running, Seconds_Behind_Master */  

4 )服务器资源监控:

磁盘空间(重点监控数据库专用分区,避免因日志或数据目录占满导致服务中断)、CPU、内存、SWAP 及网络 I/O(通用指标本文不赘述)

关键风险点:

示例1

/* 表空间监控 */
SELECT 
  table_schema AS `Database`,
  SUM(data_length + index_length) / 1024 / 1024 AS `Size_MB`
FROM information_schema.TABLES 
GROUP BY table_schema;

示例2

/* 查看表空间使用(InnoDB) */  
SELECT table_schema, table_name,  
  ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb  
FROM information_schema.TABLES  
ORDER BY size_mb DESC;  

其他核心资源:

关键细节:数据库专用分区空间不足是常见故障点。即使服务器总磁盘空间充足,若分配给 MySQL 数据/日志目录的分区过小,仍会导致服务不可用

数据库可用性监控实现方案

1 ) 网络连接验证

仅本地连接成功不能确保远程网络可用(受防火墙、TCP 连接数限制影响)。需通过以下方式验证:

mysqladmin ping 命令:

mysqladmin -u monitor_user -p'password' -h 192.168.1.100 ping

建立监控专用账号,循环检测多台服务器,通过返回状态判断连通性。

Telnet 端口检测(手动测试):

telnet 192.168.1.100 3306 

模拟应用连接(推荐):

编写代码模拟真实应用连接方式(如特定驱动版本),规避因客户端兼容性问题导致的隐蔽故障。

2 ) 读写服务验证

检查 read_only 参数:主库必须关闭 read_only;主从切换后需确认新主库此参数为 OFF

轻量级读写测试:定时对监控表执行简单操作(如 UPDATE monitor_table SET check_time=NOW()),避免产生额外负载。

最低成本读验证:执行无依赖查询 SELECT @@version,兼容所有 MySQL 版本

参考:

-- 检查读能力 
SELECT @@version;
-- 写入测试(示例)
INSERT INTO monitor_table (id) VALUES (1) ON DUPLICATE KEY UPDATE id=1;

3 ) 连接数阈值监控

关键变量:

连接数突增(如缓存失效或阻塞引发)可能导致连接耗尽,监控方法:

获取配置参数:

SHOW VARIABLES LIKE 'max_connections'; -- 最大连接数
# 或
SHOW GLOBAL VARIABLES LIKE 'max_connections';

实时状态检测:

SHOW GLOBAL STATUS LIKE 'Threads_connected'; -- 当前连接数 
# 或
SHOW GLOBAL STATUS LIKE 'Threads_connected';

报警规则:(Threads_connected / max_connections) > 80% 时触发告警。

数据库性能监控关键指标

性能监控需持续记录数据趋势,核心指标如下:

1 ) QPS & TPS 计算

QPS(每秒查询量):

QPS = (Queries₂ - Queries₁) / 时间间隔  
-- Queries 取自 SHOW GLOBAL STATUS 的输出 

TPS(每秒事务量):

TPS = [(Com_insert₂ + Com_update₂ + Com_delete₂) - 
      (Com_insert₁ + Com_update₁ + Com_delete₁)] / 时间间隔 

2 ) 并发线程监控

监控状态变量:

SHOW GLOBAL STATUS LIKE 'Threads_running'; -- 实时并发数 

并发量突增可能预示阻塞或缓存雪崩,需结合 CPU 使用率分析

3 ) InnoDB 阻塞监控

MyISAM 引擎缺乏原生锁监控,建议迁移至 InnoDB。InnoDB 阻塞检测 SQL:

SELECT 
    r.trx_id AS waiting_trx_id,
    r.trx_mysql_thread_id AS waiting_thread_id,
    r.trx_query AS waiting_query,
    b.trx_id AS blocking_trx_id,
    b.trx_mysql_thread_id AS blocking_thread_id,
    b.trx_query AS blocking_query,
    TIMESTAMPDIFF(SECOND, r.trx_wait_started, NOW()) AS wait_time_sec
FROM information_schema.innodb_lock_waits w 
JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id 
JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id 
WHERE TIMESTAMPDIFF(SECOND, r.trx_wait_started, NOW()) > 60; -- 阻塞超时阈值(秒)

注意:若阻塞事务已完成,可能无法捕获原始 SQL,需结合日志分析

4 ) MySQL 主从复制监控详解

复制链路状态监控

依赖 SHOW SLAVE STATUS 输出:

SHOW SLAVE STATUS\G

关键字段:

任一状态异常即触发告警

复制延迟精确检测

Seconds_Behind_Master 不准确(网络中断时可能误判)。推荐方案:

主库获取二进制日志位置:

-- 主库执行 
SHOW MASTER STATUS; -- File: mysql-bin.000001, Position: 154 

-- 从库执行 
SHOW SLAVE STATUS;   -- 对比 Relay_Master_Log_File 和 Exec_Master_Log_Pos 

从库对比同步进度:

SELECT 
   relay_master_log_file, 
   exec_master_log_pos 
FROM performance_schema.replication_applier_status_by_worker;

判断延迟:

数据一致性校验

使用 Percona Toolkit 的 pt-table-checksum

pt-table-checksum \
  --user=monitor_user \
  --password='password' \
  --databases=mydatabase \
  --replicate=test.checksum # # 在test库创建校验表 

要求:主库账号需具备 SELECTPROCESSSUPER 权限

操作说明:

主库执行命令,在 test 库创建 checksum 表存储校验结果。

工具自动对比主从库数据差异。

需配置监控账号权限:

GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'monitor_user'@'%';

服务器资源监控补充

磁盘空间:重点监控数据目录(如 /var/lib/mysql)和日志分区

其他资源:

监控实施补充说明

1 ) 工具选择灵活性:

开发者可通过Shell、Python等编写脚本,集成到Zabbix/Nagios中

NestJS监控端点示例(获取数据库状态):

import { Controller, Get } from '@nestjs/common';  
import { Connection } from 'mysql2/promise';  

@Controller('monitor')  
export class MonitorController {  
  constructor(private connection: Connection) {}  

  @Get('status')  
  async getDbStatus() {  
    const [rows] = await this.connection.query('SHOW GLOBAL STATUS');  
    const qps = rows.find(row => row.Variable_name === 'Queries').Value;  
    return { status: 'OK', qps };  
  }  
}  

2 ) 性能优化关联性:

查询性能监控需结合执行计划分析(EXPLAIN),但本文不重复展开

SQL 示例

1 ) SQL 监控脚本关键总结

-- 检查连接数 
SHOW GLOBAL STATUS WHERE Variable_name = 'Threads_connected';
-- 获取 InnoDB 锁阻塞 
SELECT * FROM information_schema.innodb_lock_waits;
-- 主从状态检查 
SHOW SLAVE STATUS\G;

/* 综合健康检查 */
SELECT 
  (SELECT VARIABLE_VALUE FROM performance_schema.global_status 
   WHERE VARIABLE_NAME='Uptime') AS uptime,
  (SELECT SUM(VARIABLE_VALUE) FROM performance_schema.global_status 
   WHERE VARIABLE_NAME IN ('Com_select','Com_insert','Com_update','Com_delete')) AS qps,
  (SELECT VARIABLE_VALUE FROM performance_schema.global_status 
   WHERE VARIABLE_NAME='Threads_running') AS active_threads;

总结:

Nestjs 工程实例

1 )方案1

import { Controller, Get } from '@nestjs/common';
import { execSync } from 'child_process';
 
@Controller('monitor')
export class DbMonitorController {
  @Get('qps')
  getQPS(): number {
    const prevQueries = this.getStatusVariable('Queries');
    setTimeout(() => {
      const currQueries = this.getStatusVariable('Queries');
      return (currQueries - prevQueries) / 5; // 假设5秒间隔 
    }, 5000);
  }
 
  private getStatusVariable(name: string): number {
    const output = execSync(`mysql -u root -p[密码] -e "SHOW GLOBAL STATUS LIKE '${name}'"`);
    return parseInt(output.toString().split('\t')[1]);
  }
}

2 )方案2

// 监控端点控制器 (monitor.controller.ts)
import { Controller, Get } from '@nestjs/common';
import { MysqlService } from './mysql.service';
 
@Controller('monitor')
export class MonitorController {
  constructor(private readonly mysqlService: MysqlService) {}
 
  @Get('healthcheck')
  async healthCheck() {
    return {
      status: await this.mysqlService.checkConnection(),
      metrics: await this.mysqlService.getPerformanceMetrics()
    };
  }
}
 
// MySQL服务层 (mysql.service.ts)
import { Injectable } from '@nestjs/common';
import { Connection } from 'mysql2/promise';
 
@Injectable()
export class MysqlService {
  constructor(private connection: Connection) {}
 
  async checkConnection(): Promise<string> {
    const [rows] = await this.connection.query('SELECT 1 AS status');
    return rows[0].status === 1 ? 'OK' : 'DOWN';
  }
 
  async getPerformanceMetrics() {
    const [qpsRes] = await this.connection.query(
      `SHOW GLOBAL STATUS WHERE Variable_name IN ('Queries','Threads_running')`
    );
    return {
      queries: qpsRes.find(r => r.Variable_name === 'Queries').Value,
      active_threads: qpsRes.find(r => r.Variable_name === 'Threads_running').Value
    };
  }
}

总结

数据库监控需覆盖 可用性、性能、复制、资源 四个维度:

实施建议:将监控脚本集成至 Prometheus + Grafana 或 Zabbix,实现可视化告警与历史数据分析

通过组合原生SQL监控与NestJS自动化端点,可构建覆盖可用性、性能、资源的三维监控体系,有效预防80%的数据库故障场景。监控脚本需以5-10分钟为周期采集数据,配合趋势分析实现异常预警

到此这篇关于MySQL中数据库监控核心要素与实施策略详解的文章就介绍到这了,更多相关MySQL数据库监控内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文