暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

docker-compose安装mySQL及常见问题解答

原创 zxd1412 2023-02-22
2110

一、docker-compose.yml配置

version: '3' # 指定docker-compose语法版本

services: # 从以下定义服务配置列表

mysql:

image: bingozhou/mysql5.7 # 指定使用的镜像名及标签

container_name: mysql # 实例化后的容器名

privileged: true #使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限,设置为true,不然数据卷可能挂载不了,启动不起

restart: always #设置无论遇到什么错,重启容器

ports:

# 使用宿主机的3306端口映射到容器的3306端口

# 宿主机:容器

- "3306:3306"

environment:

MYSQL_ROOT_PASSWORD: newpassword

MYSQL_DATABASE: mproject #数据库名

#自定义数据库的用户

MYSQL_USER: newuser

#自定义数据库的用户

MYSQL_PASSWORD: pwdnewuser

TZ: Asia/Shanghai

command: #使用 command 可以覆盖容器启动后默认执行的命令

--max_connections=1000 #最大连接数

--wait_timeout=28800 #非交互式连接超时时间

--interactive_timeout=28800 #交互式连接超时时间

--default-authentication-plugin=mysql_native_password #认证方式

--character-set-server=utf8mb4 #字符集

--collation-server=utf8mb4_general_ci #排序规则

volumes:

#映射mysql的数据目录到宿主机,保存数据【映射使用相对路径】

- "./data:/var/lib/mysql"

#根据宿主机下的配置文件创建容器【映射使用相对路径】

- "./my.cnf:/etc/mysql/my.cnf"

- ./init:/docker-entrypoint-initdb.d/

- /etc/timezone:/etc/timezone - /etc/localtime:/etc/localtime

重点讲解几个参数:

wait_timeout:服务器关闭非交互连接之前等待活动的秒数,单位是s,默认是28800s,也就是8小时。非交互式连接如jdbc连接数据库等。

interactive_timeout:服务器关闭交互式连接前等待活动的秒数,单位是s,默认是28800s,也就是8小时。交互式连接如navicate连接数据库等。

通俗易懂的说,就是通过mysql客户端连接数据库是交互式连接,通过jdbc连接数据库是非交互式连接。 当一个客户端连接到MySQL数据库后,如果客户端不自己断开,也不做任何操作,MySQL数据库会将这个连接保留wait_timeout 或者 interactive_timeout【哪个参数生效取决于是哪种连接方式】设置的时间,超过这个时间之后,MySQL数据库为了节省资源,就会在数据库端断开这个连接;当然,在此过程中,如果客户端在这个连接上有任意的操作,MySQL数据库都会重新开始计算这个时间。

character-set-server和collation-server:设置数据库字符集和排序规则。小编试过如果不设置的,后续在mysql里面进行设置始终都不生效。

二、my.cnf配置

[client]

# 客户端来源数据的默认字符集

default-character-set=utf8mb4

[mysqld]

# 服务端默认字符集

character-set-server=utf8mb4

# 连接层默认字符集

collation-server=utf8mb4_unicode_ci

[mysql]

# 数据库默认字符集

default-character-set=utf8mb4

三、data文件是volumes映射的宿主机的数据库文件目录

配置完上述文件之后,有几个问题值得我们考虑一下:

问题1:数据库密码设置

第一个问题就是,为了数据库的安全,往往我们需要设置稍微复杂一点的数据库连接密码,而不是直接使用root。那么是不是直接把MYSQL_ROOT_PASSWORD后面配置成我们需要设置的密码就行了呢,答案是不行的。【示例我设置的数据库连接密码newpassword】

我们可以验证一下,通过命令进入容器,再输入密码连接会提示报错。

[root@i ~]# docker exec -it mysql /bin/bash

[root@i ~]# mysql -u root -pnewpassword

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

遇到这种问题该怎么处理呢:

(1)、修改my.cnf 文件,在[mysqld]下添加

skip-grant-tables

(2)、进入容器内部登录mysql

[root@i ~]# docker exec -it mysql /bin/bash

[root@i ~]# mysql

mysql>

(3)、修改root用户密码

mysql>update mysql.user set authentication_string=password('newpassword') where user='root';

注意事项:mysql 4.6版本以上的mysql服务器password改为authentication_string;我使用的mysql镜像版本是5.7,所以用update mysql.user set password=password(‘newpassword’) where user='root',否则无法修改用户密码。

(4)、重启mysql

docker restart mysql

问题2:新增用户

有时候为了方便管理不同的权限,除了root用户之外,会再新增其他的用户,可以有三种方式来实现这种需求。

(1)第一种就是进入mysql容器,新增用户并授权

[root@i ~]# docker exec -it mysql /bin/bash

[root@i ~]# mysql -u root -pnewpassword

mysql>CREATE USER 'newuser'@'%' IDENTIFIED BY 'pwdnewuser';

mysql>GRANT All privileges ON *.* TO 'newuser'@'%';

(2)第二种在docker-compose.yml文件command下设置
#数据库名

MYSQL_DATABASE: mproject

#自定义数据库的用户

MYSQL_USER: newuser

#自定义数据库的用户

MYSQL_PASSWORD: pwdnewuser

docker-compose.yml完整配置文件如下:


注意这种方式创建的用户还需要先使用root用户登录以后给它赋予相关的权限才可以使用它进行数据库的连接:

grant all privileges on dbname.tablename to 'username'@'ip';

# 比如想给用户newuser赋予数据库mproject所有的表的权限并且不限制root用户的连接地址,代码如下

grant all privileges on mproject.* to 'newuser'@'%';

flush privileges; # 刷新权限

(3)第三种就是编写用户权限的sql文件,并把文件在docker-compose.yml进行映射。

在mysql/init文件夹下建立init.sql文件:

CREATE USER 'newuser'@'%' IDENTIFIED BY 'pwdnewuser';

GRANT All privileges ON *.* TO 'newuser'@'%';

docker-compose.yml完整配置文件如下:


配置说明:

/docker-entrypoint-initdb.d/

这个目录是数据库官方提供的初始目录,以.sql .sh .bat结尾的文件放到这个目录下面,在数据库启动的时候会自动执行。

问题3:docker-compose logs -f 日志时间与系统时间不一致

通过date命令查看时间

分别查看主机时间和容器时间,两者时间不一致,相差八个小时

UTC表示世界协调时间(Coordinated Universal Time)

CST表示中国标准时间(China Standard Time)

所以,这2个时间相差8个小时。(所以没有设置过的容器, 一般跟宿主机时间相差8h,这是由于我们在安装系统的时选择的时区是上海,而CentOS默认bios时间是utc时间,所以时间相差了8小时。)

如何解决?

(1)执行命令创建文件【没有/etc/timezone文件或者是一个空文件夹,记得删除】

echo "Asia/shanghai" > /etc/timezone

(2)在docker-compose.yml文件中

volumes: - /etc/timezone:/etc/timezone - /etc/localtime:/etc/localtime

(3)docker-compose restart 重启即可

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论