1. 获取镜像
# 查看可用的稳定版本
sudo docker search mysql
# 镜像容量:448MB
sudo docker pull mysql:5.7
# 镜像容量:287MB
sudo docker pull percona/percona-xtradb-cluster:5.7
sudo docker image ls |grep mysql
sudo docker image ls |grep percona
2. MySQL单机版
2.1. 创建数据卷
sudo mkdir -p /home/mysql/{conf,data,logs}
# 赋予data目录读写权限
sudo chmod 755 /home/mysql/data
# MySQL配置文件(字符编码设置)
vi /home/mysql/conf/my.cnf
内容如下:
[client]
default_character_set=utf8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
lower_case_table_names=1
2.2. 启动容器
# 简单安装
sudo docker run -d -p 3306:3306 --name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
# 指定数据卷安装
sudo docker run -d -p 3306:3306 --name mysql \
--privileged=true \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/logs:/var/log/mysql \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
sudo docker start mysql
sudo docker restart mysql
sudo docker stop mysql
sudo docker rm mysql
sudo docker ps -a
2.3. 验证
sudo docker exec -it mysql /bin/bash
mysql -uroot -p123456
mysql -h localhost -uroot -p123456
mysql> SHOW VARIABLES LIKE 'character%'; -- 查看字符集
mysql> create database testdb;
mysql> use testdb;
mysql> create table t1(id int,name varchar(20));
mysql> insert into testdb.t1(id,name) values(1,'zhangsan');
mysql> insert into testdb.t1(id,name) values(2,'李四'); -- 测试中文是否乱码
mysql> select * from testdb.t1;
2.4. 远程登录(非root)
CREATE USER bdapuser IDENTIFIED BY 'bdapuser';
GRANT ALL ON *.* TO 'bdapuser'@'%';
flush privileges;
-- 查询用户是否创建成功
select user,host from mysql.user;
-- host里有“%”说明是远程用户,然后退出mysql、docker容器,并用客户端工具远程登录测试
sudo docker exec -it mysql /bin/bash
mysql -h localhost -ubdapuser -pbdapuser
3. MySQL集群(主从)
3.1. 创建数据卷
sudo mkdir -p /datas/mysql-master/{conf,data,logs}
sudo mkdir -p /datas/mysql-slave/{conf,data,logs}
# 赋予data目录读写权限
sudo chmod 755 /datas/mysql-master/data
sudo chmod 755 /datas/mysql-slave/data
# MySQL配置文件(主机配置)
vi /datas/mysql-master/conf/my.cnf
# MySQL配置文件(从机配置)
vi /datas/mysql-slave/conf/my.cnf
内容如下(主机:mysql-master):
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间,默认值:0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062-主键重复;1032-主从数据库数据不一致;
slave_skip_errors=1062
内容如下(从机:mysql-slave):
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间,默认值:0,表示不自动清理
expire_logs_days=7
################# 以下为从节点特殊配置项 #################
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062-主键重复;1032-主从数据库数据不一致;
slave_skip_errors=1062
## 从节点配置中继日志
relay_log=mall-mysql-relay-bin
## 1:表示从节点将复制事件写进自己的二进制日志
log_slave_updates=1
## 从节点设置为只读(具有super权限的用户除外)
read_only=1
3.2. 启动容器
- MySQL主节点(master) ```bash sudo docker run -d -p 3307:3306 —name mysql-master \ —privileged=true \ -v /datas/mysql-master/conf:/etc/mysql/conf.d \ -v /datas/mysql-master/logs:/var/log/mysql \ -v /datas/mysql-master/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:5.7
sudo docker start mysql-master sudo docker restart mysql-master sudo docker stop mysql-master sudo docker rm mysql-master
- **MySQL从节点(slave)**
```bash
sudo docker run -d -p 3308:3306 --name mysql-slave \
--privileged=true \
-v /datas/mysql-slave/conf:/etc/mysql/conf.d \
-v /datas/mysql-slave/logs:/var/log/mysql \
-v /datas/mysql-slave/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
sudo docker start mysql-slave
sudo docker restart mysql-slave
sudo docker stop mysql-slave
sudo docker rm mysql-slave
3.3. 主从配置
- 主节点创建数据同步用户。 ```bash sudo docker exec -it mysql-master /bin/bash mysql -uroot -p123456
mysql> CREATE USER ‘slave’@’%’ IDENTIFIED BY ‘123456’; mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO ‘slave’@’%’; mysql> flush privileges;
mysql> show master status; — 在主数据库中查看主从同步状态,获取File
、Position
+———————————-+—————+———————+—————————+—————————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+———————————-+—————+———————+—————————+—————————-+
| mall-mysql-bin.000003 | 769 | | mysql | |
+———————————-+—————+———————+—————————+—————————-+
2. 从节点配置主从复制。
```bash
sudo docker exec -it mysql-slave /bin/bash
mysql -uroot -p123456
命令如下:
change master to master_host='192.168.56.101', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000003', master_log_pos=769, master_connect_retry=30;
参数说明:
master_host:主数据库的IP地址。
master_port:主数据库的运行端口。
master_user:在主数据库创建的用于同步数据的用户账号。
master_password:在主数据库创建的用于同步数据的用户密码。
master_log_file:指定从数据库要复制数据的日志文件,注意:通过查看主数据的状态,获取File参数。
master_log_pos:指定从数据库从哪个位置开始复制数据,注意:通过查看主数据的状态,获取Position参数。
master_connect_retry:连接失败重试的时间间隔,单位为秒。
- 从节点开启主从同步。 ```bash sudo docker exec -it mysql-slave /bin/bash mysql -uroot -p123456
mysql> start slave; — 从节点开启主从同步 mysql> show slave status; — 查看从数据库状态(表方式展现) mysql> show slave status \G; — 查看从数据库状态(纵向展示)
Slave_IO_Running
和Slave_SQL_Running
均为“Yes”时表示主从同步已开始工作
* . row ** *: Slave_IO_Running: Yes Slave_SQL_Running: Yes *: *: *
<a name="bU5Ez"></a>
## 3.4. 验证
```bash
sudo docker ps -a
# 主库
sudo docker exec -it mysql-master /bin/bash
mysql -uroot -p123456
mysql> create database testdb; -- 1. 主库创建数据库
mysql> use testdb;
mysql> create table t1(id int,name varchar(20)); -- 2. 主库创建表
mysql> insert into testdb.t1(id,name) values(1,'zhangsan'); -- 3. 主库添加记录
# 从库
sudo docker exec -it mysql-slave /bin/bash
mysql -uroot -p123456
mysql> show databases; -- 4. 从库验证数据库是否同步成功
mysql> use testdb;
mysql> show tables; -- 5. 从库验证表是否同步成功(创建表)
mysql> select * from testdb.t1; -- 6. 从库验证表是否同步成功(表添加记录)
4. MySQL集群(双主)
4.1. 创建数据卷
sudo mkdir -p /datas/mysql-master-A/{conf,data,logs}
sudo mkdir -p /datas/mysql-master-B/{conf,data,logs}
# 赋予data目录读写权限
sudo chmod 755 /datas/mysql-master-A/data
sudo chmod 755 /datas/mysql-master-B/data
# MySQL配置文件(主机配置)
vi /datas/mysql-master-A/conf/my.cnf
# MySQL配置文件(从机配置)
vi /datas/mysql-master-B/conf/my.cnf
内容如下(主机:mysql-master-A):
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id = 1
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin= mysql-bin
## 指定不需要同步的数据库名称
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
## 0代表读写均可
read-only=0
## 配置中继日志
relay_log=mysql-relay-bin
log-slave-updates=on
auto-increment-offset=1
auto-increment-increment=2
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
内容如下(主机:mysql-master-B):
[mysqld]
server_id = 2
log-bin= mysql-bin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
read-only=0
relay_log=mysql-relay-bin
log-slave-updates=on
auto-increment-offset=2
auto-increment-increment=2
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
4.2. 启动容器
- MySQL主节点(master-A) ```bash sudo docker run -d -p 3317:3306 —name mysql-master-A \ —privileged=true \ -v /datas/mysql-master-A/conf/my.cnf:/etc/mysql/my.cnf \ -v /datas/mysql-master-A/logs:/var/log/mysql \ -v /datas/mysql-master-A/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:5.7
sudo docker start mysql-master-A sudo docker restart mysql-master-A sudo docker stop mysql-master-A sudo docker rm mysql-master-A
- **MySQL主节点(master-B)**
```bash
sudo docker run -d -p 3318:3306 --name mysql-master-B \
--privileged=true \
-v /datas/mysql-master-B/conf/my.cnf:/etc/mysql/my.cnf \
-v /datas/mysql-master-B/logs:/var/log/mysql \
-v /datas/mysql-master-B/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
sudo docker start mysql-master-B
sudo docker restart mysql-master-B
sudo docker stop mysql-master-B
sudo docker rm mysql-master-B
4.3. 多主配置
- 主节点(master-A)创建数据同步用户。 ```bash sudo docker exec -it mysql-master-A /bin/bash mysql -uroot -p123456
mysql> CREATE USER ‘backup’@’%’ IDENTIFIED BY ‘123456’; mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO ‘backup’@’%’; mysql> flush privileges;
mysql> show master status; — 查看同步状态,获取File
、Position
+—————————+—————+———————+—————————+—————————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+—————————+—————+———————+—————————+—————————-+
| mysql-bin.000003 | 786 | | | |
+—————————+—————+———————+—————————+—————————-+
2. 主节点(master-B)配置主从复制。
```bash
sudo docker exec -it mysql-master-B /bin/bash
mysql -uroot -p123456
命令如下:
change master to master_host='192.168.56.101', master_user='backup', master_password='123456', master_port=3317, master_log_file='mysql-bin.000003', master_log_pos=786, master_connect_retry=30;
参数说明:
master_host:主数据库的IP地址。
master_port:主数据库的运行端口。
master_user:在主数据库创建的用于同步数据的用户账号。
master_password:在主数据库创建的用于同步数据的用户密码。
master_log_file:指定从数据库要复制数据的日志文件,注意:通过查看主数据的状态,获取File参数。
master_log_pos:指定从数据库从哪个位置开始复制数据,注意:通过查看主数据的状态,获取Position参数。
master_connect_retry:连接失败重试的时间间隔,单位为秒。
- 主节点(master-B)创建数据同步用户。 ```bash sudo docker exec -it mysql-master-B /bin/bash mysql -uroot -p123456
mysql> CREATE USER ‘backup’@’%’ IDENTIFIED BY ‘123456’; mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO ‘backup’@’%’; mysql> flush privileges;
mysql> show master status; — 查看同步状态,获取File
、Position
+—————————+—————+———————+—————————+—————————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+—————————+—————+———————+—————————+—————————-+
| mysql-bin.000003 | 786 | | | |
+—————————+—————+———————+—————————+—————————-+
4. 主节点(master-B)开启主从同步。
```bash
sudo docker exec -it mysql-master-B /bin/bash
mysql -uroot -p123456
mysql> start slave; -- 从节点开启主从同步
mysql> show slave status; -- 查看从数据库状态(表方式展现)
mysql> show slave status \G; -- 查看从数据库状态(纵向展示)
## `Slave_IO_Running`和`Slave_SQL_Running`均为“Yes”时表示主从同步已开始工作
*************************** *. row ***************************
*****************: ****
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
*****************: ****
*****************************: *******************************
主节点(master-A)配置主从复制。
sudo docker exec -it mysql-master-A /bin/bash mysql -uroot -p123456
命令如下:
change master to master_host='192.168.56.101', master_user='backup', master_password='123456', master_port=3318, master_log_file='mysql-bin.000003', master_log_pos=786, master_connect_retry=30;
主节点(master-A)开启主从同步。 ```bash sudo docker exec -it mysql-master-A /bin/bash mysql -uroot -p123456
mysql> start slave; — 从节点开启主从同步 mysql> show slave status; — 查看从数据库状态(表方式展现) mysql> show slave status \G; — 查看从数据库状态(纵向展示)
Slave_IO_Running
和Slave_SQL_Running
均为“Yes”时表示主从同步已开始工作
* . row ** *: Slave_IO_Running: Yes Slave_SQL_Running: Yes *: *: *
<a name="AHfLE"></a>
## 4.4. 验证
```bash
sudo docker ps -a
############### 测试1:master-A中创建库表,master-B中验证 ###############
# 主库(master-A)
sudo docker exec -it mysql-master-A /bin/bash
mysql -uroot -p123456
mysql> create database testdbA; -- 1. 主库(master-A)创建数据库
mysql> use testdbA;
mysql> create table tA(id int,name varchar(20)); -- 2. 主库(master-A)创建表
mysql> insert into testdbA.tA(id,name) values(1,'zhangA'); -- 3. 主库(master-A)添加记录
# 主库(master-B)
sudo docker exec -it mysql-master-B /bin/bash
mysql -uroot -p123456
mysql> show databases; -- 4. 主库(master-B)验证数据库是否同步成功
mysql> use testdbA;
mysql> show tables; -- 5. 主库(master-B)验证表是否同步成功(创建表)
mysql> select * from testdbA.tA; -- 6. 主库(master-B)验证表是否同步成功(表添加记录)
############### 测试2:master-B中创建库表,master-A中验证 ###############
# 主库(master-B)
sudo docker exec -it mysql-master-B /bin/bash
mysql -uroot -p123456
mysql> create database testdbB; -- 1. 主库(master-B)创建数据库
mysql> use testdbB;
mysql> create table tB(id int,name varchar(20)); -- 2. 主库(master-B)创建表
mysql> insert into testdbB.tB(id,name) values(1,'zhangB'); -- 3. 主库(master-B)添加记录
# 主库(master-A)
sudo docker exec -it mysql-master-A /bin/bash
mysql -uroot -p123456
mysql> show databases; -- 4. 主库(master-A)验证数据库是否同步成功
mysql> use testdbB;
mysql> show tables; -- 5. 主库(master-A)验证表是否同步成功(创建表)
mysql> select * from testdbB.tB; -- 6. 主库(master-A)验证表是否同步成功(表添加记录)
4.5. VIP配置(选)
此处使用Ngnix实现双主MySQL的高可用和负载均衡。Nginx安装参考:《Docker-Standalone_Nginx-1.16.1》。
创建Nginx容器:
sudo docker run -itd --name nginx-mysql -p 80:80 -p 3306:3306 nginx-stream:1.16.1
修改Ngnix配置:
# 进入终端
sudo docker exec -it nginx-mysql /bin/bash
vi /apps/nginx/conf/nginx.conf
内容如下(新增):
# TCP/UPD协议配置,与HTTP同级,需安装nginx-stream
stream {
server {
listen 3306;
proxy_pass mysql;
}
upstream mysql {
server 192.168.56.101:3317;
server 192.168.56.101:3318;
}
}
重启容器:
sudo docker restart nginx-mysql
5. MySQL集群(MMM、MHA、MGR)
6. MySQL集群(PXC)
6.1. 配置网络信息
sudo docker network create --subnet=172.30.0.0/24 mysql-pxc
sudo docker network list
6.2. 创建存储卷
sudo docker volume create v1
sudo docker volume create v2
sudo docker volume create v3
6.3. 拉取pxc集群镜像
sudo docker pull percona/percona-xtradb-cluster:5.7
# 标记本地镜像,将其归入某一仓库(可选)
sudo docker tag percona/percona-xtradb-cluster:5.7 mysql-pxc:5.7
6.4. 创建容器
第1个节点(初始化1个MySQL节点)
sudo docker run -d -p 13306:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc --name=pxc_node1 --net=mysql-pxc --ip 172.30.0.2 mysql-pxc:5.7
第2个节点(CLUSTER_JOIN:加入之前初始化的MySQL节点)
sudo docker run -d -p 13307:3306 -v v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc --name=pxc_node2 -e CLUSTER_JOIN=pxc_node1 --net=mysql-pxc --ip 172.30.0.3 mysql-pxc:5.7
第3个节点(CLUSTER_JOIN:加入之前初始化的MySQL节点)
sudo docker run -d -p 13308:3306 -v v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc --name=pxc_node3 -e CLUSTER_JOIN=pxc_node1 --net=mysql-pxc --ip 172.30.0.4 mysql-pxc:5.7
注意:容器的启动应该顺次进行,当启动第1个结点时,需要初始化元数据库
mysql
信息,这个过程需要等待一段时间,才能进行后续操作。可以通过MySQL客户端工具的连接来判断是否初始完成。6.5. 验证
```bash sudo docker ps -a
######### 测试1:pxc_node1上创建库表,pxc_node2、pxc_node3上验证
节点(pxc_node1)
sudo docker exec -it pxc_node1 /bin/bash mysql -uroot -p123456
mysql> create database testdb1; — 1. 节点(pxc_node1)创建数据库 mysql> use testdb1; mysql> create table t1(id int,name varchar(20),primary key(id)); — 2. 节点(pxc_node1)创建表(pxc需要每个库表都有主键) mysql> insert into testdb1.t1(id,name) values(1,’pxc_node1’); — 3. 节点(pxc_node1)添加记录
节点(pxc_node2)
sudo docker exec -it pxc_node2 /bin/bash mysql -uroot -p123456
mysql> show databases; — 4. 节点(pxc_node2)验证数据库是否同步成功 mysql> use testdb1; mysql> show tables; — 5. 节点(pxc_node2)验证表是否同步成功(创建表) mysql> select * from testdb1.t1; — 6. 节点(pxc_node2)验证表是否同步成功(表添加记录)
节点(pxc_node3)
sudo docker exec -it pxc_node3 /bin/bash mysql -uroot -p123456
mysql> show databases; — 7. 节点(pxc_node3)验证数据库是否同步成功 mysql> use testdb1; mysql> show tables; — 8. 节点(pxc_node3)验证表是否同步成功(创建表) mysql> select * from testdb1.t1; — 9. 节点(pxc_node3)验证表是否同步成功(表添加记录)
######### 测试2:pxc_node2上创建库表,pxc_node1、pxc_node3上验证
节点(pxc_node2)
sudo docker exec -it pxc_node2 /bin/bash mysql -uroot -p123456
mysql> create database testdb2; — 1. 节点(pxc_node2)创建数据库 mysql> use testdb2; mysql> create table t2(id int,name varchar(20),primary key(id)); — 2. 节点(pxc_node2)创建表(pxc需要每个库表都有主键) mysql> insert into testdb2.t2(id,name) values(1,’pxc_node2’); — 3. 节点(pxc_node2)添加记录
节点(pxc_node1)
sudo docker exec -it pxc_node1 /bin/bash mysql -uroot -p123456
mysql> show databases; — 4. 节点(pxc_node1)验证数据库是否同步成功 mysql> use testdb2; mysql> show tables; — 5. 节点(pxc_node1)验证表是否同步成功(创建表) mysql> select * from testdb2.t2; — 6. 节点(pxc_node1)验证表是否同步成功(表添加记录)
节点(pxc_node3)
sudo docker exec -it pxc_node3 /bin/bash mysql -uroot -p123456
mysql> show databases; — 7. 节点(pxc_node3)验证数据库是否同步成功 mysql> use testdb2; mysql> show tables; — 8. 节点(pxc_node3)验证表是否同步成功(创建表) mysql> select * from testdb2.t2; — 9. 节点(pxc_node3)验证表是否同步成功(表添加记录)
<a name="Y16dJ"></a>
## 6.6. 启停容器
```bash
# 启动pxc集群
sudo docker start pxc_node1
sudo docker start pxc_node2
sudo docker start pxc_node3
# 重启pxc集群
sudo docker restart pxc_node1
sudo docker restart pxc_node2
sudo docker restart pxc_node3
# 停止pxc集群
sudo docker stop pxc_node1
sudo docker stop pxc_node2
sudo docker stop pxc_node3
# 删除pxc集群
sudo docker rm pxc_node1
sudo docker rm pxc_node2
sudo docker rm pxc_node3
参考
博客园:Docker Mysql数据库主从同步配置方法
https://www.cnblogs.com/jinjiangongzuoshi/p/9299275.html
博客园:Docker Mysql数据库双主同步配置方法
https://www.cnblogs.com/jinjiangongzuoshi/p/9299567.html
CSDN:Docker学习二-MySQL双主互备
https://blog.csdn.net/rajayu/article/details/88840234
简书:MySQL双主双从配置-Docker
https://www.jianshu.com/p/19fde522df97
B站(专栏):docker环境下构建mysql数据库PXC集
https://www.bilibili.com/read/cv11651516