跳到主要内容

MySQL 命令速查

值班时最怕「知道该查什么,但想不起语法」。这一页把高频命令按场景分组,直接复制改参数就能用。

使用说明
  • 示例默认在 MySQL 8.0 上执行,SQL 直接贴进客户端,bash 代码块的命令在 shell 里跑。
  • 命令里的库名 shop、主机 10.0.0.11、端口 3306 按实际替换。
  • 8.0.23 起 CHANGE MASTER、START SLAVE 等旧语法逐步废弃,新写法是 REPLICATION SOURCE、REPLICA,两种都能用,建议统一用新的。

连接与信息​

命令说明
mysql -h 10.0.0.11 -P 3306 -u app -p shop连接指定库,-p 后不要直接跟密码
mysql --defaults-file=/etc/my.cnf -u root -p用指定配置文件连接,避免读到本机默认配置
SELECT VERSION();服务器版本
SELECT USER(), CURRENT_USER(), CONNECTION_ID();当前登录身份、实际匹配账号、连接 ID
SHOW DATABASES;列出所有库
SHOW TABLES; / SHOW CREATE TABLE orders\G看表清单 / 看建表语句(含索引和引擎)
SHOW VARIABLES LIKE 'datadir';数据目录位置
SHOW VARIABLES LIKE '%character%';字符集相关变量
SHOW GLOBAL STATUS LIKE 'Uptime';已运行秒数,判断有没有偷偷重启过
SHOW PROCESSLIST;当前连接与执行状态(等价 SELECT * FROM information_schema.PROCESSLIST)
SHOW FULL PROCESSLIST;带完整 SQL 文本,长语句不被截断
SHOW ENGINE INNODB STATUS\GInnoDB 全景:死锁、事务、缓冲池、IO
SELECT @@transaction_isolation;当前隔离级别
SHOW MASTER STATUS;主库 binlog 当前位点(8.2+ 也可 SHOW BINARY LOG STATUS)
SHOW BINARY LOGS;列出所有 binlog 文件与大小
# 不进交互界面直接执行
mysql -h 10.0.0.11 -u app -p shop -e "SELECT COUNT(*) FROM orders;"

# 执行 SQL 文件
mysql -h 10.0.0.11 -u root -p shop < init.sql

# 导出表结构
mysql -h 10.0.0.11 -u root -p shop -e "SHOW CREATE TABLE orders\G"

用户权限​

命令说明
CREATE USER 'app'@'10.0.0.%' IDENTIFIED BY 'xxx';建账号,host 支持 % 通配
ALTER USER 'app'@'10.0.0.%' IDENTIFIED BY 'new';改密码
ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx';换成老认证插件(仅兼容旧客户端时用)
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'app'@'10.0.0.%';授权,按最小权限给
GRANT SELECT ON shop.* TO 'readonly'@'10.0.0.%';只读账号
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.%';复制账号必需权限
REVOKE DELETE ON shop.* FROM 'app'@'10.0.0.%';回收权限
SHOW GRANTS FOR 'app'@'10.0.0.%';看某账号的最终权限
DROP USER 'app'@'10.0.0.%';删账号
SELECT User, Host, plugin FROM mysql.user;账号清单与认证插件
FLUSH PRIVILEGES;仅在直接改 mysql.user 表后需要
-- 排查「授权了却没权限」:看实际匹配到哪个账号
SELECT CURRENT_USER();

-- 查空密码账号(安全隐患)
SELECT User, Host, plugin FROM mysql.user WHERE authentication_string = '';

-- 锁定账号(离职交接时先锁不删)
ALTER USER 'app'@'10.0.0.%' ACCOUNT LOCK;

备份恢复​

命令说明
mysqldump -uroot -p --single-transaction --source-data=2 --all-databases > all.sql全库一致性备份并记录位点(8.0.26 之前参数叫 --master-data=2)
mysqldump -uroot -p --single-transaction --databases shop > shop.sql单库备份(含 CREATE DATABASE)
mysqldump -uroot -p --no-data shop orders > orders.sql只备份表结构
mysqldump -uroot -p --single-transaction --where="id<1000000" shop orders > part.sql按条件备份部分数据
mysqldump -uroot -p --routines --triggers --events --all-databases带上存储过程、触发器、事件
mysql -uroot -p < all.sql恢复全备
xtrabackup --backup --user=root --password=xxx --target-dir=/backup/full物理全备
xtrabackup --prepare --target-dir=/backup/full应用 redo,让备份可恢复
xtrabackup --copy-back --target-dir=/backup/full拷回数据目录(需先停库并清空 datadir)
mysqlbinlog --start-datetime='2024-01-01 02:00:00' binlog.000001从指定时间开始解析 binlog 内容
mysqlbinlog binlog.000001 > /tmp/inc.sql导出 binlog 为 SQL 文件,方便检查后再回放
mysql -uroot -p < /tmp/inc.sql回放 binlog 做时间点恢复
PURGE BINARY LOGS BEFORE '2024-01-01 00:00:00';清理过期 binlog(别 rm)
SHOW BINARY LOGS;确认清理结果
# 备份 + 压缩 + 记录时间,一条命令
mysqldump -uroot -p'xxx' --single-transaction --source-data=2 \
--routines --triggers --events --all-databases \
| gzip > /backup/full_$(date +%F_%H%M).sql.gz

# 恢复时先解压再导入
gunzip < /backup/full_2024-01-01_0200.sql.gz | mysql -uroot -p
恢复前确认三件事
  1. 目标实例的版本与字符集跟备份源一致;
  2. gtid_purged 不会和现有 GTID 冲突(用 --set-gtid-purged=OFF 或重置实例);
  3. 备份文件校验过(md5sum、行数抽查),别拿一个截断的文件往下恢复。

复制管理​

命令说明
CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.0.0.11', SOURCE_USER='repl', SOURCE_PASSWORD='xxx', SOURCE_AUTO_POSITION=1;配置复制源(GTID 模式)
CHANGE MASTER TO ...旧语法,8.0.23 前使用;新版本仍兼容
START REPLICA; / STOP REPLICA;启停复制(旧语法 START SLAVE)
STOP REPLICA SQL_THREAD; / START REPLICA SQL_THREAD;只操作回放线程,IO 继续拉日志
SHOW REPLICA STATUS\G复制状态,重点看 Running 与延迟
SHOW REPLICA STATUS\G 中的 Retrieved_Gtid_Set / Executed_Gtid_Set已拉取 / 已执行的 GTID 集合
SHOW PROCESSLIST;主库上能看到每个从库的 dump 线程
RESET REPLICA ALL;清空复制配置(重建从库前用)
SET GLOBAL rpl_semi_sync_source_enabled = ON;开半同步(主库,需先装插件)
SELECT * FROM performance_schema.replication_applier_status_by_worker;并行复制各 worker 的回放状态
SELECT @@gtid_mode, @@enforce_gtid_consistency;确认 GTID 状态
-- 判断从库是否追平:两个集合相等就是追平
SHOW REPLICA STATUS\G
-- Retrieved_Gtid_Set: 3e11fa47-...:1-10523
-- Executed_Gtid_Set: 3e11fa47-...:1-10523

-- 从库看复制通道的连接状态(主库上查是空的)
SELECT CHANNEL_NAME, SERVICE_STATE, LAST_ERROR_MESSAGE
FROM performance_schema.replication_connection_status;
跳过一条报错事务
STOP REPLICA SQL_THREAD;
SET GTID_NEXT = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:100';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START REPLICA SQL_THREAD;

跳过之后主从数据就不一致了,务必记录跳过的 GTID 并安排校验修复。

诊断查询​

命令说明
SHOW GLOBAL STATUS LIKE 'Threads_connected';当前连接数
SHOW GLOBAL STATUS LIKE 'Threads_running';正在执行的线程数(比 connected 更能反映压力)
SHOW GLOBAL STATUS LIKE 'Max_used_connections';历史连接峰值
SHOW VARIABLES LIKE 'max_connections';连接上限
SHOW GLOBAL STATUS LIKE 'Questions';累计语句数,算 QPS 用
SHOW GLOBAL STATUS LIKE 'Com_commit';累计提交数,算 TPS 用
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';物理读次数,算命中率用
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';逻辑读次数
SHOW GLOBAL STATUS LIKE 'Slow_queries';累计慢查询数
SHOW VARIABLES LIKE 'slow_query_log%';慢日志开关与文件位置
SHOW VARIABLES LIKE 'long_query_time';慢查询阈值
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';锁等待超时秒数
SELECT * FROM information_schema.INNODB_TRX;当前所有事务(含长事务)
SELECT * FROM performance_schema.data_locks;当前持有的锁(8.0 替代 INNODB_LOCKS)
SELECT * FROM performance_schema.data_lock_waits;锁等待关系
SELECT * FROM sys.innodb_lock_waits;锁等待的人话版视图
SELECT * FROM sys.statement_analysis LIMIT 10;按耗时排 TOP SQL
SELECT * FROM sys.schema_unused_indexes;从未被使用的索引
SELECT * FROM sys.schema_redundant_indexes;冗余索引
KILL CONNECTION 12345;断开连接(8.0 语法,KILL QUERY 只终止语句)
EXPLAIN SELECT ...;看执行计划
EXPLAIN ANALYZE SELECT ...;实际执行并给出真实耗时(8.0.18+)
ANALYZE TABLE orders;刷新统计信息,修执行计划跑偏
OPTIMIZE TABLE orders;重建表回收碎片(大表用 gh-ost)
SHOW WARNINGS;上一条语句的警告,排查隐式转换很有用
-- 一条 SQL 看全实例健康度
SELECT
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Threads_connected') AS conn,
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Threads_running') AS running,
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Slow_queries') AS slow_total,
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Uptime') AS uptime_sec;

-- 找长事务(超过 60 秒)
SELECT trx_id, trx_state,
TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS seconds,
trx_rows_locked, trx_rows_modified, LEFT(trx_query, 80) AS sql_head
FROM information_schema.INNODB_TRX
WHERE TIMESTAMPDIFF(SECOND, trx_started, NOW()) > 60
ORDER BY seconds DESC;
别在生产随便跑这些

OPTIMIZE TABLE、ANALYZE TABLE、CHECK TABLE 在大表上都会带来真实的 IO 压力,OPTIMIZE 还会锁表。诊断类命令里,EXPLAIN ANALYZE 会真正执行 SQL,SELECT COUNT(*) 在大表上也是全扫。执行前先想清楚代价。