在运维工作中,如何验证开源mysql数据库,有没有业务在连接或使用?
这是一个很常见的运维场景。要判断一个MySQL实例是否还有业务在用,不能只看"有没有连接",还需要区分活跃连接和空闲连接,并观察一段时间内的连接动态。下面给你一个系统化的排查方案:
快速查看当前连接数
登录MySQL后,先查看全局连接状态:
-- 当前已建立的连接总数(含空闲)
SHOW STATUS LIKE 'Threads_connected';
-- 当前正在执行SQL的连接数(真正活跃的)
SHOW STATUS LIKE 'Threads_running';
如果
Threads_connected只有 1(就是你自己的管理连接),那基本可以判断没有业务在用。
查看所有连接详情
SHOW FULL PROCESSLIST;
这会列出所有连接的详细信息,包括:
| 字段 | 含义 |
|---|---|
| Id | 线程ID,可用于 KILL 命令 |
| User | 连接的MySQL用户名 |
| Host | 来源IP+端口,可判断是哪个应用服务器 |
| db | 当前使用的数据库 |
| Command | 命令类型(Query=执行中,Sleep=空闲) |
| Time | 当前状态持续秒数 |
| State | 执行阶段(如 Sending data、Locked) |
| Info | 正在执行的SQL语句 |
关键判断逻辑:
- 排除掉你自己的连接(
SHOW FULL PROCESSLIST那条)和系统线程(event_scheduler) - 如果剩下的连接中,
Command全是Sleep且Time很大,说明是空闲连接池,没有实际业务请求 - 如果有
Command = 'Query'的连接,说明有业务正在执行SQL,不能停
用SQL精确过滤(推荐)
-- 排除系统线程和自己,只看业务连接
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO
FROM information_schema.PROCESSLIST
WHERE COMMAND != 'Sleep'
AND USER NOT IN ('event_scheduler', 'system user')
AND ID != CONNECTION_ID();
如果这条查询返回 0 行,说明当前没有活跃的业务SQL在执行。
-- 按来源IP和用户名统计连接数
SELECT USER, HOST, COUNT(*) AS conn_count
FROM information_schema.PROCESSLIST
GROUP BY USER, HOST
ORDER BY conn_count DESC;
这条能帮你快速识别哪些机器、哪些账号在连接,判断是否来自已知业务。
安全停库的完整流程
单看一次快照不够可靠,建议按以下步骤操作:
1. 持续观察(至少观察一个业务周期)
# 每10秒打印一次连接数,观察一段时间
while true; do
mysql -e "SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Threads_running';" 2>/dev/null
echo "--- $(date) ---"
sleep 10
done
如果是在业务低峰期(如凌晨),建议至少观察 30分钟到1小时,确认连接数始终为 0 或只有空闲连接。
2. 检查是否有未提交的事务
SELECT * FROM information_schema.INNODB_TRX;
如果有未提交的事务,停库会导致事务回滚,需要谨慎。
3. 检查是否有从库在复制
SHOW SLAVE HOSTS;
-- 或
SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND = 'Binlog Dump';
如果有从库连接,停掉主库会导致主从断开。
4. 优雅关闭
确认安全后,使用优雅关闭命令:
mysqladmin -u root -p shutdown
或者在MySQL内执行:
SHUTDOWN;
这会让MySQL等待当前正在执行的事务完成后才关闭,比直接 kill -9 安全得多。
温馨提示
- 连接池的空闲连接(
Sleep状态)不代表有业务在用,但说明有应用配置了这个数据库地址,停库后应用可能会报错,建议提前通知业务方 - 如果这个MySQL是某个微服务的数据库,即使当前没连接,也可能在流量高峰时突然有连接进来,建议确认应用配置中是否还指向了这个实例
- 可以在停库前先把MySQL端口改为不可达(如iptables规则),观察几天看是否有告警,作为最终确认手段

浙公网安备 33010602011771号