学习的时候可以直接使用docker的mysql镜像搞,就不用多台机器或者虚拟机了。
参考命令:
// 创建网络,在同一个网络的容器可以直接使用容器的名字进行通信
docker network create mysql-copy-network
// 创建主节点
docker run --name mysql80-M -e MYSQL_ROOT_PASSWORD=root -d --net mysql-copy-network mysql:8.0
// 创建从节点
docker run --name mysql80-S -e MYSQL_ROOT_PASSWORD=root -d --net mysql-copy-network mysql:8.0
创建完毕之后,进入从节点,确保从节点可以ping通主节点(ping mysql80-M)。
异步复制(默认)
Master将事务binlog事件写入到binlog文件中,此时Master会通知Dump线程发送这些新的binlog,然后Master就会继续处理提交操作,而不会保证这些binlog传到任何一个Slave节点上。
配置主节点
首先,修改配置文件,加入以下配置。
[mysqld]
server_id=1
log-bin=mysql-bin
binlog-ignore-db=mysql
主要是设置服务器的server_id,打开binlog,设置不同步的库(mysql)。
重启mysql服务。
其次,添加用户供从库连接主库使用(使用MySQL客户端连上主节点,然后执行以下命令)。
CREATE user 'repl'@'从库ip' IDENTIFIED WITH mysql_native_password by '密码';
grant replication slave on *.* to 'repl'@'从库ip';
flush privileges;
接着查看主库的状态:
show master status;
记下结果中的File和Position,示例:
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 844 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
配置从节点
首先,修改从节点的配置:
[mysqld]
server_id=2
重启MySQL服务。
其次,配置从库连接主库所需要的信息(使用MySQL客户端连上从节点,然后执行以下命令):
change master to master_host='主库ip', master_port=3306,
master_user='repl',
master_password='刚才配置的密码',
master_log_file='刚才配置主节点时显示的file,如mysql-bin.000001',
master_log_pos=刚才配置主节点时显示的Position,如844;
启用复制:
start slave;
查看从库状态:
show slave status\G
如果输出的信息中包含:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
说明IO线程和SQL线程正常运行,可以正常工作。
确认复制工作正常
在主库上创建数据库test_for_copy、创建表student、插入测试数据:
create database test_for_copy;
use test_for_copy;
create table student(id int primary key auto_increment, name varchar(255), age int);
insert into student(name, age) VALUES('zhang san', 18);
在从库上查询数据:
use test_for_copy;
select * from student;
正常情况下,从库应该能查到主库插入的数据。
半同步复制
半同步复制是通过插件Semi-sync实现的。
说明:
必须在主库和从库都启用半同步复制,否则会使用异步复制。
如果在主库启用了半同步复制,并且至少有一个支持半同步复制的从库,则主库上执行事务提交的线程将等待,直到至少一个半同步从库确认已收到事务的所有事件(从库会向主库发送ACK),或者直到发生超时。
只有在将事件写入中继日志并刷新到磁盘后,从库才会确认收到事件的事件,向主库发送ACK。
配置主节点
确认是否已经安装半同步插件rpl_semi_sync_master(默认是没有安装的):
show plugins;
如果输出里,没有rpl_semi_sync_master,说明没有安装,需要安装。
安装半同步插件:
install plugin rpl_semi_sync_master soname 'semisync_master.so'
安装后可以再次show plugins,确认已经正确安装。
启用主库的半同步:
show variables like 'rpl%';
set persist rpl_semi_sync_master_enabled=on;
确认主节点的半同步已经开始:
show global status like 'rpl%';
应该输出:
+--------------------------------------------+-------+
| 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_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
配置从节点
同理安装插件,需要注意的是,从库装的插件和主库是不一样的:
install plugin rpl_semi_sync_slave soname 'semisync_slave.so'
启用插件:
show variables like 'rpl%';
set persist rpl_semi_sync_slave_enabled=on;
重启IO线程:
stop slave io_thread;
start slave io_thread;
确保从节点的半同步已经开启:
show global status like 'rpl%';
应该输出:
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
验证半同步功能正常
在主库插入一条数据:
INSERT INTO student(name, age) VALUES('wang wu', 19);
再看主库的状态:
show global status like 'rpl%';
其中,Rpl_semi_sync_master_yes_tx应该变为1,这个参数指的是已经成功使用半同步处理的事务数。
延时复制
设置一个固定的延迟时间(n秒),即当主库数据发生变更时,从库隔n秒才开始同步。
只需要在Slave节点修改master_delay参数即可。
stop slave;
change master to master_delay=10; -- 延迟10s
start slave;