在MySQL数据库中,在进行 数据迁移 和 从库 只读状态设置 时,都会涉及到 只读状态 和 Master-Slave 主从关系设置, 以下针对 real_only 只读属性 做些笔记记录:

1) 对于 MySQL 单实例数据库 和 master 库,如果需要设置为只读状态,需要进行如下操作和设置:
将 MySQL 设置为只读状态的命令(可以登录 mysql 执行下面命令, 或者在 my.cnf 配置文件中添加 "read_only=1" ,然后重启mysql服务):

mysql> show global variables like "%read_only%";
mysql> flush tables with read lock;
mysql> set global read_only=1;
mysql> show global variables like "%read_only%";

将MySQL从只读状态设置为读写状态的命令:

mysql> unlock tables;
mysql> set global read_only=0;

 

2) 对于需要保证 master-slave 主从同步的 salve 库
将 slave从库 设置为 只读状态,需要执行的命令为  (下面命令中的1 也可以写成 on):

mysql> set global read_only=1;

将 salve 库从 只读状态 变为 读写状态,需要执行的命令是:

mysql> set global read_only=0;

对于Mysql数据库读写状态,主要靠 "read_only" 全局参数来设定;

默认情况下, 数据库是用于读写操作的,所以 read_only 参数也是 0 或 faluse 状态,

这时候不论是本地用户还是远程访问数据库的用户,都可以进行读写操作;

如需设置为只读状态,将该 read_only 参数设置为 1 或 TRUE 状态,但设置 read_only=1 状态有两个需要注意的地方:
1) read_only=1 只读模式,不会影响 slave 同步复制的功能,所以在 MySQL slave 库中设定了 read_only=1 后,

通过 "show slave status\G" 命令查看salve状态,可以看到 salve 仍然会读取 master 上的日志,并且在 slave 库中应用日志,保证主从数据库同步一致;
2) read_only=1 只读模式,限定的是普通用户进行数据修改的操作,但不会限定具有super权限的用户的数据修改操作

(但是如果设置了" super_read_only=on ", 则就会限定具有 super 权限的用户的数据修改操作了);

在MySQL中设置 read_only=1 后,普通的应用用户进行 insert、update、delete 等会产生数据变化的 DML 操作时,

都会报出数据库处于只读模式不能发生数据变化的错误,

但具有super权限的用户,例如在本地或远程通过root用户登录到数据库,还是可以进行数据变化的DML操作;

(也就是说" real_only "只会禁止普通用户权限的 mysql 写操作,不能限制 super 权限用户的写操作;

如果要想连 super 权限用户的写操作也禁止,就使用" flush tables with read lock; ",这样设置也会阻止主从同步复制!)

 

锁表操作
为了确保所有用户,包括具有 super 权限的用户也不能进行读写操作,就需要执行给所有的表加读锁的命令 "flush tables with read lock;",

这样使用具有super权限的用户登录数据库,想要发生数据变化的操作时,也会提示表被锁定不能修改的报错。

这样通过设置" read_only=1 "和" flush tables with read lock; "两条命令,就可以确保数据库处于只读模式,不会发生任何数据改变,

在MySQL进行数据库迁移时,限定 master 主库不能有任何数据变化,就可以通过这种方式来设定。

但同时由于加表锁的命令对数据库表限定非常严格,

如果再 slave 从库上执行这个命令后,slave 库可以从 master 读取binlog日志,但不能够应用日志,slave库不能发生数据改变,当然也不能够实现主从同步了,

这时如果使用 " unlock tables; " 解除全局的表读锁,slave 就会应用从 master 读取到的 binlog 日志,继续保证主从库数据库一致同步。

为了保证主从同步可以一直进行,在 slave 库上要保证具有 super 权限的 root 等用户只能在本地登录,不会发生数据变化,

其他远程连接的应用用户只按需分配为 select,insert,update,delete 等权限,保证没有 super 权限,

show grants for admin@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER,
SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, 
SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'admin'@'%';

show grants for canal@'%';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';

show grants for root@'%';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

则只需要将 salve 设定" read_only=1 "模式,即可保证主从同步,又可以实现从库只读。

相对的,设定" read_only=1 "只读模式开启的解锁命令为设定" read_only=0 ";

设定全局锁 " flush tables with read lock; ",对应的解锁模式命令为:"unlock tables;".

当然设定了 read_only=1 后,所有的 select 查询操作都是可以正常进行的。

show grants for ytt2@'localhost';
GRANT INSERT, UPDATE, DELETE, CREATE, ALTER, SUPER ON *.* TO ytt2@localhost;

动态权限就是对 SUPER 权限的细分。 SUPER 权限在未来将会被废弃掉。
现在只想这个用户有 SUPER 的子集,设置变量的权限。
单独赋予用户 两个能设置系统变量的 动态权限,完了把 SUPER 拿掉。 

mysql> grant session_variables_admin,system_variables_admin on *.* to ytt2@'localhost';
mysql> revoke super on *.* from ytt2@'localhost'; 
mysql> show warnings; 

我们看到这个 WARNINGS 提示 SUPER 已经废弃了。