zoukankan      html  css  js  c++  java
  • 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;

     

     

     



  • 相关阅读:
    Comet OJ
    AtCoder Grand Contest 002题解
    AtCoder Grand Contest 001 题解
    线性基求交
    2019牛客暑期多校训练营(第四场)题解
    AtCoder Grand Contest 036题解
    计算几何 val.2
    计算几何 val.1
    模拟退火学习笔记
    动态点分治学习笔记
  • 原文地址:https://www.cnblogs.com/zhangty333/p/13805099.html
Copyright © 2011-2022 走看看