OneSQL :: 利用限制登录模式,进行更顺利的主备切换,或保护故障现场!

MySQL简单可靠的逻辑复制功能可以让你快速搭建可以读写的备库,并可以让应用同时连接到主库和备库做读写分离,以提升以提升系统处理能力,也可以在单个MySQL节点发生故障时,利用DNS或虚拟IP机制,进行快速的切换。但在非常重要的业务场景(比如库存处理、资金处理)下,可能并不允许太过于灵活的切换,比如绝对不允许应用程序同时更新主库和备库(指一部份应用节点还连在主库,另一部份应用节点连到和备库,然后同时发生了业务交易),以避免数据不一致的情况。在这种关键业务场景下,应当如何来进行顺利的主备切换呢?初步一想,觉得可以有以下几种方式:

  1. 更改数据库的端口并重起,以防应用同时连接到主备?
  2. 修改DNS映射表,以便让应用连接到新的主库?
  3. 发送一个动态变更通知,让所有的应用连接到新的IP地址?
  4. 使用一个虚拟IP地址来做高可用切换?

如果有超过100台应用服务器连接到同一台MySQL服务器,并且业务很关键,容不得半点数据不一致的场景,如何来进行一次顺序的主备切换维护操作?使用Oracle数据库时,从来不需要考虑这么多的事情,因为同一时间点,只能接连主库,备库要么处于应用不可连接的状态,或者是处于不可写入的只读状态。 Oracle主备切换的第一步是将原来的主库切换为备库模式,这时主备都不能连接;第二步是检查备库是否完全跟上主库,即是否收到完整的主库的日志;第三步是将备库切换成主库并做相应的DNS修改。

可以看到,在整个过程中应用不会发生双乱写的情况,所以不用担心数据一致性问题,要做到这一点,就需要在MySQL里实现同样的机制,在任何一个时间点,只有一台MySQL能被应用程序连接。为此平民软件在OneSQL中引入了限制登录模式,可以有三种状态:

  1. Root模式:只有Root用户能连接到数据库,可以用来故障时进行现场保护,或者开放服务前进行预处理工具。
  2. 复制模式:允许Root用户和复制管理账号连接数据库,其他应用程序不能连接,相当于是Oracle的备库模式。
  3. 工作模式:允许所有用户连接MySQL数据库。

几种不同模式可以通过动态更改参数“tcc_login_restrict_mode”的值来进行切换:

mysql> show variables like 'tcc_login%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| tcc_login_restrict_mode | 0     |
+-------------------------+-------+
1 row in set (0.00 sec)

可以有三个值可以选择,如下所示:

  1. 值“0”表示工作模式。
  2. 值“1”表示复制模式。
  3. 值“2”表示root模式。

从正式模式切换到复制模式、或root模式时,当前的应用连接会在处理完当前事务后,自动退出。当应用偿试登录处于root模式或复制模式的MySQL里,会得到如下错误,相当于是提供了不准确的密码:

[root@osd3 onesql5.6]# bin/mysql -u test -p --socket=/tmp/mysql2.sock
Enter password:
ERROR 1045 (28000): Access denied for user 'test'@'localhost' .....

当我们再来思考OneSQL的主备切换时,步骤就更加清晰了。第一步,先将OneSQL的主库切换到复制模式,这时应用的连接会陆续断开;第二步,确保原主库上没有任何应用过的的连接,如果还有可以进行处理,然后检查主备是否处于一致的状态;第三步,将从库切换成工作模式,准备应用程序连接。在整个过程中,应用不可能同时连接主备两个数据库,并且切换的过程中不涉及MySQL 的重起,从而非常易于自动化。

针对最前面列出的机制,更改端口进行重起,比较耗时,操作也比较复杂,需要更改备库的Master信息以完后最后的日志同步,不是最好的方案;单纯使用DNS并不能保证所有应用节点的DNS缓存都已经更新,会很容易发生两边双写的情况;变更应用的连接信息,需要有一个统一的配置中心,同样存在配置无法同时达到应用的可能性;基于HA机制的虚拟IP只能用于同同网段的主备切换。结合OneSQL的限制登录模式,就可以让切换变得更加简单、可靠。