mysql 容器崩溃,连接未正常关闭,会损坏数据卷,那 redis 呢

2022-10-05 17:12:52 +08:00
 king666wyx

数据卷挂载来存储数据。但是容器的 Volumes 设计是围绕 Union FS 镜像层提供持久存储,数据安全缺乏保证。如果容器突然崩溃,数据库未正常关闭,可能会损坏数据。另外,容器里共享数据卷组,对物理机硬件损伤也比较大。

Question: 1.数据库连接未正常关闭,为什么会损坏到数据及物理机硬件 2.如果说 docker 中装了 redis ,在容器崩溃的条件下,是否会同 mysql 一样,损伤到数据及物理机硬件 3.其它数据库类型及存储呢

1930 次点击
所在节点    Docker
21 条回复
boris93
2022-10-05 17:43:35 +08:00
我理解 redis 的数据是存在内存里的,持久化靠 rdb 和 aof ,如果意外关闭,rdb 会丢失落盘间隔之间存进去的数据,aof 也有可能会丢最后几条命令,但是不至于数据完全损毁
ThirdFlame
2022-10-05 17:43:45 +08:00
没想明白为啥会损坏物理机硬件。

最少我没遇到过由于 mysql 容器未正常关闭,影响存量数据的情况。(当时突发的更新、删除、插入操作,这种受影响很正常)
king666wyx
2022-10-05 17:49:11 +08:00
@boris93 连接未正常关闭,操作 io 未完成,是否会造成损毁
king666wyx
2022-10-05 17:49:35 +08:00
@ThirdFlame 这是目前网上主流的说法,但是具体深度一点的原因不清楚
XiaoxiaoPu
2022-10-05 18:04:36 +08:00
@king666wyx 只是内容农场机翻+到处复制而已,不是什么主流的说法
boris93
2022-10-05 19:00:22 +08:00
@king666wyx #3
连接是不是正常关闭跟磁盘 io 好像没啥关系
写 rdb 和 aof 也就是那么一下子的事,正好写到半道 redis 崩了的几率小之又小,考虑这个问题不如考虑怎么搞集群搞备份
king666wyx
2022-10-05 19:28:36 +08:00
@boris93 崩不崩溃不是我关心的,我关心的是不是跟 mysql 一样伤磁盘
king666wyx
2022-10-05 19:28:59 +08:00
@XiaoxiaoPu 那主要是我们该怎么理解
boris93
2022-10-05 21:10:06 +08:00
@king666wyx #7 来源请求?容器异常关闭怎么会伤硬件?
king666wyx
2022-10-05 21:16:04 +08:00
@boris93 操作 io 的行为在进行中,未释放
documentzhangx66
2022-10-06 04:37:18 +08:00
#-------------------------
#-------------------------
1.DB 的 HA ,需要彻底隔离的至少 2 个物理 Node 。而且,如果需要强一致性,DB Client 还不能直接访问 DB Server ,而是 DB Client 需要访问 DB Middleware ,比如 DB Proxy ,通过 DB Proxy 来连接两个物理节点的 DB ,来保证两个物理节点的数据,同时 flush to 持久化存储介质后,DB Proxy 才能 Response to DB Client:该事务执行成功。

这是最低配最入门版本的 HA ,扯这事,是因为,你就一个单节点 Mysql ,崩溃后,就算数据全丢都很正常,所以不用太在意损坏数据卷,因为你不做 HA ,相当于不在乎数据安全问题。

#-------------------------
#-------------------------
2.当 Mysql 容器崩溃后,也就是 Mysql 的单个物理节点崩溃后,发生什么事情都不奇怪,所以发生连接未正常关闭就太正常了,比如 Mysql 直接挂掉,导致 DB Server 的连接管理组件崩溃,tcp-socket 没向 DB Client 做任何回应,也接着崩了,DB Client 那边:

A.可能会直接 tcp keep alive 超时,然后报连接未正常关闭错误。

B.DB Server 崩溃后,DB Server 的上层宿主,比如 OS 、docker 的网络管理组件等等,可能会发出 tcp 关闭数据包 FIN Packet ,同时 DB Client 业务层发现 tcp 连接关闭后,业务层面却没有执行安全关闭逻辑,然后也会报这个连接未正常关闭错误。

我没有具体研究过 Mysql 逻辑,但数据库在这个问题上的处理逻辑都差不多。

#-------------------------
#-------------------------
3.物理机硬件损伤也比较大 ?????

你是觉得,存储介质,在那里噼里啪啦响着,就容易损坏对吧?

比如以前有这样的说法,硬盘一直开着 BT 下载,就很容易坏。道理的确是这样,但问题是,你买硬盘回来,是打算宠着用,每天还要亲亲抱抱举高高嘛?

硬盘用坏,不是因为 Mysql 或 Redis 崩溃,而是机械硬盘长期非连续读写,磁头经常移动,寿元当然消耗得快。SSD 的 TLC 甚至廉价 QLC ,无论你 4k rand io 还是 seq io ,长时间大量写入,也容易耗光它的寿元。

其它数据库类型及存储也同理。

另外,与其怕这,还不如担心灰尘导致内存条击穿,造成内存故障,如果内存不是 RECC / ECC ,以及数据传输没做校验,导致数据复制与移动发生错误,这个问题更要命。
king666wyx
2022-10-06 12:37:48 +08:00
@documentzhangx66 mysql 本身不是有 innodb_flush_log_at_trx_commit 吗,怎么会崩溃后数据丢失也正常呢
documentzhangx66
2022-10-06 21:40:06 +08:00
@king666wyx

崩溃的意思是,因为软件 bug 或硬件缺陷,导致程序没按正常逻辑去处理。

这些都不是 innodb_flush_log_at_trx_commit 能够处理的事情。

比如 DB 在 malloc 时没处理 NUMA 的场景,导致 malloc 失败,DB 整体崩溃,而此时恰好 DB 有别的线程在处理日志数据落地到数据文件的逻辑,DB 崩溃造成数据文件的 lock 没处理,且存在脏数据。

再比如内存条是非 ECC / RECC 的,且突然有了坏块,坏块位置刚好是 DB 事务 queue length 位置,由 length 由 1024 突然变成 拷斤锟,于是 queue 后续的 data 读到了内存中的未知区域,这些数据被当成正常数据刷入日志文件,最后日志数据落地到数据文件时,发现数据结构与表结构对不上,报错。

这些还是内部逻辑。

外部的情况会更复杂,比如使用超过物理磁盘容量的稀疏虚拟磁盘文件,当实际数据量超出物理磁盘容量后,如果存储组件有 bug ,会导致超过容量的数据全部存储失败,且无告警。

再比如某些分布式文件系统,内部有 bug ,双副本的独占文件块在被 DB 使用时,其中某个物理节点被管理员强制进入维护状态。此时文件系统,本来应该按业界操作规范,先另寻可用物理节点,然后进行版本记录 -> 版本之前的历史数据同步 -> 版本后的新数据同步 -> 锁上整个分布式文件系统的写操作 -> 同步最后差异数据 -> 解锁写操作。但因为 bug 的存在,当某个物理节点被管理员强制进入维护状态时,另一个可用物理节点的超时等待时间过长,积压数据过多,积压的数据因程序 bug ,没能进入 swap 与 持久存储缓存,导致这唯一可用的节点也因为 oom 而崩了,最终丢失数据。

还有一个不仅是丢失数据,而是直接数据全毁的例子,某知名大牌虚拟化厂商,其快照实现有 bug ,本来多层快照,在 HDD 介质中,导出时,因需要大量 4k rand 操作,来进行多层快照合并,速度贼慢,而且写这块实现的程序员,贪图方便,使用了无缓存无副本的直接对快照文件进行文件内处理的高风险方法;此时,用户态的管理工具,是另一个程序员写的,两人没沟通、没写上处理逻辑,导致管理工具,没有等待与检查快照合并逻辑,而是简单粗暴地直接使用了一个超时时间,超时后就直接中断快照合并逻辑。当快照数量多,数据量大的情况下,前者的合并操作因超时,被后者打断,导致了在用户角度看来,复制整个虚拟磁盘或虚拟机时,超时失败,且原始虚拟机磁盘数据损坏。简单来说,就好比,你复制一个电影,复制失败了,且原始的电影也播放不了。
king666wyx
2022-10-07 17:14:58 +08:00
@documentzhangx66 即使你说的很对,但是都是数据库层面的,我问的是基于 docker 层面的
documentzhangx66
2022-10-07 17:42:48 +08:00
@king666wyx 再仔细看看? docker 层面的问题,我在上面已经说了。
king666wyx
2022-10-07 17:49:00 +08:00
@documentzhangx66 那结论就是所有数据库层面的都不适用于 docker 了
king666wyx
2022-10-07 17:52:31 +08:00
@documentzhangx66 其实从更多层面来看,问题性应该是数据库处理机制身上而不是 docker 身上,所以还是有点不理解那些文章强行把 mysql 的问题说成 docker 的
documentzhangx66
2022-10-07 21:06:59 +08:00
@king666wyx

1.数据库安全是分很多等级的。比如自己玩的数据库,做好了定期备份,并且不在乎丢失最后几条数据,那么用 Mysql Docker 是没问题的。

2.你说的对,要确保数据安全,应该从数据库处理机制入手,而不是 docker 。

3.正经企业级的数据库安全,一般是这样做的:

A.多副本节点的完全冗余。

B.每个节点又有 CDP (连续数据保护)作为支撑。

C.普通 2 - 3 级等保系统,会有专门备份一体机,每日一个完整备份。

金融级一般是 1 小时一个完整备份。
julyclyde
2022-10-08 11:01:06 +08:00
跟 unionFS 也没多大关系啊
和下面那些层都无关的,其实只访问了最上边一层
caotian
2022-10-08 16:27:14 +08:00
我已经用 docker 跑 mysql 好几年了, 而且跑了很多个实例, 目前的观点是, 确实会有损坏的风险。
也害怕 mysql 挂了,所以买了阿里云的数据库备份服务, 据称是可以恢复到秒的, 一直比较放心,大不了恢复一下。但是!!!有一次给服务器做了 apt upgrade, docker 有升级版本, 直接被结束 service, 升级完后, mysql 容器挂了,并且不能正常启动,有报数据库文件有损坏,当时有阿里云的数据库备份所以并不担心,于是删了容器,重建,然后用阿里云的备份来恢复却一直失败,印象中似乎是阿里云的备份服务备份了一些错误的数据,导致恢复失败。最后没办法用了当天的全量备份恢复了,还好是晚上折腾的,系统晚上没有人使用,所以全量备份的也是最新的数据。
另外一次印象比较深的是 mysql cpu 占用太高 ecs 死机, 强制重启后, mysql 容器也是挂了, 也是通过备份恢复的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/884767

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX