• 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
    -----------------------------------------------------------------------------------------------------------------------------------------
     
  • 相关阅读:
    根据索引删除数组内信息时导致程序崩溃
    C/C++判断字符串是否包含某个子字符串
    Qwidget布局操作之QGridLayout(网格布局)
    Qt获取文件路径、文件夹路径
    javascript DOM document属性
    javascript dom页面中的location属性
    javascript页面常用事件
    python的高阶函数式编程
    python set 集合复习--点滴
    python异常
  • 原文地址:https://www.cnblogs.com/archoncap/p/5147337.html
Copyright © 2020-2023  润新知