• MySQL主从复制


    1、主从复制架构和原理

    1.1服务性能扩展方式      Scale Up,向上扩展,垂直扩展     

                                            Scale Out,向外扩展,横向扩展

    1.2MySQL的扩展             读写分离
                复制:每个节点都有相同的数据集,向外扩展,基于二进制日志的单向复制

    1.3复制的功用

        @数据分布    @负载均衡读    @备份    @高可用和故障切换    @MySQL升级测试

    1.4主从复制架构

    一主一从复制架构

     一主多从复制架构

     1.5主从复制原理

     主从复制相关线程
    主节点:
    dump Thread为每个SlaveI/O Thread启动一个dump线程,用于向其发送binary log events
    从节点:
    I/O ThreadMaster请求二进制日志事件,并保存于中继日志中
    SQL Thread从中继日志中读取日志事件,在本地完成重放

    跟复制功能相关的文件

      master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等   

      relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地relay log日志的对应关系 

      mariadb-relay-bin.00000#: 中继日志,保存从主节点复制过来的二进制日志,本质就是二进制日志

    范例: 中继日志

    [root@slave ~]#file /var/lib/mysql/mariadb-relay-bin.000001
    /var/lib/mysql/mariadb-relay-bin.000001: MySQL replication log, server id 18
    MySQL V5+, server version 10.3.17-MariaDB-log
    [root@slave ~]#mysqlbinlog /var/lib/mysql/mariadb-relay-bin.000001|head
    /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
    /*!40019 SET @@session.max_insert_delayed_threads=0*/;
    /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
    DELIMITER /*!*/;
    # at 4
    #200615 17:58:48 server id 18 end_log_pos 256 CRC32 0x7bd00c79 Start:
    binlog v 4, server v 10.3.17-MariaDB-log created 200615 17:58:48
    BINLOG '
    WEbnXg8cAAAA/AAAAAABAAAAAAQAMTAuMy4xNy1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    1.6主从复制特点

      @异步复制       @主从数据不一致比较常见

    1.7各种复杂架构

    @一master/一slave    @一主一从    @从服务器还可以再有从服务器     @Master/Master     

    @一从多主:适用于多个不同数据库     @环状复制
     

    2、实现主从复制配置

    参考官网
    https://mariadb.com/kb/en/library/setting-up-replication/
    https://dev.mysql.com/doc/refman/5.5/en/replication-configuration.html

    主节点配置:

    (1) 启用二进制日志

    [root@centos8 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
    [mysqld] log_bin

    (2) 为当前节点设置一个全局惟一的ID

    [mysqld]
    server-id=          #设置的IP最后一位            
    log-basename=master #可选项,设置datadir中日志名称,确保不依赖主机名 文件前缀

    server-id的取值范围

    1 to 4294967295 (>= MariaDB 10.2.2),默认值为

    0 to 4294967295 (<= MariaDB 10.2.1),默认值为0,如果从节点为0,所有master都将拒绝此slave连接 

    (3) 创建有复制权限的用户账号

    GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'HOST' IDENTIFIED BY 'replpass';
                               主机IP 密码

    (4) 查看从二进制日志的文件和位置开始进行复制

    MariaDB [(none)]>SHOW MASTER LOG;

    从节点配置:

    (1) 启动中继日志

    [mysqld]
    server_id=#         #为当前节点设置一个全局惟的ID号
    log-bin           #启用二进制
    read_only=ON        #设置数据库只读,针对supper user无效
    relay_log=relay-log    #relay log的文件路径,默认值hostname-relay-bin
    relay_log_index=relay-log.index #默认值hostname-relay-bin.index

    (2) 使用有复制权限的用户账号连接至主服务器,并启动复制线程

    CHANGE MASTER TO MASTER_HOST='masterhost',
    MASTER_USER='repluser',
    MASTER_PASSWORD='replpass',
    MASTER_LOG_FILE='mariadb-bin.xxxxxx',
    MASTER_LOG_POS=#;
    START SLAVE [IO_THREAD|SQL_THREAD];
    SHOW SLAVE STATUS;

    范例:

    #主节点
    [root@master ~]#vim /etc/my.cnf.d/mariadb-server.cnf
    [mysqld]
    server-id=134
    log-bin
    [root@master ~]#systemctl restart mariadb
    [root@master ~]#mysql
    MariaDB [(none)]> grant replication slave on *.* to repluser@'10.0.0.%' identified by '123456';
    #查看二进制文件和位置
    MariaDB [(none)]> show master logs;
    +--------------------+-----------+
    |     Log_name       | File_size |
    +--------------------+-----------+
    | mariadb-bin.000001 |   28052   |
    | mariadb-bin.000002 | 545 |
    +--------------------+-----------+
    2 rows in set (0.001 sec)
    #从节点
    [root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
    [mysqld]
    server-id=135
    [root@slave ~]#systemctl restart mariadb
    [root@slave1 ~]#mysql MariaDB [(none)]> help change master to

     MariaDB [(none)]>CHANGE MASTER TO MASTER_HOST='10.0.0.134',
     MASTER_USER='repluser',
     MASTER_PASSWORD='123456',
     MASTER_PORT=3306,
     MASTER_LOG_FILE='mariadb-bin.000002',
     MASTER_LOG_POS=545;

    MariaDB [(none)]> start slave;
    Query OK, 0 rows affected, 1 warning (0.000 sec)

    MariaDB [(none)]> show slave statusG
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
              Master_Host: 10.0.0.134
              Master_User: repluser
              Master_Port: 3306
             Connect_Retry: 60
            Master_Log_File: mariadb-bin.000002
             Read_Master_Log_Pos: 26987890
                  Relay_Log_File: mariadb-relay-bin.000002
                   Relay_Log_Pos: 26987902
            Relay_Master_Log_File: mariadb-bin.000002
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
             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: 26987890
             Relay_Log_Space: 26988213
             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 #复制的延迟时间
      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: 8
                       Master_SSL_Crl:
                  Master_SSL_Crlpath:
                         Using_Gtid: No
                        Gtid_IO_Pos:
            Replicate_Do_Domain_Ids:
        Replicate_Ignore_Domain_Ids:
                      Parallel_Mode: conservative
                          SQL_Delay: 0
                SQL_Remaining_Delay: NULL
            Slave_SQL_Running_State: Slave has read all relay log; waiting for the
    slave I/O thread to update it
                   Slave_DDL_Groups: 34
     Slave_Non_Transactional_Groups: 0
         Slave_Transactional_Groups: 100006
    1 row in set (0.000 sec)

    范例:主服务器非新建时,主服务器运行一段时间后,新增从节点服务器

    如果主节点已经运行了一段时间,且有大量数据时,如何配置并启动slave节点
        @通过备份恢复数据至从服务器

        @复制起始位置为备份时,二进制日志文件及其POS

    #在主服务器完全备份
    [root@master ~]#mysqldump -A -F --single-transaction --master-data=1 > /backup/fullbackup_`date +%F_%T`.sql
    [root@master ~]#ll /backup/
    total 2988
    -rw-r--r-- 1 root root 3055918 Nov 27 17:41 fullbackup_2020-10-13_09:33:07.sql
    [root@master ~]#scp /backup/fullbackup_2020-10-13_09:33:07.sql 10.0.0.135:/data/

    #建议优化主和从节点服务器的性能
    MariaDB [hellodb]> set global innodb_flush_log_at_trx_commit=2
    MariaDB [hellodb]> set global sync_binlog=0
    MariaDB [hellodb]> set global innodb_flush_log_at_trx_commit=2;
    Query OK, 0 rows affected (0.001 sec)
    MariaDB [hellodb]> show variables like 'sync_binlog';
    +---------------------+-------+
    | Variable_name | Value |
    +---------------------+-------+
    | sync_binlog | 0 |
    |---------------------+-------+
    5 rows in set (0.001 sec)
    #将完全备份还原到新的从节点
    [root@slave ~]#dnf -y install mariadb-server
    [root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
    [mysqld]
    server-id=135
    read-only [root@slave ~]#systemctl restart mariadb
    #配置从节点,从完全备份的位置之后开始复制
    [root@slave ~]#grep '^CHANGE MASTER' /data/fullbackup_
    2020-10-13_09:33:07.sql
    CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
    [root@slave ~]#vim /data/fullbackup_
    2020-10-13_09:33:07.sql
    CHANGE MASTER TO
    MASTER_HOST='10.0.0.134',
    MASTER_USER='repluser',
    MASTER_PASSWORD='123456',
    MASTER_PORT=3306,
    MASTER_LOG_FILE='mariadb-bin.000003',
    MASTER_LOG_POS=389;
    [root@slave ~]#mysql < /data/fullbackup_2020-10-13_09:33:07.sql
    [root@slave ~]#mysql

    MariaDB [(none)]> show slave statusG;

    *************************** 1. row ***************************
                   Slave_IO_State:
    Master_Host: 10.0.0.134
    Master_User: repluser
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File: mariadb-bin.000003
    Read_Master_Log_Pos: 389
    Relay_Log_File: mariadb-relay-bin.000001
    Relay_Log_Pos: 4
    Relay_Master_Log_File: mariadb-bin.000003
    Slave_IO_Running: No
    Slave_SQL_Running: No
    .
    .
    .省略

    3、主从复制相关

    3.1限制服务器为只读

    read_only=ON
    #注意:此限制对拥有SUPER权限的用户均无效

    注意:以下命令会阻止所有用户, 包括主服务器复制的更新

    FLUSH TABLES WITH READ LOCK;

    3.2在从节点清除信息
    注意:一下都需要先stop slave

    RESET SLAVE #从服务器清除master.info ,relay-log.info, relay log ,开始新的relay log
    RESET SLAVE ALL #清除所有从服务器上设置的主服务器同步信息,如HOST,PORT, USER和PASSWORD 等

    3.3复制错误解决方法

    可以在从服务器忽略几个主服务器的复制事件,此为global变量,或指定跳过事件的ID
    注意: Centos 8.1以上版本上主从节点同时建同名的库和表不会冲突,建主键记录会产生冲突

    #系统变量,指定跳过复制事件的个数
    SET GLOBAL sql_slave_skip_counter = N
    #服务器选项,只读系统变量,指定跳过事件的ID
    [mysqld]
    slave_skip_errors=1007|ALL

    范例:复制冲突的解决
    #CentOS7上Mariadb5.5 在slave创建库和表,再在master上创建同名的库和表,会出现复制冲突,而在

    CentOS8上的Mariadb10.3上不会冲突
    #如果添加相同的主键记录都会冲突
    MariaDB [(none)]> show slave statusG
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
    Master_Host: 10.0.0.134
    Master_User: repluser
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File: mariadb-bin.000002
    Read_Master_Log_Pos: 26988271
    Relay_Log_File: mariadb-relay-bin.000003
    Relay_Log_Pos: 557
    Relay_Master_Log_File: mariadb-bin.000002
    Slave_IO_Running: Yes
    Slave_SQL_Running: No
    Replicate_Do_DB:
    Replicate_Ignore_DB:
    Replicate_Do_Table:
    Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
    Replicate_Wild_Ignore_Table:
    Last_Errno: 1007
    Last_Error: Error 'Can't create database 'db4'; database
    exists' on query. Default database: 'db4'. Query: 'create database db4'
    Skip_Counter: 0
    Exec_Master_Log_Pos: 26988144
    Relay_Log_Space: 26988895
    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: NULL
    Master_SSL_Verify_Server_Cert: No
    Last_IO_Errno: 0
    Last_IO_Error:
    Last_SQL_Errno: 1007 #错误编码
    Last_SQL_Error: Error 'Can't create database 'db4'; database
    exists' on query. Default database: 'db4'. Query: 'create database db4'
    Replicate_Ignore_Server_Ids:
    Master_Server_Id: 8
    Master_SSL_Crl:
    Master_SSL_Crlpath:
    Using_Gtid: No
    Gtid_IO_Pos:
    Replicate_Do_Domain_Ids:
    Replicate_Ignore_Domain_Ids:
    Parallel_Mode: conservative
    SQL_Delay: 0
    SQL_Remaining_Delay: NULL
    Slave_SQL_Running_State:
    Slave_DDL_Groups: 37
    Slave_Non_Transactional_Groups: 0
    Slave_Transactional_Groups: 100006
    1 row in set (0.000 sec)

    #方法1
    MariaDB [(none)]> stop slave;
    MariaDB [(none)]> set global sql_slave_skip_counter=1;
    MariaDB [(none)]> start slave;
    #方法2
    [root@slave1 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
    [mysqld]
    slave_skip_errors=1007|ALL
    [root@slave1 ~]#systemctl restart mariadb

    1.4START SLAVE 语句,指定执到特定的点

    START SLAVE [thread_types]
    START SLAVE [SQL_THREAD] UNTIL
    MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
    START SLAVE [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos
    thread_types:
    [thread_type [, thread_type] ... ]
    thread_type: IO_THREAD | SQL_THREAD

    1.5 保证主从复制的事务安全
    参看https://mariadb.com/kb/en/library/server-system-variables/
    master节点启用参数:

    sync_binlog=1 每次写后立即同步二进制日志到磁盘,性能差     #如果用到的为InnoDB存储引擎:
    innodb_flush_log_at_trx_commit=1                    #每次事务提交立即同步日志写磁盘
    innodb_support_xa=ON                                #分布式事务MariaDB10.3.0废除
    sync_master_info=#                                  #次事件后master.info同步到磁盘

    slave节点启用服务器选项:

    skip-slave-start=ON #不自动启动slave

    slave节点启用参数:

    sync_relay_log=# #次写后同步relay log到磁盘
    sync_relay_log_info
    =# #次事务后同步relay-log.info到磁盘

    3.6案例:当master服务器宕机,提升一个slave成为新的master

    #找到哪个从节点的数据库是最新,让它成为新master
    [root@centos8 ~]#cat /var/lib/mysql/relay-log.info
    5
    ./mariadb-relay-bin.000002
    1180
    mysql-bin.000002
    996
    0
    #新master修改配置文件,关闭read-only配置
    [root@slave1 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
    [mysqld]
    server-id=135
    read-only=OFF
    log-bin=/data/mysql/logbin/mysql-bin
    #清除旧的master复制信息
    MariaDB [hellodb]>set global read_only=off;
    MariaDB [hellodb]>stop slave;
    MariaDB [hellodb]>reset slave all;
    #在新master上完全备份
    [root@slave1 ~]#mysqldump -A --single-transaction --master-data=1 -F >backup.sql
    [root@slave1 ~]#scp backup.sql 10.0.0.136:
    #分析旧的master二进制日志,将未同步到新master的二进制文件导出,恢复到新master,尽可能恢复数据
    #其他所有slave重新还原数据库,指向新的master
    [root@slave2 ~]#vim backup.sql
    CHANGE MASTER TO
      MASTER_HOST='10.0.0.135',
        MASTER_USER='repluser',
          MASTER_PASSWORD='123456',
            MASTER_PORT=3306,
    MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=371;
    MariaDB [hellodb]>stop slave;
    MariaDB [hellodb]>reset slave all;
    MariaDB [hellodb]>set sql_log_bin=off;
    MariaDB [hellodb]>source backup.sql;
    MariaDB [hellodb]>set sql_log_bin=on;
    MariaDB [hellodb]>start slave;

     

     

     



  • 相关阅读:
    codeforces 455B A Lot of Games(博弈,字典树)
    HDU 4825 Xor Sum(二进制的字典树,数组模拟)
    hdu 1800 Flying to the Mars(简单模拟,string,字符串)
    codeforces 425A Sereja and Swaps(模拟,vector,枚举区间)
    codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)
    HDU 4148 Length of S(n)(字符串)
    codeforces 439D Devu and Partitioning of the Array(有深度的模拟)
    浅谈sass
    京东楼层案例思维逻辑分析
    浅谈localStorage和sessionStorage
  • 原文地址:https://www.cnblogs.com/zhangty333/p/13805099.html
Copyright © 2020-2023  润新知