Java开源博客My-Blog之mysql容器重复初始化的严重bug修复过程
写在前面的话
《Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦》
《Java开源博客My-Blog之docker容器组件化修改》
My Blog项目已经开源了两个多月,也收获了不少star,在这里谢谢各位朋友的建议及帮助。由于个人原因,这个开源项目最初的定位其实是一个docker技术与springboot框架整合的Java博客系统实战项目,而且是一个容器技术的练手项目,技术的偏重也更多的在容器技术及容器编排上。
虽然上个版本做了一些改动,将docker踢出主目录,原因也是为了照顾其他关注和想要使用My Blog的朋友能够很快的上手项目,但是docker容器技术依然是这个项目不可缺少的一部分,从项目创建那一刻即是如此,今后也是如此,只不过为了项目更友好而做了一些改动使其不会强耦合于项目中。
问题描述
从项目开源至今,大大小小的问题已经发现且解决了不少,但是直到近期才完全修复掉的一个大问题就是mysql容器重复初始化导致原数据被抹去的bug。
熟悉这个项目的朋友应该知道,项目初期为了让mysql容器可以自动初始化数据花了多少精力,但是这个一直让我觉得很完美的改动却有一个非常致命的缺陷,一旦数据容器mysql挂掉了或者需要重启,原先的数据就都没了,即使只是重启也会抹去原先的数据,这个就很尴尬了,我原以为最坚硬的盔甲却成了最柔弱的软肋,这件事真的让我低迷了很久。
一开始并没有发现这个问题,而是在项目运行一段时间之后,某一天由于服务器资源问题(服务器配置差)需要重启,进而导致myblog容器和mysql容器也得重启,但是在重启后发现原来添加的博客数据及留言数据消失了!

取而代之的是schema.sql中的几条初始化数据,当时也认真确认是否存在错误操作导致了数据被清空,结果就是一切流程都正常,过程中并没有误操,这个问题也只有在重启时会出现,这是流程设计的问题而且是一个十分致命的问题,如果不解决,将是这个项目最大的一个污点。
问题原因
FROM mysql:5.7
ENV MYSQL_DATABASE test
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql
#设置容器启动时执行的命令
CMD ["bash", "/mysql/setup.sh"]
以上为mysql容器的Dockerfile文件,文件中定义了容器的启动语句是执行setup.sh脚本文件,即mysql容器每次启动都会执行setup.sh,包括第一次启动及此后的重启,而每次执行setup.sh都会重新初始化数据,这里的数据初始化包括什么呢?查看docker-extension/mysql目录下的文件可知,此过程会删除原来的数据库,重新插入初始化数据库中的数据及数据库的用户权限,再次目瞪狗呆。

过程记录
一开始并没有意识到严重性,因此也并没有投入特别多的精力在这个问题上,而是把重点更多的放在其他bug的修复上,但是随着自己博客数据的增多,及使用此项目的朋友渐渐增多,有一天我忽然有种重压在心头的感觉,对于技术人员来说,web应用发生数据丢失这种事情实在是一件头痛的事,有过这种经历的人都会抗拒类似事件的出现,试想一下,运行良好的网站由于重启,导致数据全部丢失了,这种事情谁受得了,而且还是用了My Blog项目,是可忍孰不可忍!
虽然知道严重性,也无法容忍这个bug继续存在于项目中,但是却一直找不到合适的解决办法,容器启动过程中,能够修改的也就是shell语句了,而原来的语句是直接执行,并没有判断是否已经存在tale数据库,因此会导致覆盖问题,新的setup.sh文件中一定要解决数据库是否存在的判断问题。
一开始是根本没思路,通过一点点的动手实践,整个思路也渐渐清晰,通过shell脚本执行mysql命令,并根据得到的输出判断是否已经存在项目数据库,如果已经存在,就不再进行初始化,而是不进行任何操作即可,如果不存在,即第一次启动mysql容器,则进行数据初始化操作。
主要问题有:
- shell如何执行数据库操作;
- 能够直接被shell操作的命令且可以判断目标数据库是否存在的语句较少;
- 得不到输出(error直接退出);
- shell操作字符串的一些问题。
虽然现在很简单的就将问题整理出来,但是在实际操作过程中却是困难重重,上面所罗列的任何一个问题处理不掉,修复工作都无法继续进行,经过一次又一次的调试失败,最终找到了能够执行且可以用来判断数据库的sql语句,终于解决掉了这个bug,卡着进度最久的就是这个步骤,在shell脚本中始终无法处理mysql服务器返回的信息,接下去的判断逻辑根本无法执行。

如图,在执行'mysql > use tale;'sql命令时,每次都有此错误返回,虽然是预想中的返回,如果针对此错误返回值即可正确的判断是否已存在tale数据库,但是shell在执行到此语句时,收到此错误信息就直接退出进程了,因此根本无法继续进行。
针对shell操作字符串的一些问题,也单独整理了两篇笔记,可以在我的博客目录中看到,这里就不在贴链接了。

虽然只有这么一个段落,但是前前后后有两周的时间都在考虑及实践如何修复这个问题,setup.sh文件也如上图中local history一样,一次又一次的修改。问题终于解决了,该如何形容心情呢?暴露出的最大弱点修复了,皆大欢喜,如释重负,活在梦里...
处理结果
新版本的mysql容器:
第一次启动的日志输出

重启时的日志输出

如图所示,最终得到了想要的结果,重启时可以正确的判断容器中的mysql服务器中是否已经存在tale数据库,如果已经存在则不再重新初始化数据,修复了这个较为严重的bug。
问题修复之后,紧接着也就更新了阿里云容器仓库中的镜像,因为原镜像的版本较低依然存在此问题。
# 标记本地镜像,将其归入阿里云镜像仓库
docker tag dockerextension_mysql registry.cn-hangzhou.aliyuncs.com/13/myblog:mysql
# 登录阿里云容器仓库
docker login ...
# 上传镜像至容器仓库
docker push registry.cn-hangzhou.aliyuncs.com/13/myblog:mysql

上传成功,最新版的mysql镜像已经不存在那个严重的bug了。
结语
永远不要把你今天可以做的事留到明天做。拖延是偷光阴的贼。抓住他吧!
有问题,还是要解决的,不管你想着拖多久,该解决的还是要去解决。
这是一篇bug修复的复盘文章,也是一篇工作笔记,如果是第一次了解该项目,相信你即使看完后也是一脸懵逼,这是十分正常的,如果你想继续了解该项目可以查看整个系列文章Java开源博客My-Blog(SpringBoot+Docker)系列文章,也可以到我的GitHub仓库或者开源中国代码仓库中查看源码及详细的部署过程和使用文档。
首发于我的私人博客,编辑于2017年7月25日凌晨00:46。
Java开源博客My-Blog之mysql容器重复初始化的严重bug修复过程的更多相关文章
- Java开源博客My-Blog(SpringBoot+Docker)系列文章
My Blog 1.Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦 2.My-Blog搭建过程:如何让一个网站从零到可以上线访问 3.将数据的初始化放到 ...
- Java 开源博客——B3log Solo 0.6.6 正式版公布了!
Java 开源博客 -- B3log Solo 0.6.6 正式版公布了!欢迎大家下载. 该版本号引入了数据库连接池:Druid. 另外,欢迎观摩 B3log 团队的新项目:Noty,也很欢迎大家參与 ...
- Java 开源博客——B3log Solo 0.6.7 正式版公布了!
Java 开源博客 -- B3log Solo 0.6.7 正式版公布了!欢迎大家下载. 另外,欢迎观摩 B3log 团队的新项目:Wide,也很欢迎大家參与进来 :-) 特性 基于标签的文章分类 P ...
- Java 开源博客——B3log Solo 0.6.1 正式版发布了!
Java 开源博客 —— B3LOG Solo 0.6.1 正式版发布了!欢迎大家下载. 该版本主要是改善细节体验,并加入了一款 Metro 风格的皮肤. 特性 基于标签的文章分类 Ping Goog ...
- Java 开源博客——B3log Solo 0.6.7 正式版发布了!
Java 开源博客 -- B3log Solo 0.6.7 正式版发布了!欢迎大家下载. 另外,欢迎观摩 B3log 团队的新项目:Wide,也非常欢迎大家参与进来 :-) 特性 基于标签的文章分类 ...
- Java 开源博客——B3log Solo 0.6.6 正式版发布了!
Java 开源博客 -- B3log Solo 0.6.6 正式版发布了!欢迎大家下载. 该版本引入了数据库连接池:Druid. 另外,欢迎观摩 B3log 团队的新项目:Noty,也非常欢迎大家参与 ...
- Java 开源博客——B3log Solo 0.6.5 正式版发布了!
Java 开源博客 -- B3log Solo 0.6.5 正式版发布了!欢迎大家下载. 该版本主要是改善细节体验,也是 B3log Solo 的最后一个大版本. 这个版本发布后,B3log Solo ...
- Java 开源博客 Solo 1.9.0 发布 - 新皮肤
这个版本主要是改进了评论模版机制,让大家更方便皮肤制作,并发布了一款新皮肤:9IPHP. Solo 是一款一个命令就能搭建好的 Java 开源博客系统,并内置了 15+ 套精心制作的皮肤.除此之外,S ...
- Java 开源博客 Solo 2.5.0 发布
Java 开源博客 Solo 2.5.0 发布 Solo 是一款一个命令就能搭建好的 Java 开源博客系统,如果你想开个独立博客,请一定不要错过! 2.5.0 版本主要支持了 Markdown/JS ...
随机推荐
- java 按字节读写二进制文件(Base64编码解码)
最近在做项目时遇到这样一个需求:依次读取本地文件夹里所有文件的内容,转为JSON,发送到ActiveMQ的消息队列, 然后从MQ的消息队列上获取文件的信息,依次写到本地.常见的文件类型,比如.txt ...
- SQL PLUS的语句执行Commit
oracle 中有个commit,是用来提交事务的.今天发现sql developer和sql plus的数据查询不一样. 如果我们对数据库进行增删改查,在提交sql语句之后,如果不点击commit, ...
- SSD 下的 MySQL(5.5) IO 优化
一 目录 一 目录 二 背景 三 SSD 特性 四 基于 SSD 的数据库优化 五 A 项目 MySQL 主从关系图 六 程序切换之前调优 6.1 修改系统 IO 调度算法 6.2 修改 innodb ...
- JavaScript高级特性-创建对象的九种方式
1. 对象字面量 通过这种方式创建对象极为简单,将属性名用引号括起来,再将属性名和属性值之间以冒号分隔,各属性名值对之后用逗号隔开,最后一个属性不用逗号隔开,所有的属性名值对用大括号括起来,像这样: ...
- linux下安装mysql简单步骤
linux下使用yum安装mysql 1.安装 查看有没有安装过: yum list installed mysql* rpm -qa | grep mysql* 查看有没有安装包: yum list ...
- 【PAT】B1060 爱丁顿数(25 分)
逻辑问题,对我来说还是挺有难度的,一开始想不通 我输入数据并以数据为下标,数据出现次数为内容存储 然后从后遍历计算所有大于当前下标的元素出现的次数 最后遍历一遍确定是否为爱丁顿数,如果大于当前已经找到 ...
- MDX 脚本语句 -- Scope
在多维表达式 (MDX) 中,下列语句用于管理 MDX 脚本中的上下文.作用域和流控制. 主题 说明 calculate语句 计算子多维数据集,还可以确定子多维数据集中所包含的求解次序 case语句 ...
- HEU预热赛
A题: 一道dp的题目 dp[i][j] = k 代表 i行放j个棋子有k中可能 dp[i][j] = dp[i-1][0] + dp[i-1][1] + dp[i-1][2] +...dp[i-1] ...
- IO流_演示键盘录入
读取一个键盘录入的数据,打印到控制台上 键盘本身就是一个标准的输入设备,对于java而言,对于这种输入设备都有相应的对象在System类中 import java.io.IOException; im ...
- B - Modular Inverse
The modular modular multiplicative inverse of an integer a modulo m is an integer x such that a-1≡x ...