Docker入门篇-使用Mysql镜像解决UTF8中文乱码问题.

Docker

使用Mysql镜像

Docker_Hub,Mysql官方镜像说明
Mysql官方镜像Dockerfile
Mysql容器解决非UTF8乱码问题

在使用Mysql官方镜像5.7的时候,会遇到中文乱码的问题,原因是官方镜像的字符集默认不是UTF8,这时候去google,会找到一些文章都在说SET character_set_client = utf8;这样的更改根本不起作用.最终的解决办法,还是需要按照修改mysqld.conf或者 my.conf 配置文件来解决.

导入并启动Mysql容器

拉取Mysql镜像,如果提示需要登录先执行docker login,根据提示输入账号密码登录.

docker pull mysql:5.7

启动 Mysql容器

docker run -it --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

进入容器查看字符编码, latin1 使用的默认的字符集,这样的话就极有可能出现中文乱码的问题。

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

复制代码

编写/home/test/mysql.conf/mysqld.cnf配置文件

[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
port=13306
#character-set-client-handshake=FALSE
character-set-server=utf8mb4
character-set-filesystem=utf8mb4
collation-server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'
lower-case-table-names=1 # 解决数据库读取区分大小写问题

skip-character-set-client-handshake
mysql skip-name-resolve
复制代码

启动Mysql容器

docker run -itd --name mysql -p 13306:13306 -v /home/test/project/mysql/:/var/lib/mysql -v /home/test/mysql.conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v /etc/localtime/:/etc/localtime/:ro -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
有些博客给的命令后面还需要加下面两个配置,因为后面需要解决utf8的问题,直接将他们配置进配置文件
--character-set-server=utf8mb4 --collation-server=utf8md4_unicode_ci

创建用户并启动Mysql容器

docker run -itd --name mysql --restart=always -p 13306:13306 -e MYSQL_USER="testw" -e MYSQL_PASSWORD="123456" -e MYSQL_ROOT_PASSWORD="123456"

docker更新一些配置

docker update --restart=always mysql

docker 启动参数说明

-i: 以交互模式运行容器,通常与 -t 同时使用;-it
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-d: 后台运行容器,并返回容器ID;
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
--name="nginx-lb": 为容器指定一个名称;
-e username="ritchie": 设置环境变量;
-v 文件映射: 宿主机文件夹:容器文件夹;(主要用于数据库数据的持久化到宿主机,防止容器损坏导致数据丢失.)
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--restart: 重启策略:
    1. no,默认策略,在容器退出时不重启容器
    2. on-failure,在容器非正常退出时(退出状态非0),才会重启容器
    3. on-failure:3,在容器非正常退出时重启容器,最多重启3次
    4. always,在容器退出时总是重启容器
    5. unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器


# 不常用的
-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-P: 随机端口映射,容器内部端口随机映射到主机的端口
--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h "mars": 指定容器的hostname;
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
--link=[]: 添加链接到另一个容器;
--expose=[]: 开放一个端口或一组端口;
--volume , -v: 绑定一个卷
复制代码

docker run命令参数说明

# 整个命令
docker run -itd --name mysql -p 13306:13306 --restart=always -v /home/test/project/mysql/:/var/lib/mysql -v /home/test/mysql.conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v /etc/localtime/:/etc/localtime/:ro -e MYSQL_USER="testw" -e MYSQL_PASSWORD="123456" -e MYSQL_ROOT_PASSWORD="123456 mysql:5.7

# 拆解注释
docker run
# 按照上面的注释, -i(以交互模式运行容器) -t(为容器重新分配一个伪输入终端) -d(后台运行容器,并返回容器ID)
-itd 
# 指定容器的名字
--name mysql 
# 指定端口映射 宿主机端口:容器端口(这里容器端口是13306,所以 [mysqld]配置 port=13306)
-p 13306:13306 
# 指定容器的重启策略(在容器退出时总是重启容器)
--restart=always 
# 持久化mysql数据到本机,docker官方也强烈建议把mysql数据持久到本地,因为mysql容器很可能出现损坏(一旦损坏,数据将丢失).
-v /home/test/project/mysql/:/var/lib/mysql 
# 单独配置进行替换mysqld默认配置,解决UTF8的字符集的问题,并进行Mysql优化.
-v /home/test/mysql.conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
#  解决容器内获取的时间和主机的时间不一样的问题
-v /etc/localtime/:/etc/localtime/:ro 
# 创建用户名和密码
-e MYSQL_USER="testw"
-e MYSQL_PASSWORD="123456"
# 设置root用户的密码
-e MYSQL_ROOT_PASSWORD="123456 
# 指定启动的镜像
mysql:5.7

复制代码

进入 Mysql查看字符集,character_set_system系统字符集一般都是utf8,其他项都是utf8mb4.


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

复制代码

使用mysql 容器来连接数据库

docker run mysql容器来模拟Mysql环境进行远程连接Mysql容器,实现不用进入容器内部可以可以进行Mysql操作.

docker run -it --rm mysql:5.7 mysql -uroot -h 10.122.30.199 -P 13306 -p

mysql skip-name-resolve

mysql skip-name-resolve 的解释
mysql中skip-name-resolve的问题
远程访问慢的解决方案

Mysql中 8个 character_set变量说明

使用show variables like "%char%";

mysql> show variables like "%character%";

+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | latin1                           |
| character_set_connection | latin1                           |
| character_set_database   | latin1                             |
| character_set_filesystem | binary                           |
| character_set_results    | latin1                           |
| character_set_server     | latin1                             |
| character_set_system     | latin1                             |
| character_sets_dir       | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.00 sec)
复制代码
变量名 注释
character_set_client 主要是用来设置客户端使用的字符集
character_set_connection 主要用来设置连接数据库时的字符集,如果程序中没有指明连接数据库使用的字符集类型则按照这个字符集设置.
character_set_database 主要用来设置默认创建数据库的编码格式,如果在创建数据库时没有设置编码格式,就按照这个格式设置.
character_set_filesystem 文件系统的编码格式,把操作系统上的文件名转化成此字符集,即可character_set_client转换character_set_filesystem.默认binary是不做任何转换的.
character_set_results 数据库给客户端返回时使用的编码格式,如果没有指明,使用服务器默认的编码格式.
character_set_server 服务器安装时指定的默认编码格式,这个变量建议由系统自己管理,不要认为定义.
character_set_system 数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是存储系统元数据的编码格式.
character_set_dir 这个变量是字符集安装的目录.

以上这些参数如何起作用:

  1. 库、表、列字符集的由来
    建库时,若末明确指定字符集,则采用character_set_server指定的字符集.
    建表时: 若未明确指定字符集,则采用当前库所采用的字符集.
    新增时, 修改表字段时,若未明确指定字符集,则采用当前表所采用的字符集.
  2. 更新、查询涉及到字符集变量
    更新流程字符集转换过程: character_set_client–>character_set_connection–>表字符集。
    查询流程字符集转换过程: 表字符集–>character_set_result
  3. character_set_database
    当前默认数据库的字符集,比如执行use xxx后,当前数据库变为xxx,

在启动Mysql后,只要关注下面变量是否符合要求

  • character_set_client
  • character_set_connection
  • character_set_database
  • character_set_results
  • character_set_server

下面3个系统变量我们不需要关心,不会影响乱码等问题

  • character_set_filesystem
  • character_set_system
  • character_sets_dir

创建数据库并导入导出数据

创建数据库

CREATE DATABASE IF NOT EXISTS test_databasedefault CHARSET utf8 COLLATE utf8_general_ci.

导入数据

source G:\aa\test.sql(导入数据库表)

导出数据

mysqldump -h localhost -u root -p test> G:\aa\test.sql

MySQL字符编码转换原理

MySQL Server收到请求时将请求数据从 character_set_client 转换为 character_set_connection进行内部操作前将请求数据从 character_set_connection 转换为 内部操作字符集(character_set_server),步骤如下:

  1. 使用每个数据字段的 CHARACTER SET 设定值;
  2. 若上述值不存在,则使用对应数据表的字符集设定值
  3. 若上述值不存在,则使用对应数据库的字符集设定值
  4. 若上述值不存在,则使用character_set_server设定值.
  5. 最后将操作结果从内部操作字符集转换为character_set_results;

image.png

docker-compose启动Mysql

新建 docker-compose.yml

services:
  mysql:
    image: mysql:5.7
#    command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']
    volumes:
      - /home/test/project/mysql/:/var/lib/mysql
      - ./mysql/:/docker-entrypoint-initdb.d/
      - /home/test/mysql.conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
      - ./sqlfile:/app/sqlfile
    environment:
      - "MYSQL_DATABASE=apigateway-ai"
      - "MYSQL_USER=appuser"
      - "MYSQL_PASSWORD=123456"
      - "MYSQL_ROOT_PASSWORD=root"
    ports:
        - "13306:13306"
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: “1g”
复制代码

制作Mysql镜像

创建和定制Mysql镜像
大佬2013年的构建一个Mysql镜像
基于Docker的Mysql镜像 搭建主从复制

先说说为什么要自己制作镜像:
首先Mysql、Nginx、Redis、Tomcat、等都有官方的镜像。一般情况下我们直接使用它就可以。

Docker images

  • KERNEL 是每个linux操作系统都有的,image不包含.
  • DEBIAN-image 代表我们常见的Linux系统(不包含 KERNEL),如 CentOS、Ubuntu、Debian 等又称为Linux发行版。这些除了包含Kernel外,包含大量的操作系统扩展、各种管理工具、开发工具、图像界面支持等。通常都是庞然大物,命令行版本的文件系统也有几百兆。这些镜像大约 100~200M。
  • BUSY BOX-image 代表精简的Linux系统,如 Alpine、busybox、CoreOS等,仅支持一些最基本Linux命令和一个简单应用包管理,以及以满足云应用需求的支持。这些镜像5~10M。
  • ADD EMACS-image 代表 Emacs这样的基础应用,它仅在基础操作系统文件基础上添加了自己的代码和依赖包;
  • ADD APACHE-image 代表 Apache web 应用,建立在已有 emacs 镜像基础上,即文件系统加了apache 及其依赖包.这样形成多层叠加的文件系统,尽管Apache-image仅包含了自己的内容,但启动后,我们可以访问基础操作系统、emacs提供的程序和软件包。
  • WRITEBLE COTAINER 是镜像中程序在与主机(Host)隔离环境下运行进程产生的中间文件。

因此:

image是文件(增量)与环境(Context)配置文件的集合.

docker-compose安装

apt-get install python-pip
pip install --upgrade pip
pip install docker-compose
docker-compose -version
复制代码

Mysql容器的运行

  • 运行容器并与宿主机时间同步:

-v /etc/localtime:/etc/localtime

参考资料

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享