zoukankan      html  css  js  c++  java
  • Keepalived + MySQLfailover + GTIDs 高可用

    架构图

        10.1.1.207    mysql master + keepalived
        10.1.1.206    mysql slave ( backup master ) + keepalived
        10.1.1.208    mysql slave
        10.1.1.210    mysqlfailover ( monitor )
        10.1.1.211    VIP
     
    keepalive

     

    配置基于GTIDs的主从

    本实验在GTIDs主从的基础上进行,GTIDs配置步骤省略。但不懂的可以参考如下步骤配置 比较简单
    1. 修改Master配置文件
    2. 启动所有MySQL
        -- 先启动Master 再启动slave
        service mysql start
     
     3.配置slave
        -- slave下执行

    开启master与备用master之间的主从半同步

    -- 情景
            大家都知道,mysql5.7以前的主从经常会发生延迟(据说5.7彻底解决了主从延迟),试想一下,如果master故障了,要升slave(备用master)为master,但此slave的数据严重延迟于master,甚至是连binlog都还没读过来的那种。那么此时如果数据往这个新master上写,数据肯定会出现混乱。这可是悲剧大事。解决方法如下
    -- MySQL半同步复制

      开启半同步后,在master提交一个写事务之后,master会block这个事务,直到备用master确认已经接受到了该复制事件,这时master才向应用程序确认提交成功。否则超时中断半同步,直到重新满足条件开启。

    在master提交事务之后,而slave未来得及接收复制事件,这时候master crash的话,应用程序会切换到slave上,并重新发起事务,这正好是我们所需要的,满足高可用的初衷。但是这里存在一个缺陷,那就是在master恢复之后,原来的事务已经提交,这时候复制会出现问题。

    解决办法:在原来的master恢复之后数据重做(推荐),或者跳过重复数据错误。

     
    -- 模块默认在MYSQL_INSTALL_PATH/lib/plugin/semisync*.so
     
    1. 在master与备用master上开启半同步
    -- 安装半同步模块和临时开启半同步 -- 在master与备用master上操作
    -- 在master上启用半同步

    (rpl_semi_sync_master_timeout=1000)表示主库在某次事务中,如果等待时间超过1000毫秒,那么则降级为普通模式,不再等待备库。如果主库再次探测到,备库恢复了,则会自动再次回到Semi-sync状态。建议把半同步跑在高速网络环境中
    -- 在备用master上启用半同步
    -- 修改 master与备用master 配置文件 下次启动生效
    -- 查看半同步状态

    安装配置MySQLfailover  

    在monitor监控机上
    -- 安装 使用mysql官方yum源安装
    yum install -y mysql-utilities.noarch                               -- 安装mysqlfailover
    yum install -y mysql                                                         -- 安装mysql客户端
    -- 在所有mysql上给mysqlfailover监控机授权 -- 在master上操作即可 因为会自动同步
    -- 修改所有mysql配置
    -- 把备用master和其他slave的mysql设置为read_only  防止后面使用到的keepalived误漂移或其他误操作导致数据写错地方 强大mha套件也是这样做的
    vim /etc/my.cnf
    添加以下配置
    read_only=1                                                            -- mysql只读
    -- 重启所有mysql 由于有些参数为只读(report_host) 所以只能修改配置文件并重启mysql
    mysqladmin -predhat shutdown
    service mysqld start
    -- 确认slave_master_info的表引擎为innodb
    mysql> show create table slave_master_info;
    ENGINE=InnoDB                                                                -- 若此表引擎不为innodb请修改表引擎

    配置MySQLfailover

    -- 授权 把主从帐号权限精确到登录IP (用IP范围的话在failover时会自动创建用户,下一次failover时就会卡住 切换失败)

    -------------------------------- 主从帐号权限没有精确到IP会出现的错误 -----------------------------------------------------------------------------
    Q-quit R-refresh H-health G-GTID Lists U-UUIDs
    Failed to reconnect to the master after 3 attemps.
    Failover starting in 'auto' mode...
    Replication user not found but --force used.                                    -- 如果主从帐号权限是用IP范围 就会出现这样的错误 找不到主从帐号
    # Candidate slave 10.1.1.206:3306 will become the new master.
    # Checking slaves status (before failover).
    # Preparing candidate for failover.
    # Creating replication user if it does not exist.
    # ERROR: ERROR: Cannot grant replication slave to replication user.        -- 提示用户问题 本次切换会成功 但下一次切换就会卡住 失败
    # Stopping slaves.
    # Performing STOP on all slaves.
    # Switching slaves to new master.
    # Disconnecting new master as slave.
    # Starting slaves.
    # Performing START on all slaves.
    # Checking slaves for errors.
    # Failover complete.
     
    Failover console will restart in 5 seconds.
    -- 编写脚本
    -- 编写failover后执行的辅助脚本 在monitor监控机上操作
    -- 启动监控
    启动界面状态 -------------------------------------------------------------------------------------------

    模拟故障

    -- 把10.1.1.207 master 关掉
    mysqladmin -predhat shutdown
     monitor 监控机切换过程显示--------------------------------------------------------------------------------------
    Q-quit R-refresh H-health G-GTID Lists U-UUIDs L-log entries
    Failed to reconnect to the master after 3 attemps.                                     -- 检测到master挂掉
    Failover starting in 'auto' mode...
    # Candidate slave 10.1.1.206:3306 will become the new master.                -- 升候选者10.1.1.206为新master
    # Checking slaves status (before failover).
    # Preparing candidate for failover.
    # Creating replication user if it does not exist.
    # Spawning external script.
    # Script completed Ok.                                                                                    -- failover前脚本执行成功
    # Stopping slaves.
    # Performing STOP on all slaves.
    # Switching slaves to new master.
    # Disconnecting new master as slave.
    # Starting slaves.
    # Performing START on all slaves.
    # Spawning external script.
    # Script completed Ok.                                                                                    -- failover后脚本执行成功
    # Checking slaves for errors.
    # Failover complete.
     
    Failover console will restart in 5 seconds.
     切换完成后显示 --------------------------------------------------------------------------------------------------------
    -- 查看新master的状态
    -- 查看slave 10.1.1.208的状态
    mysql> show slave statusG;
                      Master_Host: 10.1.1.206                                            -- 已成功切换为206的slave
    -- 恢复原master 并成为新master的从
    -- 重新启动监控 为下一次切换做准备 切记更换命令里主和从的IP
    -- 先按shift + q 退出监控
    mysqlfailover --master=replm:replm@10.1.1.206 --slaves=replm:replm@10.1.1.207,replm:replm@10.1.1.208 --candidates=replm:replm@10.1.1.207 --force --log=/var/log/mysqlfailover.log --exec-after=/usr/local/sbin/mysqlfailover_after.sh
    -- 这次master为206 slave为207和208 备用master(候选者)为207
    -- 这次把新master 207关掉
    mysqladmin -predhat shutdown
    -- 查看slave 208状态
    show slave statusG;
                      Master_Host: 10.1.1.207                                                            -- 成功切换到原master207上
    -- 查看原master状态
    show variables like 'read_only';
    | read_only     | OFF   |                                                                                 -- 成功取消只读
    mysql> show status like '%semi_sync%';
    | Rpl_semi_sync_master_status                | ON    |                                       -- 半同步master状态为on
     
    互为failover切换成功 现206的恢复过程参考207 以此类推 切记注意更换master和备用master的IP(不然会很悲剧的)
     
    引入Keepalived管理VIP 达到failover对前端应用透明
     
    -- 安装keepalived 在mysql master和备用master 上
    yum install -y openssl-devel
    ./configure --prefix=/usr/local/keepalived && make && make install 
     
    -- 编写mysqld健康检查脚本 在mysql master和备用master 上
    -- 配置keepalived
    -- 在mysql master 207上配置
    -- 在mysql 备用master 206上配置
    -- 启动keepalived
    -- 在启动keepalived前先确保mysqld都已正常启动
    -- 先启动mysql master上的keepalived
    /usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf            -- 指定配置文件启动keepalived
     
    -- 再启动mysql 备用master上的keepalived
    /usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf            -- 指定配置文件启动keepalived
     
    -- 观看VIP情况 分别在mysql master与备用master上
    ip a s                                                                    -- 使用ip命令查看
        inet 10.1.1.211/32 scope global eth0             -- 现在的VIP只会出现在mysql master上 , 备用master不会有此VIP
     
    -- 模拟故障
    -- 先把mysql master关闭
    mysqladmin -predhat shutdown
    此时vip会漂移到备用master上 (在master上取消此IP 并在备用master配上此IP 此过程自动完成)
     
    -- 再把mysql master启动
    service mysqld start
    此时keepalived已检查到mysqld恢复正常,但由于设置了应用恢复时不抢回VIP 所以此时VIP还是在备用master上 防止mysqld手动重启后误把VIP抢了过来 。keepalived的切换过程和状态可以查看日志 tail -f /var/log/messages
     
    -- 把mysql 备用master关闭
    此时vip会漂移到master上
     
    -- 再把mysql 备用master启动
    此时vip还是在master上
     
    关闭keepalived 注意:
    如果是需要关闭keepalived 要根据keepalived的状态进行判断 先关闭没有配上vip的服务器的keepalived 再关另外一个 以防发生vip漂移
     

    Keepalived + Mysqlfailover 联合测试

     
    -- 把mysqld 恢复正常主从关系 207为主 206 208为从
     
    -- 按顺序启动keepalived
     
    -- 启动mysqlfailover
     
    -- 编写测试脚本 在monitor监控机上
    -- 脚本达到无限插入数据并插入失败重新提交
    -- 创建库和表
    create database db01;
    create table t1(id int,name char(3));
     
    -- 给监控机赋予mysqld权限
    grant all on db01.* to user_db01@'10.1.1.210' identified by 'redhat';
     
    -- 执行测试脚本 并查看结果
    chmod +x /usr/local/sbin/mysql_insert.sh                    -- 赋予权限
    /usr/local/sbin/mysql_insert.sh                                      -- 执行脚本
    新建一个终端 查看日志
    tail -f /tmp/mysql_insert.log                                           -- 查看日志
    ------------------------- 没出现故障时的日志是这样的 ------------------------------
    Warning: Using a password on the command line interface can be insecure.
    insert into db01.t1 values(94,'a')
    0
    ---------------------------------------------------------------------------------------
    -- 把mysqld master 207关掉
    mysqladmin -predhat shutdown
    ----------------------- mysql 发生故障 keepalived还没漂移时 -----------------------
    Warning: Using a password on the command line interface can be insecure.
    insert into db01.t1 values(108,'a')                                                                                -- shutdown前的插入 108
    0
    Warning: Using a password on the command line interface can be insecure.
    ERROR 2003 (HY000): Can't connect to MySQL server on '10.1.1.211' (111)             -- 已shutdown的插入 显示插入失败 连不上mysql (因为mysql已经关闭了)
    insert into db01.t1 values(109,'a')                                                                                -- 开始发生故障的插入 109
    1
    ------------------------ vip 已漂移到206 但mysqlfailover还没切换时 -----------------
    Warning: Using a password on the command line interface can be insecure.
    ERROR 1290 (HY000) at line 1: The MySQL server is running with the --read-only option so it cannot execute this statement        -- 已经通过vip连接上备用master 此时备用master的角色还没切换成master的 但由于设置了read_only 所以此时数据插入失败 才保证了数据一致性
    insert into db01.t1 values(109,'a')                                                                                 -- 看 还是插入109
    1
    ------------------------ mysqlfailover进行故障切换后 把206正式升为master 并把208挂到206上 -------------------------------------
    Warning: Using a password on the command line interface can be insecure.                                                                                        -- 由于failover后执行脚本把mysql的read_only取消 插入成功
    insert into db01.t1 values(109,'a')                                                                                -- 看 还是插入109哦 保证了故障切换不会发生数据不一致
    0
    -----------------------------------------------------------------------------------------------------------------------------------------
     
  • 相关阅读:
    二分图 洛谷P2055 [ZJOI2009]假期的宿舍
    并查集 洛谷P1640 [SCOI2010]连续攻击游戏
    贪心 洛谷P2870 Best Cow Line, Gold
    贪心 NOIP2013 积木大赛
    快速幂 NOIP2013 转圈游戏
    倍增LCA NOIP2013 货车运输
    树形DP 洛谷P2014 选课
    KMP UVA1328 Period
    动态规划入门 BZOJ 1270 雷涛的小猫
    KMP POJ 2752Seek the Name, Seek the Fame
  • 原文地址:https://www.cnblogs.com/archoncap/p/5147337.html
Copyright © 2011-2022 走看看