标签:主键 ble 用户 innodb 存在 ant 数据文件 加密方式 select
MySQL 的主从复制又叫 Replication、AB 复制。至少需要两个 MySQL 服务(可以是同一台机器,也可以是不同机器之间进行)。
比如A服务器做主服务器,B服务器做从服务器,在A服务器上进行数据的更新,通过 binlog 日志记录同步到B服务器上,并重新执行同步过来的 binlog 数据,从而达到两台服务器数据一致。
MySQL 数据库的主从复制方案,与使用 scp/rsync 等命令进行的文件级别复制类似,都是数据的远程传输。只不过 MySQL 的主从复制是其自带的功能,无需借助第三方工具,而且MySQL的主从复制并不是数据库磁盘上的文件直接拷贝,而是通过逻辑的 binlog 日志复制到要同步的服务器本地,然后由本地的线程读取日志里面的 SQL 语句,重新应用到 MySQL 数据库中。
谈起为什么在大多数情况下部署 Mysql 常常使用 Mysql 主从模式进行部署这个问题,本来也去网上搜寻了一些答案,其中原因主要有以下几点:
MySQL 主从复制默认是异步的模式。MySQL增删改操作会全部记录在 Binlog 中,当 slave 节点连接 master 时,会主动从 master 处获取最新的 Binlog 文件。并把 Binlog 存储到本地的 relay log 中,然后去执行 relay log 的更新内容。
在传统的复制里面,当发生故障,需要主从切换,需要找到 Binlog 和 位点信息,恢复完成数据之后将主节点指向新的主节点。在 MySQL 5.6 里面,提供了新的数据恢复思路,只需要知道主节点的 IP、端口以及账号密码就行,因为复制是自动的,MySQL 会通过内部机制 GTID 自动找点同步。接下来我们要部署的主从也是基于这种模式。
GTID 指的是全局事务 ID,全程是 Global Transaction Identifier ,在整个事务流程中每一个事务 ID 是全局唯一的,且在整个主从复制架构中该 ID 都不会相同。
基于 GTID 的主从复制方式的出现,主要是用于替换传统的日志点 复制方式。通过GTID 可以保证每个主库提交的事务在集群中都有 唯一 的一个事务 ID。强化了数据库主从的一致性和故障恢复数据的容错能力,在主库 宕机发生主从切换 的情况下,GTID 方式可以让其他从库自动找到新主库复制的位置。而且 GTID 可以忽略已经执行过的事务,减少了数据发生错误的概率。
GTID 由server_uuid +tid 组成,其中:
server_uuid
是在 Mysql 首次启动过程中自动生成的一个uuid(128位)
随机值,生成后会将该值存储到数据目录的auto.cnf
中。因为是随机值,所以不同服务器的 Mysql 的server_uuid 都是不相同的。1
,每次提交事务的时候分配给这个事务并加1
。其组成样式如下:
fb90fba5-60cf-11eb-b5fa-000c295fbc5f:21
假设从库开启了 binlog,那么执行流程如下:
GTID
,其会随着事务一起记录到 binlog
日志中。I/O Thread
会读取主节点的 binlog
日志文件并存储在从节点的 relaylog
日志中。从节点将主节点的 GTID
这个值配置到 gtid_next
中,即下一个要读取的 GTID 值。gtid_next
中的值,然后查找自己的 binlog
日志中是否有这个 GTID
。GTID
的事务已经执行过了,就忽略掉。binlog
日志中。在读取执行事务前会先检查其他session
中是否持有该 GTID
,确保不被重复执行。GTID 复制是针对事务来说的,一个事务只对应一个 GTID,好多的限制就在于此。其中主要限制如下:
create table table_name select * from table_name
。InnoDB
存储引擎的表)的操作又包含非事务表(使用 MyISAM
存储引擎的表)。CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE
语句操作。ql_slave_skip_counter
参数的语法。需要在 Mysql 配置文件中添加下面几条配置:
## 开启 gtid 模式
gtid_mode=on
## 配置不允许任何事务违反 GTID 一致性,用于保证数据一致性
enforce_gtid_consistency=on
## 开启 Binlog 并指定名称(可选)
log_bin=binlog
## 从节点从主节点接收到更新且执行,是否将记录存到从节点的 binlog 日志中(可选)
log-slave-updates=on
## 当从数据库启动的时候,从节点不会启动复制(可选)
skip-slave-start=1
MySQL8.0 之前 mysql 密码加密方式为 mysql_native_password,而 MySQL8.0 版本默认新添加的用户密码默认使用的 caching_sha2_password,因此进行使用主从复制时可能会遇到错误,需要将加密方式改成 mysql_native_password。
我个人理解,基于GTID的MySQL复制流程为:
1、Master写入记录前生成一个GTID
2、Master将GTID和数据一起写入二进制日志中
3、Master刷新日志数据到磁盘中
4、Slave读取Master的二进制日志中的GTID
5、Slave判断该GTID是否已经写入中继日志,如果写入了则说明该GTID代表的数据已经存在,跳过该条数据不将其重复录入到中继日志中
6、Slave继续往下读取Master二进制日志,直到读取到Slave中继日志中不存在的GTID即开始将其写入Slave中继日志,SQL线程启动,开始刷新数据到Slave磁盘中
7、复制过程结束
这样就可以避免Slave中漏写Master的数据或者重复写入。
Linux版本:CentOS7
MySQL版本:mysql8.0
Docker版本:19.03.9
DockerCompose版本:1.27.4
有很多种配置主从同步的方法,可以总结为如下的步骤:
.
├── config
│ ├── master.cnf
├── master-data
├── .env
└── docker-compose.yml
config/master.cnf
: MySQL Master节点的配置文件docker-compose.yml
: 构建主从节点与挂载数据目录的docker-compose配置文件master-data
: 主节点数据位置,当然生产环境要挂到别的位置.env
: 环境变量文件.env
文件# default environment arguments for docker-compose.yml
# set master volumes dir
MASTER_DATA=./mysql-volumes/data/master
MASTER_LOGS=./mysql-volumes/logs/master
MASTER_CONF=./mysql-volumes/conf/master
# set master root password
MASTER_PASSWD=P@ssw0rd
MASTER_DATA
是 Master节点的数据目录,需要修改到宿主机对应的位置。MASTER_LOGS
是 Master节点的日志目录,需要修改到宿主机对应的位置。MASTER_CONF
是 Master节点的配置目录,需要修改到宿主机对应的位置。MASTER_PASSWD
是主节点的root密码,bin目录下的脚本会读取这个变量的值从而进行访问数据库
cd ./mysql-volumes/conf/master
vim master.cnf
配置内容如下:
[mysqld]
max_connections = 2000
default-time_zone=‘+8:00‘
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
#gtid:
server_id = 1 #服务器id
gtid_mode = on #开启gtid模式
enforce_gtid_consistency = on #强制gtid一致性,开启后对于特定create table不被支持
#binlog
log_bin = mysql-binlog
log_slave_updates = on
binlog_format = row #强烈建议,其他格式可能造成数据不一致
#relay log
skip_slave_start = 1
default_authentication_plugin = ‘mysql_native_password‘ #更改加密方式
version: ‘3.3‘
services:
mysql-master:
image: mysql:8.0
container_name: mysql-master
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
ports:
- 3316:3306
environment:
- MYSQL_ROOT_PASSWORD=${MASTER_PASSWD}
volumes:
- ${MASTER_CONF}:/etc/mysql/conf.d
- ${MASTER_LOGS}:/var/log/mysql
- ${MASTER_DATA}:/var/lib/mysql
在docker-compose.yml目录下执行docker-compose up -d
# 连接mysql服务
docker exec -it mysql-master mysql -uroot -pP@ssw0rd
#查看server_id是否生效
show variables like ‘%server_id%‘;
# 查看MASTER状态
SHOW MASTER STATUS\G
# 创建主从复制账号
CREATE USER ‘replicasName‘@‘%‘ IDENTIFIED BY ‘replicasPasswd‘;
GRANT REPLICATION SLAVE ON *.* TO ‘replicasName‘@‘%‘;
flush privileges;
select user,host from mysql.user;
.env
文件# default environment arguments for docker-compose.yml
# set slave volumes dir
SLAVE_DATA=./mysql-volumes/data/slave
SLAVE_LOGS=./mysql-volumes/logs/slave
SLAVE_CONF=./mysql-volumes/conf/slave
# set slave root passwor
SLAVE_PASSWD=P@ssw0rd
SLAVE_DATA
是 Salve节点的数据目录,需要修改到宿主机对应的位置。SLAVE_LOGS
是 Salve节点的日志目录,需要修改到宿主机对应的位置。SLAVE_CONF
是 Salve节点的配置目录,需要修改到宿主机对应的位置。SLAVE_PASSWD
是主节点的root密码,bin目录下的脚本会读取这个变量的值从而进行访问数据库
cd ./mysql-volumes/conf/slave
vim slave.cnf
配置内容如下:
[mysqld]
max_connections = 2000
default-time_zone = ‘+8:00‘
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
#GTID:
server_id = 2 #服务器id
gtid_mode = on #开启gtid模式
enforce_gtid_consistency = on #强制gtid一致性,开启后对于特定create table不被支持
#binlog
log_bin =mysql-binlog
log_slave_updates = on
binlog_format = row #强烈建议,其他格式可能造成数据不一致
#relay log
skip_slave_start = 1
default_authentication_plugin = ‘mysql_native_password‘ #更改加密方式
read_only = on #设置只读
version: ‘3.3‘
services:
mysql-slave:
image: mysql:8.0
container_name: mysql-slave
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
ports:
- 3326:3306
environment:
- MYSQL_ROOT_PASSWORD=${SLAVE_PASSWD}
volumes:
- ${SLAVE_CONF}:/etc/mysql/conf.d
- ${SLAVE_LOGS}:/var/log/mysql
- ${SLAVE_DATA}:/var/lib/mysql
在docker-compose.yml目录下执行docker-compose up -d
# 连接mysql
docker exec -it mysql-slave mysql -uroot -pP@ssw0rd
#查看server_id是否生效
show variables like ‘%server_id%‘;
# 查看MASTER状态
SHOW SLAVE STATUS\G
# 从节点使用备份账户连接主节点,开启备份
CHANGE MASTER TO
master_host=‘192.168.147.152‘,
master_port=3316,
master_user=‘replicasName‘,
master_password=‘replicasPasswd‘,
master_auto_position=1;
# 启动同步
RESET SLAVE;
START SLAVE;
查看SLAVE状态,都为yes表示基于GTID的MySQL主从复制已经成功!
参考:
https://blog.csdn.net/pbrlovejava/article/details/88046025
https://www.freeaihub.com/post/93490.html
docker-compose部署 Mysql 8.0 主从模式,基于GTID
标签:主键 ble 用户 innodb 存在 ant 数据文件 加密方式 select
原文地址:https://www.cnblogs.com/bigfairy/p/14772021.html