环境
硬件
配置 | 测试配置 |
---|---|
CPU | 1.8GHz |
内存 | 4GB |
核心 | 4核 |
带宽 | 1000Mb |
软件
- VMware® Workstation 16 Pro 16.1.1 build-17801498
- CentOS Linux release 7.6.1810 (Core)
- Mysql 5.7
规划
HOST | IP | 说明 |
---|---|---|
node3 | 192.168.88.88 | 主节点 |
node4 | 192.168.88.94 | 备份节点 |
知识点
binlog形式
statement:就是把每一条SQL记录到binlog中。
row:是把每一行修改的具体数据记录到binlog中。
mixed:MySQL会灵活的区分,需要记录sql还是具体修改的记录。
只记录SQL的话binlog会比较小,但是有些SQL语句在主从同步数据的时候,可能会因为选择不同的索引在数据同步过程中出现数据不一致。记录Row的话就可以保证主从同步不会存在SQL语意偏差的问题,同时Row类型的日志在做数据恢复的时候也比较容易,但是Row会导致binlog过大。
同步策略
异步模式:主库按照自己的流程处理完数据,会直接返回结果,不会等待主库和从库之间的数据同步。 优点:效率高。 缺点:Master节点挂掉之后,Slave节点会丢失数据。
全同步模式:主库会等待所有从库都执行完sql语句并ACK完成,才返回成功。 优点:有很好的数据一致性保障。 缺点:会造成数据操作延迟,降低了MySQL的吞吐量。
半同步模式:主库会等待至少有一个从库把数据写入relay log并ACK完成,才成功返回结果。 半同步模式介于异步和全同步之间。
after_commit 与 after_sync
after_commit:
- Master节点写数据到Binlog,并且执行Sync操作。
- Master发送数据给Slave节点,同时commit主库的事务。
- 收到ACK后Master节点把数据返回给客户端。
主库等待ACK时,事务已经commit,主库的其他事务可以读到commit的数据,这个时候如果Master崩溃,slave数据丢失,发生主从切换,会导致出现幻读。
after_sync:
- Master节点写数据到Binlog,并且执行Sync操作。
- Master发送数据给Slave节点,等等slave的ACK通知。
- 收到ACK后Master节点commit事务。
after_sync是mysql5.7才推出的模式,解决after_commit主从切换可能产生幻读的问题。
GTID
GTID是MYSQL5.6新增的特性,GTID(Global Transaction Identifier)全称为全局事务标示符,用以数据库实例事务唯一标识,其组成主要是source_id和transaction_id 即GTID = source_id:transaction_id。其中source_id是数据库启动自动生成的数据库实例唯一标识,保存在配置文件中,而transaction_id则是事务执行的序列号。
搭建过程
安装mysql5.7
参考之前文章《CentOS7 通过yum安装Mysql》
迁移存储文件目录
参加之前文章《Mysql 5.7 修改存储文件目录》
同步策略采用半同步策略,使用after_sync,事务采用GTID。
主节点配置
vim /etc/my.cnf
MASTER配置信息
[client]
socket=/joinway/data/mysql/mysql.sock
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
datadir=/joinway/data/mysql
socket=/joinway/data/mysql/mysql.sock
skip-external-locking=1
skip-name-resolve=1
server_id=88
log_timestamps=system
log_bin = /joinway/data/mysql/node3-mysql-bin
log_bin_index = /joinway/data/mysql/node3-mysql-bin.index
binlog_ignore_db=mysql
binlog_ignore_db=information_schema
relay_log_recovery=ON
relay_log=/joinway/data/mysql/node3-mysql-relay-bin
relay_log_index=/joinway/data/mysql/node3-mysql-relay-bin.index
plugin_load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 3000
symbolic-links=0
gtid_mode=on
enforce-gtid-consistency=on
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
创建salve用户。
mysql -p
# 只读赋权
GRANT SELECT ON *.* TO 'salve'@'192.168.88.94' IDENTIFIED BY 'Slave!23';
# 从权限 赋权
GRANT REPLICATION SLAVE ON *.* TO 'salve'@'192.168.88.94' IDENTIFIED BY 'Slave!23';
# 刷新权限
FLUSH PRIVILEGES;
查看master状态
SLAVE配置信息
[client]
socket=/joinway/data/mysql/mysql.sock
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
datadir=/joinway/data/mysql
socket=/joinway/data/mysql/mysql.sock
skip-external-locking=1
skip-name-resolve=1
server_id=94
log_timestamps=system
log_bin = /joinway/data/mysql/node4-mysql-bin
log_bin_index = /joinway/data/mysql/node4-mysql-bin.index
binlog_ignore_db=mysql
binlog_ignore_db=information_schema
relay_log_recovery=ON
relay_log=/joinway/data/mysql/node4-mysql-relay-bin
relay_log_index=/joinway/data/mysql/node4-mysql-relay-bin.index
plugin_load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 3000
symbolic-links=0
gtid_mode=on
enforce-gtid-consistency=on
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
开启同步
mysql -p
stop slave;
CHANGE MASTER TO MASTER_HOST='192.168.88.88',MASTER_USER='salve', MASTER_PASSWORD='Slave!23',MASTER_AUTO_POSITION=1;
start slave;
show slave status\G;
常用维护命令。
show slave status\G
show master status\G
show processlist \G
reset master;
reset slave;
stop slave;
start slave;
show variables like '%gtid%';
测试
master 添加数据
mysql -p
在master上添加数据。
show databases;
create database db_test;
use db_test;
create table t_test(c_name varchar(8));
insert into t_test values ('aaa');
select c_name from t_test;
slave同步状态
mysql -p
在slave上查看
show databases;
use db_test;
select c_name from t_test;
数据同步成功。