MySQL 学习 - Replication集群 - 搭建 - GTID模式
程序员文章站
2024-03-21 08:54:10
...
前言
GTID(Global Transaction ID)是MySQL5.6引入的功能,可以在集群全局范围标识事务,用于取代过去通过binlog文件偏移量定位复制位置的传统方式。借助GTID,在发生主备切换的情况下,MySQL的其它Slave可以自动在新主上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。
本文根据GTID搭建,MySQL 5.6 后引入支持
- Replication集群是MySQL自带的数据同步机制
- MySQL通过读取、执行另一个MySQL的bin_log日志,实现数据同步
使用限制
- 无法再使用 create table … select 建立表
- 无法再事务中使用 create temporary table 建立临时表
- 无法使用关联更新同时更新事务表和非事务表
基本原理
具体流程
- 主库将变更写入到主库的binlog中
- 从库的IO进程读取主库binlog内容存储到Relay Log日志中
- 从库的SQL进程读取Relay Log日志中内容在从库中重放
Master 与 Slave 是单向同步的,如果我们想要双向同步,可以让双方互为主从关系
配置主从数据库服务器参数
参数 | 说明 |
---|---|
log_bin | 启动二进制日志,配置路径就为存储路径 如配置 mysql-bin 那就会放入datadir 并以这个为前缀 |
server-id | 在mysql集群中每个id都不一致,建立建议使用服务器IP后两段作为ID 比如192.168.10.68 ID可以命名为 1068 |
relay_log | 启动 relay_log,配置路径就为存储路径 如配置 relay-bin 那就会放入datadir 并以这个为前缀 |
relay_only | 不能执行写操作的,不管有没有 save权限,但supper用户依旧可以,如:root 好处是:避免误操作写入从服务器,导致主从数据不一致 |
super_read_only | super用户也不可以执行写操作,Mysql>=5.7 |
skip_slave_start | 在slave服务器重启后,不会自动启动复制链路 正常情况我们需要检查没有问题后,手动启动 |
master_info_repository | 存储到数据库表中 |
relay_log_info_repository | 将主从同步的信息,存储到innodb的表中 |
流程
-
主节点必须开启binlog日志,主从节点都要开启server_id
-
主节点的同步账号必须具有reload、super、replication slave 权限
-
主从节点的配置文件都要开启GTID,否则无法利用延时节点找回数据
[mysqld] log_bin = mysql-bin server-id = 10565 gtid_mode = on enforce-gtid-consistency log-slave-updates = on
-
从节点必须开启 relay_log 日志
[mysqld] log_bin = mysql-bin server-id = 10566 # gtid gtid_mode = on enforce-gtid-consistency log-slave-updates = on relay_log = relay-bin
-
slave打开只读属性,避免程序误写入,导致主从失效
read_only = on super_read_only = on
环境配置
环境说明
主机名 | IP | 角色 |
---|---|---|
docker-master | 192.168.105.65 | Master |
docker-slave | 192.168.105.66 | Slave |
mysql配置文件 my.cnf
vim my.cnf
[client]
socket = /var/run/mysqld/mysqld.sock
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/datadir
basedir = /var/lib/mysql
log_bin = mysql-bin
relay_log = relay-bin
server-id = 1111
# 数据字符集
character_set_server = utf8
# 允许远程访问的IP地址
bind-address = 0.0.0.0
# 跳过DNS解析
skip-name-resolve
symbolic-links= 0
# gtid
gtid_mode = on
enforce-gtid-consistency
log-slave-updates = on
master节点
server-id = 10565
slave节点
server-id = 10566
两个节点启动docker
如果你还不会Docker建议学一下把,我博客也有文章
docker run -d -p 3306:3306 --name my-mysql \
-v $PWD/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
-v $PWD/db_backup:/data/db_backup \
-v $PWD/mysql:/var/lib/mysql \
-v $PWD/datadir:/var/lib/datadir \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7.27
master节点操作
登录mysql
mysql -uroot -p123456
首先创建一个用户
create user 'backup'@'%' identified by '123456';
进行授权
相比全量备份,多了一个 replication slave
grant select,reload,lock tables,replication slave,replication client,show view,event,process,file on *.* to 'backup'@'%';
查看
show grants for 'backup'@'%';
创建数据库,创建测试表
create database test;
use test;
CREATE TABLE `student` (
`student_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`student_name` varchar(64) NOT NULL COMMENT '学生名字',
PRIMARY KEY (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入数据
INSERT INTO student(`student_id`, `student_name`) VALUES (1, 'A');
INSERT INTO student(`student_id`, `student_name`) VALUES (2, 'B');
INSERT INTO student(`student_id`, `student_name`) VALUES (3, 'C');
INSERT INTO student(`student_id`, `student_name`) VALUES (4, 'D');
Slave节点
登录mysql
mysql -uroot -p123456
停止slave
stop slave;
修改链路
change master to
master_host='192.168.105.65',
master_port=3306,
master_user='backup',
master_password='123456',
master_auto_position = 1;
启动
start slave;
查看链路状态
show slave status \G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
等个几秒,或者直接查看也行,看主从同步成功没
use test;
select * from student;
+------------+--------------+
| student_id | student_name |
+------------+--------------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
+------------+--------------+
验证主从同步
master节点,插入数据
INSERT INTO student(`student_id`, `student_name`) VALUES (5, 'E');
slave节点查询数据
select * from student;
+------------+--------------+
| student_id | student_name |
+------------+--------------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
+------------+--------------+
Slave 节点收尾工作
退出Docker容器 如果用Docker的话
exit
加入只读属性,避免程序员误写入数据,导致主从同步失败
vim my.cnf
[mysqld]
# 主从配置中,加入这两个只读属性
read_only = on
super_read_only = on
重启mysql 这里说说哈,Docker你就直接重启容器就行
service mysql restart
测试从节点是否限制插入数据
INSERT INTO student(`student_id`, `student_name`) VALUES (6, 'F');
ERROR 1290 (HY000): Unknown error 1290