zoukankan      html  css  js  c++  java
  • Mysql组复制之单主模式(一)

    环境
    系统:CentOS release 6.9 (Final)
    Mysql:5.7
    机器: S1 10.0.0.7 lemon
    S2 10.0.0.8 lemon2
    S3 10.0.0.9 lemon3
     
    架构图
     
     
    一、安装初始化数据库
     
    1)安装相关依赖包
    yum -y install gcc make cmake ncurses-devel libxml2-devel libtool-ltdl-devel gcc-c++ autoconf automake bison zlib-devel
     
    2)安装bootst库
    wget http://www.sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz
    tar -zxvf boost_1_59_0.tar.gz
    cd boost_1_59_0
    ./bootstrap.sh
    ./b2 stage threading=multi link=shared
    ./b2 install threading=multi link=shared
    (threading=multi 表示使用多线程安装 link=shared表示只安装shared库,忽略静态库的安装)
     
    3)下载编译安装Mysql
    wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.17.tar.gz
    tar -zxvf mysql-5.7.17.tar.gz
    cd mysql-5.7.17
    cmake .
    make && make install
     
    4)创建数据目录 并更改权限
    mkdir /data/mysql
    useradd mysql
     
    chown -R mysql:mysql /data/mysql
    chown -R mysql:mysql /usr/local/mysql
     
    5)初始化数据库的数据目录(包含系统数据库和相关表)
    /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --initialize
     
    注:这里的初始化有两个参数可选,区别如下
    --initialize 会生成一个随机密码
    --initialize-insecure 不会生成一个随机密码 登录的时候就不需要密码
     
    --initialize-insecure这个是不会生成随机密码的:(线上环境尽量不要使用这种,使用了记得改密码)
     
     
    --initialize这个是会生成随机密码的:
     
     
    二、配置组复制实例
     
    1)修改配置文件 vim /usr/local/mysql/my.cnf
    [mysqld]
    #基本设置
    user=mysql
    datadir=/data/mysql
    basedir=/usr/local/mysql
    port=3306
    socket=/usr/local/mysql/mysql.sock
    pid-file=/usr/local/mysql/mysql.pid
    log-error=/usr/local/mysql/error.log
     
    #复制框架,根据Mysql组复制要求配置复制
     
    #唯一标识号1
    server_id=1
    gtid_mode=ON #组复制使用全局事务标识符,来精确追踪哪些事务已在所有server实例上提交,从而能判断哪些server执行了与已提交事务冲突的事务
    enforce_gtid_consistency=ON
    master_info_repository=TABLE
    relay_log_info_repository=TABLE
    binlog_checksun=NONE
    log_slave_updates=ON #server需记录applier应用的二进制日志
    log_bin=binlog #MySQL组复制会复制二进制日志的内容,因此需打开二进制日志
    binlog_format=ROW #组复制依赖于行的复制格式
     
    #组复制设置
    transaction_write_set_extraction=XXHASH64
    loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
    loose-group_replication_start_on_boot=off
    loose-group_replication_local_address="10.0.0.7:33061"
    loose-group_replication_group_seeds="10.0.0.7:33061;10.0.0.8:33061;10.0.0.9:33061"
    loose-group_replication_bootstrap_group=off
     
    2)修改密码
     
    1)启动mysql
    nohup /usr/local/mysql/bin/mysqld --defaults-file=/usr/local/mysql/etc/my.cnf &
     
    这里启动的时候看日志肯能会有如下:这表示开始的时候还没有安装group_replication插件,后面会安装,所以可以先不用管
     
     
     
    2)把密码给改了
     
    sock链接到/tmp/mysql.sock;(当重启mysql登陆不进的时候,可以先把/tmp/mysql.sock删除,再重新做链接)
    ln -s /usr/local/mysql/mysql.sock /tmp/mysql.sock 
     
    3)通过在日志里的临时密码登录进去后,修改密码,不修改密码会报错
     
     
    set password=password('123456');

     
     
    3、用户凭证
     
    创建具有REPLICATION-SLAVE权限的Mysql用户,该操作不记录到二进制日志中,以避免将更改传递到其他的server实例。创建用户:rpl_user,密码rpl_pass
     
    1)关闭二进制日志,以下的操作不写入二进制日志
    set sql_log_bin=0;
    2)创建rpl_user用户
    create user rpl_user@'%';
    @‘%’表示用户可以在哪个主机上用此账号登录,%表示可以从任何远程主机登录,如果只允许从本机登录,@‘localhost’
     
    3)授权
    grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';
    replication slave 表示对此操作授权
    on *.* 表示授予该用户对所有数据库和表的相应操作权限
     
    4) 刷新
    flush privileges;
     
    5)再打开二进制日志
    set sql_log_bin=1;

     
    6)将server设置为,在下次需要从其他成员恢复状态时,使用group_replication_recovery复制通道的给定凭证
    change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';

    分布式恢复是加入组的server执行的第一步,这句话的意思是说恢复是其他待会儿加入这个组的服务的第一个步骤。如果未正确设置这些凭证,server将无法执行恢复过程并获得与其他组成员同步,因此最终无法加入组。如果成员无法通过server的主机名正确识别其他成员,server将无法执行恢复过程并获得与其他组成员同步,则恢复过程可能会失败。尽量设置不一样的主机名
     
    use performance_schema
    select *from replication_group_members;
     
    4、启动组复制
     
    1)配置并启动server s1 ,安装组复制插件
     
    install plugin group_replication soname 'group_replication.so';
     
    2)检查插件是否安装成功
     
    show pluginsG;

     
    3)要启动组,得指示server s1的引导组,然后启动组复制程序
    此引导组仅由单个server独立完成,该server启动组并且只启动一次。引导配置选项的值不保存在配置文件中的原因就是这个。如果将其保存在配置文件中,则在重新启动时,server会自动引导具有相同名称的第二个组,这将导致两个不同的组具有相同的名称。同样的适用于停止和启动插件。
     
    启动组复制:
    global group_replication_bootstrap_group 为引导变量,用于第一次启动group_replicaiton时打开进行引导,启动完group_replication后将其关闭,相当于第一个组成员启动时,要对组进行初始化
     
    启动group_replication:
    set global group_replication_bootstrap_group=ON;
    start group_replication;
    set global group_replication_bootstrap_group=off;
     
     
    4)此时可以看到这个组已经创建并且已经有一个成员了
     
    select *from replication_group_members;

     
     
    5)做测试
     
    创建一个test数据库,然后在这个库里添加一张表,并插入值
    create database test;
    use test;
    create table t1(
    -> c1 int primary key,
    -> c2 text not null
    -> );
    insert into t1 values (1,"lemon");

     
    6)查看是否写入二进制日志
     
    show binlog events ;

     
     
    这样只是默认查询第一个二进制文件,这里纠结了好久为什么会没有数据,因为第5步创建的数据库语句是放在另一个binlog里,所以查询的时候得加文件名
     
    show binlog events in 'binlog.000002';

     
     
    5、向组类添加实例
     
    1)添加第二个实例
     
    10.0.0.8 lemon2
     
    2)修改配置文件
     
    [mysqld]
    user=mysql
    datadir=/data/mysql
    basedir=/usr/local/mysql
    port=3306
    socket=/usr/local/mysql/s1.sock
    pid-file=/usr/local/mysql/mysql.pid
    log-error=/usr/local/mysql/error.log
     
    server_id=2
    gtid_mode=ON
    enforce_gtid_consistency=ON
    master_info_repository=TABLE
    relay_log_info_repository=TABLE
    binlog_checksum=NONE
    log_slave_updates=ON
    log_bin=binlog
    binlog_format=ROW
     
    transaction_write_set_extraction=XXHASH64
    loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
    loose-group_replication_start_on_boot=off
    loose-group_replication_local_address="10.0.0.8:33061"
    loose-group_replication_group_seeds="10.0.0.7:33061,10.0.0.8:33061,10.0.0.9:33061"
    loose-group_replication_bootstrap_group=off
     
    与第一个server的区别是
    server_id=2
    oose-group_replication_local_address="10.0.0.8:33061",得改成本机的IP和端口号
     
    3)初始化数据目录(与第一个server一样)
    4)启动数据库
    5)修改密码
    6)添加用户凭证
    7)安装组复制插件
    8)将server 2 添加到组
    这里不需要再执行组的初始化(引导组),但是得执行下面这一句,如果不在会报错:
     
    重要:
    set global group_replication_allow_local_disjoint_gtids_join=ON;
     
     
     
    9)查看组内是否有两个成员了
     
    这里有两个成员了,但是刚刚加进来的这个是处于RECOVERY状态,正常的是要ONLINE状态
     
     
    error.log日志:
     
     
    看这个报错:就是说在server2上连server1的数据库 以这种方式连rpl_user@lemon:3306 连不上
    这个问题一看就知道,是因为server2并不知道主机名为lemon是那台机器,因此必须得添加主机名和IP
     
    vim /etc/hosts
    10.0.0.7 lemon
    10.0.0.8 lemon2
    10.0.0.9 lemon3
     
    10)查看数据库及表数据,看在server1创建的数据是否同步过来
     
     
    server 2自动的连接到s1,并从其获取丢失的数据
     
    6、按照上述步骤添加第三个实例
     
     
     
    到这里为止,单主模式下的组复制就已经完成了,这种搭建部署花时间就会,想要深入理解原理,更好的使用这些技术,得要有场景,有环境,有机会去操作才行。永远缺少一个机会
     
    三、模拟主机器挂了
     
    模拟主机器挂了,会自动选取另一台主,可以通过下面的命令查看哪一台被升为主了
     
    select * from global_status where variable_name="group_replication_primary_member";

     
    或者
     
    SELECT * FROM performance_schema.replication_group_members WHERE MEMBER_ID = (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member');

     
    等原来的主恢复之后,不会自动的加入组,必须得手动打开组复制才会加入
     
     
     
    注:不能将自动启动的配置加在配置文件里,会报错,而且不会自动加入组复制
     
    四:将显示出来的主机名变为IP地址
     
     
     
    在配置文件里加上:report_host=10.0.0.7,重启后:
     
     
     
    另外两个也一样
     
    五、replication_group有关的信息
     
     
    有关的几张表:
     
    1)replication_group_members
     
     
    其中mermber_state的状态有如下几种:
    ONLINE:表示正常
    RECOVERING:该成员正在成为该组的有效成员,并且正在恢复过程中,从数据源节点接受状态信息
    OFFLINE:插件已加载,但成员不属于任何组
    ERROR:本地成员的状态,恢复阶段或应用更改时出现错误,server就会出现此状态
    UNREACHABLE:不可达
     
    组复制不是同步复制,但最终是同步的。事物以相同的顺序传递给所有组成员,但他们的执行不同步,也就是说在接受事务被提交之后,每个成员以其自己的速度提交
     
    2)replication_group_member_stats
     
     
    CHANNEL_NAME: 组复制通道的名称
    MEMBER_ID: 该组成员的UUID
    COUNT_TRANSACTIONS_IN_QUEUE: 队列中等待冲突检测检查的事务数,检查后,排队等待应用
    COUNT_TRANSACTIONS_CHECKED: 已进行过冲突检查的事务数
    COUNT_CONFLICTS_DETECTED: 表示未通过冲突检查的事务数
    COUNT_TRANSACTIONS_ROWS_VALIDATING: 冲突检测数据库的当前大小
    TRANSACTIONS_COMMITTED_ALL_MEMBERS: 已在当前视图的所有成员上成功提交的事务
    LAST_CONFLICT_FREE_TRANSACTION: 最后一个经检查无冲突的事务标识符
     
    3)replication_connection_status
     
     
    4)replication_applier_status
     
     
    REMAINING_DELAY: 是否配置了应用延迟
    COUNT_TRANSACTIONS_RETRIES:应用事务的重试次数
     
    六、如何做到MGR主节点故障自动切换
    MGR单主模式下,当主节点故障,MGR内部将会发起一轮新的选举,选出新的主,这是由MGR内部决定并执行的。但是当应用的连接遇到主节点挂掉的情况下,是不会自动发生切换的,也就是说,MGR内部没有提供一种机制,来实现主节点故障切换对应用无感知。
     
    相关链接:
     
  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/lemon-le/p/9241910.html
Copyright © 2011-2022 走看看