【docker】配置mysql及数据持久化


前言


一、使用docker时常用的命令

1、用usermod命令向docker用户组添加新用户

当前登陆用户是hero,直接使用命令docker ps会报错
Cannot connect to the Docker daemon at unix:///home/hero/.docker/desktop/docker.sock. Is the docker daemon running?

  • 增加用户权限
  • 考虑home目录下面残存的.docker文件夹的配置
sudo usermod -aG docker hero

# 等效命令如下
# sudo gpasswd -a $USER docker

重新登陆后,再使用不带sudo前缀的命令

docker ps
systemctl daemon-reload && systemctl restart docker

问题:使用docker ps的时候不行,使用sudo docker ps的时候可以。
思考:使用sudo是提升权限,可hero用户已具备docker组的权限了,为什么还是不行?
分析:可能是docker的配置过程使用了装饰模式,并在不断的装饰流程中存在优先级更高的配置。
操作:删除hero专属的/home/hero/.docker文件夹,就一切正常了。
结论:曾安装过docker中残留的配置文件夹.docker将/etc/docker中的套接字设置覆盖了,使用sudo命令不经过当前用户的配置文件夹。

2、给docker的images打标签

docker image tag mysql:latest mysql:new

docker image tag mysql:latest mysql:new

# 删除原来的镜像
docker rmi mysql:new

重新登陆后,再使用不带sudo前缀的命令

docker ps
systemctl daemon-reload && systemctl restart docker

问题:使用docker ps的时候不行,使用sudo docker ps的时候可以。
思考:使用sudo是提升权限,可hero用户已具备docker组的权限了,为什么还是不行?
分析:可能是docker的配置过程使用了装饰模式,并在不断的装饰流程中存在优先级更高的配置。
操作:删除hero专属的/home/hero/.docker文件夹,就一切正常了。
结论:曾安装过docker中残留的配置文件夹.docker将/etc/docker中的套接字设置覆盖了,使用sudo命令不经过当前用户的配置文件夹。

二、docker相关的环境配置

1、配置文件的生效条件

/etc/profile文件的环境变量所有用户可用,只在用户登陆的时候执行一次,安装编译好的全局软件时常用。

2、 系统状态查看

三、工具配置

  • docker添加镜像源
  • docker配置mysql

1、配置docker镜像源

# 1. 去阿里云获取私有的镜像源地址  
# https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

sudo vi /etc/docker/daemon.json  
# 2. 输入类似下面的内容(下面的n1856ohl是虚拟的,你需要到阿里云的容器镜像服务中复制)

{
  "registry-mirrors": ["https://n1856ohl.mirror.aliyuncs.com"]
}

# 3. 保存上面结果后,重启docker以便使配置生效
systemctl restart docker

进行验证

docker info

输出的倒数几行出现提示Registry Mirrors:后面的内容正确

 ......(省略前面部分内容)          
 Docker Root Dir: /var/lib/docker          
 Debug Mode: false          
 Experimental: false          
 Insecure Registries:          
  127.0.0.0/8          
 Registry Mirrors:          
  https://n1856ohl.mirror.aliyuncs.com/          
 Live Restore Enabled: false          

2、使用docker创建容器(以mysql为例)

查看镜像版本信息

可以去网站https://hub.docker.com/查看镜像的版本信息

拉取镜像

拉取镜像的命令可以在docker官网寻找,或者直接使用命令docker search mysql:8.0 --no-trunc寻找
docker pull mysql:8.0.18

创建和启动

init-create-container-mysql8.sh
其中创建目录的-p有如下作用:
如果目录不存在,mkdir -p 会创建它以及所有必要的上级目录。如果目录已经存在,mkdir -p 会静默地成功执行,不会显示任何错误消息或警告。

# 新建挂载目录,分别是数据、配置文件   
mkdir -p /my_data/docker_data/mysql8/lib_data   
mkdir -p /my_data/docker_data/mysql8/logs  

mkdir -p /my_data/docker_data/mysql8/conf  
cp my.cnf /my_data/docker_data/mysql8/conf/my.cnf  
bash create-container-mysql8.sh  

运行文件create-container-mysql8.sh的内容如下,特别注意以下几点

  • 每行中,符号""后面不要留下空格,否则会运行错误;
  • 使用-v挂载的是宿主机路径:容器路径,如果没有针对容器内环境进行特定修改,那么容器内的路径是固定的不可修改的!
  • 从第二点出发再强调一下,宿主机路径也就是真实物理机路径放在冒号前面
#!/bin/sh 
docker run \
-p 3307:3306 \
--name mysql8 \
--privileged=true \
--restart unless-stopped \
-v /my_data/docker_data/mysql8/conf:/etc/mysql/conf.d \
-v /my_data/docker_data/mysql8/logs:/logs \
-v /my_data/docker_data/mysql8/lib_data:/var/lib/mysql \
-v /etc/localtime:/etc/localtime \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:8.0.20

# -p 端口映射 【这里有个特殊的地方是把3306映射给了3307、后续链接数据库的时候用3307链接不用3306】
# --name mysql8  名称是mysql8
# --privileged=true 挂载文件权限设置
# --restart unless-stopped 设置 开机后自动重启容器
# -v /my_data/docker_data/mysql8/conf:/etc/mysql/conf.d               \ 挂载配置文件
# -v /my_data/docker_data/mysql8/logs:/logs                           \  挂载日志
# -v /my_data/docker_data/mysql8/lib_data:/var/lib/mysql              \ 挂载数据文件 持久化到主机
# -v /etc/localtime:/etc/localtime 容器时间与宿主机同步
# -e MYSQL_ROOT_PASSWORD=123456 设置密码
# -d mysql:8.0.20 指定之前pull的image,如果pull过多个mysql,就要加上冒号并注明版本号

超级简单化的示例版本

#启动
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Lzslov123! -d mysql:8.0.20

进入mysql容器

# 进入容器内部 
docker exec -it mysql8 bash 

# 在容器内部登陆mysql,使用mysql的root用户,密码是之前启动镜像的123456
mysql -u root -p

# 查看mysql自带的root用户的原始数据表
show databases;

在这里插入图片描述
“WITH mysql_native_password” 是 MySQL 数据库中的一种身份验证插件,用于对用户进行身份验证。它使用 MySQL 原生的密码加密算法,是 MySQL 8.0 版本之后默认的身份验证方式。使用 “WITH mysql_native_password” 可以保证数据库的安全性,并且兼容旧版本的 MySQL 客户端。

如果是mysql8之前的版本,那么就要额外使用ALTER USER ‘root’@‘%’ IDENTIFIED WITH mysql_native_password BY ‘123456’;
创建新用户,并更改可以使用的作用域。

# 使用记录有用户信息的数据库mysql
use mysql

#添加远程登录用户 
CREATE USER 'sxl'@'%' IDENTIFIED WITH mysql_native_password BY '20000307';
GRANT ALL PRIVILEGES ON *.* TO 'sxl'@'%'; 

# 查看mysql服务中mysql数据表中记录的用户和允许访问的站点IP范围     
select user,host from user;

#删除多余的root用户
DROP USER 'root'@'localhost'; 
  
select user,host from user;

在这里插入图片描述

在这里插入图片描述

退出mysql容器

使用Ctrl +D,或者输入exit后回车

停止并删除容器

docker   stop mysql8  
docker rm -f mysql8  

docker ps命令只能看到当前正在运行的容器,
docker ps -a命令能看到正在运行的容器和已stop的容器,
docker rm -f 命令可以删除容器,
docker start 命令可以重新启动容器,
docker restart 等效于docker stop + docker start命令

四、导入数据

使用vscode迁移后,

进入mysql容器,然后使用下面的命令进入mysql

mysql -u root -p

source /home/my_app_data_10_1_1_102-2024_07_23_20_52_48-dump.sql

show databases;

五、错误记录

1、启动失败问题排查

(1)利用logs来寻找启动失败的原因

先将启动选项里面的–restart unless-stopped变为–restart no,然后启动镜像后,使用命令docker logs mysql8
在这里插入图片描述
docker rm -f mysql8
chmod 755 my.cnf
bash init-create-container-mysql8.sh

还是会出现错误:
[ERROR] [MY-011087] [Server] Different lower_case_table_names settings for server ('1') and data dictionary ('0').

在这里插入图片描述

原因是之前的my.cnf没有生效,而数据文件生效。
数据文件中默认的linux设置中mysql8的默认设置是lower_case_table_names=0,和现在的lower_case_table_names=1冲突。

措施是删除数据持久文件夹/my_data/docker_data/mysql8/lib_data的内容,并重新部署

docker logs mysql8
docker ps
在这里插入图片描述

2. 记录相关设置,开发时候留意

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

STRICT_TRANS_TABLES:
这个模式要求 MySQL 对事务型表(InnoDB、NDB)执行严格的检查。如果插入或更新的数据违反了表的列定义(如数据类型不匹配、超出范围等),MySQL 将拒绝执行并返回错误。这有助于防止数据损坏,确保数据的完整性和准确性。然而,对于非事务型表(如 MyISAM),此模式可能不会强制执行严格的检查。

NO_ZERO_IN_DATE:
禁用日期和月份中的零值。这意味着,如果尝试插入或更新日期字段为 ‘2023-00-01’ 或 ‘2023-01-00’,MySQL 将拒绝此类操作并返回错误。这有助于防止创建无效的日期值。

NO_ZERO_DATE:
禁用零日期(‘0000-00-00’)。在默认情况下,MySQL 允许使用 ‘0000-00-00’ 作为有效的日期值,但这在某些情况下可能会引起混淆或错误。启用此模式后,任何尝试插入或更新为零日期的操作都将被拒绝。

ERROR_FOR_DIVISION_BY_ZERO:
当执行除法运算时,如果除数为零,MySQL 默认会返回 NULL。但是,如果启用了此模式,MySQL 将改为返回错误,而不是 NULL。这有助于捕获潜在的逻辑错误,特别是在数据可能意外包含零值的情况下。

NO_ENGINE_SUBSTITUTION:
禁止在自动创建或修改表时,如果首选的存储引擎不可用,MySQL 自动选择其他存储引擎。默认情况下,如果 MySQL 无法使用指定的存储引擎(如 InnoDB),它可能会选择另一个可用的存储引擎(如 MyISAM)。启用此模式后,如果首选的存储引擎不可用,MySQL 将拒绝创建或修改表,并返回错误。


总结

易错点:

  1. 写sql语句的时候,from不要写成form;
  2. 从mysql8开始,数据库一开始的初始化就要决定好区分不区分大小写,并且后续不支持修改,详情见[4];
  3. 记录my.cnf里面的sql_mode设置,进行开发的时候注意遵守;

[1] https://www.cnblogs.com/wuyicode/p/18136825
[2] https://blog.csdn.net/a1150499208/article/details/131437199
[3] https://www.runoob.com/docker/docker-install-mysql.html
[4] https://www.cnblogs.com/greatsql/p/16634739.html

  • 30
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值