mysql笔记:25. docker环境中mysql主从复制、主主复制实操


Docker容器是现在的主流技术,容器提供了细粒度的系统隔离机制,每个容器都完全独立,其中包括了应用以及所有需要的系统依赖,可以把系统中每个服务放入容器,让各个服务都以容器的形式运行,这样就大大简化了系统的部署过程,更加便于维护。

一、准备工作

1. 安装配置Docker

各位看官根据自己的操作系统和喜好选择相应的Docker进行安装和配置。使用docker pull命令拉取mysql 8的镜像文件。

> docker pull mysql:8

2. 准备MySQL相关的配置和数据目录

本次演示以一主二从共三台服务器为例进行演示。在当前目录创建三个配置文件目录和三个数据目录:

> cd /Users/Tom/docker
> 
> mkdir mysqlconf
> mkdir mysqlconf/master
> mkdir mysqlconf/slave1
> mkdir mysqlconf/slave2
> 
> mkdir mysqldata
> mkdir mysqldata/master
> mkdir mysqldata/slave1
> mkdir mysqldata/slave2
> 
> tree -L 2
.
├── README.md
├── mysqlconf
│   ├── master
│   ├── slave1
│   └── slave2
└── mysqldata
    ├── master
    ├── slave1
    └── slave2

运行MySQL容器并从中拷贝MySQL配置文件到本地备用,配置文件目录:/etc/my.cnf

# 语法:
docker cp <containerId>:/path/to/file /path/on/host

# 示例:temp_mysql8是本次启动的MySQL容器名称
docker cp temp_mysql8:/etc/my.cnf .

拷贝配置文件到已创建的配置文件目录:

cp my.cnf mysqlconf/master/my.cnf
cp my.cnf mysqlconf/slave1/my.cnf
cp my.cnf mysqlconf/slave2/my.cnf

> tree -L 3
.
├── README.md
├── mysqlconf
│   ├── master
│   │   └── my.cnf
│   ├── slave1
│   │   └── my.cnf
│   └── slave2
│       └── my.cnf
└── mysqldata
    ├── master
    ├── slave1
    └── slave2

二、基于日志点的主从复制

1. 配置Master服务器

1.1 修改配置文件

编辑主服务器的MySQL配置文件mysqlconf/master/my.cnf,添加下列配置项:

[mysqld]
server-id=1
log-bin=mysql-binlog
binlog-do-db=your-database-name
default_authentication_plugin=mysql_native_password

1.2. 在docker中启动Master节点

docker run -P --name mysqlmaster \
    -v $PWD/mysqldata/master:/var/lib/mysql \
    -v $PWD/mysqlconf/master/my.cnf:/etc/my.cnf \
    -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8

参数含义说明:

  • -P:本机与容器的端口映射
  • --name:为容器指定一个名称mysqlmaster
  • MYSQL_ROOT_PASSWORD:指定MySQL中root用户的密码为123456
  • -d:指定容器运行方式为后台运行
    容器启动后登录MySQL并检查配置是否生效:
$> docker exec -it mysqlmaster bash
# mysql -uroot -p123456
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+

如果登录MySQL提示错误:Access denied for user 'root'@'localhost' (using password: YES),可能是你密码输入错误,也可能是加密插件导致的。MySQL8使用的默认加密插件是 caching_sha2_password,而MySQL5.6使用的是mysql_native_password,当你在控制台使用明文密码登录的时候走的是mysql_native_password加密,而数据库记录的是caching_sha2_password加密后的密码。两个密文不一致导致登录失败。解决办法是在配置文件中指定加密插件:default_authentication_plugin=mysql_native_password

1.3. 创建用户并授权

在Master上创建一个复制用户并授权

mysql> CREATE USER 'repl'@'%' identified by 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
# 刷新用户权限信息
mysql> FLUSH PRIVILEGES;

# 查看Master状态
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1531 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

执行结果中显示二进制日志文件为mysql-bin.000003,日志位置为1531。Slave就是从这个日志点开始进行复制的。

2. 配置Slave1服务器

2.1. 修改配置

编辑从服务器slave1的MySQL配置文件mysqlconf/slave1/my.cnf,添加下列配置项:

[mysqld]  
server-id=2
relay-log=mysql-relay-bin
replicate-do-db=your_database_name

2.2. 启动服务

docker run -P --name mysqlslave1 \
    -v $PWD/mysqldata/slave1:/var/lib/mysql \
    -v $PWD/mysqlconf/slave1/my.cnf:/etc/my.cnf \
    -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8

容器启动后登录MySQL并检查配置是否生效:

$> docker exec -it mysqlslave1 bash
# mysql -uroot -p123456
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

2.3. 指定Master

指定Master的信息,包括IP、用户、密码、日志文件和位置。

mysql> change master to master_host='172.17.0.2', master_user='repl', master_password='123456', master_log_file='mysql-bin.000003', master_log_pos=828

可以使用docker inspect mysqlmaster | grep IPAddress查看Master节点的IP信息

2.4. 开始复制

mysql> start slave;

mysql> show slave status \G;
...
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...

最关键的是这两项信息:

  • Slave_IO_Running:
  • Slave_SQL_Running:

3. 配置Slave2服务器

3.1. 修改配置

编辑从服务器slave2的MySQL配置文件mysqlconf/slave2/my.cnf,添加下列配置项:

[mysqld]  
server-id=3
relay-log=mysql-relay-bin
replicate-do-db=your_database_name

3.2. 启动服务

docker run -P --name mysqlslave2 \
    -v $PWD/mysqldata/slave2:/var/lib/mysql \
    -v $PWD/mysqlconf/slave2/my.cnf:/etc/my.cnf \
    -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8

容器启动后登录MySQL并检查配置是否生效:

$> docker exec -it mysqlslave2 bash
# mysql -uroot -p123456
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 3     |
+---------------+-------+

3.3. 指定Master

指定Master的信息,包括IP、用户、密码、日志文件和位置。

mysql> change master to master_host='172.17.0.2', master_user='repl', master_password='123456', master_log_file='mysql-bin.000003', master_log_pos=828

3.4. 开始复制

mysql> start slave;

mysql> show slave status \G;
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...

最关键的是这两项信息:

  • Slave_IO_Running:
  • Slave_SQL_Running:

4. 测试效果

4.1. 更新数据

在Master节点上创建一个新的数据库和表,并任意插入一条数据:

mysql> create database test;
mysql> use test;
mysql> create table user(id bigint(20) primary key, name varchar(20));
mysql> insert into user value(1, 'Tom');
mysql> select * from user;

4.2. 查看同步结果

在Slave1和Slave2节点查看test.user表的数据:

mysql> select * from test.user;
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
+----+------+

结果表明主从复制环境配置成功。

三、基于GTID的主从复制

基于GTID的主从复制配置步骤跟基于日志点的主从复制配置基本相似,差别在于配置和指定Master时使用的命令参数略有差异。具体如下:

1. Master配置文件

打开配置文件mysqlconf/master/my.cnf,在[mysqld]部分添加配置:

[mysqld]
server-id=1
# 启动二进制日志
log-bin=mysql-bin
binlog_format=row
# 开启GTID模式
gtid_mode=on
# 强制GTID一致性
enforce_gtid_consistency=true
  • binlog_format:指定二进制日志格式为row

2. Slave配置文件

打开配置文件mysqlconf/slave1/my.cnfmysqlconf/slave2/my.cnf,分别在[mysqld]部分添加配置:

# slave1节点配置
server_id=2
log-bin=mysql-bin
log_slave_updates=1
gtid_mode=on
enforce_gtid_consistency=true
master_info_repository=TABLE
relay_log_info_repository=TABLE
read_only=ON
  • log_slave_updates:参数决定了在从服务器上是否将复制事件写入二进制日志文件(Binary Log)。默认情况下,这个参数是0,表示关闭,也就是说从服务器不会将复制事件写入二进制日志。
  • relay_log_info_repository:指定中继日志的存储方式,默认是文件,这样配置是使用了两个表,是INNODB存储引擎,好处是当出现数据库崩溃时,利用INNODB引擎事务的特点,对这两个表进行恢复,以保证从服务器可以从正确位置恢复数据。
  • read_only:指定从服务器是否只读,此参数对超级用户无效,并且不会影响从服务器的复制。这个参数主要保证从服务器的数据安全性。

# slave2节点配置
server_id=3
log-bin=mysql-bin
log_slave_updates=1
gtid_mode=on
enforce_gtid_consistency=true
master_info_repository=TABLE
relay_log_info_repository=TABLE
read_only=ON

3. 指定Master信息

change master to master_host='172.17.0.2', master_user='repl', master_password='123456', master_auto_position=1;
CHANGE MASTER TO   
  MASTER_HOST='172.17.0.2',
  MASTER_USER='repl',
  MASTER_PASSWORD='123456',
  MASTER_AUTO_POSITION=1;

四、主主复制

主从复制支持在一台Master数据库的写入和其他Slave数据库只读操作。但这种部署架构有个缺点:只有Master数据库具有写操作。当数据库写操作很多时,它的压力比较大。为了解决这个问题,可以对上述主从架构优化,改成主主复制,使每个数据库都能写入操作,同时,将写入的数据复制到其他数据库中。即数据库之间互为主从复制关系。
主主复制的搭建也比较简单,就是在主从复制的操作基础上增加一些配置和步骤即可。
使用两个MySQL服务器节点互为主从进行演示。

1. 基于日志点的主主复制

1.1. 修改节点1的MySQL配置

配置文件路径:mysqlconf/master1/my.cnf

[mysqld]
server_id=10
log-bin=mysql-bin
binlog_format=row
auto-increment-increment=2
auto-increment-offset=1
  • auto-increment-increment:设置自增长的步进值,一般有n台MySQL设置为n即可
  • auto-increment-offset:设置自增长的起始值,一般用n台MySQL的顺序号即可

主主备份配置中,最重要的就是配置自增长的步进值和起始值。通过设置它们防止多个数据库更新数据时主键重复而造成冲突。

1.2. 修改节点2的MySQL配置

配置文件路径:mysqlconf/master2/my.cnf

[mysqld]
server_id=11
log-bin=mysql-bin
binlog_format=row
auto-increment-increment=2
auto-increment-offset=2

1.3. 启动两个MySQL

docker run -P --name mysqlmaster1 \
    -v $PWD/mysqldata/master1:/var/lib/mysql \
    -v $PWD/mysqlconf/master1/my.cnf:/etc/my.cnf \
    -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8

docker run -P --name mysqlmaster2 \
    -v $PWD/mysqldata/master2:/var/lib/mysql \
    -v $PWD/mysqlconf/master2/my.cnf:/etc/my.cnf \
    -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8

1.4. 连接MySQL并创建用户

分别连接上两个MySQL,并在每一个MySQL上创建复制用户用于后续的配置。

create user 'repl'@'%' identified by '123456';
grant replication slave on *.* to 'repl'@'%';
flush privileges;

1.5. 配置Master信息

通过docker inspect命令得知当前两个节点的IP分别为172.17.0.3172.17.0.4
先登录172.17.0.3,查询:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      843 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

登录172.17.0.4,使用上述查询的File、Position信息配置Master节点信息:

change master to master_host='172.17.0.3', 
    master_user='repl', 
    master_password='123456', 
    master_log_file='mysql-bin.000003', 
    master_log_pos=843;

同理,登录172.17.0.4查询master节点信息,然后登录172.17.0.3配置Master。

# 在172.17.0.4上查询
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1577 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

# 在172.17.0.3上配置
mysql> change master to master_host='172.17.0.4', master_user='repl', master_password='123456', master_log_file='mysql-bin.000003', master_log_pos=1577;

1.6. 开启复制

在两个节点上分别执行start命令开启复制功能

mysql> start slave;

mysql> show slave status;

1.7. 复制测试

分别在两个节点上执行一些更新操作,如INSERT、UPDATE或DELETE,然后去另一个节点查询相关数据是否已变更。

2. 基于GTID的主主复制

这种方式比上述方式更加简单,不用去查看日志File和Position,直接配置即可。注意复制用户创建两次要配置忽略mysql库,也可以创建一次复制用户,然后同步信息后另一个库不再创建复制用户。只是这种方式相当于多个节点使用相同的用户账号、密码,存在一定的安全风险。

2.1. 修改节点的MySQL配置

配置文件路径:mysqlconf/master1/my.cnf

[mysqld]
server_id=1
log-bin=mysql-bin
binlog_format=row
gtid_mode=on
enforce_gtid_consistency=true
auto-increment-increment=2
auto-increment-offset=1

配置文件路径:mysqlconf/master2/my.cnf

[mysqld]
server_id=2
log-bin=mysql-bin
binlog_format=row
gtid_mode=on
enforce_gtid_consistency=true
auto-increment-increment=2
auto-increment-offset=2

2.2. 配置Master信息

change master to master_host='172.17.0.3', master_user='repl', master_password='123456', master_auto_position=1;

change master to master_host='172.17.0.4', master_user='repl', master_password='123456', master_auto_position=1;

start slave;
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 首先,在两个不同的主机上分别安装dockerdocker-compose。 2. 在其一个主机上创建一个名为`docker-compose.yml`的文件,如下所示: ``` version: '3' services: master: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: testdb volumes: - ./master-init:/docker-entrypoint-initdb.d ports: - "3306:3306" networks: - db-network command: --server-id=1 --log-bin=mysql-bin --binlog-do-db=testdb slave: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: password volumes: - ./slave-init:/docker-entrypoint-initdb.d ports: - "3307:3306" networks: - db-network command: --server-id=2 --log-bin=mysql-bin --binlog-do-db=testdb --relay-log=mysqld-relay-bin --relay-log-index=mysqld-relay-bin.index --read-only=1 --replicate-do-db=testdb networks: db-network: ``` 在该文件,我们定义了两个服务:`master`和`slave`。`master`服务使用mysql:5.7镜像,并将其端口映射到主机的3306端口。 `slave`服务也使用mysql:5.7镜像,并将其端口映射到主机的3307端口。我们还定义了一个`db-network`网络,以使两个服务能够相互通信。 3. 在同一台主机上创建一个名为`master-init`的文件夹,并在其创建一个名为`init.sql`的文件,如下所示: ``` CREATE DATABASE testdb; CREATE TABLE testdb.users ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL ); INSERT INTO testdb.users (username, email) VALUES ('john', '[email protected]'), ('jane', '[email protected]'); ``` 在这个文件,我们定义了一个名为`testdb`的数据库,以及一个名为`users`的表,然后插入了一些数据。 4. 在同一台主机上创建一个名为`slave-init`的文件夹,并在其创建一个名为`init.sql`的文件,如下所示: ``` CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='root', MASTER_PASSWORD='password', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE; ``` 在这个文件,我们定义了`slave`服务的主服务器是`master`,用户名为`root`,密码为`password`,并指定了主服务器的端口和binlog文件的名称和位置。然后,我们启动了从服务器。 5. 在同一台主机上打开终端,切换到包含`docker-compose.yml`文件的目录,并运行以下命令: ``` docker-compose up ``` 这将启动两个服务:`master`和`slave`。在输出,您应该看到MySQL服务器已成功启动,并且主从复制已经开始。 6. 测试主从复制是否正常工作。我们可以使用以下命令登录到`master`服务器的MySQL shell: ``` mysql -h localhost -u root -p ``` 然后,我们可以使用以下命令创建一个新用户: ``` USE testdb; INSERT INTO users (username, email) VALUES ('mike', '[email protected]'); ``` 现在,我们可以使用以下命令登录到`slave`服务器的MySQL shell: ``` mysql -h localhost -P 3307 -u root -p ``` 然后,我们可以使用以下命令检查是否已成功复制数据: ``` USE testdb; SELECT * FROM users; ``` 如果一切正常,您将看到`users`表包含了新创建的`mike`用户。 这就是使用docker-compose搭建MySQL主从复制的整个过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值