systemctl start docker
systemctl enable docker

docker inspect --format='{{.NetworkSettings.IPAddress}}' master

docker inspect master 可以查看卷映射关系

----------------mysql 5.7

# 将容器中的日志、数据、配置文件关联映射到宿主机当中,容器删除或者挂掉也不怕数据丢失,主机中的数据还在
docker run -d -p 3307:3306 --privileged=true -v /home/mysql-master/log:/var/log/mysql -v /home/mysql-master/data:/var/lib/mysql -v /home/mysql-master/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql_master docker.io/mysql:5.7
#解释
docker run -d -p 3307:3306 --privileged=true
 -v /home/mysql-master/log:/var/log/mysql   #日志
 -v /home/mysql-master/data:/var/lib/mysql  #数据
 -v /home/mysql-master/conf:/etc/mysql#配置文件
 -e MYSQL_ROOT_PASSWORD=123456   #root密码
 --name mysql_master docker.io/mysql:5.7  #设置名字
 

docker 实现mysql主从
1.docker安装mysql

docker pull mysql:5.7
2.运行mysql的主从容器

docker run -p 3306:3306 --name mysql-master  -v /mydata/mysql-master/conf:/etc/mysql/conf.d -v /mydata/mysql-master/logs:/logs -v /mydata/mysql-master/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

docker run -p 3307:3306 --name mysql-slave  -v /mydata/mysql-slave/conf:/etc/mysql/conf.d -v /mydata/mysql-slave/logs:/logs -v /mydata/mysql-slave/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

3.在/mydata/mysql-master/conf下创建my.cnf文件

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=103
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql  
## 指定需要同步的数据库名称  #binlog-do-db=
## 开启二进制日志功能  
#记录所有更改数据的语句,可以用于主从服务器之间的数据同步,以及服务器遇到故 障时数据的无损失恢复。
log-bin=mall-mysql-bin  
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M  
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed  
#statement 记录所有的写操作到bin-log文件 缺点:sql语句执行set time=now() 会出现主从不一致  
#row 记录每行的变换  缺点:数据量大的时候,记录数据多
#mixed是statement和row的混合  
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
 
#通用查询日志
#记录所有连接的起始时间和终止时间,以及连接发送给数据库服务器的所有指令, 对我们复原操作的实际场
#景、发现问题,甚至是对数据库操作的审计都有很大的帮助。
general_log=ON  
general_log_file=/var/lib/mysql/mysql-general.log 
 
#慢查询日志
#记录所有执行时间超过long_query_time的所有查询,方便我们对查询进行优化。
slow_query_log=ON 
slow_query_log_file=/var/lib/mysql/mysql-slow.log 
long_query_time=3 
#设置慢查询的阈值为3秒,超出此设定值的SQL即被记录到慢查询日志
log_output=FILE
max_allowed_packet=200M
 
#错误日志
#记录MySQL服务的启动、运行或停止MySQL服务时出现的问题,方便我们了解服务器的 状态,从而对服务器进行维护。
log-error=/var/lib/mysql/mysql-error.log 

/mydata/mysql-master-slave/conf创建my.cnf文件

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=104
## 指定不需要同步的数据库名称
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=all 
 
# relay_log配置中继日志
#用于主从服务器架构中,从服务器用来存放主服务器二进制日志内容的一个中间文件。 从服务器通过读取中继#日志的内容,来同步主服务器上的操作。
relay_log=mall-mysql-relay-bin  
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  
## slave设置为只读(具有super权限的用户除外)
read_only=1 

-----------------------------------重启

docker mysql-master restart

docker mysql-slave  restart

4.运行docker exec -t 容器名称或容器id /bin/bash 进入master容器实例

5.运行 mysql -uroot -proot进入容器

6.master容器实例内创建数据同步用户

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
7.在主数据库中查看主从同步状态 show master status;--未有信息

8.按照4.5步进入slave容器内部 运行如下命令
 
change master to master_host='宿主ip', master_user='slave', master_password='123456', master_port=3308, master_log_file='mall-mysql-bin.000001', master_log_pos=154, master_connect_retry=30;
 9.在从数据库中开启主从同步 start slave;

10.在从数据库中查看主从同步状态 show slave status \G;

----------------重启宿主机看数据

[root@docker ~]# service docker restart

[root@docker ~]# docker exec -it mysql-master bash
Error response from daemon: Container e3e107c403746090f530bd19abd92e5164053b60cff75b7b0453801766ace039 is not running

[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS                       PORTS     NAMES
2af2051a89ce   mysql:5.7   "docker-entrypoint.s…"   31 minutes ago   Exited (0) 2 minutes ago               mysql-slave
e3e107c40374   mysql:5.7   "docker-entrypoint.s…"   31 minutes ago   Exited (137) 2 minutes ago             mysql-master

[root@docker ~]# docker mysql-master start
docker: 'mysql-master' is not a docker command.

[root@docker ~]# docker start mysql-master 
mysql-master
[root@docker ~]# docker start mysql-slave 
mysql-slave
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
2af2051a89ce   mysql:5.7   "docker-entrypoint.s…"   33 minutes ago   Up 5 seconds    33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-slave
e3e107c40374   mysql:5.7   "docker-entrypoint.s…"   33 minutes ago   Up 10 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-master
[root@docker ~]# docker ps 
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
2af2051a89ce   mysql:5.7   "docker-entrypoint.s…"   33 minutes ago   Up 7 seconds    33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-slave
e3e107c40374   mysql:5.7   "docker-entrypoint.s…"   33 minutes ago   Up 12 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-master

[root@docker ~]# docker exec -it mysql-master bash
bash-4.2# mysql -uroot -proot 
mysql: [Warning] Using a password on the command line interface can be insecure.

mysql> show master status;
 +-----------------------+----------+--------------+------------------+-------------------+
 | File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
 +-----------------------+----------+--------------+------------------+-------------------+
 | mall-mysql-bin.000003 |      154 |              | mysql            |                   |
 +-----------------------+----------+--------------+------------------+-------------------+
 1 row in set (0.00 sec)

mysql> exit
Bye
bash-4.2# exit

[root@docker ~]# docker exec -it mysql-slave bash
bash-4.2# 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.

mysql> show slave status \G
 *************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 192.168.1.141
                   Master_User: slave
                   Master_Port: 3306
                 Connect_Retry: 30
               Master_Log_File: mall-mysql-bin.000003
           Read_Master_Log_Pos: 154
                Relay_Log_File: mall-mysql-relay-bin.000008
                 Relay_Log_Pos: 377
         Relay_Master_Log_File: mall-mysql-bin.000003
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
    
           Exec_Master_Log_Pos: 154
               Relay_Log_Space: 760
               Until_Condition: None
              
 1 row in set (0.00 sec)mysql> show variables like '%dir%'
     -> ;
 +-----------------------------------------+----------------------------+
 | Variable_name                           | Value                      |
 +-----------------------------------------+----------------------------+
 | basedir                                 | /usr/                      |
 | binlog_direct_non_transactional_updates | OFF                        |
 | character_sets_dir                      | /usr/share/mysql/charsets/ |
 | datadir                                 | /var/lib/mysql/            |
 | ignore_db_dirs                          |                            |
 | innodb_data_home_dir                    |                            |
 | innodb_log_group_home_dir               | ./                         |
 | innodb_max_dirty_pages_pct              | 75.000000                  |
 | innodb_max_dirty_pages_pct_lwm          | 0.000000                   |
 | innodb_tmpdir                           |                            |
 | innodb_undo_directory                   | ./                         |
 | lc_messages_dir                         | /usr/share/mysql/          |
 | plugin_dir                              | /usr/lib64/mysql/plugin/   |
 | slave_load_tmpdir                       | /tmp                       |
 | tmpdir                                  | /tmp                       |
 +-----------------------------------------+----------------------------+
 15 rows in set (0.01 sec)mysql> exit
 Bye
 bash-4.2# cd /var/lib/mysql
 bash-4.2# mkdir rick
 bash-4.2# exit
 exit
 [root@docker /]# cd mydata
 [root@docker mydata]# ls
 mysql-master  mysql-slave
 [root@docker mydata]# cd mysql-slave
 [root@docker mysql-slave]# ls
 conf  data  logs
 [root@docker mysql-slave]# cd d*
 [root@docker data]# cd rick
 [root@docker rick]# -------------mysql 8

一.CentOS7.9安装Docker20

1.安装yum-utils工具

yum install -y yum-utils


2.设置docker的依赖源

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo


注释:CentOS直接使用yum命令安装的Docker版本为1.13.1属于旧版docker的最后一个版本,所以需要配置一个repo,才能安装新版的Docker-CE(社区版)。Docker-EE(企业版)需收费读者自行了解即可,这里使用CE社区版

3.安装docker

yum -y install docker-ce


4.查看安装的版本

docker -v
docker version


5. 查看配套设置的版本

yum list installed | grep docker


6.拉取MySQL8镜像

docker pull mysql:8


注解:mysql:5.7代表mysql版本为5.7

查看docker镜像

docker images


容器内执行宿主docker exec_容器内执行宿主docker exec


二.部署MySQL集群(一主二从)

1.创建主从MySQL的配置及数据文件的存储目录

# 创建主服务的配置目录和数据目录
mkdir -p /usr/local/mysqlData/master/cnf
mkdir -p /usr/local/mysqlData/master/data

# 创建1号从服务器的配置目录和数据目录
mkdir -p /usr/local/mysqlData/slave/cnf
mkdir -p /usr/local/mysqlData/slave/data

# 创建2号从服务器的配置目录和数据目录
mkdir -p /usr/local/mysqlData/slave2/cnf
mkdir -p /usr/local/mysqlData/slave2/data


创建两个从服务器的配置是因为MySQL配置的server-id不能重复

2.配置主服务器的配置文件

vim /usr/local/mysqlData/master/cnf/mysql.cnf


配置文件如下

[mysqld]
## 设置server_id,注意要唯一
server-id=1
## 开启binlog
log-bin=mysql-bin
## binlog缓存
binlog_cache_size=1M
## binlog格式(mixed、statement、row,默认格式是statement)
binlog_format=mixed
##设置字符编码为utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4


3.配置从服务器的配置文件

# 1号从服务器
vim /usr/local/mysqlData/slave/cnf/mysql.cnf
# 2号从服务器
vim /usr/local/mysqlData/slave2/cnf/mysql.cnf


配置文件如下(1号的server-id设置为2,2号的server-id设置为3,不重复即可)

[mysqld]
## 设置server_id,注意要唯一
server-id=2
## 开启binlog
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
## 如果需要同步函数或者存储过程
log_bin_trust_function_creators=true
## binlog缓存
binlog_cache_size=1M
## binlog格式(mixed、statement、row,默认格式是statement)
binlog_format=mixed
##设置字符编码为utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
slave_skip_errors=1062
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4


4.创建主从MySQL镜像

# 主服务器实例化
docker run -itd -p 3317:3306 --name master -v /usr/local/mysqlData/master/cnf:/etc/mysql/conf.d -v /usr/local/mysqlData/master/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8 

# 1号从服务器实例化
docker run -itd -p 3318:3306 --name slaver -v /usr/local/mysqlData/slave/cnf:/etc/mysql/conf.d -v /usr/local/mysqlData/slave/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8 

# 2号从服务器实例化
docker run -itd -p 3319:3306 --name slaver2 -v /usr/local/mysqlData/slave2/cnf:/etc/mysql/conf.d -v /usr/local/mysqlData/slave2/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8


参数解释

-p 指定容器暴露的端口,宿主机(物理机)端口: docker实例端口
-p 3317:3306 把物理机的3317端口给实例的端口3306端口进行映射

-v 给容器挂载存储卷,挂载到容器的某个目录
-v /usr/local/mysqlData/master/cnf:/etc/mysql/conf.d 把刚创建的配置文件夹映射成实例的/etc/mysql/conf.d
-v /usr/local/mysqlData/master/data:/var/lib/mysql 数据文件夹的映射

-e 指定环境变量,容器中可以使用该环境变量
-e MYSQL_ROOT_PASSWORD=123456 设置MySQL的root账号密码为123456

5.查看已创建的实例

docker ps -a


6.创建mysql连接用户

# 创建用户 reader设置密码为reader
CREATE USER reader IDENTIFIED BY 'reader';
# 给予reader同步权限
GRANT REPLICATION SLAVE ON *.* to 'reader'@'%';
FLUSH PRIVILEGES;


注解:其余的用户,远程连接的自行设置

7.获取主服务器的连接信息

# MySQL的连接信息
SHOW MASTER STATUS;

#新开连接 获取master实例的在docker的地址
docker inspect --format='{{.NetworkSettings.IPAddress}}' master
172.17.0.2


从服务器连接主服务器(两台从服务器均是以下操作)

# 配置连接的参数
change master to master_host='172.17.0.2',master_user='reader',master_password='reader',master_log_file='mysql-bin.000003',master_log_pos=2259;

-----如果docker inspect --format='{{.NetworkSettings.IPAddress}}' master 这个3306不行,也可以用对外的ip地址连接

change master to master_host='192.168.1.141',  master_user='reader',master_password='reader',master_port=3317, master_log_file='mysql-bin.000003',master_log_pos=861 ;
  
# 启动同步
start slave;
# 查看是否成功
show slave status\G

# 两项都为Yes时代表成功。
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes

# 失败需要使用停止连接后检查其他账号密码,地址,pos等参数

# 停止连接,如果一次成功无需使用该命令
stop slave;



三.结果

主服务器执行命令

SHOW SLAVE HOSTS;


容器内执行宿主docker exec_docker_02

能从主服务器查询到两台从服务器的ID以及端口。完成MySQL部署。

💡检查是否存在 MySQL 镜像
docker images

PS F:\Space\mysql> docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        latest    3218b38490ce   2 months ago   516MB

PS F:\Space\mysql> docker image rm 3218b38490ce

PS F:\Space\mysql> docker images
 

PS F:\Space\mysql> docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
mysql        5.7.37    538ec2c8721c   3 days ago   448MB

可以看到我已经成功下载 5.7.37 版本的 MySQL,但是这个日期是什么鬼创建时间明明是刚刚,这里却显示 3 天前,当然这些可以不用太担心,反正能用就行。

💡运行MySQL镜像并设置密码
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

PS F:\Space\mysql> docker run --name java_mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.37
87893aae49c42597508318eea1ad48e8f64c6e3d22ed999f3fbe5bb626d8110a
PS F:\Space\mysql>

💡查看MySQL镜像是否运行
docker ps

PS F:\Space\mysql> docker ps
 

💡 进入运行的容器
docker exec -it <容器 ID> bash

PS F:\Space\mysql> docker exec -it 87893aae49c4 bash
root@87893aae49c4:/#
1

💡查看数据文件位置
show variables like '%dir%';

mysql> show variables like '%dir%';
 +-----------------------------------------+----------------------------+
 | Variable_name                           | Value                      |
 +-----------------------------------------+----------------------------+
 | basedir                                 | /usr/                      |
 | binlog_direct_non_transactional_updates | OFF                        |
 | character_sets_dir                      | /usr/share/mysql/charsets/ |
 | datadir                                 | /var/lib/mysql/            |
 | ignore_db_dirs                          |                            |
 | innodb_data_home_dir                    |                            |
 | innodb_log_group_home_dir               | ./                         |
 | innodb_max_dirty_pages_pct              | 75.000000                  |
 | innodb_max_dirty_pages_pct_lwm          | 0.000000                   |
 | innodb_tmpdir                           |                            |
 | innodb_undo_directory                   | ./                         |
 | lc_messages_dir                         | /usr/share/mysql/          |
 | plugin_dir                              | /usr/lib/mysql/plugin/     |
 | slave_load_tmpdir                       | /tmp                       |
 | tmpdir                                  | /tmp                       |
 +-----------------------------------------+----------------------------+
 15 rows in set (0.01 sec)

📕外部连接MySQL
其实如果你希望容器里面的MySQL,可以通过外部的图像界面管理的话,只需要将端口映射一下就行了。
docker run -p <本机端口:数据库端口> --name <容器名称> -e MYSQL_ROOT_PASSWORD=<数据库密码> -d mysql:<版本号>

PS C:\Users\19095> docker run -p 8888:3306 --name java -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.37
 

可以观察到在本地我通过 localhost 主机的8888端口成功连接上容器里面的数据库管理系统。

❌问题
❌中文字符存储错误
说什么来什么,我以为系统字符集为 utf8 ,那么我创建表的时候应该默认是 utf8 字符格式,终究还是太年轻了,技术不到家经验不足一起的毛病。

先看一下报错,本来就是想测试一下是什么影响表的默认字符集😌。这不是失误,而是故意为之,没错就是这样的😂。
show variables like '%char%';

 
其实上面也有介绍如何查看MySQL数据库客户端与服务端的字符集设置,不过还是介绍一下,避免大伙还去前面看命令。

alter table <表名> convert to character set utf8;

mysql> alter table person   convert to CHARSET utf8;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

显然我可以插入中文字符了,但是你以为这样就结束了。其实还并没有,因为终端还是无法显示中文。

mysql> select * from person;
 +--------+------+------+
 | name   | age  | sex  |
 +--------+------+------+
 | hjhcos |   13 | ?    |
 +--------+------+------+


 
通过命令查看数据,sex 字符的数据直接打问号,这非常不方便我查询。

mysql> set character_set_results = utf8;
 Query OK, 0 rows affected (0.00 sec)mysql> show variables like '%char%';
 +--------------------------+----------------------------+
 | Variable_name            | Value                      |
 +--------------------------+----------------------------+
 | character_set_client     | latin1                     |
 | character_set_connection | latin1                     |
 | character_set_database   | latin1                     |
 | character_set_filesystem | binary                     |
 | character_set_results    | utf8                       |
 | character_set_server     | latin1                     |
 | character_set_system     | utf8                       |
 | character_sets_dir       | /usr/share/mysql/charsets/ |
 +--------------------------+----------------------------+
 8 rows in set (0.00 sec)mysql> select * from java.person;
 +--------+------+------+
 | name   | age  | sex  |
 +--------+------+------+
 | hjhcos |   13 | 男  |
 +--------+------+------+

mysql> show variables like '%char%'; 

docker run --name mysql-slave --privileged=true -v /home/mysql/slave1-data:/var/lib/mysql -p 3307:3306 --link mysql-master:master -e MYSQL_ROOT_PASSWORD=a123456. -d xiaochunping/mysql-slave
 

docker restart mysql-master