Docker 数据卷:MySQL 数据同步实战

目录

前言

前提:

[实战1:在mysql添加 数据,本地是否同步](#实战1:在mysql添加 数据,本地是否同步)

[1 使用 docker images 命令 查看当前已下载 的镜像](#1 使用 docker images 命令 查看当前已下载 的镜像)

[2 使用 docker pull 命令 从dockerhub 远程仓库 拉取指定镜像 9.6.0](#2 使用 docker pull 命令 从dockerhub 远程仓库 拉取指定镜像 9.6.0)

[3 执行docke run 创建 mysql 容器 ,并将mysql容器的默认的配置和数据存储目录挂载到本地目录](#3 执行docke run 创建 mysql 容器 ,并将mysql容器的默认的配置和数据存储目录挂载到本地目录)

[4 使用 dataGrip 图形操作界面,连接刚创建的mysql03 mysql 服务器 ,并创建一个mysql-test 数据库](#4 使用 dataGrip 图形操作界面,连接刚创建的mysql03 mysql 服务器 ,并创建一个mysql-test 数据库)

[5 使用docker exec 命令 进入 mysql 终端 ,验证mysql-test 是否创建成功](#5 使用docker exec 命令 进入 mysql 终端 ,验证mysql-test 是否创建成功)

[6 验证 本地data目录 数据是否同步](#6 验证 本地data目录 数据是否同步)

[实战2 :本地映射的mysql 配置目录添加日志配置,是否会同步到 mysql 容器](#实战2 :本地映射的mysql 配置目录添加日志配置,是否会同步到 mysql 容器)

[问题1: 使用 docker logs mysql03 打印 新增mysql-test 数据库的日志 ,但是看日志后,并没有找到新增mysql-test](#问题1: 使用 docker logs mysql03 打印 新增mysql-test 数据库的日志 ,但是看日志后,并没有找到新增mysql-test)

[验证:在本地映射的mysql 配置目录添加日志配置,是否会同步到 mysql 容器](#验证:在本地映射的mysql 配置目录添加日志配置,是否会同步到 mysql 容器)

核心总结


前言

上一篇博客,简单介绍了Docker 数据卷 含义和相关示例,帮助大家 去理解Docker 数据卷 到底是干什么的?

https://blog.csdn.net/m0_74124657/article/details/157519062

本篇博客,将通过使用 Docker 数据卷技术,实现 MySQL 数据的同步


前提:

1 已经下载了dockerDesktop操作软件,配置 docker环境,可以使用docker命令

https://blog.csdn.net/m0_74124657/article/details/156836207?spm=1001.2014.3001.5502

2 具备良好的网络环境,支持从dockerHub 拉取mysql 镜像

如果可以正常点击 dockerhub 中下载mysql 镜像的界面,说明网络畅通:https://hub.docker.com/_/mysql

3 已经下载 好操作mysql 数据库的 图形化软件:DataGrip ,DBeaver,Navicat 等等

4 了解mysql 容器 默认读取配置数据写入的目录

容器内路径:/etc/mysql/conf.d

这是 MySQL 容器默认加载额外配置文件的目录,容器启动时会自动读取这里的配置。

作用:

你可以在宿主机的 /home/mysql/conf 里直接修改配置(比如调整字符集、连接数、缓存大小),无需进入容器。

配置会持久保存在宿主机,就算容器删除、重建,配置也不会丢失。


容器内路径:/var/lib/mysql

这是 MySQL 容器默认存储数据的目录,所有数据库的表和数据都存在这里。

作用:

数据持久化:如果不挂载,容器删除后,里面的 MySQL 数据会跟着容器一起消失;挂载后,数据保存在宿主机目录,容器重建后依然可以复用。

备份方便:直接备份宿主机的 /home/mysql/data 目录,就相当于备份了整个 MySQL 数据库。


实战1:在mysql添加 数据,本地是否同步

1 使用 docker images 命令 查看当前已下载 的镜像

可以发现,我已经下载好最新的mysql,并且 可以看到右侧 有一个 大写 的" U"标志 表示这个镜像曾经创建过一个或多个容器

2 使用 docker pull 命令 从dockerhub 远程仓库 拉取指定镜像 9.6.0

复制代码
docker pull mysql:9.6.0

拉取成功,第二次使用 docker images 命令,可以看到刚拉取的9.6.0版本的镜像

3 执行docke run 创建 mysql 容器 ,并将mysql容器的默认的配置和数据存储目录挂载到本地目录

3.1 展示错误示例

我选中的区域,展示的是错误示例

  • 给容器设置名字不能有空格,否则误认为你添加的命名是镜像名
  • 容器名字重复了,表示之前已经过mysql02的容器

正确创建 mysql 容器 命令如下:

复制代码
docker run -d -p 3310:3306 -v /home/dj/conf:/etc/mysql/conf.d -v /home/dj/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 --name=mysql03

3.2 使用docker ps 验证 mysql03 容器是否启动成功

3.3 验证 mysql 容器 默认的配置目录和数据存储目录是否挂载到本地

命令:

复制代码
docker inspect mysql03

如下图所示:可以看到 ,mysql 容器挂载成功了,之后 数据库数据的变化和配置的更新都会同步到本地的目录。相反如果 本地目录中存储 mysql 数据的目录,配置目录发生改变,也会同步到容器。 -----相当于我们学习vue3 前端框架中的model 语法 " 双向绑定 "

4 使用 dataGrip 图形操作界面,连接刚创建的mysql03 mysql 服务器 ,并创建一个mysql-test 数据库

可以看到 成功连接上了mysql 服务器 ,并创建了 mysql-test 数据库

5 使用docker exec 命令 进入 mysql 终端 ,验证mysql-test 是否创建成功

命令:

复制代码
docker exec -it mysql03  mysql -uroot -p123

6 验证 本地data目录 数据是否同步

实战2 :本地映射的mysql 配置目录添加日志配置,是否会同步到 mysql 容器

问题1: 使用 docker logs mysql03 打印 新增mysql-test 数据库的日志 ,但是看日志后,并没有找到新增mysql-test

上网浏览发现:

1 Docker logs 默认只捕获 MySQL 的启动 / 错误日志

Docker 容器的日志默认只收集 MySQL 的标准输出(STDOUT/STDERR),也就是容器启动初始化、错误信息这些内容。

而你执行的 CREATE DATABASE 属于普通 SQL 操作,默认不会被记录到错误日志里,所以不会出现在 docker logs 的输出中。

2 MySQL 默认不开启通用查询日志

要想看到所有 SQL 操作(包括创建数据库、表、增删改查等),需要手动开启 MySQL 的 通用查询日志(general_log)。

实战:如何让创建数据库的操作出现在 Docker 日志中(调试用)

本质上,就是 验证,在本地映射的mysql 配置目录添加配置,是否会同步到 mysql 容器

验证:在本地映射的mysql 配置目录添加日志配置,是否会同步到 mysql 容器

测试步骤

  • 在你挂载的配置目录 /home/dj/conf 里创建 my.cnf 文件,添加以下内容

将操作 mysql 的日志,写入到general.log 日志文件中

复制代码
sudo tee /home/dj/conf/my.cnf <<EOF
[mysqld]
general_log = 1
general_log_file = /var/log/mysql/general.log
EOF

这个命令的意思是将EOF 中间的内容 通过tee 命令 写入到 my.cnf 文件

general_log = 1
**注意:**general_log 是 MySQL 的布尔型变量,1 等价于 ON(开启日志),0 等价于 OFF(关闭日志)

general_log_file = /dev/stdout

**注意:**MySQL 把通用查询日志的内容,输出到 MySQL 进程的「标准输出(stdout,文件描述符 1)」,可以理解为,


  • 使用root 权限创建 my.cnf文件 ,将命令写入的到文件中

  • 执行 sudo tee 命令将配置写入到 my.cnf文件

如下图所示,配置已成功写入

  • 重启 mysql03容器

命令:

复制代码
docker restart mysql03
  • 修改my.cnf的权限(适配mysql低权限用户)

问题:之前sudo tee 命令是使用root 权限将配置写入到 本地的与mysql 容器映射的配置目录中的,也就是说 修改后的日志配置是root 级别 ,但是我们操作的mysql 还是使用的是mysql权限 比root 权限要低

命令:可以看到打印的日志中是root 权限

复制代码
docker exec -it mysql03 ls -l /etc/mysql/conf.d/my.cnf

解决办法

复制代码
docker exec -it mysql03 chown mysql:mysql /etc/mysql/conf.d/my.cnf

再次查看权限,发现已从root:root成功修改为mysql:mysql

  • 查看 mysql 容器 日志,是否生效

验证 MySQL 通用日志(general_log)当前状态

  • eneral_log:显示 ON 表示通用日志已开启,OFF 表示关闭(这是你之前反复调试的核心指标)。

  • general_log_file:显示日志文件的存储路径(比如你现在配置的 /var/log/mysql/general.log)。

    docker exec -it mysql03 mysql -uroot -p123 -e "SHOW VARIABLES LIKE 'general_log%'"

  • 向 mysql-test2数据库 插入一条id=6 的数据

    docker exec -it mysql03 mysql -uroot -p123 -e 'USE mysql-test2; INSERT INTO mysql-test2 (id) VALUES (6);'

  • 使用docker exec -it mysql03 grep -i 'insert into `mysql-test2`' /var/log/mysql/general.log查看日志

    docker exec -it mysql03 grep -i 'insert into mysql-test2' /var/log/mysql/general.log

结尾补充:因为 操作2 : 执行 sudo tee 命令将配置写入到 my.cnf文件,导致将my.cnf文件权限抬高到root 级别,最好的解决办法是,从一开始 将日志配置写入到 my.cnf文件 就只使用 tee命令,不要添加 sudo 。

当你一开始直接 使用下面的命令时,就不需要后面使用chown 命令操作文件的权限了

复制代码
tee /home/dj/conf/my.cnf <<EOF
[mysqld]
general_log = 1
general_log_file = /var/log/mysql/general.log
EOF

核心总结

Docker 挂载 MySQL 配置文件时,重启容器是配置生效的必要操作,但不是充分操作:

  • 仅写配置 + 挂载 + 重启 → 若配置文件是 root 权限(sudo tee 导致),MySQL 读不到,配置不生效;
  • 写配置 + 挂载 +改对权限+ 重启 → MySQL 重启时能正常读取配置文件,新配置才会真正生效;

Docker 的 bind 挂载特性是内容 + 权限双同步,sudo tee 在本地造的权限问题,会直接同步到容器内,成为配置加载的 "隐形障碍"。

相关推荐
礼拜天没时间.2 小时前
《Docker实战入门与部署指南:从核心概念到网络与数据管理》:环境准备与Docker安装
运维·网络·docker·容器·centos
每天瞎忙的农民工2 小时前
Ubuntu 24 安装npm22
linux·运维·ubuntu·npm
张小凡vip2 小时前
Kubernetes---存储方案:Rook自动结合Ceph
ceph·容器·kubernetes
j_xxx404_2 小时前
Linux:进程控制(创建/终止/等待/获取退出信息/多进程)
linux·运维·服务器
Cyber4K3 小时前
【Kubernetes专项】K8s 控制器 StatefulSet 从入门到企业实战应用
云原生·容器·kubernetes
BUG_MeDe3 小时前
LINUX MTU/MSS(1500 1460等)的一些理解
linux·运维·服务器
风流倜傥唐伯虎3 小时前
Windows 版 Docker 的 Linux 环境(docker-desktop)与 builder-jammy-base:latest 镜像核心区别
linux·docker·容器
曹牧3 小时前
Nginx:正向代理与反向代理
运维·nginx
Ha_To3 小时前
2026.1.30 搭建docker仓库
运维·docker·容器