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 status\G
*************************** 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 status\G;

*************************** 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 status\G
*************************** 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;

 

 

 

 



 

posted @ 2020-10-12 20:34  养了27年的狗  阅读(136)  评论(0编辑  收藏  举报
Live2D