博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在 Docker 中使用 mysql 的一些技巧
阅读量:5172 次
发布时间:2019-06-13

本文共 6989 字,大约阅读时间需要 23 分钟。

  • 启动到后台:  docker-compose start

  • docker-composer 执行命令: entrypoint: pwd
app:    build: ./app    working_dir: /app    volumes:      - ./app:/app      - ~/.m2:/root/.m2    expose:      - "8080"    depends_on:      - nginx      - mysql    entrypoint: pwd

 

 

今天我写一点在 Docker 容器中使用 MYSQL 的 tips.

要不要在生产环境使用 Docker 运行数据库这么深奥的问题,等我踩足够的坑再来写吧。
但是至少在开发和测试环境你可以用 docker 管理数据库啊。

Compose file

先贴一个我常用的 docker-compose 片段,后边进行详细的解释。这是日常使用的状态,此处省略了别的服务。

version: '2'services:    mysql:        image: mysql:5.7.16 ports: - ${DB_PORT}:3306 environment: - TZ=Asia/Shanghai command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - ./mysql_data:/var/lib/mysql restart: unless-stopped

版本

一定要锁定镜像到最小的版本,因为mysql镜像升级后需要你手动在容器中执行命令去 mysql-upgrade,否则很久之后,你才发现有的数据已经损坏了。

实在想升级,升级步骤如下:

  • 如果是用 docker run 启动的,那么停掉再启动个新的。如果是用 docker-compose 启动的,直接改版本号 pull 镜像重新 up。

  • 在新的版本启动后执行 docker exec -it 你的容器名称或id mysql-upgrade

端口

如果想在外部通过工具访问,需要将3306端口映射到host上的一个端口,不准备外部访问的环境则不必。

一般来说开发和测试环境还是经常需要登到数据库上查看的。

时区

添加环境变量 TZ 让mysql用你的默认时区启动。

这是因为 mysql 的基础镜像是 debian, 这个环境变量可以声明 debian 的时区,然后被 mysql 继承。

字符编码

mysql 的镜像默认编码是 latin1 这可不行,在中国我们一般都用 UTF8 。

一般我们要是在主机上配置 mysql 的话,是去修改配置文件。但使用容器时映射进去一个配置文件是很复杂的。
于是我们有个简单的办法,mysql 接受很多 flag 通过启动时传入。其中就有声明服务器默认编码的。
我们的 command 命令就是给 mysql 在启动时加了两个参数。

存储

容器中有需要持久化存储的内容时就会有点麻烦。一般有两种方案,一种是映射主机的一个目录,一种是利用数据卷。

在很长时间的使用中,我总结出了这个比较方便的办法。

  • 因为 docker-compose 有个潜规则就是大家一般都在有 compose 文件那个目录执行命令。

  • 于是我们做一个以环境名称命名的文件夹,里边是 compose 文件,.env 文件,和各种需要持久化的文件夹。

  • 在 compose 文件中,我们映射文件夹用相对目录。

  • 最后,这个文件夹就是一个整体,只需要把它拷贝在任何机器任何地方都可以启动这个环境。

初始化

mysql 容器在首次启动的时候,必须指定一个root密码才能启动,指定的方式是声明环境变量 MYSQL_ROOT_PASSWORD 。

一旦在指定的数据文件夹发现已经存在库的时候,这个参数就会被忽略掉。
所以我们只需要在第一次启动的时候加上,后面有了数据后都去掉就好了。

导入导出

在容器中运行的 mysql 该怎么导入导出数据或结构呢?照这么做吧:

# Backupdocker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE > backup.sql# Restoredocker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE < backup.sql

就这么多吧,还有什么 Tips ,欢迎大家补充。

 

测试创建一个docker-compose.yml测试

以下配置了外部数据卷、外部配置文件、外部初始化文件(文件名必须以.sh或者.sql结尾)

这样配置之后,数据库本地直接连接得上去,而且使用的是你配置的账号密码。

version: '3'services:  db: image: 'mysql/mysql-server:5.7' restart: always container_name: mysql volumes: - data:/var/lib/mysql - ./mysql/config/my.cnf:/etc/my.cnf - ./mysql/init:/docker-entrypoint-initdb.d/ ports: - '3306:3306' volumes: data: driver: local

/mysql/config/my.cnf

[mysqld]user=mysqldefault-storage-engine=INNODBcharacter-set-server=utf8[client]default-character-set=utf8[mysql]default-character-set=utf8

/mysql/init/init.sql

CREATE USER 'luna'@'%' IDENTIFIED BY 'pwdluna'; GRANT All privileges ON *.* TO 'luna'@'%';

使用DockerCompose搭建MySQL高可用集群,并平滑迁移

 
 
 

!!!由于MySQL官方驱动还不支持Group Replication,因此当前只是服务端可用,客户端驱动还需要等待新版本。

本文描述如何使用Docker+DockerCompose来部署一个MySQL的高可用集群。

此集群由3个MySQL实例组成,一个Master节点,2个Secondary节点。Master可读写,Secondary可读。集群之间会自动同步数据。Master失效剩余的Secondary会自动选举Master。

  • 请准备三台Linux VM(Ubuntu14.04),最好是异地的
  • 每台VM上请部署docker

由于公司内部网络隔离,很多地址需要从公司内镜像网站下载。请注意,某些配置步骤在可以直连外网的情况下并不需要。

配置Docker环境(每台VM)

  1. 在配置文件/etc/default/docker中DOCKER_OPTS选项添加--insecure-registry hub.witcloud.huawei.com,并重启docker服务

  2. 执行apt-get install python-pip

  3. 配置pip公司内网镜像

    在~/.pip/目录下增加pip.conf文件然后编辑其内容为:[global]trusted-host=rnd-mirrors.huawei.comindex-url=http://rnd-mirrors.huawei.com/pypi/simple/
  4. 安装docker-compose

    pip install docker-compose

部署完成后就可以使用docker-compose来进行镜像的下载和容器的启动了。

使用Docker部署MySQL(每台VM)

首先我们要编写DockerCompose文件,用于配置MySQL镜像的启动。

mkdir /home/docker/mysql -pvim /home/docker/mysql/docker-compose.yml

注意:因为数据库容量未来可能较大,因此最好将大容量磁盘挂载到/data目录。

version: '2'services:  mysql: network_mode: "host" environment: MYSQL_ROOT_PASSWORD: "blu3Spoon55" image: hub.witcloud.huawei.com/it-ark/mysql restart: unless-stopped volumes: - "/data/mysql/db:/var/lib/mysql" - "/data/mysql/conf:/etc/mysql/conf.d"

MYSQL_ROOT_PASSWORD为管理员密码,请自己设置一个强密码。

配置Group Replication节点(每台VM)

需要注意的差异如下:

  1. server_id每台VM不同
    节点1: 1节点2: 2节点3: 3
  2. loose-group_replication_local_address每台VM不同
    节点1: 10.183.22.167:24901 节点2: 100.112.98.176:24901 节点3: 10.167.117.41:24901
  3. bind-addressreport_host绑定为各VM的IP地址

我们使用配置文件来对集群进行配置:

mkdir /data/mysql/conf -pvim /data/mysql/conf/ha.cnf

文件内容:

[mysqld]  #Encodingcollation-server = utf8_unicode_ciinit-connect='SET NAMES utf8'character-set-server = utf8#Replication Framework  gtid_mode=ONenforce_gtid_consistency=ONmaster_info_repository=TABLErelay_log_info_repository=TABLEbinlog_checksum=NONElog_slave_updates=ONlog_bin=binlogbinlog_format=ROW# Host specific replication configurationserver_id=1bind-address="10.183.22.167" report_host="10.183.22.167" loose-group_replication_local_address ="10.183.22.167:24901" #Group Replication transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="9a261783-7436-4df7-be2c-97fc7b37eb85" loose-group_replication_start_on_boot=on loose-group_replication_group_seeds="10.183.22.167:24901,100.112.98.176:24901,10.167.117.41:24901" loose-group_replication_bootstrap_group=off loose-group_replication_ip_whitelist="10.183.22.167,100.112.98.176,10.167.117.41,127.0.0.1/8"

依次启动每个节点,进行数据库内部配置

  1. 启动节点数据库

    docker-compose up -d
  2. 使用数据库工具链接节点

  3. 仅针对节点2,3,第一个节点不用:清理Docker容器内部产生的binlog,从完全干净的状态进行集群同步

    RESET MASTER ;
  4. 创建group replication所需要的用户

    SET SQL_LOG_BIN =0;CREATE USER rpl_user@'%' IDENTIFIED BY 'rpl_pass'; GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; FLUSH PRIVILEGES ; SET SQL_LOG_BIN =1; CHANGE MASTER TO MASTER_USER ='rpl_user', MASTER_PASSWORD ='rpl_pass' FOR CHANNEL 'group_replication_recovery';
  5. 安装组复制插件

    INSTALL PLUGIN group_replication SONAME 'group_replication.so';

    检查是否插件是否启用:

    mysql> SHOW PLUGINS;+----------------------------+----------+--------------------+----------------------+-------------+| Name                       | Status   | Type               | Library              | License     |+----------------------------+----------+--------------------+----------------------+-------------+| binlog | ACTIVE | STORAGE ENGINE | NULL | PROPRIETARY | (...) | group_replication | ACTIVE | GROUP REPLICATION | group_replication.so | PROPRIETARY | +----------------------------+----------+--------------------+----------------------+-------------+
  6. 启动group replication

    • 节点1:
      SET GLOBAL group_replication_bootstrap_group=ON;START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF;
    • 节点2/3
      START GROUP_REPLICATION;
  7. 仅针对节点1: 增加一些测试数据,用于测试节点2和节点3是否同步了数据

    CREATE DATABASE test;use test; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL); INSERT INTO t1 VALUES (1, 'mysql集群测试');

客户端使用

!!!由于MySQL官方驱动还不支持Group Replication,因此当前只是服务端可用,客户端驱动还需要等待新版本。

官方支持使用Replication,以支持MySQL Group Replication。

只需要在连接字符串中配置即可:

jdbc:mysql:loadbalance://100.112.98.176:3306,10.183.22.167:3306,10.167.117.41:3306

应用程序代码无需修改,驱动会自动判断可用的Master。

Master/Secondary异步延时

由于Master/Secondary之间的数据同步存在一定延时,可能导致先写入后读取的时候,读取不到数据。

举例说明:

  1. 线程A在Master 1上插入一条数据,id为6217614201566007296
  2. 线程A把此ID(6217614201566007296)给线程B
  3. 线程B在Secondary 1上通过此ID(6217614201566007296)读取数据
  4. 但是此时数据还未从Master1同步到Secondary 1
  5. 线程B读取数据为空

因此,在这种情况下,由于写入到读取之间可能存在延时,那么在写入之后的处理阶段(比如线程B),需要增加重试或者延时,来等待数据同步。

这也是分布式数据库最终一致性带来的问题。

参考资料:

 

转载于:https://www.cnblogs.com/bigben0123/p/8880940.html

你可能感兴趣的文章
有关快速幂取模
查看>>
NOI2018垫底记
查看>>
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
(转)Tomcat 8 安装和配置、优化
查看>>
(转)Linxu磁盘体系知识介绍及磁盘介绍
查看>>
跨域问题整理
查看>>
[Linux]文件浏览
查看>>
获取国内随机IP的函数
查看>>
Spring Mvc模式下Jquery Ajax 与后台交互操作
查看>>
(转)matlab练习程序(HOG方向梯度直方图)
查看>>
tableView
查看>>
Happy Great BG-卡精度
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>