一、背景及分析

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

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

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

  1. for f in /docker-entrypoint-initdb.d/*; do
  2. process_init_file "$f" "${MysqL[@]}"
  3. done

process_init_file函数定义如下:

  1. process_init_file() {
  2. local f="$1"; shift
  3. local MysqL=( "$@" )
  4. case "$f" in
  5. *.sh) echo "$0: running $f"; . "$f" ;;
  6. *.sql) echo "$0: running $f"; "${MysqL[@]}" < "$f"; echo ;;
  7. *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${MysqL[@]}"; echo ;;
  8. *) echo "$0: ignoring $f" ;;
  9. esac
  10. echo
  11. }

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

二、解决方案

2.1 Dockerfile

内容如下:

  1. FROM MysqL:5.7
  2. copY sql/*.sql /docker-entrypoint-initdb.d/

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

2.2 准备好sql文件

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

  1. -- 创建db_test数据库
  2. create database `db_test` default character set utf8 collate utf8_general_ci;
  3. use db_test;
  4. -- 创建用户表
  5. DROP TABLE IF EXISTS `user`;
  6. CREATE TABLE `user` (
  7. `id` bigint(20) NOT NULL,
  8. `email` varchar(255) DEFAULT NULL,
  9. `first_name` varchar(255) DEFAULT NULL,
  10. `last_name` varchar(255) DEFAULT NULL,
  11. `username` varchar(255) DEFAULT NULL,
  12. PRIMARY KEY (`id`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  14. -- 插入数据
  15. INSERT INTO `user` (`id`, `email`, `first_name`, `last_name`, `username`)
  16. VALUES(0,'li@latelee.org','Late','Lee','latelee');

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

2.3 创建镜像

  1. docker build -t MysqLtest .

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

2.4 容器启动

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

  1. version: '2'
  2. services:
  3. database:
  4. image: MysqLtest
  5. #image: singula/MysqL
  6. container_name: MysqL
  7. ports:
  8. - "3406:3306"
  9. volumes:
  10. - ./MysqL_data:/var/lib/MysqL
  11. - /home:/home
  12. environment:
  13. MysqL_ROOT_PASSWORD: 123456

使用下列命令启动:

  1. docker-compose up -d

验证数据库表:

  1. $ docker exec -it MysqL bash
  2. bash-4.2# MysqL -uroot -p123456
  3. MysqL> use db_test;
  4. MysqL> select * from user;
  5. +----+----------------+------------+-----------+----------+
  6. | id | email | first_name | last_name | username |
  7. +----+----------------+------------+-----------+----------+
  8. | 0 | li@latelee.org | Late | Lee | latelee |
  9. +----+----------------+------------+-----------+----------+
  10. 1 row in set (0.00 sec)

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

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

退出容器后,停止容器:

  1. docker-compose down

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

三、实践指导

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

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

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

MySQL启动时自动创建数据库的更多相关文章

  1. 让docker中的mysql启动时自动执行sql文件

    本文提要 本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动MySQL服务接受外部连接,主要是通过Docker ...

  2. 让docker中的mysql启动时自动执行sql

    在用docker创建mysql容器的时,有时候我们期望容器启动后数据库和表已经自动建好,初始化数据也已自动录入,也就是说容器启动后我们就能直接连上容器中的数据库,使用其中的数据了. 其实mysql的官 ...

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

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

  4. 查询事件状态,mysql查看事件是否开启,设置启动时自动开启方法

    1.查看事件是否开启 SHOW VARIABLES LIKE 'event_scheduler' 2.设置当前事件开启 SET GLOBAL event_scheduler = 1; 或 SET GL ...

  5. Code First 迁移----官方 应用程序启动时自动升级(MigrateDatabaseToLatestVersion 初始值设定项)

    Code First 迁移 如果使用的是 Code First 工作流,推荐使用 Code First 迁移改进应用程序的数据库架构. 迁移提供一组允许以下操作的工具: 创建可用于 EF 模型的初始数 ...

  6. SpringBoot使用Hibernate,实现自动创建数据库表【博客数据库设计】

    我们准备设计博客,那就要设计数据库. 我们可以使用Hibernate来自动生成数据库. 博客数据库的结构: 实体类: 博客 Blog 博客分类 Type 博客标签 Tag 博客评论 Comment 用 ...

  7. EF自动创建数据库步骤之三(自定义数据库初始器)

    EF自动创建数据库需要我们告诉数据库如何进行初始化:如创建表后是否需要插入一些基础数据,是否 需要创建存储过程.触发器等.还有就是EF有三种初始化方式(参见下面三个类): DropCreateData ...

  8. SpringBoot程序启动时在Oracle数据库中建表充值

    例子工程下载链接:https://files.cnblogs.com/files/xiandedanteng/gatling20200428-1.zip 需求:在工程启动时在Oracle数据库中建表. ...

  9. EntityFramework SQLiteCodeFirst 自动创建数据库 关闭级联删除

    外键的级联删除: 如A表中有主键idA, B表中设置外键(ForeignKey)为A表中的主键idA, 当A表中的记录被删除时, B表中所有引用此条记录的记录(即所有外键为idA的记录)将自动被删除 ...

  10. sql2008 计划自动创建数据库分区【转】

    本文转自:http://jingyan.baidu.com/article/6b97984d9a26ec1ca3b0bf77.html sql2008 计划自动创建数据库分区 固定增量的数据,自动创建 ...

随机推荐

  1. 墨天轮沙龙 | 北京大学李文杰:面向知识图谱应用的图数据库系统gStore

    在6月8日举办的[墨天轮数据库沙龙第七期-开源生态专场]中,北京大学重庆大数据研究院图数据库与知识图谱实验室副主任.北京大学王选计算机研究所全职博士后 李文杰老师分享了<面向知识图谱应用的图数据 ...

  2. KubeSphere 在直播应用中的实践

    本文是上海站 Meetup 讲师唐明根据其分享内容整理的文章. 引言 目前媒体的主流传播渠道已从传统的报纸.广播.电视转向了互联网,各种视频及社交 App 成为了人们获取资讯的首选途径.苏州市广播电视 ...

  3. 极客时间「大师课·深度剖析 RocketMQ5.0」上线啦,欢迎免费领取!

    从初代开源消息队列崛起,到 PC 互联网.移动互联网爆发式发展,再如今 IoT.云计算.云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头. 目前,消息中间件在国内许多行业的关键应用 ...

  4. 手写js new,new的过程到底发生了什么

    在JavaScript中,new关键字的应用可以说是再平常不过了,最基础的有new Array().new Set(),再而就是new一个自己创建的构造函数,也就是创建一个该构造函数的示例.如:var ...

  5. spring注解@PostConstruct

    该注解可以实现在运行工程时,自动运行该注解下的方法: @PostConstruct是java5的时候引入的注解,指的是在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为 ...

  6. Java,启动!

    即日起,Java启动!目标是年后找到大厂Java日常实习,特立此随笔作证. 学习路线: Java基础(Java基础用不了多少时间,因为之前有学习过,大概花费1~2周,做到理解案例代码,看懂知识点原理即 ...

  7. C++ stl锁的使用

    我们在日常开发中经常要用到锁,这里记录一下实际开发过程中stl提供的锁的使用. 1.读写锁 读写锁算是用到的比较多的一种类型,主要实现对于同一个共享数据区,一个时间点只能有一个线程进行写(增删改),但 ...

  8. 制作并量化GGUF模型上传到HuggingFace和ModelScope

    llama.cpp 是 Ollama.LMStudio 和其他很多热门项目的底层实现,也是 GPUStack 所支持的推理引擎之一,它提供了 GGUF 模型文件格式.GGUF (General Gau ...

  9. c++设计模式:设计原则

    c++设计八大原则(降低改变带来的代码修改) 一.依赖倒置原则(DIP) 1.高层模块(稳定)不应该依赖于低层模块(变化),二者应该依赖于抽象(更稳定) <高层模块 包括 低层模块所依赖的抽象, ...

  10. Python 在PDF中绘制线条、矩形、椭圆形

    在PDF中绘制图形可以增强文档的视觉效果.通过添加不同类型的形状,如实线.虚线.矩形.圆形等,可以使文档更加生动有趣,提高读者的阅读兴趣.这对于制作报告.演示文稿或是教材特别有用.本文将通过以下几个示 ...