前言
不得不说,docker部署8版本是真的优点坑啊,网上很多文章教程也都是失效的,但是可能很多写文章根本就没有发现,为什么这么说呢?
主要原因就是挂在配置文件的这一步,其实很多挂在都是失效的,只不过能正常启动,没有被发现罢了,下边咱们来细说!!!
下载部署
下载mysql8,这里咱们以mysql8.0.21为例。
docker pull mysql:8.0.21
下载完成,但是直接启动使用,会有两个问题,一个是大小写的问题,一个是group by无法使用的问题。
1、大小写问题
mysql8默认区分大小写,所以如果我们的表明是大写,但是代码里使用小写,那么就会找不到这个表,这就相当恶心了。
那么咱们可以通过设置来解决:
lower_case_table_names=1
很简单,在我们启动mysql的时候,加上这个配置即可。
docker run -p 3306:3306 \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always -d mysql:8.0.21 \
--lower_case_table_names=1
或者直接在my.cnf中的mysqld属性下添加lower_case_table_names=1即可。
2、group by无法查询的问题
select @@sql_mode
这是因为mysql8默认加了ONLY_FULL_GROUP_BY
这个,所以就不能查询,那么我们直接在配置文件中重新配置即可。
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
好啦,基本就是这两个问题,都能找到解决办法。
但是最坑的地方来了,那么我们该怎么挂在配置文件呢?看看dockerhub中mysql怎么说的:
当然,网上很多文章也是这么说的,我也信了,所以耽误了我一天的时间。。。
-v /mydata/mysql/conf:/etc/mysql/conf.d
我试了无数次,将mysql/conf.d下的文件挂载在外边,一开始没有问题的,如果不是前边两个问题的出现,我都没发现,挂载根本不起作用。
没办法了,我只能按照mysql5的配置方法,直接挂载/etc/mysql/my.cnf,在网上教程中照搬找了一个基本配置:
[mysqld]
user=mysql
character-set-server=utf8
lower_case_table_names=1
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
-v /mydata/mysql/conf/my.cnf:/etc/mysql/my.cnf
别说,真有反应了,能加载挂载的配置文件了,不容易,但是还是启动报错:
Failed to access directory for --secure-file-priv. Please make sure that dir
啥原因呢?搜了半天,网上给的解决办法,一个都不行,真是恶心了。。。
没办法了,去mysql官网上看看吧,这一看才发现被一些不负责任的博客和dockerhub上的内容耍了。。。
从这两处能够看出来,要想成功挂载,要满足两个条件:
第一,要保持原来的my.cnf,而不是直接覆盖挂载;
第二,要挂载/etc/mysql/my.cnf,而不是所谓的conf.d。
好啦,明白怎么弄了,实践一下吧,先普通启动以下mysq8
docker run -p 3306:3306 --name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always \
-d mysql:8.0.21
然后将里边的配置文件my.cnf复制出来
docker cp mysql:/etc/mysql/my.cnf ./
然后再这个文件的基础上修改即可。
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
skip-character-set-client-handshake
skip-name-resolve
secure-file-priv= NULL
lower_case_table_names=1
# 设置sql_mode,去掉了ONLY_FULL_GROUP_BY
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
# Custom config should go here
!includedir /etc/mysql/conf.d/
挂载运行mysql吧
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always \
-d mysql:8.0.21
好啦,正常启动!!!看看有没有生效吧
SHOW GLOBAL VARIABLES LIKE "%lower%"
select @@sql_mode
好啦,终于没问题了。
另外,提一下mysql8默认编码的事,mysql8默认编码是utf8mb4,utf8mb4_0900_ai_ci
,所以如果符合你的编码要求,这个就不用设置了,如果要设置的话可以这样:
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
# 下边两行初始化不起作用
# init_connect='SET NAMES utf8mb4'
# init_connect='SET collation_connection = utf8mb4_general_ci'
character-set-server=utf8
collation-server=utf8mb4_general_ci
skip-character-set-client-handshake
skip-name-resolve
lower_case_table_names=1
# 设置sql_mode,去掉了ONLY_FULL_GROUP_BY
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
但是mysql8设置init_connect并没有用,试了很多次,都没用,看官网这么说的,好像不支持初始化修改:
那只能在建库的时候指定或者sql命令修改指定了,比如下边的:
SET NAMES utf8mb4
set collation_connection = utf8mb4_general_ci;