几点说明:
MySQL5.7 和MySQL8.0在构建方面会有些细节不同,这里以MySQL8.0进行部署
单机MySQL部署
1. 拉取镜像
docker pull mysql
2. 准备好挂载的目录和文件
在使用docker -v来挂载时如果是目录,在宿主机上可以不用提前创建好,docker会自动创建,但是如果是文件需要提前准备好,比如 -v /opt/mysql/log/mysqld.log:/var/log/mysqld.log 我们实质上是想把docker 中的mysqld.log文件挂载到对应的宿主机上,由于宿主机上没有mysqld.log这个文件,这样直接写docker会把mysqld.log当作文件夹然后创建,与此同时,docker中的mysqld.log 这个文件是存在的,导致的结果是把docker中的mysqld.log 文件挂载到宿主机上的mysqld.log 文件夹上,从而报错。
所以我们提前把这个文件准备好
perl
[root@localhost ~]# mkdir -p /opt/mysql/log
[root@localhost ~]# touch /opt/mysql/log/mysqld.log
[root@localhost ~]# cd /opt/mysql/log/
[root@localhost log]# ls
mysqld.log
3. 基于镜像构建 MySQL 容器
ruby
docker run -d --name mysql_8.0 -p 3306:3306 \
-v /opt/mysql/log/mysqld.log:/var/log/mysqld.log \
-v /opt/mysql/mysql/:/var/lib/mysql \
-v /opt/mysql/conf.d/:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
mysql
运行命令后,成功构建出MySQL容器实例
命令解释:
(1)/var/log/mysqld.log是mysql的日志文件
(2)/var/lib/mysql mysql数据存储的地方
(3)/opt/mysql/conf.d mysql配置文件存储的地方
关于挂载mysql配置文件稍微说明下:
在hub.docker.com/_/mysql上介绍说... /etc/mysql/my.cnf 和 /etc/mysql/conf.d/config-file.cnf 中的组合启动设置,后者的设置优先。而本文章就直接使用了/etc/mysql/conf.d/作为配置文件目录进行挂载,在后面会创建config-file.cnf 文件。
为什么不选择 /etc/mysql/my.cnf 作为配置文件使用? 主要有以下几点:
(1)我在没有挂载任何目录的情况下以最简单的方式启动一个容器,进入容器里面,发现在/etc/mysql这个目录中没有my.cnf文件,在/etc/mysql/conf.d目录中也没有config-file.cnf文件,我猜想都需要我们自己创建
(2)但是在/etc 目录下有my.cnf文件 打开一看,在配置文件最后一行有:!includedir /etc/mysql/conf.d/
所以我猜想启动 MySQL 容器实例后会使用/etc/my.cnf作为默认的配置文件,同时会组合使用 /etc/mysql/conf.d/
目录下的配置文件,同时我猜想对于 /etc/mysql/conf.d/
目录下的配置文件应该必须以. cnf 作为后缀(猜想,没试验) ,所以我不清楚会不会使用 /etc/mysql/my.cnf 作为配置文件,我也没试验。
主从集群
主从集群的部署和单机部署,就是多部署几个实例,然后再做一些额外的配置。
主MySQL部署配置
1. 部署主MySQL
ruby
docker run -d --name mysql-master -p 3307:3306 \
-v /opt/mysql-master/log/mysqld.log:/var/log/mysqld.log \
-v /opt/mysql-master/mysql/:/var/lib/mysql \
-v /opt/mysql-master/conf.d/:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
mysql
注意2点:
(1)端口映射不要再使用3306了,在部署单机的时候已经被使用掉了
(2)和部署单机一样,提前把/opt/mysql-master/log/mysqld.log文件创建出来
2. 配置主MySQL
(1)/opt/mysql-master/conf.d/ 目录下创建config-file.cnf 文件,填写下面内容
ini
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
server_id=1
log-bin=mysql-bin
read-only=1
binlog-do-db=master_slave_test
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
-
server_id=1 在主从集群架构下,每个MySQL实例的server_id不能相同 为整数
-
binlog-do-db=master_slave_test 表示我们哪个数据库要进行主从复制
vi /opt/mysql-master/conf.d/config-file.cnf
(2)进入到主mysql客户端,在主mysql上创建一个用户,并给它配置replication slave权限,最后退出重启服务
sql
[root@localhost log]# docker exec -it mysql-master mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.1.0 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> grant replication slave on *.* to 'slave'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
[root@localhost log]# docker restart mysql-master
mysql-master
[root@localhost log]#
使用 CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; 创建slave用户并配置123456密码时,使用了WITH mysql_native_password参数,表示直接可以使用密码进行连接,不然的话后面在从mysql中直接使用密码进行连接会出问题
或者可以直接在配置文件config-file.cnf(my.cnf)进行修改
[mysqld]
default_authentication_plugin=mysql_native_password
(3)关键一步,进入主mysql,show master status\G
查看状态
至此,主MySQL的部署和配置已经完成了!
从MySQL部署和配置
1. 部署从MySQL
ruby
docker run -d --name mysql-slave -p 3308:3306 \
-v /opt/mysql-slave/log/mysqld.log:/var/log/mysqld.log \
-v /opt/mysql-slave/mysql/:/var/lib/mysql \
-v /opt/mysql-slave/conf.d/:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
mysql
同样注意2点:
(1)端口映射不要再使用3306和3307了,在部署单机和主MySQL的时候已经被使用掉了
(2)和部署单机一样,提前把/opt/mysql-slave/log/mysqld.log文件创建出来
2. 配置从MySQL
(1)/opt/mysql-slave/conf.d/ 目录下创建config-file.cnf 文件,内容和在配置主MySQL的一样,只不过需要注意把server_id修改成2,不能和主MySQL一样
ini
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=master_slave_test
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
- 添加完配置文件之后重启,然后进入到从MySQL的客户端,使用如下命令连接主MySQL
ini
change master to master_host='172.17.0.3', master_user='slave', master_password='123456', master_log_file='mysql-bin.000002', master_log_pos=157, master_port=3306;
(1)master_host='172.17.0.3' master_port=3306 表示我们连接的主mysql的IP和端口,可以使用docker inspect mysql-master查看自己的主MySQL的IP
(2)master_user='slave', master_password='123456' 表示连接主mysql使用的用户和密码,就是我们之前在主MySQL上配置的
(3)master_log_file='mysql-bin.000001', master_log_pos=608 要和对应的主mysql一致,进入到自己的主MySQL使用 show master status\G 查看
执行连接,然后再使用 start slave 命令启动主从复制服务 再使用 show slave status\G 查看状态
yaml
[root@localhost ~]# docker exec -it mysql-slave mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.1.0 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> change master to master_host='172.17.0.3', master_user='slave', master_password='123456', master_log_file='mysql-bin.000002', master_log_pos=157, master_port=3306;
Query OK, 0 rows affected, 9 warnings (0.03 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 172.17.0.3
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 157
Relay_Log_File: 7cbfc79bcf01-relay-bin.000002
Relay_Log_Pos: 326
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 157
Relay_Log_Space: 543
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 05680767-64e2-11ee-9f2d-0242ac110003
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 10
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
mysql>
至此,从MySQL已经部署和配置完了,并且成功连上主MySQL,开启了主从复制服务。
验证主从集群可用
进入到主mysql中,创建master_slave_test数据库(配置文件中指定的主从复制数据库名称),然后创建user表,添加几条记录,查看从MySQL是否有数据
1. 主MySQL
sql
[root@localhost log]# docker exec -it mysql-master mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.1.0 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 157
Binlog_Do_DB: master_slave_test
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
mysql> create database master_slave_test;
Query OK, 1 row affected (0.01 sec)
mysql> use master_slave_test;
Database changed
mysql> CREATE TABLE `user` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(125) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, `age` int NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci ROW_FORMAT = Dynamic;
Query OK, 0 rows affected, 4 warnings (0.04 sec)
mysql> select * from user;
Empty set (0.02 sec)
mysql> INSERT INTO `user` VALUES (1, 'zhangsan', 18);
Query OK, 1 row affected (0.01 sec)
mysql> select * from user;
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | zhangsan | 18 |
+----+----------+------+
1 row in set (0.00 sec)
2. 从MySQL查看
完结。