实现mysql主主复制架构

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现mysql主主复制架构相关的知识,希望对你有一定的参考价值。

实验环境,假设公司想要对一台运行了一段时间的mysql服务器,做一个主主复制架构,以提升数据库的读写能力。







老服务器用M0表示
新服务器用M1表示

一,对M0服务器做一个全备份

    mysqldump -A -F -E -R --single-transaction --master-data=1 --flush-privileges --triggers --hex-blob > /mysqlbackup/all.sql

    命令解析:
        -A:备份所有数据库,含create database语句

        -F:备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A时,会导致刷新多次数据库,在同一时刻执行转储和日志刷新,--single-transaction 之刷新一次二进制日志
        --single-transaction :只刷新一次二进制日志
        --flush-privileges: 备份mysql或相关时需要使用
        --triggers:备份表相关的触发器,默认启用,用--skiptriggers,不备份触发器 
        --master-data=【1|2】:注意:此选项须启用二进制日志
         1:所备份的数据之前加一条记录为CHANGE MASTER TO语 句,非注释,不指定#,默认为1     
         2:记录为注释的CHANGE MASTER TO语句  此选项会自动关闭--lock-tables功能,自动打开--lock-alltables功能(除非开启--single-transaction) 

二,查看当前备份位置


    [[email protected] ~]# grep -i ^change*  /mysqlbackup/all.sql 
    CHANGE MASTER TO MASTER_LOG_FILE=‘mariadb-bin.000005‘, MASTER_LOG_POS=245;

    当前备份位置是mariadb-bin.000002的245,之前的所有内容都备份了

三,将全备份拷贝到M1服务器上

    scp /mysqlbackup/all.sql  192.168.68.17:/data/

四,修改M0服务器配置文件

    vim /etc/my.cnf
    在[mysqld]配置块中添加如下配置
    [mysqld]
    server_id=0             #设置为当前节点设置一个全局惟一的ID号
    innodb_file_per_table #启用数据库仪表结构分离存放在两个不同文件
    auto_increment_offset=1     #设置字段自动增长的起始值1
    auto_increment_increment=2  #增长的幅度为2
    log_bin                     #启用二进制日志

五,重启M0的mysql服务,使配置生效

    systemctl restart mairadb

六,在M0上创建拥有复制权限的用户账号

    M0 [(none)]>GRANT REPLICATION SLAVE  ON *.* TO ‘repluser‘@‘HOST‘ IDENTIFIED BY ‘replpass‘; 

    命令解析:
        ‘repluser‘@‘HOST‘ :设置用户名即主机ip或网段,网段用%表示 例如10.0.0.%
        IDENTIFIED BY:设置密码
        *.* :表示所有数据库,所有表
        GRANT REPLCATION SLAVE:就是允许该用户复制数据

    该命令作用就是授权repluser能拷贝数据库的所有内容

七,在M1上安装mairadb

    yum install mairadb-server

八,修改M1配置文件

     vim /etc/my.cnf
        在[mysqld]配置块中添加如下配置
        [mysqld]
        server_id=0             #设置为当前节点设置一个全局惟一的ID号
        innodb_file_per_table #启用数据库仪表结构分离存放在两个不同文件
        auto_increment_offset=2    #设置字段自动增长的起始值2
        auto_increment_increment=2  #增长的幅度为2
        log_bin                     #启用二进制日志

九,启动M1的mairadb服务

    systemctl restart mariadb

十,为了安全在M1执行下面的命令

    "mysql_secure_installation"

    第一项问你:输入root密码  回车即可,因为没有
    第二项问你:需要设置root密码么,
    第三项问你:需要删除空账号用户么,
    第四项问你:禁止root用户远程登入么,
    第五项问你:需要删除test测试数据库么,
    第六项问你:现在重新加载权限表吗 ,

十一,在M1上恢复备份数据

    登入mysql终端执行下面的命令

     M1 [(none)]>source /data/all.sql

十二,在M1上同样也创建一个拥有复制权限的用户账号

     M1 [(none)]>GRANT REPLICATION SLAVE  ON *.* TO ‘repluser‘@‘HOST‘ IDENTIFIED BY ‘replpass‘; 

        命令解析:
            ‘repluser‘@‘HOST‘ :设置用户名即主机ip或网段,网段用%表示 例如10.0.0.%
            IDENTIFIED BY:设置密码
            *.* :表示所有数据库,所有表
            GRANT REPLCATION SLAVE:就是允许该用户复制数据

        该命令作用就是授权repluser能拷贝数据库的所有内容

十三,在M1使用有复制权限的用户账号连接至主服务器,并启动复制线程

1,使用有复制权限的用户账号连接至主服务器

         M1 [(none)]> CHANGE MASTER TO 
             MASTER_HOST=‘host‘,        #指定M0主机IP
             MASTER_USER=‘repluser‘,    #指定M0被授权的用户名
             MASTER_PASSWORD=‘replpass‘,#指定M0被授权的用户密码 MASTER_LOG_FILE=‘mysql-bin.xxxxx‘, #指定从M0服务器的那个二进制日志开始复制
             MASTER_LOG_POS=#;          #二进制日志位置,可以在M1服务器上执行该命令查看,show master logs;

2,启动复制线程IO_THREAD和SQL_THREAD

    M1 [(none)]>START SLAVE;

3,查看线程状态


    M1 [(none)]> show slave status\G
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.68.7
                      Master_User: repluser
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mariadb-bin.000005
              Read_Master_Log_Pos: 245
                   Relay_Log_File: mariadb-relay-bin.000002
                    Relay_Log_Pos: 843
            Relay_Master_Log_File: mariadb-bin.000005
                 Slave_IO_Running: Yes  "重点关注如果是NO表示线程没起来"
                Slave_SQL_Running: Yes "重点关注 如果是NO表示该线程没起来"
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 557
                  Relay_Log_Space: 1139
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: 0 "该项表示同步时间 0表示即使同步"
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1

十四,在M0使用有复制权限的用户账号连接至主服务器,并启动复制线程

1,使用有复制权限的用户账号连接至主服务器

     M0 [(none)]> CHANGE MASTER TO 
         MASTER_HOST=‘host‘,        #指定M1主机IP
         MASTER_USER=‘repluser‘,    #指定M1被授权的用户名
         MASTER_PASSWORD=‘replpass‘,#指定M1被授权的用户密码 MASTER_LOG_FILE=‘mysql-bin.xxxxx‘, #指定从M1服务器的那个二进制日志开始复制
         MASTER_LOG_POS=#;          #二进制日志位置,可以在M0服务器上执行该命令查看,show master logs;

2,启动复制线程IO_THREAD和SQL_THREAD

     M0 [(none)]> START SLAVE; 

3,查看线程状态


    M0 [(none)]> show slave status\G
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.68.17
                      Master_User: repluser
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mariadb-bin.000001
              Read_Master_Log_Pos: 55732
                   Relay_Log_File: mariadb-relay-bin.000002
                    Relay_Log_Pos: 843
            Relay_Master_Log_File: mariadb-bin.000001
                 Slave_IO_Running: Yes  "重点关注如果是NO表示线程没起来"
                Slave_SQL_Running: Yes "重点关注 如果是NO表示该线程没起来"
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 557
                  Relay_Log_Space: 1139
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: 0 "该项表示同步时间 0表示即使同步"
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1

十五,同步测试,创建表查看自动增长字段两边是否冲突

1,在M0上创建一张测试表

   create table t1(id int unsigned primary key auto_increment,name varchar(30));

    该命令就是在test数据库中创建一张名为t1,有两个字段,一个字段是id,另一个是name,其中id是整数,而且是主键,并且还是自动增长,name字段是任意字符,字符长度只有30个

2,查看M1是否同步

    M1 [test]> show tables;
    +----------------+
    | Tables_in_test |
    +----------------+
    | t1             |
    +----------------+

3,在M1,test数据库的t1表中插入两条记录

    MariaDB [test]> insert t1(name) values(‘wang‘);
    Query OK, 1 row affected (0.01 sec)

    MariaDB [test]> insert t1(name) values(‘li‘);
    Query OK, 1 row affected (0.02 sec)

    MariaDB [test]> select * from t1
        -> ;
    +----+------+
    | id | name |
    +----+------+
    |  2 | wang |
    |  4 | li        |
    +----+------+
    2 rows in set (0.00 sec)

    "注意:
    为什么id是2,4呢,这就是在M1的配置文件中的这两行的作用
        auto_increment_offset=2    #设置字段自动增长的起始值2
        auto_increment_increment=2  #增长的幅度为2"
    而M0上在这张表上插入的内容就是以基数增长了,但是它不会不全前面缺的数,而是一直增张。

        M0 [test]> select * from t1;
        +----+-------+
        | id | name  |
        +----+-------+
        |  2 | wang  |
        |  4 | li         |
        |  5 | zhang |
        |  7 | huang |
        +----+-------+
        4 rows in set (0.00 sec)

总结:

  • 主主复制:互为主从
    • 容易产生的问题:数据不一致;因此慎用
  • 考虑要点:表某一个字段设置为自动增长的id值时
    • 配置一个节点使用奇数id,需要在配置文件中添加如下
      • auto_increment_offset=1 开始点
      • auto_increment_increment=2 增长幅度
    • 另一个节点使用偶数id,需要在配置文件中添加如下
      • auto_increment_offset=2
      • auto_increment_increment=2
  • 两台服务器都必须开启二进制日志功能,并且都要有授权复制数据的用户

以上是关于实现mysql主主复制架构的主要内容,如果未能解决你的问题,请参考以下文章

Mysql实现数据库主从复制主主复制半同步复制

主从复制及主主复制的实现

搭建MySQL的主从半同步主主复制架构

Mysql-主从复制架构的扩展主主-多从

mysql数据库的主从复制和主主复制

Memcached 主主复制+ Keepalived 实现 Memcached 高可用架构集群