写在前面的话

《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修复过程的更多相关文章

  1. Java开源博客My-Blog(SpringBoot+Docker)系列文章

    My Blog 1.Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦 2.My-Blog搭建过程:如何让一个网站从零到可以上线访问 3.将数据的初始化放到 ...

  2. Java 开源博客——B3log Solo 0.6.6 正式版公布了!

    Java 开源博客 -- B3log Solo 0.6.6 正式版公布了!欢迎大家下载. 该版本号引入了数据库连接池:Druid. 另外,欢迎观摩 B3log 团队的新项目:Noty,也很欢迎大家參与 ...

  3. Java 开源博客——B3log Solo 0.6.7 正式版公布了!

    Java 开源博客 -- B3log Solo 0.6.7 正式版公布了!欢迎大家下载. 另外,欢迎观摩 B3log 团队的新项目:Wide,也很欢迎大家參与进来 :-) 特性 基于标签的文章分类 P ...

  4. Java 开源博客——B3log Solo 0.6.1 正式版发布了!

    Java 开源博客 —— B3LOG Solo 0.6.1 正式版发布了!欢迎大家下载. 该版本主要是改善细节体验,并加入了一款 Metro 风格的皮肤. 特性 基于标签的文章分类 Ping Goog ...

  5. Java 开源博客——B3log Solo 0.6.7 正式版发布了!

    Java 开源博客 -- B3log Solo 0.6.7 正式版发布了!欢迎大家下载. 另外,欢迎观摩 B3log 团队的新项目:Wide,也非常欢迎大家参与进来 :-) 特性 基于标签的文章分类 ...

  6. Java 开源博客——B3log Solo 0.6.6 正式版发布了!

    Java 开源博客 -- B3log Solo 0.6.6 正式版发布了!欢迎大家下载. 该版本引入了数据库连接池:Druid. 另外,欢迎观摩 B3log 团队的新项目:Noty,也非常欢迎大家参与 ...

  7. Java 开源博客——B3log Solo 0.6.5 正式版发布了!

    Java 开源博客 -- B3log Solo 0.6.5 正式版发布了!欢迎大家下载. 该版本主要是改善细节体验,也是 B3log Solo 的最后一个大版本. 这个版本发布后,B3log Solo ...

  8. Java 开源博客 Solo 1.9.0 发布 - 新皮肤

    这个版本主要是改进了评论模版机制,让大家更方便皮肤制作,并发布了一款新皮肤:9IPHP. Solo 是一款一个命令就能搭建好的 Java 开源博客系统,并内置了 15+ 套精心制作的皮肤.除此之外,S ...

  9. Java 开源博客 Solo 2.5.0 发布

    Java 开源博客 Solo 2.5.0 发布 Solo 是一款一个命令就能搭建好的 Java 开源博客系统,如果你想开个独立博客,请一定不要错过! 2.5.0 版本主要支持了 Markdown/JS ...

随机推荐

  1. go 排序sort的使用

    已知一个的struct组成的数组,现在要按照数组中的一个字段排序.python有sort方法,那golang要怎么实现呢?其实golang也有sort方法,并且使用简单,功能强大. 我们先看一下sor ...

  2. Python之SGDRegressor

    实现: # -*- coding: UTF-8 -*- import numpy as npfrom sklearn.linear_model import SGDRegressor __author ...

  3. CSS图片水平垂直居中

    Html: <div id="></img></div> </div> CSS: #MainContent { display:table-c ...

  4. EF扩展 更新指定字段

    using System.Data.Entity.Infrastructure; using System.Threading.Tasks; /// <summary> /// EF扩展 ...

  5. 分布式文件系统(HDFS)与 linux系统文件系统 对比

    初次接触分布式文件系统,有很多迷惑.通过参考网络文章,这里进行对比一下Hadoop 分布式文件系统(HDFS)与 传统文件系统之间的关系:   Linux 文件系统 分布式文件系统 块 块对应物理磁盘 ...

  6. kvm企业级虚拟化环境部署

    由于要做毕设了,不得不要搭建Linux环境,自己做的课题是ELK日志分析相关.因此要大干一场,一下子计划采用近10台机器来做试验,但由于我这里只有三台物理机,所以我就搞起了虚拟化kvm.在Linux里 ...

  7. 第 16 章 C 预处理器和 C 库(预定义宏)

    /*------------------------------------- predef.c -- 预定义宏和预定义标识符 ------------------------------------ ...

  8. 17秋 软件工程 第六次作业 Beta冲刺 Scrum4

    17秋 软件工程 第六次作业 Beta冲刺 Scrum4 各个成员冲刺期间完成的任务 世强:完成APP用户签到模块.群发短信模块前端界面: 陈翔:恢复Github项目,完成Scrum博客: 树民:和超 ...

  9. 网络编程_UDP协议_发送端与接收端

    创建UDP传输的发送端 : 1.建立udp的socket服务   2.将要发送的数据封装到数据包中   3.通过udp的socket服务 将数据包发送出去   4.关闭socket服务(因为调用了系统 ...

  10. C#异步编程の----Threadpool( 线程池)

    简介: 一个托管线程的创建需要数千个CPU周期,并且当发生线程切换时也会带来明显的开销.考虑线程的重用,避免不断重复创建新的线程是提高系统效率的一种方式. 线程池是一种提供效率的方式,它创建好一些线程 ...