Docker 创建的 MySQL 乱码

Docker创建MySQL实例的时候,如果不手动指定字符集的值,将会使用默认值,但是默认值没有统一成utf8, 有时会带来乱码问题。

基本概念

MySQL是分为服务端(Server)和客户端(Client)的。

服务端就是执行mysqld这个文件启动服务。

客户端可以用多种,比如:Navicat, SQLyog, MySQL client命令行。

本文说的MySQL客户端指的是MySQL命令行,即执行mysql这个文件去连接mysqld启动起来的服务。

问题复现

创建MySQL 5.7 docker容器

docker run -p 3306:3306 --name mymysql \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 \
--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

此时不能远程连接这个MySQL Server

需要进入mysql client

mysql -u root -p

然后输入密码123456,进入client操作界面。

使用use命令选中mysql这个数据库;

> use mysql;
Database changed

执行如下命令:

mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

此时就可以通过远程客户端连接这个mysql server了(先确保防火墙指定端口是开放的)。

查看此时服务器的各种编码:

mysql> show variables like '%character%';
+--------------------------+----------------------------+
| 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/charsets/ |
+--------------------------+----------------------------+

发现有几项并不是utf8格式的。

此时可以通过在客户端设置相应的编码暂时解决

mysql> set character_set_client=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| 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/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

之所以说是暂时解决,是因为这种修改只对当前client会话有效。退出当前会话,重新与mysql server建立一个新的会话,修改就失效了。

解决方法是有的。

解决办法

可以通过创建docker mysql 实例的时候建立宿主机mysql配置文件和容器内mysql配置文件的映射。

在宿主机创建目录/opt/my_real_mysql_dir/用于存放mysql相关的文件。

/opt/my_real_mysql_dir/下创建conf目录,用于存放配置文件.
/opt/my_real_mysql_dir/下创建data目录,用于存放具体数据。

/opt/my_real_mysql_dir/conf新建my.cnf文件,内容如下:

[mysql]
default-character-set=utf8

[mysqld]
port=3306
skip-host-cache
skip-name-resolve
character-set-server=utf8
init_connect='SET NAMES utf8'

[client]
port=3306
default-character-set=utf8

然后按照如下方式创建mysql容器实例。

docker run -p 3306:3306 --name myrealmysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /opt/my_real_mysql_dir/conf:/etc/mysql/conf.d \
-v /opt/my_real_mysql_dir/data:/var/lib/mysql \
-d mysql:5.7 

按照这种方式创建、运行mysql容器,可以最大化的自定义配置。

重新使用mysql client连接mysql server,检查其各种字符集。

mysql> show variables like '%character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

都已经是utf8.

这样可以很好地规避开发过程中的MySQL乱码问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值