在 Docker 中使用 mysql 的一些技巧
启动到后台: 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 该怎么导入导出数据或结构呢?照这么做吧:
# Backup
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE > backup.sql
# Restore
docker 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=mysql
default-storage-engine=INNODB
character-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)
在配置文件/etc/default/docker中DOCKER_OPTS选项添加
--insecure-registry hub.witcloud.huawei.com
,并重启docker服务执行
apt-get install python-pip
配置pip公司内网镜像
在~/.pip/目录下增加pip.conf文件 然后编辑其内容为: [global]
trusted-host=rnd-mirrors.huawei.com
index-url=http://rnd-mirrors.huawei.com/pypi/simple/
安装docker-compose
pip install docker-compose
部署完成后就可以使用docker-compose来进行镜像的下载和容器的启动了。
使用Docker部署MySQL(每台VM)
首先我们要编写DockerCompose文件,用于配置MySQL镜像的启动。
mkdir /home/docker/mysql -p
vim /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)
需要注意的差异如下:
server_id
每台VM不同节点1: 1
节点2: 2
节点3: 3
loose-group_replication_local_address
每台VM不同节点1: 10.183.22.167:24901
节点2: 100.112.98.176:24901
节点3: 10.167.117.41:24901
bind-address
和report_host
绑定为各VM的IP地址
我们使用配置文件来对集群进行配置:
mkdir /data/mysql/conf -p
vim /data/mysql/conf/ha.cnf
文件内容:
[mysqld]
#Encoding
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
#Replication Framework
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
# Host specific replication configuration
server_id=1
bind-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"
依次启动每个节点,进行数据库内部配置
启动节点数据库
docker-compose up -d
使用数据库工具链接节点
仅针对节点2,3,第一个节点不用:清理Docker容器内部产生的binlog,从完全干净的状态进行集群同步
RESET MASTER ;
创建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';
安装组复制插件
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 |
+----------------------------+----------+--------------------+----------------------+-------------+
启动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;
- 节点1:
仅针对节点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,因此当前只是服务端可用,客户端驱动还需要等待新版本。
官方ConnectJ支持使用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之间的数据同步存在一定延时,可能导致先写入后读取的时候,读取不到数据。
举例说明:
- 线程A在Master 1上插入一条数据,id为6217614201566007296
- 线程A把此ID(6217614201566007296)给线程B
- 线程B在Secondary 1上通过此ID(6217614201566007296)读取数据
- 但是此时数据还未从Master1同步到Secondary 1
- 线程B读取数据为空
因此,在这种情况下,由于写入到读取之间可能存在延时,那么在写入之后的处理阶段(比如线程B),需要增加重试或者延时,来等待数据同步。
这也是分布式数据库最终一致性带来的问题。
参考资料:
在 Docker 中使用 mysql 的一些技巧的更多相关文章
- linux小白成长之路8————访问Docker中的mysql
[内容指引] 本篇实战演示如何操作Docker中的mysql数据库,包含以下五个知识点: 登录容器: 登录mysql: 运行SQL指令创建数据库: 退出mysql: 退出容器: 1.登录容器 我们在上 ...
- 在docker中安装mysql
#!/bin/sh # 安装docker # 在docker中安装mysql # 解决了docker容器中无法输入中文的问题 ##########################安装docker # ...
- 在docker中使用mysql数据库,在局域网访问
1.获取mysql镜像 docker pull mysql:5.6 注意:此处之所以获取mysql5.6是因为mysql5.7在centos7中启动可能会报错 2.查看镜像列表 docker imag ...
- docker微服务部署之:四、安装docker、docker中安装mysql和jdk1.8、手动构建镜像、部署项目
docker微服务部署之:三,搭建Zuul微服务项目 1.Centos7安装Docker 详见:Centos7安装Docker 2.Docker中安装jdk1.8 详见:使用Docker构建jdk1. ...
- Docker中安装mysql
1.docker 中下载 mysql docker pull mysql 2.启动 docker run -itd --name mysql -p 3306:3306 -e MYSQL_ROOT_PA ...
- 0018SpringBoot连接docker中的mysql并使用druid数据源
由于druid数据源自带监控功能,所以引用druid数据源 1.centos7中安装并启动docker 2.docker安装并启动mysql 3.pom.xml中引入druid依赖 4.applica ...
- 使用EF操作Docker中的Mysql实例
为啥我会选择mysql呢?因为我的服务器配置较低,而SqlServer在docker中的实例,服务器的运行内存应当保持在2G+,我没有这个条件,它会爆出这样的错误 sqlservr: This pro ...
- docker中使用mysql数据库详解(在局域网访问)
开发过程中经常需要安装.调试mysql数据库,还需要在各种操作系上安装包依赖,实在是繁琐,因此就研究了一下如何在docker上运行一个mysql镜像,省却了我安装.找依赖的问题. 注:本文所有内容均在 ...
- 宿主机连接docker中的mysql
宿主机连接docker中的mysql dokcer安装mysql docker run \ --name mysql \ -v $PWD/mysql:/var/lib/mysql \ -p 330 ...
随机推荐
- [转帖]ipvsadm命令参考及其应用例子
ipvsadm命令参考及其应用例子 https://blog.csdn.net/orichisonic/article/details/47375227 只是简单创建了 service和添加serve ...
- Oracle创建表空间、用户以及给用户赋权
--创建表空间 create tablespace waterboss datafile 'd:\waterboss.dbf' size 100m autoextend on next 10m --创 ...
- ToroiseGit提交代码上传到阿里云的Gitlab
https://blog.csdn.net/xiaomogg/article/details/51903004(copy) 准备 具体过程 准备 1.拥有一个GitHub账户 2.安装了Tortois ...
- day 7-6 GIL,死锁,递归锁与信号量,Event,queue,
摘要: 1.死锁与递归锁 2.信号量 3.Event 4.Timer 5.GIL 6.Queue 7.什么时候该用多线程和多进程 一. 死锁与递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过 ...
- Eclipse中修改jsp、html……的编码格式
一般如果使用的是Eclipse的默认编码格式,在我们保存的时候会提示选择保存的编码格式,保存后英文没有问题,但是中文就会乱码. 修改方式是: Windows——>Preferences——> ...
- 转《在浏览器中使用tensorflow.js进行人脸识别的JavaScript API》
作者 | Vincent Mühle 编译 | 姗姗 出品 | 人工智能头条(公众号ID:AI_Thinker) [导读]随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升.在 ...
- mysql关联、子查询索引优化
1.驱动表:加索引不起作用,因为全表扫描.表1 left join 表2 ,此时表1是驱动表 被驱动表:给这个加索引. 关联查询 子查询时 尽量不使用not in 或者not exists 而是用 ...
- C/S和B/S应用程序的区别
一.C/S和B/S介绍: 1.C/S介绍: Client/Server架构,即客户端/服务器架构.是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销 ...
- jenkins插件findbugs+pmd+checkstyle结合sonar与maven(java环境代码质量和代码规范管理)
一.下载jdk并安装(最好jdk官网下载解压安装的) 二.下载maven并安装maven 三.安装jenkins及插件 安装checkstyle.pmd.findbugs.maven.sonar等相关 ...
- 库存盘点打印功能生成PDF速度太慢使用页面缓存
一.业务需求 二.产品设计 三.UI设计 四.程序设计 1.使用behavior配置页面缓存 class WmsCheckController extends Controller { /** * @ ...