mysql主从复制中如何设置只读权限与数据访问控制

来源:这里教程网 时间:2026-02-28 20:45:18 作者:

MySQL 从库设置
read_only=1
是最基础的只读保障

主从架构中,从库默认不禁止写入,人为或应用误连从库执行

UPDATE
/
DELETE
/
INSERT
会导致数据漂移,破坏复制一致性。必须显式启用
read_only
系统变量。

在从库的

my.cnf
中添加:

[mysqld]
read_only = 1

重启 MySQL 或动态生效(需 SUPER 权限):

SET GLOBAL read_only = ON;

注意:

read_only
不影响 SUPER 用户,所以务必同时限制高权限账号访问从库;它也不阻止 SQL 线程自身写入(即复制操作仍可进行),这是设计预期。

禁止 SUPER 用户在从库写入:用
super_read_only
补漏

read_only
对 SUPER 用户无效,而运维脚本、备份工具或 DBA 临时连接常带 SUPER 权限,容易绕过只读限制。MySQL 5.7+ 提供
super_read_only
变量,开启后连 SUPER 用户也无法写入(除 SQL 线程外)。

启用方式(动态优先,避免重启):

SET GLOBAL super_read_only = ON;

该变量依赖

read_only=ON
,若后者为 OFF,则
super_read_only
设为 ON 会自动把
read_only
拉起。生产环境建议两者都设,并写入配置文件:

[mysqld]
read_only = 1
super_read_only = 1

检查是否生效:

SELECT @@read_only, @@super_read_only;

返回均为

1
才算真正锁死写入通道。

用账号权限控制替代“全库只读”,更精准

仅靠

read_only
是实例级防护,无法区分业务角色。应配合账号粒度授权,例如让报表用户只能查特定库表:

创建专用只读账号:
CREATE USER 'reporter'@'%' IDENTIFIED BY 'pwd123';
仅授予
SELECT
权限(不含
INSERT
/
UPDATE
/
DELETE
/
CREATE
等):
GRANT SELECT ON `sales_db`.* TO 'reporter'@'%';
刷新权限:
FLUSH PRIVILEGES;

关键点:

read_only
和账号权限是正交机制——前者防误操作,后者控访问边界。即使某账号有 SUPER 权限,只要没显式授权写权限,日常查询仍受
GRANT
约束;而
super_read_only=ON
则进一步堵住 SUPER 的写入口。

验证只读是否真实生效:别只信配置文件

配置写完不等于生效,常见疏漏包括:变量未全局设置、配置文件加载错误、MySQL 版本不支持

super_read_only
(如 5.6)、或被启动脚本覆盖。

上线前务必实测:

用普通账号尝试写:
INSERT INTO test.t1 VALUES (1); → 应报错 ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
用 root/SUPER 账号尝试写:
UPDATE test.t1 SET id=2 WHERE id=1; → 若 <code>super_read_only=OFF</code>,此操作会成功,立即破坏一致性
检查复制线程是否仍在运行:
SHOW SLAVE STATUS\G
Slave_SQL_Running: Yes
Seconds_Behind_Master
非持续增长,说明只读未干扰复制本身

最容易被忽略的是:某些中间件(如 ProxySQL、ShardingSphere)或 ORM 连接池会复用连接并缓存权限状态,修改权限后需重启连接池或触发连接重建,否则旧连接仍可能持有旧权限上下文。

相关推荐