MYSQL 常用监控指标及监控方法
【MySQL】常用监控指标及监控方法
对之前生产中使用过的 MySQL 数据库监控指标做个小结。
指标分类 | 指标名称 | 指标说明 |
性能类指标 | QPS | 数据库每秒处理的请求数量 |
TPS | 数据库每秒处理的事务数量 | |
并发数 | 数据库实例当前并行处理的会话数量 | |
连接数 | 连接到数据库会话的数量 | |
缓存命中率 | 查询命中缓存的比例 | |
高可用指标 | 可用性 | 数据库是否可以正常对外服务 |
阻塞 | 当前阻塞的会话数 | |
慢查询 | 慢查询情况 | |
主从延迟 | 主从延迟时间 | |
主从状态 | 主从链路是否正常 | |
死锁 | 查看死锁信息 |
【QPS 指标】
1 | show global status where variable\_name in ('Queries', 'uptime'); |
QPS = (Queries2 -Queries1) / (uptime2 - uptime1)
【TPS 指标】
1 | show global status where variable\_name in ('com\_insert' , 'com\_delete' , 'com\_update', 'uptime'); |
事务数 TC ≈’com_insert’ , ‘com_delete’ , ‘com_update’
TPS ≈ (TC2 -TC1) / (uptime2 - uptime1)
【并发数】
1 | show global status like '**Threads\_running**'; |
【连接数】
- 当前连接数
1
show global status like 'Threads\_connected';
- 最大连接数 生产中配置报警阈值:Threads_connected / max_connections > 0.8
1
show global status like 'max\_connections';
【缓存命中率】
- innodb 缓冲池查询总数
1
show global status like 'innodb\_buffer\_pool\_read\_requests';
- innodb 从磁盘查询数 生产中配置报警阈值:(innodb_buffer_pool_read_requests - innodb_buffer_pool_reads) /innodb_buffer_pool_read_requests > 0.95
1
show global status like 'innodb\_buffer\_pool\_reads';
【可用性】
方法 1:周期性连接数据库并执行
select @@version;
方法 2:mysqladmin -u 数据库用户名 -p 数据库密码 -h 数据库实例 IP ping
【阻塞】
- MySQL5.7 之前
1
2
3
4
5
6
7
8
9select b.trx\_mysql\_thread\_id as '被阻塞线程',
b.trx\_query as '被阻塞SQL',
c.trx\_mysql\_thread\_id as '阻塞线程',
c.trx\_query as '阻塞SQL',
(unix\_timestamp()-unix\_timestamp(c.trx\_started)) as '阻塞时间'
from information\_schema.innodb\_lock\_waits a
join information\_schema.innodb\_trx b on a.requesting\_trx\_id=b.trx\_id
join information\_schema.innodb\_trx c on a.blocking\_trx\_id=c.trx.id
where(unix\_timestamp()-unix\_timestamp(c.trx\_started))>阻塞秒数 - MySQL5.7 及之后
为方便查询阻塞指标,MySQL 将 2 张表 join 构造了一个 view sys.innodb_lock_waits,查询语句得以大大简化。1
2
3
4
5
6
7
8select waiting\_pid as '被阻塞线程',
waiting\_query as '被阻塞SQL',
blocking\_pid as '阻塞线程',
blocking\_query as '阻塞SQL',
wait\_age as '阻塞时间',
sql\_kill\_blocking\_query as '建议操作'
from sys.innodb\_lock\_waits
where(unix\_timestamp()-unix\_timestamp(wait\_started))>阻塞秒数
【慢查询】
方法 1:开启慢查询日志。
my.inf
1
2
3
4slow\_query\_log=on
slow\_query\_log\_file=存放目录
long\_query\_time=0.1秒
log\_queries\_not\_using\_indexes=on注:只对新建连接生效,实时生效使用命令 set global 上述配置项。
方法 2:
1
select \* from information\_schema.'processlist';
【主从延迟】
- 方法 1:
1
show slave status;
问题:
该方法是基于 relaylog 的时间与 master 的时间差值,并不太准,例如大事务时,主从延时已发生,但 relaylog 还未生成。
- 方法 2:使用 Percona 的 pt-heartbeat 工具
Master 后台周期写入:
1 | pt-heartbeat --user=Master用户名 --password=Master密码 --h MasterIP --create-table --database 测试库名 --updatte --daemonize --interval=1 |
–create-table 在 Master 上创建心跳监控表 heartbeat,通过更新该表知道主从延迟的差距。
–daemonize 后台执行。
–interval=1 默认 1 秒执行一次。
Slave 后台周期同步读取:
1 | pt-heartbeat --user=Slave用户名 --password=Slave密码 --h SlaveIP --database 库名 --monitor --daemonize --log /slave\_lag.log |
–monitor 参数是持续监测并输出结果
【主从状态】
1 | show slave status; |
【死锁】
方法 1:查看最近一次死锁信息:
1
show engine innodb status;
方法 2:使用 Percona 的 pt-deadlock-logger 工具
- 打开死锁打印全局开关
1
set global innodb\_print\_all\_deadlocks=on;
- 使用 pt-deadlock-logger 工具
监控到的死锁结果可以输出到文件、指定表、或者界面打印。
1 | pt-deadlock-logger h=数据库IP,u=数据库用户名,p=数据库密码 |
输出结果非常详尽:
server: 数据库服务器地址,即死锁产生的数据库主机
ts: 检测到死锁的时间戳
thread: 产生死锁的线程 id,这个 id 和 show processlist 里面的线程 id 是一致的
txn_id:innodb 的事务 ID
txd_time: 死锁检查到前,事务执行时间
user: 执行 transcation 的用户名
hostname: 客户端主机名
ip: 客户端 ip
db: 发生死锁的 DB 名
tbl: 死锁发生的表名
idx: 产生死锁的索引名 (在上面这个 demo 里面, 我们直接走的主键,加的记录锁)
lock_type: 锁的类型 (记录锁,gap 锁,next-key 锁)
lock_mode: 锁模式 (S,X)
wait_hold: 是否等着锁释放,一般死锁都是两个 wait
victim: 该会话是否做了牺牲,终止了执行
query: 造成死锁的 SQL 语句