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)图解
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 status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#如果IO线程和SQL线程都为no,那么就是slave没有开启
主从数据库出错
1)IO线程出错
mysql> show slave status\G
Slave_IO_Running: No
Slave_SQL_Running: Yes
mysql> show slave status\G
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 status\G
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.查看
二、延时复制
延时从库只做'备份',不提供任何对外服务
#即便不配置主库延时配置,从库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 status\G
*************************** 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一致开启就好
实例
#思考问题:
总数据量级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;
三、半同步复制(实时同步)
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 status\G
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 status\G
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