主从复制

mysql主从复制(异步复制)

配置主从的条件

1.一台带有数据的主库
2.一台崭新的从库,或者初始化之后的

#初始化
cd /usr/local/mysql/scripts/ && rm -rf ../data && ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

1.主库操作

1.主库配置server_id
2.主库开启binlog
3.主库授权连接的用户
4.查看binlog信息(之后不能再有刷新binlog的操作) -------------
5.导出数据(mysqldump)
mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql

#查看binlog信息之后,不能再有刷新binlog的操作
#主从数据的同步,是为了创建或删除的某些时候不报错
#主从配置的过程中,可以写入数据,因为change master to的时候已经记录了那个位置点,所以同步的时候只需要指定那个位置点就好,那么这样从库就可以同步到主库的所有的数据了

2.从库操作

1.从库配置server_id(从库不需要配置binlog,因为只配置主从复制的话,从库不会写入binlog,写入中继日志)
2.确认主库授权的用户可以连接从库(ssh)
3.导入主库数据
4.配置主库信息(change master to)(连接,会自动同步位置点之后的数据)
5.开启slave(IO线程 dump线程)


#从库不需要开启binlog,因为从库从主库获取的binlog存放到了中继日志(relay-log),中继日志就相当于从库的binlog
#当数据量很大的时候,主从复制不是实时的情况将会很突出(中继日志里面的SQL语句SQL线程执行)
#主从复制实际上是异步复制

3.主从复制原理

1)图解

UqHM90.md.jpg

2)文字描述

1.主库配置server_id和开启binlog
	[mysqld]
	server_id=1
	log_bin=/usr/local/mysql/data/mysql-bin
2.主库授权从库连接的用户
	grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
3.主库查看binlog信息,与服务器信息
	show master status;
3.5 主库导出所有数据(不会记录在SQL)
mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
head -22 /tmp/full.sql | tail -1
	
4.从库配置跟主库'不一致'server_id,没有binlog不能show master status;
	[mysqld]
	server_id=2
5.配置主从,通过change master to指定'从库主库的信息':ip、用户、密码、端口、binlog位置点(b不加引号)、binlog名字(#端口 位置点不能加引号)
change master to
master_host='172.16.1.53',
master_user='rep',
master_port=3306,
master_password='123',
master_log_file='mysql-bin.000003',
master_log_pos=120;
6.从库开启IO线程(连接主库)和sql线程(获取主库信息)
start slave;
7.从库连接主库以后,'IO线程'会向主库的'dump线程'发起询问,询问是否有新数据
8.dump线程被询问,去'查找新数据',并将新数据'返回给IO线程'
9.'IO线程'拿到数据先写入'TCP缓存')(三次握手,四次挥手)
10.'TCP缓存'将数据写入'中继日志relay-log',并返回给IO线程一个'ACK'
11.'IO线程'收到ACK会记录当前位置点到'master.info'
12.'sql线程'会读取relay-log,'执行'从主库获取的sql语句
13.执行完以后将执行到的'位置点,记录'到relay-log.info

#binlog中的位置点放到中继日志relay-log中,位置点数值会发生变化(但是之间的数据不变)
#主从用户的授权必须是*.*
grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
#使用过滤复制,可以使从库只同步主库的某一个库,因此一个从库可以同步不同的主库
#主从复制,从库会同步主库位置点之后的数据变化(之前的并不会同步)

4.主从中涉及到的文件或者线程

1)主库

1.binlog:主库执行的sql语句
2.dump线程:'对比'binlog是否更新,'获取'新的binlog

2)从库

1.IO线程:连接主库,询问新数据,'dump线程'获取新数据
2.SQL线程:'执行'从主库拿来的sql语句
3.relay-log:中继日志,'记录'从主库拿过来的binlog
4.master.info:'记录'主库binlog信息,会随着同步进行更新
5.relay-log.info:'记录'sql线程执行到了哪里,下次从哪里开始'执行'

主从复制的搭建

1.主库操作

1)配置

[root@db03 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/service/mysql/data/mysql-bin

[root@db03 ~]# /etc/init.d/mysqld restart

2)授权一个用户

mysql> grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
Query OK, 0 rows affected (0.03 sec)

3)查看binlog信息

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      326 |   只同步           |  不同步                |                   |
自己去找binlog,然后同步
1 row in set (0.00 sec)

4)导出所有数据

[root@db03 data]# mysqldump -uroot -p -A --master-data=2 --single-transaction > /tmp/full.sql

[root@db03 data]# scp /tmp/full.sql 172.16.1.52:/tmp/

2.从库操作

1)配置

[root@db02 ~]# vim /etc/my.cnf
[mysqld]
server_id=2

[root@db02 ~]# /etc/init.d/mysqld start

2)验证主库用户

[root@db02 ~]# mysql -urep -p -h172.16.1.52

3)同步数据

[root@db02 ~]# mysql -uroot -p123 < /tmp/full.sql

4)配置主从

change master to
master_host='172.16.1.52',
master_user='rep',
master_password='123',
master_log_file='mysql-bin.000018',
master_log_pos=120;

5)开启线程

mysql> start slave;
Query OK, 0 rows affected (0.04 sec)

6)查看主从

mysql> show slave statusG
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            
#如果IO线程和SQL线程都为no,那么就是slave没有开启

主从数据库出错

1)IO线程出错

mysql> show slave statusG
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
            
mysql> show slave statusG
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
            
#排查思路
1.网络
	[root@db02 ~]# ping 172.16.1.53
2.端口
	[root@db02 ~]# telnet 172.16.1.53 3306
3.防火墙(Connecting)
4.主从授权的用户错误
5.反向解析
	skip-name-resolve
6.UUID或server_id相同

2)SQL线程出错

mysql> show slave statusG
             Slave_IO_Running: Yes
            Slave_SQL_Running: No

#原因:
1.主库有的数据,从库没有
2.从库有的数据,主库没有
总而言之就是主从才能够数据不一致,create drop insert 导致SQL线程断开连接

#处理方式一:自欺欺人
1.临时停止同步
mysql> stop slave;
2.将同步指针向下移动一个(需要重复操作,断一次跳一次)
mysql> set global sql_slave_skip_counter=1;
3.开启同步
mysql> start slave;

#处理方式二:掩耳盗铃
1.编辑配置文件
[root@db01 ~]# vim /etc/my.cnf
#在[mysqld]标签下添加以下参数
slave-skip-errors=1032,1062,1007

#处理方式三:正解
重新同步数据,重新做主从(重新获取binlog位置点即可)

# mysql主从复制的意义就是主库和从库数据的一致,如果配置好主从之后,主从数据还不一致,那么主从就失去意义了


一、主从复制(步骤)(异步复制)

1.主库操作

1.配置server_id,开启binlog
2.主库授权用户
grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';
3.查看binlog信息
mysql> show master status;
4.导出数据库数据
[root@db03 mysql]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql

#主库不要change自己,不然要 stop slave;reset slave;

2.从库操作

1.配置server_id
2.配置主从
change master to
master_host='172.16.1.52',
master_user='rep',
master_password='123',
master_log_file='mysql-bin.000003',
master_log_pos=120;
Query OK, 0 rows affected, 2 warnings (2.94 sec)
3.导入数据
mysql> source /tmp/full.sql;
4.开启线程
start slave;
5.查看

UqHM90.md.jpg

二、延时复制

延时从库只做'备份',不提供任何对外服务
#即便不配置主库延时配置,从库SQL线程执行的SQL语句在大数据的情况下,'来不及'执行,仍然会有延迟

#解决主库从库延时复制
1.读写分离,多做几个从库,那个快读哪个
2.拆库拆表
3.基于GTID的主从复制,开启多个SQL线程

1.配置延时复制(已经有主从)

1.停止主从
mysql> stop slave;
Query OK, 0 rows affected (0.03 sec)

2.配置延时时间(reset slave all;)
change master to
master_delay=180;

master_host='172.16.1.52',
master_user='rep',
master_password='123',
master_log_file='mysql-bin.000018',
master_log_pos=120,

3.开启主从
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.1.52 #被用于连接主服务器的当前ip
                  Master_User: rep		#被用于连接主服务器的当前用户
                  Master_Port: 3306
                Connect_Retry: 60	#–master-connect-retry选项的当前值
                
              Master_Log_File: mysql-bin.000001 #I/O线程当前正在读取的主服务器二进制日志文件的名称
          Read_Master_Log_Pos: 468 --------------------
#在当前的主服务器二进制日志中,I/O线程已经读取的位置。
          
               Relay_Log_File: db03-relay-bin.000002	#中继日志
                Relay_Log_Pos: 283	--------------------		
#中继日志位置点
#在主服务器的二进制日志中的(Relay_Master_Log_File, Exec_Master_Log_Pos)对应于在中继日志中的(Relay_Log_File,Relay_Log_Pos)。
        Relay_Master_Log_File: mysql-bin.000001	#主库binlog
        
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            
              Replicate_Do_DB: 	
#使用–replicate-do-db和–replicate-ignore-db选项指定的数据库清单。(过滤库复制白名单)
          Replicate_Ignore_DB: (过滤库复制黑名单)
          
           Replicate_Do_Table: 
#使用–replicate-do-table,–replicate-ignore-table,–replicate-wild-do-table和–replicate-wild-ignore_table选项指定的表清单。
       Replicate_Ignore_Table:  #(过滤表复制白名单)
      Replicate_Wild_Do_Table:  #(过滤表复制黑名单,支持正则)
  Replicate_Wild_Ignore_Table: 
  
                   Last_Errno: 0 #主从数据不一致导致的错误消息数
                   Last_Error: 
                   
                 Skip_Counter: 0  
#最近被使用的用于SQL_SLAVE_SKIP_COUNTER的值
          Exec_Master_Log_Pos: 468 -------------------------
#来自主服务器的二进制日志的由SQL线程执行的上一个时间的位置
              Relay_Log_Space: 455  
#所有原有的中继日志结合起来的总大小
              
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
Until_Condition具有以下值:
o 如果没有指定'UNTIL'子句,则没有值
o 如果从属服务器正在读取,直到达到主服务器的二进制日志的'给定位置'为止,则值为Master
o 如果从属服务器正在读取,直到达到其中继日志的'给定位置'为止,则值为Relay
Until_Log_File和Until_Log_Pos用于指示日志文件名和位置值。日志文件名和位置值定义了'SQL线程在哪个点中止执行'。
                
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
#这些字段显示了被从属服务器使用的参数。这些参数用于连接主服务器。
Master_SSL_Allowed具有以下值:
o 如果允许对主服务器进行SSL连接,则值为Yes
o 如果不允许对主服务器进行SSL连接,则值为No
o 如果允许SSL连接,但是从属服务器没有让SSL支持被启用,则值为Ignored。
与SSL有关的字段的值对应于–master-ca,–master-capath,–master-cert,–master-cipher和–master-key选项的值
               
        Seconds_Behind_Master: 0 
#本字段测量从属服务器SQL线程和从属服务器I/O线程之间的时间差距,单位以秒计
##延时的SQL语句距离在从库执行的已过去时间
        
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 #主
                  Master_UUID: ebc5b10d-cf5f-11ea-b071-000c299d6beb
             Master_Info_File: /service/mysql-5.6.46-linux-glibc2.12-x86_64/data/master.info
             #master_info_file
                    SQL_Delay: 180
                    #sql线程延时180秒
          SQL_Remaining_Delay: NULL
          #延时的SQL语句距离在从库执行的剩余时间(xx秒后执行)
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
                
#延时复制中,延时的SQL语句保存在只能中继日志
[root@db03 data]# ll
total 110668
-rw-rw---- 1 mysql mysql       56 Jul 27 00:49 auto.cnf
-rw-rw---- 1 mysql mysql    37295 Jul 27 01:27 db03.err
-rw-rw---- 1 mysql mysql        5 Jul 27 01:17 db03.pid
-rw-rw---- 1 mysql mysql      172 Jul 27 01:27 db03-relay-bin.000001
-rw-rw---- 1 mysql mysql      374 Jul 27 02:04 db03-relay-bin.000002
-rw-rw---- 1 mysql mysql       48 Jul 27 01:27 db03-relay-bin.index
#延时复制的作用是:做备份,MHA
#当发现主从数据不一致的时候,stop slave;同步主库数据,重新做主从
#同步主库数据,最好重新mysqldump 一下,以免漏数据(别人刷新了binlog)
#reset slave;刷新从库binlog(清空)
#如果没有做主从复制,可以关闭主库的binlog来达到’避免binlog内脏数据的记录‘,

2.配置延时复制(没有主从)

1.搭建出一台mysql
同步数据mysqldump
2.配置主从
mysql> change master to
    -> master_host='172.16.1.51',
    -> master_user='rep',
    -> master_password='123',
    -> master_log_file='mysql-bin.000001',
    -> master_log_pos=424,
    
    -> master_delay=180;
3.开启线程
mysql> start slave;

#可以自由选择主库位置点

3.关闭延时从库

mysql> stop slave;
mysql> change master to master_delay=0;
mysql> start slave;

4.注意:

#如果做了主从,就不能关闭主库的binlog了,因为主库执行的drop在中级日志中已经记录,从库早晚都会执行(删库),
	所以把主库的binlog'一直开启',这样从库的中继日志就可以通过主库的恢复来恢复,'但是从库的slave要关闭'(实际上从库还是会执行主库执行错的语句,只不过又执行了重建语句)
	如果'关闭'了主库的binlog,那么从库将不能恢复,主从数据不一致,主从复制失败

#binlog一致开启就好

UqHM90.md.jpg

实例

#思考问题:
总数据量级500G,正常备份去恢复需要1.5-2小时
1)配置延时3600秒
mysql>CHANGE MASTER TO MASTER_DELAY = 3600;

2)主库
drop database db;

3)怎么利用延时从库,恢复数据?
提示:
1、从库relaylog存放在datadir目录下
2、mysqlbinlog 可以截取relaylog内容(#relaylog就是binlog)
3、show relay log events in 'db01-relay-bin.000001'; (#看drop之前)


#处理的思路:
1)停止SQL线程(#防止从库执行drop语句损坏'备份'数据)
mysql> stop slave sql_thread;

2)截取relaylog到误删除之前点
relay-log.info 获取到上次运行到的位置点,作为'恢复起点'
分析relay-log的文件内容,获取到'误删除之前'position

#实例
1)关闭延时
mysql -S /data/3308/mysql.sock
mysql> stop slave;
mysql> CHANGE MASTER TO MASTER_DELAY = 0;
mysql> start slave;

2)模拟数据
mysql -S /data/3307/mysql.sock
source  /root/world.sql
use world;
create table c1 select * from city;		#创建且复制数据
create table c2 select * from city;

3)开启从库延时5分钟
mysql -S /data/3308/mysql.sock
show slave status G
stop slave;
CHANGE MASTER TO MASTER_DELAY = 300;	#延时同步
start slave;
mysql -S /data/3307/mysql.sock
use world;
create table c3 select * from city;		#模拟延时同步后数据的写入
create table c4 select * from city;

4)破坏,模拟删库故障。(以下步骤在5分钟内操作完成。)
mysql -S /data/3307/mysql.sock
drop database world;

5)从库,关闭SQL线程
mysql -S /data/3308/mysql.sock
stop slave sql_thread;  #只关闭SQL线程

6)截取relay-log
#备份起点:
cd /data/3308/data/
cat relay-log.info
./db01-relay-bin.000002	
283
#终点:(drop之前)
mysql -S /data/3308/mysql.sock
show relaylog events in 'db01-relay-bin.000002'
db01-relay-bin.000002 | 268047 

mysqlbinlog --start-position=283  --stop-position=268047 /data/3308/data/db01-relay-bin.000002 >/tmp/relay.sql 

#可以通过relay.sql恢复从库到drop之前,恢复了之后,也可以通过Mysqldump -d导出指定库的SQL语句,再导入到主库,主库恢复
1)取消从库身份
mysql> stop io_thread;
mysql> reset slave all;

2)恢复数据
mysql> set sql_log_bin=0;
mysql> source /tmp/relay.sql
mysql> use world
mysql> show tables;


三、半同步复制(实时同步)

UqHM90.md.jpg

1.半同步复制概念

从'MYSQL5.5'开始,支持半自动复制。
之前版本的MySQL Replication都是'异步'(asynchronous)的,(dump线程和IO线程之间没有延迟,IO 线程和SQL线程在'大量访问'的时候即便不配置延时复制,仍然会有'延迟')

主库在执行完一些事务后,是'不会管'备库的进度的。
如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),
这时'备库中的数据就是不完整的'。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。
'半同步复制'(Semi synchronous Replication)则一定程度上保证提交的事务已经传给了至少一个备库。出发点是保证主从数据一致性问题,安全的考虑。

5.5 出现概念,但是不建议使用,性能太差(#IO线程阻止主库SQL语句的执行)
5.6 出现group commit 组提交功能,来提升开启半同步复制的性能
5.7 更加完善了,在group commit基础上出现了MGR(#主库高可用)
5.7 的增强半同步复制的新特性:after commit; after sync;

#缺点:
1.性能差,影响主库效率
2.半同步复制,有一个超时时间(IO线程等待SQL线程时间),超过这个时间'恢复主从复制'
3.当数据量很大的时候,SQL线程的语句还没有执行的话,会组织主库数据的写入
4.#小的访问量可以做半同步复制

#半同步复制是在主从复制的基础上做的

2.配置半同步

1)主库操作

#登录数据库
[root@db01 ~]# mysql -uroot -p123
#查看是否有动态支持
mysql> show global variables like 'have_dynamic_loading';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| have_dynamic_loading | YES   |
+----------------------+-------+
#安装自带插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
#启动插件(临时开启)
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
#设置超时
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;

#修改配置文件,在[mysqld]标签下添加如下内容(不用重启库)
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000

检查安装:
mysql> show variables like'rpl%';
+------------------------------------+----------+
| Variable_name                      | Value    |
+------------------------------------+----------+
| rpl_semi_sync_master_enabled       | ON       |	#
| rpl_semi_sync_master_timeout       | 10000    |
| rpl_semi_sync_master_trace_level   | 32       |
| rpl_semi_sync_master_wait_no_slave | ON       |	#
| rpl_stop_slave_timeout             | 31536000 |	#停止主从的时间
+------------------------------------+----------+
mysql> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     | #有几个客户端
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     | #

#数据库自带的未安装的插件(.so)
[root@db02 ~]# ll /service/mysql/lib/plugin/
total 3484
-rwxr-xr-x 1 7161 31415  16581 Sep 27  2019 adt_null.so
-rwxr-xr-x 1 7161 31415 426219 Sep 27  2019 semisync_master.so  #
-rwxr-xr-x 1 7161 31415 249327 Sep 27  2019 semisync_slave.so   #
-rwxr-xr-x 1 7161 31415  14173 Sep 27  2019 test_udf_services.so
-rwxr-xr-x 1 7161 31415  99629 Sep 27  2019 udf_example.so
-rwxr-xr-x 1 7161 31415 193667 Sep 27  2019 validate_password.so

2)从库操作

#登录数据库
[root@mysql-db02 ~]# mysql -uroot -p123
#安装slave半同步插件
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';
#启动插件
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
#重启io线程使其生效
stop slave io_thread;
start slave io_thread;
#编辑配置文件(不需要重启数据库),在[mysqld]标签下添加如下内容
[root@mysql-db02 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_slave_enabled =1
#查看是否生效
mysql> show global status like 'rpl_semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+

#
mysql> create database sssss;
Query OK, 1 row affected (0.01 sec)

mysql>  show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |  #主库半同步复制有几个客户端
| Rpl_semi_sync_master_net_avg_wait_time     | 1812  |
| Rpl_semi_sync_master_net_wait_time         | 1812  |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    | #主库是否开启半同步
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 2273  |
| Rpl_semi_sync_master_tx_wait_time          | 2273  |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     | #从库执行半同步的SQL语句
+--------------------------------------------+-------+

3)额外参数

rpl_semi_sync_master_timeout=milliseconds(#默认)
设置此参数值(ms),为了防止半同步复制在没有收到确认的情况下发生堵塞,如果Master在超时之前没有收到任何确认,将恢复到正常的异步复制,并继续执行没有半同步的复制操作。

rpl_semi_sync_master_wait_no_slave={ON|OFF}
如果'一个事务被提交',但Master'没有任何Slave的连接',这时不可能将事务发送到其它地方保护起来。默认情况下,'Master会在时间限制范围内继续等待Slave的连接',并'确认'该事务已经被正确的写到磁盘上。
可以使用此参数选项关闭这种行为,在这种情况下,如果没有Slave连接,Master就会恢复到异步复制。
#企业架构

1.开发环境	
	2台
2.测试环境 (沙盒环境一般游戏公司做)
	2台
	测试并发等
	部署环境与生产一样
3.灰度发布(不删档内测)
4.生产环境
	20台机子
	
#除了开发环境,别的环境都需要运维维护

四、过滤复制

1.过滤复制的方式

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      305 |   白名单      |    黑名单        |                   |
+------------------+----------+--------------+------------------+-------------------+

1)白名单

#从库
只过滤库
replicate-do-db=test
只过滤库下表
replicate-do-table=test.t1
只过滤库下以t开头的表
replicate-wild-do-table=test.t*
#主库
binlog-do-db=test
binlog-do-table=test.t1
binlog-wild-do-table=test.t*

2)黑名单

#从库
replicate-ignore-db=test
replicate-ignore-table=test.t1
replicate-wild-ignore-table=test.t*
#主库
binlog-ignore-db=test
binlog-ignore-table=test.t1
binlog-wild-ignore-table=test.t*

2.从库配置过滤复制

1)主库创建两个库

create database wzry;
create database lol;

#过滤复制只在配置了之后才会'过滤'并复制该库以后的内容
#不管是主从复制,延时复制,半同步复制,过滤复制,都要先同步数据,再做主从复制

2)第一台从库配置

[root@db02 data]# vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=wzry

[root@db02 data]# systemctl restart mysqld

#查看主从状态
mysql> show slave statusG
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: wzry  #从库配置文件中指定要同步的库

3)配置第二台从库

[root@db03 ~]# vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=lol

[root@db03 ~]# systemctl restart mysqld

#查看主从状态
mysql> show slave statusG
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: lol #从库要同步主库的库

4)验证过滤复制

#1.主库操作
use wzry
create table cikexintiao(id int);
use lol
create table fuleierzhuode(id int);

#第一台从库查看
mysql> use wzry
mysql> show tables;
+----------------+
| Tables_in_wzry |
+----------------+
| cikexintiao    |
+----------------+
mysql> use lol
mysql> show tables;

#第二台从库查看
mysql> use wzry
mysql> show tables;
mysql> use lol
mysql> show tables;
+---------------+
| Tables_in_lol |
+---------------+
| fuleierzhuode |
+---------------+

3.配置过滤多个库

1)方法一:

[root@db02 data]# vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=wzry,lol

2)方法二:

[root@db02 data]# vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=wzry
replicate-do-db=lol

4.过滤复制配置在主库

1.配置(#只过滤)
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/usr/local/mysql/data/mysql-bin
binlog-do-db=wzry

2.查看主库状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      120 | wzry         |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

3.在主库的wzry库和lol库添加数据

4.从库查看数据,只能看到wzry库的数据

5.过滤复制总结

#配置在从库时
1.配置白名单:IO线程将主库的数据拿到了relay-log,但是sql线程'只执行白名单配置'的数据库相关语句
1.配置黑名单:IO线程将主库的数据拿到了relay-log,但是sql线程'只不执行黑名单配置'的数据库相关语句

#配置在主库时
1.配置白名单:binlog'只记录'白名单相关的sql语句
2.配置黑名单:binlog'只不记录'黑名单相关的sql语句

#所以过滤复制一般配置在从库,因为如果配置在了主库,那么binlog将部分记录

五、基于GTID的主从复制

1.什么是GTID

1.'全局事务标识符'
2.组成:UUID + TID    #数据库的id+事务的id(依次递增)
	   f03a53e0-cd46-11ea-a2c4-000c292c767e:1
#UUID
[root@db02 ~]# cat /service/mysql/data/auto.cnf 
[auto]
server-uuid=ebc5b10d-cf5f-11ea-b071-000c299d6beb

#停止主从
stop slave;
reset slave all;

2.GTID主从复制的优点

1.GTID同步时开启'多个SQL线程','每一个库'同步时开启'一个线程'
2.binlog在'rows模式下',binlog内容比'寻常'的主从更加简洁
3.GTID主从复制会记录主从信息,'不需要手动配置binlog和位置点'

3.GTID主从复制的缺点

1.备份时更加麻烦,需要额外加一个参数 --set-gtid=on
2.主从复制出现错误,没有办法跳过错误(#不能跳过就不能跳过吧)

4.搭建GTID主从复制

1)配置三台数据库

#配置第一台主库
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/usr/local/mysql/data/mysql-bin

#配置第一台从库
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
server_id=2

#配置第二台从库
[root@db03 ~]# vim /etc/my.cnf
[mysqld]
server_id=3

2)查看是否开启GTID

mysql> show variables like '%gtid%';
+---------------------------------+-----------+
| Variable_name                   | Value     |
+---------------------------------+-----------+
| binlog_gtid_simple_recovery     | OFF       |
| enforce_gtid_consistency        | OFF       |
| gtid_executed                   |           |
| gtid_mode                       | OFF       |
| gtid_next                       | AUTOMATIC |
| gtid_owned                      |           |
| gtid_purged                     |           |
| simplified_binlog_gtid_recovery | OFF       |
+---------------------------------+-----------+
8 rows in set (0.00 sec)

3)开启GTID

#主库配置
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/usr/local/mysql/data/mysql-bin
gtid_mode=on
enforce_gtid_consistency
log-slave-updates

#从库1的配置
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
server_id=2
log_bin=/usr/local/mysql/data/mysql-bin
gtid_mode=on
enforce_gtid_consistency
log-slave-updates

#从库2的配置
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
server_id=3
log_bin=/usr/local/mysql/data/mysql-bin
gtid_mode=on
enforce_gtid_consistency
log-slave-updates


4)扩展

#配置log-slave-updates参数的场景(主库的binlog在写入中继日志的同时,也写入从库的binlog)
1.基于GTID的主从复制(报错)
2.双主架构,mysql+keepalived
3.级联复制
4.MHA

5)主库创建用户

mysql> grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';

6)主库数据同步到从库

mysqldump -uroot -p -R --triggers --master-data=2 --single-transaction -A > /tmp/full.sql
scp ...
mysql ... < full.sql

7)从库配置主从

change master to
master_host='172.16.1.51',
master_user='rep',
master_password='123',
master_auto_position=1;

#自动连接主库位置点(当前binlog 120)
master_auto_position=1
原文地址:https://www.cnblogs.com/syy1757528181/p/13405363.html