本环境是基于 Centos 7.8 系统构建MySQL-5.7.14
具体构建,请参考 MySQL-5.7.14 环境构建
功能介绍
是我们人为配置的一种特殊从库.人为配置从库和主库延时N小时.
为什么要有延时从:
解决数据库故障的问题
- 物理损坏: 主从复制非常擅长解决物理损坏,比如主库rm 删除数据库数据,直接将应用切换到从库.
- 逻辑损坏:普通主从复制没办法解决逻辑损坏,比如主库 drop database dbname
故障恢复思路:
- 1主1从,从库延时5分钟,主库误删除1个库
- 5分钟之内 侦测到误删除操作
- 停从库SQL线程
- 截取relaylog
- 起点 :停止SQL线程时,relay最后应用位置
- 终点:误删除之前的position(GTID)
- 恢复截取的日志到从库
- 从库身份解除,替代主库工作
案例实施
从库配置延时同步
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_delay=300;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
主库创建relay数据库、relay表,并插入两条数据
mysql> create database relay;
Query OK, 1 row affected (0.00 sec)
mysql> use relay;
Database changed
mysql> create table tb1(id int);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into tb1 values(1),(2);
Query OK, 2 rows affected (0.17 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from tb1;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
查看从库延时同步状态
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
从库
# 停止sql线程
mysql> stop slave sql_thread;
Query OK, 0 rows affected (0.00 sec)
[root@mysql-source_code ~]# mkdir /backup/mysqld/ -p
[root@mysql-source_code ~]# mysqlbinlog --start-position=385 --stop-position=908 mysql-source_code-relay-bin.000002 -r /backup/mysqld/relay.sql
[root@mysql-source_code ~]# ll /backup/mysqld/relay.sql
-rw-r----- 1 root root 2707 Feb 6 11:35 /backup/mysqld/relay.sql
恢复从库中继日志
mysql> source /backup/mysqld/relay.sql
查看从库恢复数据状况
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| mysql |
| performance_schema |
| relay |
| sys |
+--------------------+
7 rows in set (0.00 sec)
mysql> use relay
Database changed
mysql> select * from tb1;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
从库身份解除
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0.01 sec)
功能介绍
过滤复制可以从两方面下手:
- 配置主库的dump线程, 让其只发送需要同步的db二进制
- 配置从库的sql线程, 让其只回放我们需要同步的db二进制文件
修改主控配置文件
[root@mysql-yum ~]# vim /etc/my.cnf
binlog_ignore_db=d2
[root@mysql-yum ~]# systemctl restart mysqld
主库创建数据库
mysql> create database d1;
Query OK, 1 row affected (0.00 sec)
mysql> create database d2;
Query OK, 1 row affected (0.00 sec)
mysql> create database d3;
Query OK, 1 row affected (0.00 sec)
mysql> show databases like 'd_';
+---------------+
| Database (d_) |
+---------------+
| d1 |
| d2 |
| d3 |
+---------------+
3 rows in set (0.00 sec)
从库查看
mysql> show databases like 'd_';
+---------------+
| Database (d_) |
+---------------+
| d1 |
| d3 |
+---------------+
2 rows in set (0.00 sec)
修改从库配置文件
[root@mysql-source_code ~]# vim /etc/my.cnf
[mysqld3307]
replicate_ignore_db=mysql_1
[root@mysql-source_code ~]# mysqld_multi stop 3307
[root@mysql-source_code ~]# mysqld_multi start 3307
主库创建数据库
mysql> create database mysql_1;
Query OK, 1 row affected (0.00 sec)
mysql> create database mysql_2;
Query OK, 1 row affected (0.00 sec)
mysql> create database mysql_3;
Query OK, 1 row affected (0.00 sec)
mysql> show databases like 'mysql__';
+--------------------+
| Database (mysql__) |
+--------------------+
| mysql_1 |
| mysql_2 |
| mysql_3 |
+--------------------+
3 rows in set (0.00 sec)
从库查看
mysql> show databases like 'mysql__';
+--------------------+
| Database (mysql__) |
+--------------------+
| mysql_2 |
| mysql_3 |
+--------------------+
2 rows in set (0.00 sec)
无论是级联情况,还是一主多从情况,都可以通过GTID自动找点儿,而无需像之前那样通过File_name和File_position找点儿了。
具体原理
- master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
- slave端的i/o 线程将变更的binlog,写入到本地的relay log中。
- sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
- 如果有记录,说明该GTID的事务已经执行,slave会忽略。
- 如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog
案例实施
配置主库配置文件
[root@mysql-yum ~]# vim /etc/my.cn
[mysqld]
log_bin=mysql-bin
server_id=1
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[root@mysql-yum ~]# systemctl restart mysqld
主库创建同步账号
mysql> grant replication slave on *.* to zwq@'192.168.5.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec
配置从库配置文件
[root@localhost ~]# vim /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = zwq
pass = 123456
[mysqld3306]
socket = /mysql/3306/mysql.sock
port = 3306
pid-file = /mysql/3306/mysql.pid
datadir = /mysql/3306/data
basedir = /usr/local/mysql
server_id=2
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysqld3307]
socket = /mysql/3307/mysql.sock
port = 3307
pid-file = /mysql/3307/mysql.pid
datadir = /mysql/3307/data
basedir = /usr/local/mysql
server_id=3
replicate_ignore_db=mysql_1
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[root@mysql-source_code ~]# mysqld_multi stop 3306,3307
[root@mysql-source_code ~]# netstat -lnutp | grep 330
[root@mysql-source_code ~]# mysqld_multi start 3306,3307
[root@mysql-source_code ~]# netstat -lnutp | grep 330
tcp6 0 0 :::3306 :::* LISTEN 3932/mysqld
tcp6 0 0 :::3307 :::* LISTEN 3949/mysqld
--- 3306
mysql> change master to
-> master_host='192.168.5.11',
-> master_user='zwq',
-> master_password='123456',
-> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.06 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
--- 3307
mysql> change master to
-> master_host='192.168.5.11',
-> master_user='zwq',
-> master_password='123456',
-> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.11 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
测试:
创建数据库
mysql> create databases s1;
mysql> show databases like 's_';
+---------------+
| Database (s_) |
+---------------+
| s1 |
+---------------+
1 row in set (0.00 sec)
从库查看
--- 3306
mysql> show databases like 's_';
+---------------+
| Database (s_) |
+---------------+
| s1 |
+---------------+
1 row in set (0.01 sec)
--- 3307
mysql> show databases like 's_';
+---------------+
| Database (s_) |
+---------------+
| s1 |
+---------------+
1 row in set (0.00 sec)
半同步简介: 解决主从数据一致性问题
在默认情况下,MySQL的复制是异步的,这意味着主服务器及其从服务器是独立的。异步复制可以提供最佳的性能,因为主服务器在将更新的数据写入它的二进制日志(Binlog)文件中后,无需等待验证更新数据是否已经复制到从服务器中,就可以自由处理其它进入的事务处理请求。但这也同时带来了很高的风险,如果在主服务器或从服务器端发生故障,会造成主从数据的不一致,甚至在恢复时造成数据丢失。
从MySQL5.5开始引入了一种半同步复制功能,该功能可以确保主服务器和访问链中至少一台从服务器之间的数据一致性和冗余。在这种配置结构中,一台主服务器和其许多从服务器都进行了配置,这样在复制拓扑中,至少有一台从服务器在父主服务器进行事务处理前,必须确认更新已经收到并写入了其中继日志 (Relay Log)。当出现超时,源主服务器必须暂时切换到异步复制模式重新复制,直到至少有一台设置为半同步复制模式的从服务器及时收到信息。
继5.5半同步复制后,MySQL5.6又对其进行了优化和改进,其中有两个地方较为重要:
- 在主从切换后,在传统的方式里,需要找到binlog和POS点,然后更改master指向,而在mysql5.6里,你无须再知道binlog和POS点,你只需要知道master的IP、端口,账号密码即可,因为同步复制是自动的,mysql通过内部机制GTID自动找点同步。
- 多线程复制,以前的版本,同步复制是单线程的,只能一个一个执行,在MySQL5.6里,可以做到多个库之间的多线程复制,但一个库里的表,多线程复制是无效的。
配置思路
加载插件
主:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
从:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
查看是否加载成功:
show plugins;
启动:
主:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
从:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
重启从库上的IO线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
查看是否在运行
主:
show status like 'Rpl_semi_sync_master_status';
从:
show status like 'Rpl_semi_sync_slave_status';