一、背景及分析

MySQL容器启动时,会自动创建一些必要的数据库,比如MySQL,这是官方默认的做法。但是,在实际中,还需要让MySQL自动创建我们自定义的数据库。本文就此应用场合进行探究。

一般的做法是,启动容器并挂载数据目录后,使用MySQL客户端连接服务器,再手动输入sql语句创建(或导入.sql文件),当然也可以直接在容器内创建(方法同上)。由于挂载了数据目录,因此可持久化保存。但是,这些方法在部署数据库比较繁琐,不方便,特别是在初测阶段,会频繁地从头开始搭建环境。

如果能在MySQL容器启动时,自动执行我们自己的.sql文件,就不需要那么麻烦了,其实MySQL容器的启动脚本已经考虑了这种场合。通过MySQL镜像构建脚本docker-entrypoint.sh(参考这里
),发现如下语句:

for f in /docker-entrypoint-initdb.d/*; doprocess_init_file "$f" "${mysql[@]}"
done

process_init_file函数定义如下:

process_init_file() {local f="$1"; shiftlocal mysql=( "$@" )case "$f" in*.sh)     echo "$0: running $f"; . "$f" ;;*.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;*)        echo "$0: ignoring $f" ;;esacecho
}

从上面语句看到,脚本将需要执行的文件(如.sh或.sql)放到/docker-entrypoint-initdb.d目录下,那么docker-entrypoint.sh就会自动执行。明白了原理,解决方案就十分简单了。

二、解决方案

2.1 Dockerfile

内容如下:

FROM mysql:5.7
COPY sql/*.sql /docker-entrypoint-initdb.d/

为了方便起见,所有.sql文件都放到Dockerfile同级的sql目录。

2.2 准备好sql文件

下面是测试用的.sql文件,文件名为test.sql,内容如下:

-- 创建db_test数据库
create database `db_test` default character set utf8 collate utf8_general_ci;use db_test;-- 创建用户表
DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (`id` bigint(20) NOT NULL,`email` varchar(255) DEFAULT NULL,`first_name` varchar(255) DEFAULT NULL,`last_name` varchar(255) DEFAULT NULL,`username` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;-- 插入数据
INSERT INTO `user` (`id`, `email`, `first_name`, `last_name`, `username`)
VALUES(0,'li@latelee.org','Late','Lee','latelee');

主要内容是创建user表,并插入测试的数据。

2.3 创建镜像

docker build -t mysqltest .

创建镜像名称为mysqltest,注意最后的点号.,表示使用当前目录的Dockerfile

2.4 容器启动

docker-compose.yml文件内容如下:

version: '2'
services:database: image: mysqltest#image: singula/mysqlcontainer_name: mysqlports:- "3406:3306"volumes:- ./mysql_data:/var/lib/mysql- /home:/homeenvironment:MYSQL_ROOT_PASSWORD: 123456

使用下列命令启动:

docker-compose up -d

验证数据库表:

$ docker exec -it mysql bash
bash-4.2# mysql -uroot -p123456
mysql> use db_test;
mysql> select * from user;
+----+----------------+------------+-----------+----------+
| id | email          | first_name | last_name | username |
+----+----------------+------------+-----------+----------+
|  0 | li@latelee.org | Late       | Lee       | latelee  |
+----+----------------+------------+-----------+----------+
1 row in set (0.00 sec)

使用如下语句修改邮箱地址:

update user set email='cst@cststudio.com.cn' where username='latelee';

退出容器后,停止容器:

docker-compose down

再次重复上述命令启动、查看数据,可以看到邮件地址是最新的,从而验证了数据能永久存储。

三、实践指导

.sql脚本只有第一次启动时创建(或说没有数据库时则会创建),已创建的,不会覆盖掉,否则这个机制就无法正式应用项目中。

.sql脚本中,也可以创建账号、密码,这样就不用在docker-compose文件指定环境变量了。起到了一定的保护作用。

如果要完全迁移数据,需要将数据目录(文中为mysql_data目录)与docker-compose.yml文件一起迁移。

我的docker随笔15:MySQL启动时自动创建数据库相关推荐

  1. mysql创立不了数据库_以下不属于MySQL安装时自动创建的数据库是( ) (5.0分)_学小易找答案...

    [单选题]下列删除itcast数据库的sql语句中,正确的是 (5.0分) [单选题]MySQL提供的( )语句可查看数据表的创建语句. (5.0分) [单选题]下面选项中,属于定点数的类型是 (5. ...

  2. 正在创建系统还原点_如何使Windows在启动时自动创建系统还原点

    正在创建系统还原点 By default, System Restore automatically creates a restore point once per week and also be ...

  3. ssh整合mysql不能自动生成表_ssh整合思想 Spring与Hibernate的整合 项目在服务器启动则自动创建数据库表...

    Spring整合Hibernate Spring的Web项目中,web.xml文件会自动加载,以出现欢迎首页.也可以在这个文件中对Spring的配置文件进行监听,自启动配置文件, 以及之前Struts ...

  4. 取消CATIA启动时自动创建的Product或Part

  5. mysql手动启动1067错误_解决MySQL启动时万恶的1067错误(转)

    解决MySQL启动时万恶的1067错误(转)[@more@]我的机器不知为何,安装MySQL的时候,一到配置那一步就无休止的等待,只好结束任务,然而启动MySQL的时候出现1067错误提示.卸载,依然 ...

  6. ubuntu启动时自动挂载windows分区

    这是本人的/etc/fstab文件,其中设置的启动时自动挂载的windows分区,可用df命令查看挂载信息 开始还需要新建对应的文件夹,如 sudo mkdir /media/WINDOWS,sudo ...

  7. 电脑重启后python导入的库不见_为什么python不会在启动时自动导入每个模块?

    我正在玩Python 2.7,每个人都知道,在每个程序的开头,你总是需要导入模块.例如:import random import time for x in range(1, 300): print ...

  8. Android 编程下帧动画在 Activity 启动时自动运行的几种方式

    Android 开发过程中部分 Activity 在显示的时候就要求给用户显示一个进度框来改善用户体验,比如:Activity 在启动的时候就去联网请求数据.读取数据库内容等.进度框显示样式如下,采用 ...

  9. Tomcat启动时自动加载Servlet

    转自:http://zhaoyongpan.blog.51cto.com/2714930/676239 想实现这样的功能: 1.   Tomcat启动时随即启动Servlet; 2.   Servle ...

最新文章

  1. 对下载的包进行修改--python
  2. windows下使用自带certutil工具校验文件MD5、SHA1、SHA256
  3. VTK:绘制截锥体用法实战
  4. JS里面的懒加载(lazyload)
  5. linux 热拔插硬盘,带电热插拔硬盘造成硬盘故障
  6. linux lanmp 安装教程,Linux 安装 lanmp
  7. MySQL替换函数REPLACE替换字符串方法
  8. 十大排序思维导图(个人理解)
  9. 上传文件到本地操作和上传到Azure云上
  10. java 释放锁_Java并发编程:锁的释放
  11. 确定部分分式中待定系数的留数方法
  12. 【数据结构】【A鹿】malloc和其他相关预备知识
  13. springboot jpa 实现复杂的sql 如 A and (B or C)
  14. 基于RBAC 的SAAS系统权限设计
  15. 学习半年Java的初次经验分享
  16. 原厂技术支持FLD5302和FLD5303升压充电芯片
  17. PVLAN 技术介绍
  18. 上海-苏州 100公里徒步旅行心情分享(一)
  19. UE4 EventTick
  20. unable to open debugger port java.net.SocketException socket closed 解决方法汇总,不定期更新

热门文章

  1. MFC开发IM-第七篇、mfc设置默认编辑框内容
  2. Google和微软哪个更可怕?
  3. 创业要有创意--应当注意的八大细节
  4. 中国电信:1月5G套餐用户数净增826万户
  5. 全球第一!苹果市值冲破3万亿美元 创历史记录
  6. 腾讯大动刀:微信试行松绑外链!用户已可打开淘宝、抖音等链接
  7. 网约车司机用橡胶棍追打女乘客被行政拘留
  8. “你什么色?”网易云人格主导色被刷屏后遭微信屏蔽:因包含互动测试内容...
  9. 会玩!格力公开“磁悬浮床垫”专利
  10. 全球芯片短缺将持续到2022年 GPU备货将受影响?