在MySQL运维中,实时掌握数据库的查询吞吐与事务处理能力是保障系统稳定的基础。QPS(Queries Per Second)表示每秒执行的查询次数,TPS(Transactions Per Second)表示每秒完成的事务数。通过MySQL自带的SHOW GLOBAL STATUS命令,我们可以读取全局状态计数器,利用两次采样之间的增量来推算实时指标,无需借助第三方监控代理。

一、SHOW GLOBAL STATUS中的关键计数器
MySQL的SHOW GLOBAL STATUS会返回大量以计数形式存在的状态变量,这些变量从服务启动开始累计。要计算QPS和TPS,我们主要关注以下几个值:Queries、Com_commit、Com_rollback。其中Queries包含了所有由客户端发出的语句(包括存储过程内部的语句),而Com_commit和Com_rollback分别记录显式提交和回滚的事务数。
需要注意的是,Queries并不等于QPS的唯一口径。在某些业务场景中,如果使用了预编译语句或存储过程,统计方式会有细微差别,但作为通用监控,以Queries增量计算QPS是最直观的做法。TPS则通常由Com_commit与Com_rollback之和的增量来表征,因为这代表了实际落盘或撤销的事务动作。
二、QPS的计算方法与实践
QPS的计算逻辑是:在时间点T1读取Queries值为Q1,在时间点T2读取Queries值为Q2,时间间隔为Δt秒,则QPS = (Q2 - Q1) / Δt。这种方式本质是平均速率,采样间隔越短,越能反映实时波动。一般建议采样间隔设为1到5秒,避免过于频繁查询带来额外开销。
下面是一段使用Python获取并计算QPS的示例脚本,它通过两次查询状态变量完成差值运算:
import time
import pymysql
def get_status_value(conn, var_name):
with conn.cursor() as cur:
cur.execute("SHOW GLOBAL STATUS LIKE '%s'" % var_name)
result = cur.fetchone()
return int(result[1])
conn = pymysql.connect(host='127.0.0.1', user='root', password='test', database='mysql')
q1 = get_status_value(conn, 'Queries')
t1 = time.time()
time.sleep(1)
q2 = get_status_value(conn, 'Queries')
t2 = time.time()
qps = (q2 - q1) / (t2 - t1)
print("实时QPS: %d" % qps)
conn.close()
该脚本在本地127.0.0.1实例上建立连接,睡眠一秒后再次读取,从而得出这一秒内的平均QPS。在实际生产环境中,可以将此逻辑放入定时任务,将结果写入时序数据库,便于绘制曲线。此方法的优点是实现简单、无侵入,缺点是在高并发下sleep精度可能受系统负载影响,但对监控用途完全可以接受。
三、TPS的计算方法与代码实现
TPS的计算与QPS类似,但需同时关注提交和回滚。公式为:TPS = ((Com_commit2 + Com_rollback2) - (Com_commit1 + Com_rollback1)) / Δt。回滚同样消耗事务资源,因此必须计入TPS口径,否则会低估数据库实际事务压力。
以下示例展示如何一次性读取多个状态变量并计算TPS:
import time
import pymysql
def get_multi_status(conn, names):
data = {}
with conn.cursor() as cur:
for name in names:
cur.execute("SHOW GLOBAL STATUS LIKE '%s'" % name)
row = cur.fetchone()
data[name] = int(row[1])
return data
conn = pymysql.connect(host='127.0.0.1', user='root', password='test', database='mysql')
first = get_multi_status(conn, ['Com_commit', 'Com_rollback'])
time.sleep(1)
second = get_multi_status(conn, ['Com_commit', 'Com_rollback'])
tps = ((second['Com_commit'] + second['Com_rollback']) - (first['Com_commit'] + first['Com_rollback'])) / 1
print("实时TPS: %d" % tps)
conn.close()
上述代码通过一次循环查询两个变量,避免了多次往返。在真实业务中,如果使用了隐式提交(如autocommit=1下的单条DML),Com_commit不会增加,此时TPS参考意义下降,可改用Questions或Queries结合写入量评估。理解这一点有助于防止误判:并非所有写入都体现为Com_commit计数。
四、常见误区与监控建议
不少初学者会把Threads_running或Threads_connected当作QPS,这是概念混淆。Threads_running仅表示当前正在执行语句的线程数,它是一个瞬时并发量,而不是速率。例如系统可能有10个线程在跑,但每秒查询可能高达上千,二者量纲不同。
在构建监控体系时,建议将QPS、TPS与CPU使用率、缓冲池命中率联合分析。当QPS突降而Threads_running升高,往往意味着出现锁等待或慢查询;当TPS持续高位但QPS不高,可能是事务过大或频繁回滚。通过SHOW GLOBAL STATUS的轻量轮询,配合阈值告警,能够以极低代价覆盖核心吞吐监控。
五、在Shell中快速查看的写法
如果不想写Python,也可以用MySQL客户端加Shell命令实现简易监控。下面的脚本利用mysql命令两次取值并用awk计算:
#!/bin/bash
get_q() {
mysql -h 127.0.0.1 -u root -ptest -e "SHOW GLOBAL STATUS LIKE 'Queries'" | awk 'NR==2{print $2}'
}
q1=$(get_q)
sleep 1
q2=$(get_q)
echo "QPS: $((q2 - q1))"
该脚本假设一秒内差值即为QPS,适用于临时排查。但要注意密码明文在命令行可能存在安全风险,生产环境应使用配置文件或环境变量传参。总体而言,基于SHOW GLOBAL STATUS的计算方式灵活、通用,是每位DBA和后端开发者都应掌握的基础观测手段。
MySQLSHOW_GLOBAL_STATUSQPS_TPS修改时间:2026-08-02 16:39:30