FLUSH 与 RESET 语句
导学
修改了用户权限但新权限没生效?更新了表结构但查询缓存还返回旧数据?需要清空慢查询日志重新统计?FLUSH 和 RESET 是 MySQL 运维的"刷新按钮"和"重置开关"——前者让 MySQL 重新加载内存中的各种缓存和状态,后者直接清空日志和统计信息。掌握这两个语句,是日常运维和故障排查的基本功。
定义
FLUSH:重新加载或清空 MySQL 服务器内部的各种缓存(表缓存、权限缓存、日志、查询缓存等),使最新更改立即生效。RESET:清空并重置各种日志文件和复制状态,比 FLUSH 更彻底,通常用于初始化或故障恢复。
核心语法
FLUSH 语句
-- 刷新表缓存(关闭所有打开的表)
FLUSH TABLES;
FLUSH TABLES table_name1, table_name2; -- 只刷新指定表
FLUSH TABLES WITH READ LOCK; -- 刷新并加全局读锁(备份用)
-- 重新加载权限表(GRANT/REVOKE 后立即生效)
FLUSH PRIVILEGES;
-- 切换日志文件(关闭当前日志,打开新日志文件)
FLUSH LOGS;
FLUSH BINARY LOGS; -- 只切换 binlog
FLUSH ERROR LOGS; -- 只切换 error log
-- 清空查询缓存(MySQL 5.7 中查询缓存已废弃,但语法仍可用)
FLUSH QUERY CACHE; -- 整理查询缓存(不删除数据)
RESET QUERY CACHE; -- 清空查询缓存
-- 清空主机缓存(解除被阻塞的主机)
FLUSH HOSTS;
-- 刷新状态变量(将部分状态重置为 0)
FLUSH STATUS;
RESET 语句
-- 清空所有 binlog 文件,重置 binlog 索引(主库慎用!)
RESET MASTER;
-- 重置从库复制状态(清空 relay log,重置复制位置)
RESET SLAVE [ALL];
-- 清空查询缓存
RESET QUERY CACHE;
SQL 示例
场景一:修改权限后刷新生效
执行语句:
-- 1. 创建新用户并授权
CREATE USER 'app_read'@'%' IDENTIFIED BY 'password123';
GRANT SELECT ON company.* TO 'app_read'@'%';
-- 2. 立即刷新权限(否则新连接可能看不到最新权限)
FLUSH PRIVILEGES;
结果解读:
- MySQL 启动时将权限表加载到内存,后续
GRANT/REVOKE/CREATE USER等语句会自动更新内存中的权限缓存 - 但直接修改权限表(如
UPDATE mysql.user SET ...)不会自动生效,必须执行FLUSH PRIVILEGES - 生产环境中,权限变更后执行
FLUSH PRIVILEGES是良好习惯,确保所有新连接立即获得最新权限 - 已有连接不受
FLUSH PRIVILEGES影响(它们的权限在连接建立时已确定)
场景二:备份前加全局读锁(FLUSH TABLES WITH READ LOCK)
执行语句:
-- 1. 刷新所有表并加全局读锁(FTWRL)
FLUSH TABLES WITH READ LOCK;
-- 2. 查看当前 binlog 位置(用于 point-in-time 恢复)
SHOW MASTER STATUS;
操作后结果:
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
|---|---|---|---|
| mysql-bin.000005 | 154 |
-- 3. 执行备份(如 mysqldump 或复制数据文件)
-- mysqldump -u root -p --all-databases > backup.sql
-- 4. 备份完成后解锁
UNLOCK TABLES;
结果解读:
FLUSH TABLES WITH READ LOCK(FTWRL)做三件事:1. 关闭所有打开的表;2. 刷新表缓存;3. 加全局读锁(阻塞所有写操作)- 这是一致性逻辑备份的标准前置操作,确保备份期间没有数据变更
SHOW MASTER STATUS在锁期间执行,记录精确的 binlog 位置,用于后续搭建从库或 point-in-time 恢复- 备份完成后必须
UNLOCK TABLES,否则写操作一直被阻塞 - InnoDB 的
--single-transaction备份不需要 FTWRL,但对 MyISAM 或混合引擎备份仍需使用
场景三:切换日志文件
执行语句:
-- 查看当前 binlog 文件
SHOW BINARY LOGS;
操作前结果:
| Log_name | File_size |
|---|---|
| mysql-bin.000005 | 1073741824 |
| mysql-bin.000006 | 524288000 |
-- 切换 binlog,关闭当前文件,开启新文件
FLUSH BINARY LOGS;
-- 查看切换后的 binlog
SHOW BINARY LOGS;
操作后结果:
| Log_name | File_size |
|---|---|
| mysql-bin.000005 | 1073741824 |
| mysql-bin.000006 | 524288000 |
| mysql-bin.000007 | 154 |
结果解读:
FLUSH BINARY LOGS(或FLUSH LOGS)关闭当前 binlog 文件,创建新的 binlog 文件- 常用于:1. 手动归档 binlog(切换后安全复制旧文件);2. 清理前确保当前事务已写入;3. 配合
PURGE BINARY LOGS管理磁盘空间 FLUSH ERROR LOGS同理,关闭并重开 error log 文件(配合日志切割工具如 logrotate)
场景四:清空主机缓存(解除连接失败阻塞)
执行语句:
-- 查看当前被阻塞的主机
SELECT * FROM performance_schema.host_cache\G
-- 清空主机缓存(解除因连接失败过多被阻塞的 IP)
FLUSH HOSTS;
结果解读:
- MySQL 会缓存客户端主机的连接信息(包括失败次数),如果某 IP 连接失败超过
max_connect_errors次,会被永久阻塞(报错Host 'xxx' is blocked) FLUSH HOSTS清空这个缓存,解除所有被阻塞的主机- 也可以调高
max_connect_errors减少误阻塞,或使用host_cache_size控制缓存大小
场景五:RESET MASTER(清空 binlog,主库慎用)
执行语句:
-- 查看当前 binlog
SHOW BINARY LOGS;
操作前结果:
| Log_name | File_size |
|---|---|
| mysql-bin.000001 | 154 |
| mysql-bin.000002 | 1234 |
| mysql-bin.000003 | 5678 |
-- 清空所有 binlog,重置索引(危险操作!)
RESET MASTER;
-- 查看结果
SHOW BINARY LOGS;
操作后结果:
Empty set (0.00 sec)
SHOW MASTER STATUS;
| File | Position |
|---|---|
| mysql-bin.000001 | 154 |
结果解读:
RESET MASTER删除所有 binlog 文件,重置 binlog 索引,从mysql-bin.000001重新开始- 主库执行会导致所有从库复制中断(从库记录的 binlog 位置对应的文件已不存在)
- 适用场景:1. 初始化测试环境;2. 主从切换后清理旧主库的 binlog;3. 确定不再需要 binlog 进行恢复时
- 执行前必须确认:没有从库依赖这些 binlog、不需要 point-in-time 恢复
场景六:RESET SLAVE(重置从库复制状态)
执行语句:
-- 停止复制
STOP SLAVE;
-- 重置从库状态(清空 relay log,重置复制位置)
RESET SLAVE;
-- 或彻底重置(清除 master.info 和 relay-log.info)
RESET SLAVE ALL;
-- 查看状态
SHOW SLAVE STATUS\G
操作后结果:
SHOW SLAVE STATUS 关键字段:
| 字段 | 值 |
|---|---|
| Master_Host | |
| Master_User | |
| Master_Log_File | |
| Read_Master_Log_Pos | 0 |
| Relay_Log_File | |
| Relay_Log_Pos | 0 |
结果解读:
RESET SLAVE停止复制,清空 relay log 文件,重置 SQL 线程和 I/O 线程位置RESET SLAVE ALL额外删除master.info和relay-log.info中的连接信息(Master_Host、Master_User等)- 适用场景:1. 从库需要重新配置复制(
CHANGE MASTER TO之前);2. 清理故障从库的混乱状态;3. 从库提升为主库后清理旧复制配置 - 执行后需要重新
CHANGE MASTER TO才能启动复制
常见误区
| 误区 | 正解 |
|---|---|
"FLUSH PRIVILEGES 每次 GRANT 后都必须执行" | 不是。GRANT/REVOKE/CREATE USER 等语句会自动刷新权限缓存。只有直接修改权限表(如 UPDATE mysql.user)后才需要手动 FLUSH PRIVILEGES。 |
"FLUSH TABLES 会关闭所有连接" | 不会。FLUSH TABLES 只关闭表文件句柄和清空表缓存,不影响客户端连接。 |
"FLUSH TABLES WITH READ LOCK 只锁表不锁库" | 不是。FTWRL 是全局读锁,阻塞所有会话的写操作(INSERT/UPDATE/DELETE/ALTER 等),直到 UNLOCK TABLES。 |
"RESET MASTER 和 FLUSH BINARY LOGS 一样" | 不一样。FLUSH BINARY LOGS 只是切换日志文件(旧文件保留);RESET MASTER 删除所有 binlog 文件,重置索引,数据永久丢失。 |
"RESET SLAVE 会删除从库数据" | 不会。RESET SLAVE 只清理复制状态(relay log、复制位置、连接信息),不触碰从库的实际数据表。 |
"FLUSH QUERY CACHE 在 5.7 很有用" | 不是。MySQL 5.7 中查询缓存(Query Cache)已默认禁用且官方建议不使用(8.0 已移除)。FLUSH QUERY CACHE 基本无用。 |
面试考点
Q:FLUSH PRIVILEGES 什么时候需要执行?
只有直接修改权限表(如
UPDATE mysql.user SET ...)后才需要手动执行。GRANT/REVOKE/CREATE USER等语句会自动刷新权限缓存。已有连接的权限在连接建立时已确定,不受FLUSH PRIVILEGES影响。
Q:FLUSH TABLES WITH READ LOCK 的作用和风险?
FTWRL 关闭所有表缓存并加全局读锁,阻塞所有写操作。用于一致性备份(配合
SHOW MASTER STATUS记录 binlog 位置)。风险:1. 写操作被阻塞,业务受影响;2. 如果持有锁的会话断开,锁自动释放;3. 长事务持有锁会导致大量写操作堆积。InnoDB 备份优先用--single-transaction避免 FTWRL。
Q:RESET MASTER 和 PURGE BINARY LOGS 的区别?
RESET MASTER删除所有 binlog 文件,重置索引,从mysql-bin.000001重新开始,主库执行会导致从库复制中断。PURGE BINARY LOGS TO 'xxx'或BEFORE 'date'只删除指定范围之前的 binlog,保留最近的文件,不影响正在运行的复制。清理 binlog 优先用PURGE,RESET MASTER只在初始化或确定不再需要任何 binlog 时使用。
Q:FLUSH LOGS 和日志切割(logrotate)的关系?
FLUSH LOGS(或FLUSH ERROR LOGS/FLUSH BINARY LOGS)关闭当前日志文件并打开新文件。配合 Linuxlogrotate工具时,logrotate 重命名日志文件后发送kill -HUP给 mysqld 或执行mysqladmin flush-logs,触发 MySQL 重新打开日志文件,实现日志切割而不中断服务。
Q:FLUSH HOSTS 解决什么问题?
某客户端 IP 因连接失败次数超过
max_connect_errors被 MySQL 永久阻塞(报错Host 'xxx' is blocked)。FLUSH HOSTS清空主机缓存,解除所有被阻塞的 IP。根本解决应排查连接失败原因(密码错误、网络问题、连接数耗尽),或调高max_connect_errors。
小结
FLUSH是"刷新":重新加载缓存、切换日志、清空缓存,使最新更改生效FLUSH PRIVILEGES在直接修改权限表后执行;GRANT/REVOKE自动刷新FLUSH TABLES WITH READ LOCK是全局读锁,用于一致性备份,备份完必须UNLOCK TABLESFLUSH BINARY LOGS切换 binlog 文件,用于归档和日志管理RESET MASTER删除所有 binlog(主库慎用),RESET SLAVE重置从库复制状态FLUSH HOSTS解除因连接失败过多被阻塞的客户端 IP
下一章引子:FLUSH 和 RESET 是运维层面的工具,而日常开发中最常接触的还是 SQL 本身。回顾整个 MySQL 5.7 教程体系,从基础查询到高级优化,从单机事务到主从复制,从字符编码到性能诊断——你已经掌握了 MySQL 5.7 的核心知识体系。