基础
参考:mysql5.7-Docker-安装-备份
拉取镜像
docker pull mysql:5.7
创建目录
mkdir /home/liangshijie/mysql-docker-file/conf
mkdir /home/liangshijie/mysql-docker-file/logs
mkdir /home/liangshijie/mysql-docker-file/data
创建配置文件
cd /home/liangshijie/mysql-docker-file/conf
vim my.cnf
[mysqld]
########################### 基础配置 ####################################
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
启动一个Mysql
通过下面的命令,可以启动一个mysql,后面默认使用此命令创建主、从节点。
docker run -p 3306:3306 --name mysql -v /home/liangshijie/mysql-docker-file/conf:/etc/mysql/conf.d -v /home/liangshijie/mysql-docker-file/logs:/var/log/mysql -v /home/liangshijie/mysql-docker-file/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# MYSQL_ROOT_PASSWORD 用于指定默认密码
基于 Pos模式的主从复制
主节点
配置文件
[mysqld]
########################### 基础配置 ####################################
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
########################### 同步配置 ####################################
# binlog刷盘策略
sync_binlog=1
# 需要备份的数据库
binlog-do-db=study
# 不需要备份的数据库
binlog-ignore-db=mysql
# 启动二进制文件
log-bin=mysql-bin
# 服务器ID
server-id=132
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
重启服务
docker restart xxx
创建从节点用的账号
GRANT REPLICATION SLAVE ON *.* TO '从机MySQL用户名'@'从机IP' identified by '从机MySQL密码';
# 例如:
grant replication slave on *.* to 'repl'@'192.168.204.%' identified by 'root';
# 刷新
flush privileges;
查看&记录主节点状态信息
这里先记一下File
于Position
信息。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 603 | study | mysql | |
+------------------+----------+--------------+------------------+-------------------+
多次反复启动容器可能File是mysql-bin.000002、3。我遇到一个坑就是从节点在进行同步的时候写mysql-bin.000002、3等,是无法同步的,还是要写mysql-bin.000001才行。
从节点
配置文件
[mysqld]
########################### 基础配置 ####################################
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
########################### 同步配置 ####################################
server-id=133
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
重启服务
# 启动、重启现有的从节点容器
docker start | restart xxx
# or 运行一个新容器
docker run -p 3306:3306 --name mysql -v /home/liangshijie/mysql-docker-file/conf:/etc/mysql/conf.d -v /home/liangshijie/mysql-docker-file/logs:/var/log/mysql -v /home/liangshijie/mysql-docker-file/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
进行同步
将上面记录的File
和Position
信息填写下去:
# 停止同步
stop slave;
# 配置账户和同步信息
change master to
master_host='192.168.204.132',
master_port=3306,
master_user='repl',
master_password='root',
master_log_file='mysql-bin.000001',
master_log_pos=154,
MASTER_AUTO_POSITION=0;
# master_log_file 一般是mysql-bin.000001
# master_log_pos 可以写1
# 启动
start slave;
检查同步情况
show slave status
关键结果:
测试
现在添加数据试试看。
可能的问题
主从延迟;
数据一致性:同步数据丢失问题;
主节点出问题之后,不好进行故障转移;
。。。
基于GTID模式的主从复制
是什么?
GTID:全局事务ID。
从5.6.5开始的一种基于GTID的复制方式。GTID 保证主节点提交的事务在从集群中可以生成唯一的ID。在主、从节点内,GTID是唯一的。
从节点执行事务时,事务的ID是从收到的binlog找到并设置的。执行前先对比自身的binlog日志中的GTID,可以防止执行重复的事务。
GTID模式强化了数据一致性,提供更方便的故障转移能力,提高容错能力。
优点:
- 数据安全性更好、故障转移更简单,更容易搭建主从复制。
- 通过GTID的实例ID快速定位事务最初谁提交的。
- 更方便集群迁移。
限制:
- 需要注意的是,表存储引擎必须一致。
- 同一个复制组必须统一开启、关闭GTID。
- 不允许SQL语句同时更新一个事务引擎表和非事务引擎表。
- 不支持如下语句:
- create table….select
- create temporary table
- drop temporary table
GTID 主从复制原理
- 更新数据时,在事务开启前生成GTID到binlog。
- 从节点IO线程将带有GTID的binlog数据写入relaylog。
- 从节点 SQL线程 读取GITD的值,并设置下一个要执行的GTID值
GTID=xxx
。然后对比自己Binlog,判断事务是否执行过了:- 执行过就忽略;
- 每执行过就执行,并记录到自己的binlog。
GTID解决了什么问题?
更方便的进行故障转移。
主节点
配置文件
[mysqld]
########################### 基础配置 ####################################
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
########################### 同步配置 ####################################
# binlog刷盘策略
sync_binlog=1
# 需要备份的数据库
binlog-do-db=study
# 不需要备份的数据库
binlog-ignore-db=mysql
# 启动二进制文件
log-bin=mysql-bin
# 服务器ID
server-id=132
########################### 使用GTID模式 #################################
gtid_mode=on
enforce_gtid_consistency=on
# 强烈建议,其他格式可能造成数据不一致
binlog_format=row
# 避免启动后还是使用老的复制协议
skip_slave_start=1
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
创建从节点用的账户(选做)
# 如果没有创建有账户则先在主节点上创建一个
GRANT REPLICATION SLAVE ON *.* TO '从机MySQL用户名'@'从机IP' identified by '从机MySQL密码';
# 例如:
grant replication slave on *.* to 'repl'@'192.168.204.%' identified by 'root';
# 刷新
flush privileges;
从节点
配置文件
[mysqld]
########################### 基础配置 ####################################
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
########################### 同步配置 ####################################
server-id=133
########################### 使用GTID模式 ################################
gtid_mode=on
enforce_gtid_consistency=on
# 强烈建议,其他格式可能造成数据不一致
binlog_format=row
# 避免启动后还是使用老的复制协议
skip_slave_start=1
# 做级联复制的时候,再开启。允许下端接入slave
#log_slave_updates=1
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
验证是否启用了GTID
mysql> show variables like '%gtid%';
+----------------------------------+------------------------------------------+
| Variable_name | Value |
+----------------------------------+------------------------------------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | 4750c043-6bdb-11ed-a1ec-0242ac110003:1-6 |
| session_track_gtids | OFF |
+----------------------------------+------------------------------------------+
开启同步
# 停止从节点
stop slave;
# 切换主节点配置,比基于pos简单不少
change master to
master_host='192.168.204.132',
master_port=3306,
master_user='repl',
master_password='root',
master_auto_position=1;
# 启动从节点
start slave;
show slave status