MySQL 8.0+ 中无 PROCESS 权限时可用 performance_schema.threads 替代 SHOW PROCESSLIST,需确保 performance_schema 开启且具备 SELECT 权限;PostgreSQL 则使用 pg_stat_activity 视图,普通用户默认仅见自身连接。
MySQL 8.0+ 里 SHOW PROCESSLIST 权限不够怎么办
直接执行 show processlist 报错 error 1227 (42501): access denied; you need at least one of the process privileges,说明当前账号没开 process 权限——这权限默认只给管理员,普通应用账号通常不配。
替代方案是查系统视图 performance_schema.threads,它只要 SELECT 权限就能读(前提是 performance_schema 开启且没被禁用):
SELECT thread_id, processlist_user, processlist_host, processlist_db, processlist_command, processlist_state, processlist_info FROM performance_schema.threads WHERE PROCESSLIST_ID IS NOT NULL;
-
processlist_*字段基本和SHOW PROCESSLIST输出对齐,但要注意processlist_info默认可能为NULL(SQL 文本被截断或隐藏),需确认performance_schema.setup_consumers中events_statements_current是否启用 - 如果只关心活跃查询,加条件
WHERE processlist_command != 'Sleep',避免淹没在大量空闲连接里 - 该视图不包含连接的创建时间,如需判断长连接,得结合
CONNECTED_TIME或自己记录连接建立时间戳
想看连接来源 IP 和端口,information_schema.PROCESSLIST 不够用
information_schema.PROCESSLIST 看起来像 SHOW PROCESSLIST 的表形式,但它字段固定、不可扩展,且从 MySQL 8.0.22 起已标记为废弃,字段如 HOST 只返回 user@host 格式,无法拆出真实 IP 和端口。
真要拿到客户端 IP+端口,必须用 performance_schema.threads 关联 performance_schema.socket_summary_by_thread_by_event_name 或直接查 performance_schema.socket_instances(需开启对应 instruments):
SELECT t.processlist_user, s.IP, s.PORT, t.processlist_db, t.processlist_info FROM performance_schema.threads t JOIN performance_schema.socket_instances s ON t.thread_id = s.THREAD_ID WHERE s.EVENT_NAME = 'wait/io/socket/sql/client_connection' AND t.PROCESSLIST_ID IS NOT NULL;
- 这个关联依赖
socket_instances表数据,而它默认只在setup_instruments启用了wait/io/socket/*时才采集 - 部分云数据库(如阿里云 RDS)会禁用
performance_schema的 socket 相关 instrument,此时这条路走不通,只能靠代理层日志或网络抓包 -
s.IP和s.PORT是客户端真实出口地址,不是中间代理(如 HAProxy)转发后的地址
PostgreSQL 怎么等效替代 SHOW PROCESSLIST
PostgreSQL 没有 SHOW PROCESSLIST,对应的是系统视图 pg_stat_activity。它比 MySQL 的更详细,但也更容易因权限或配置漏掉关键信息。
基础查询:
SELECT pid, usename, client_addr, client_hostname, client_port, backend_start, state, query FROM pg_stat_activity WHERE state != 'idle';
-
client_addr就是客户端 IP,client_port是端口,不需要额外 join;但若连接经由 PgBouncer,这里显示的是 bouncer 的地址,不是原始客户端 - 默认只允许超级用户看到所有行,普通用户只能看到自己的连接,除非 DBA 显式授予
pg_read_all_data(PG 14+)或pg_monitor角色 -
query字段可能被截断(受track_activity_query_size参数限制,默认 1024 字节),超长 SQL 会被截断,且某些敏感操作(如COPY FROM PROGRAM)会自动清空该字段
查到连接后,怎么安全终止而不是直接 KILL
MySQL 的 KILL [CONNECTION|QUERY] id 和 PostgreSQL 的 pg_terminate_backend(pid) 都是即时生效的硬中断,容易导致事务回滚、锁未释放甚至主从延迟突增。
- 优先用
KILL QUERY(MySQL)或pg_cancel_backend(pid)(PG),它们只中断当前正在执行的语句,保留连接和事务上下文,适合误操作或慢查询 - MySQL 5.7+ 支持
KILL CONNECTION,但若目标线程正持有全局锁(如FLUSH TABLES WITH READ LOCK),KILL 可能卡住,需配合INFORMATION_SCHEMA.INNODB_TRX查锁再决策 - PostgreSQL 中,如果
state = 'idle in transaction'且长时间未提交,直接pg_terminate_backend会强制回滚,但要注意:若该事务已持有了行级锁,回滚过程本身可能阻塞其他会话,建议先pg_cancel_backend尝试中断,无效再升级
真正难的从来不是“怎么查”,而是查到之后——哪个连接该杀、杀到哪一层、会不会引发连锁反应,这些都得结合业务上下文和当前锁状态来判断。










