docker-mysql8实践
- docker hub官方mysql镜像:https://hub.docker.com/_/mysql
- 官方镜像里已经有容器运行的具体说明,这里就不再赘述了
注意事项
执行sql脚本
-
当服务跑起来后,我们需要创建数据库,而一般我们都是通过脚本创建的,因此需要先把脚本拷到docker容器内,可以使用docker cp命令,将脚本拷到容器内部,然后用docker exec进入容器内,进入mysql,执行脚本
-
举个栗子:现将当前test.sql拷到容器mysql8的跟目录下,然后进入mysql创建数据库test执行test.sql
docker cp ./test.sql mysql8:/ docker exec -it mysql8 bash mysql -uroot -p create database if not exists test default charset utf8mb4 collate utf8mb4_general_ci; use test; source /test.sql; exit;
远程连接
-
一开始远程连接时关闭的,因为root用户设定了localhost才能访问,也就是只有本机可以访问
-
如果非要远程访问,则必须将localhost改为%,表示任何外部ip都可以访问(当然这是非常危险的,一般会指定特定的ip开放远程连接)
-
以下是具体操作流程:
-
先进入mysql容器中
docker exec -it 容器名或容器id bash
-
进入容器后执行
mysql -uroot -p
-
回车后敲入密码,之后可通过如下两种方法修改host
-
方法一:
mysql>use mysql; mysql>update user set host = '%' where user = 'root'; mysql>select host, user from user;
-
方法二:
-
从任何主机上使用root用户,密码:youpassword(你的root密码)连接到mysql服务器:
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OPTION; mysql> FLUSH PRIVILEGES
-
这样以后任何ip就可以远程访问了,但记得在生产环境必须将其改为指定IP段访问,这样才比较安全
大小写敏感问题
- 由于mysql8默认表名大小写敏感,因此从5.7以前切换到8的需要注意一下大小写的问题,笔者在这里建议数据库统一小写,因此不建议去修改mysql8变成大小写不敏感
- 如果原先的表已经不区分大小写,为了兼容以前的数据,那么还是得将mysql8改为大小写不敏感
- 用户可以先通过
show global variables like ‘%lower_case%’
- 查看下是否大小写敏感,其中lower_case_table_names为1表示大小写不敏感,默认是0,敏感。
这个字段是只读的,因此没法直接修改。 - 特别注意的是只有在首次运行数据的时候可以修改(即mysql刚启动服务还没有任何自定义数据库和表创建的时候),若果已经有了自己的数据库,那么无法修改此项值
- 修改的方法如下(两种办法):
- 在run的命令中增加"–lower_case_table_names=1"到末尾,注意是末尾。这样容器启动时顺便修改了此值。
- 在配置文件my.cnf中增加"lower_case_table_names=1"
caching_sha2_password问题
- 通过第三方工具在连接数据库时会报 caching_sha2_password的问题
- 解决办法如下:
- 在my.cnf中增加“default-authentication-plugin=mysql_native_password”
default-authentication-plugin=mysql_native_password
- 接着修改root用户密码,以启用新的验证方式
use mysql;
ALTER USER ‘root’@’%’ IDENTIFIED WITH mysql_native_password BY ‘new password’;
FLUSH PRIVILEGES;
创建只读用户的变化
- 在mysql8以前创建账号是可以和授权放在一条sql语句的,在8后需要变成两条
- mysql8以前的做法
-- 创建只读用户 grant SELECT on *.* to 'reader'@'%' identified by 'reader' ; -- 创建具有增删查改权限的用户 grant Select,Update,insert,delete on *.* to 'writer'@'%' identified by 'writer';
- mysql8的做法
-- 创建只读用户 create user 'reader'@'%' identified by 'reader'; grant SELECT on *.* to 'reader'@'%' ; -- 创建具有增删查改权限的用户 create user 'writer'@'%' identified by 'writer'; grant Select,Update,insert,delete on *.* to 'writer'@'%' ;
log-bin问题
- 如果sql语句出现以下错误
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)
- 那么在配置文件my.cnf中增加如下语句即可
skip-log-bin
字符警告
- 在my.cnf中配置字符集为utf8的时候出现了如下警告
–character-set-server: ‘utf8’ is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
-
意思就是说UTF8MB3快过时了,推荐用UTF8MB4。
-
在数据库中使用如下语句查看编码:
show variables like 'char%';
+--------------------------+--------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql-8.0/charsets/ | +--------------------------+--------------------------------+
-
从上面可以发现是latin1编码,这个有可能会导致中文乱码,我们最好改成utf8mb4
-
在容器内的/etc/mysql/conf.d中增加my.cnf文件(如果已经存在则增加如下内容),内容如下:
[client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] init_connect='SET collation_connection = utf8mb4_unicode_ci' init_connect='SET NAMES utf8mb4' character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci skip-character-set-client-handshake
-
无须重启服务,直接用“ show variables like ‘char%’; ”再次查询一下,发现如下:
+--------------------------+--------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql-8.0/charsets/ | +--------------------------+--------------------------------+
-
注意使用set names utf8mb4只是临时性的,重启后就会发现字符编码又变为latin1了,因此要永久还是用配置文件的方式
实际项目
-
目录结构如下:
-
其中conf下的my.cnf文件如下
[mysqld] #是否启用bin log skip-log-bin #允许最大连接数 max_connections=200 # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统 max_connect_errors=10 # 服务端使用的字符集默认为UTF8 character-set-server=utf8 # 默认使用“mysql_native_password”插件认证 default_authentication_plugin=mysql_native_password #忽略表名大小写 1--忽略 lower_case_table_names=1
-
start.sh文件如下,注意–lower_case_table_names=1 要放在最后一行
#!/bin/sh docker volume create mysql8_data docker run -it -d \ --restart always \ -p 3306:3306 \ -v mysql8_data:/var/lib/mysql \ -v /etc/localtime:/etc/localtime:ro \ -v $PWD/conf:/etc/mysql/conf.d \ -v $PWD/logs:/logs \ -e MYSQL_ROOT_PASSWORD=root \ --name mysql8 \ mysql:8.0.13 \ --lower_case_table_names=1 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-time-zone=+8:00
-
以上命令有一步是多余的,就是“docker volume create mysql8_data”,其实这一行去掉完全可以,“-v mysql8_data:/var/lib/mysql”会自动创建卷mysql8_data
-
另外提供一份docker-compose.yml
version: '3' services: mysql8: container_name: mysql8 network_mode: bridge restart: always image: mysql:8.0.13 ports: - "3306:3306" volumes: - $PWD/data:/var/lib/mysql - /etc/localtime:/etc/localtime:ro - $PWD/conf:/etc/mysql/conf.d - $PWD/logs:/logs environment: - MYSQL_ROOT_PASSWORD=root command: --lower_case_table_names=1 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-time-zone=+8:00 #设置mysql数据库的时区问题!!!! 而不是设置容器的时区问题!!!!
参考
mysql8.0创建用户授予权限报错解决方法 - 一个程序媛的成长之路 - CSDN博客
https://blog.csdn.net/skyejy/article/details/80645981
MySQL 8 配置文件 - 薛定谔 - 博客园
https://www.cnblogs.com/equation/p/9443097.html
Docker 部署 Mysql8.0 - 没长正 - CSDN博客
https://blog.csdn.net/xsj34567/article/details/80940238
CentOS 7连接mysql 8提示2059 - authentication plugin 'caching_sha2_password - Airt的博客 - CSDN博客
https://blog.csdn.net/airt_xiang/article/details/80261674