欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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 建立临时表
  • 无法使用关联更新同时更新事务表和非事务表

基本原理

具体流程

  1. 主库将变更写入到主库的binlog中
  2. 从库的IO进程读取主库binlog内容存储到Relay Log日志中
  3. 从库的SQL进程读取Relay Log日志中内容在从库中重放

MySQL 学习 - Replication集群 - 搭建 - GTID模式

Master 与 Slave 是单向同步的,如果我们想要双向同步,可以让双方互为主从关系
MySQL 学习 - Replication集群 - 搭建 - GTID模式

配置主从数据库服务器参数

参数 说明
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