mha_switch: 结合 proxysql 和 MHA 切换 MySQL 主从

By | November 18, 2017

mha_switch: 结合 proxysql 和 MHA 切换 MySQL 主从

在之前的文章proxysql 介绍及测试使用中, 详细介绍了 proxysql 的安装配置等, 不过经过时间的推移, proxysql 工具做了很多的改进, 自动检测及状态切换等功能带给我们很大的便利, 可以取代传统的 haproxy 代理, 不过由于 proxysql 的检测和状态切换机制不是实时进行, 只是间接性检测, 所以会带来了另外的困扰, 如何与已有的工具如MHA更好的结合以保证数据的一致性.

功能介绍

mha_switch 通过在自定义的脚本中加入 proxysql 检测和切换的功能比较方便的实现了 MHA 和 proxysql 之间的配合使用. mha_switch 主要实现以下功能:

解析 masterha-script.cnf 的实例配置信息;
切换 vip 信息(可选, 如果实例通过 vip 对外服务);
block/release 数据库用户;
prxoysql 切换;

配置说明

自定义脚本读取 masterha-script.cnf 文件获取主从实例和 proxysql 的配置信息, 如下所示:

10.0.21.7:3308 10.0.21.17:3308
   vip 10.0.21.97   
   block_user ^percona$|^proxysqlmon$
   block_host ^10\.0\.21\.%$
   proxysql admin2:admin2@10.0.21.5:6032:w1:r2,admin2:admin2@10.0.21.7:6032:w1:r2

10.0.21.7:3308 10.0.21.17:3308 是主从的 ip:port 信息, 如果有一主多从, 所有的 ip:port 都需要写到这里; vip 10.0.21.97 表示 master 以 vip 形式对外服务, MHA 在切换的时候也会将 vip 切到新的 master 中, 这种方式只需要程序有重连机制即可, 不需要每次切换的时候都要改一遍程序的数据库连接配置; block_userblcok_host 是需要对老 master 中进行密码反转的用户信息, 反转密码是很方便且有效的方式, 杜绝切换的时候新的连接进来, 为数据一致性加了一层防护; proxysql 是主从前面的 proysql 信息, 多个 proxysql 以逗号分开, 上面的意思大致为: 以用户名 admin2, 密码 admin2 连接 proxysql(10.0.21.5:6032), 该实例对应的写组是1, 读组是 2, MHA 切换的时候会对这两个组进行操作.

如何使用

How to use 说明了如何使用. 不过需要注意以下几点:

1. 如果要切换的 master 是存活状态, 即 --master_state=alive, 可以指定 --orig_master_is_new_slave 选项自动 change master, 不过该功能需要 MHA 0.56 版本;
2. 如果要切换的 master 是非活状态, 即 --master_state=dead, 则 MHA 直接调用 master_ip_failover 脚本, 不对对 proxysql 进行 readonly 操作;
3. 如果对 proxysql 做了主备部署或多点部署, 需要在 masterha-script.cnf 配置中增加所有的 proxysql 信息, 以逗号分隔开;
4. 脚本在更新 proxysql 的时候, 删除了相关的复制组, 禁止了 proxysql 的自动更新;

其它问题

反转密码问题

为了支持 --orig_master_is_new_slave, 对老的 master 增加了密码转回过程, 该过程放到了stop vip 过程之后(没有 vip 则在 kill 所有连接的线程之后) , 所以从这点看, 如果主从没有使用 vip, 转回密码后可能还是有程序连接进来, 不过已经设置了 read_only, 不会接受写操作.

proxysql 监控 read_only 变量自动识别主从, 为什么还要在 MHA 中操作

proxysql 是间接性检测 read_only 变量, 并不是实时检测, monitor_read_only_interval 参数指定检查 read_only 的时间间隔, 单位毫秒. 稍微有点量的MySQL实例, 一秒就能有好几千的qps 操作, 从这方面来看 proxysql 自身的 read_only 检查我觉得是会遗漏一些更新的, 比如已经切换的主, 这时候老的主就是 master, proxysql 还没检查到 read_only 变更, 就会把 sql 转发到老的主, 这个时候程序就会报 read only 相关的错误. 当然这种情况只是出现一些更新错误, 程序如果有机制补数据的话就没什么大的问题. 另外我个人觉得 proxysqlread_only 检测机制更适合主挂掉, 从成为新的主的情况, 并不适合主从互相切换的场景.

10 thoughts on “mha_switch: 结合 proxysql 和 MHA 切换 MySQL 主从

  1. dikang123

    请问反转密码是什么意思?不是很明白,我理解是不是修改业务用户的密码?

    Reply
  2. arstercz Post author

    切换主从的时候, 仅设置 read_only 并不能阻止应用程序连接数据库, 因此为了不让程序继续连接老的 master 增加了反转密码功能, 反转密码是为了临时禁制用户的连接, 这种方式是最无害的, 也不会影响用户的权限, 参考: http://code.openark.org/blog/mysql/blocking-user-accounts

    密码反转功能已经合并到了 MHA 0.56 版本里面. 见 DBHelper.pm block_user_regexp, release_user_regexp 函数.

    Reply
    1. dikang123

      MHA官方github仓库里面的master_ip_online_change好像并没有用到这个密码反转,可能只是个示例代码,它切换的时候是建议直接drop user的:
      ## Gracefully killing connections on the current master
      # 1. Set read_only= 1 on the new master
      # 2. DROP USER so that no app user can establish new connections
      # 3. Set read_only= 1 on the current master
      # 4. Kill current queries
      # * Any database access failure will result in script die.

      Reply
      1. arstercz Post author

        反转密码是我们自己增加的功能, 合并到了 MHA 仓库里;
        直接 drop user 后, 老的主恢复成新的slave后还得增加 user, 没有直接反转密码方便;
        如果不想用反转密码功能, 可以在配置里的 block_user 和 block_host 两个选项留空.

        Reply
        1. dikang123

          反转密码的过程如果写入到binlog里面,会不会导致主从同步失败?

          Reply
          1. arstercz Post author

            对老 master 的所有操作之前肯定都要关掉 sql_log_bin;
            和你们使用 drop user 一个道理, drop user 写到 binlog 影响岂不是更大?

  3. dikang123

    有个问题哈,这个密码反转不支持5.7额?

    Reply
    1. dikang123

      解决了,改了一行,MySQL 5.7之后没有user表没有password字段了,改成authentication_string 字段了
      use constant Select_User_Regexp_SQL =>
      “SELECT user, host, authentication_string AS password FROM mysql.user WHERE user REGEXP ? AND host REGEXP ?”;

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *