V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
king666wyx
V2EX  ›  Docker

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

  •  
  •   king666wyx · 2022-10-05 17:12:52 +08:00 · 1948 次点击
    这是一个创建于 812 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    第 1 条附言  ·  2022-10-07 18:20:19 +08:00
    Question:

    1.数据库连接未正常关闭,为什么会损坏到数据及物理机硬件
    损伤数据只是理论问题,硬件感觉像胡扯

    2.如果说 docker 中装了 redis ,在容器崩溃的条件下,是否会同 mysql 一样,损伤到数据及物理机硬件
    结果同 1

    3.其它数据库类型及存储呢
    结果同 1

    个人观点,有不对的希望指正
    结论:
    https://www.infoq.cn/article/can-mysql-run-in-docker
    https://www.zhihu.com/question/42976239

    很多人是瞎抄,全网文章几乎一样,理论依据可以理解为,他们讨论的问题是“mysql 是否需要容器化”很多人希望数据库容器可以像其他容器一样飘到其他节点,但是本地卷,显然不能完成。他们可能理解这样是丢数据。他们参考的是 docker 官方的一句“容器随时可以停止、或者删除”

    实际情况,mysql 单机随便搞,就是要注意它映射的数据在本地,可能不能到处飘,还有单机数据安全还有一些常规自己部署的一些注意问题(链接 1 同城人家跑了大量的 docker 容器,从实践看起来也问题不大)
    21 条回复    2022-10-09 22:08:14 +08:00
    boris93
        1
    boris93  
       2022-10-05 17:43:35 +08:00 via iPhone
    我理解 redis 的数据是存在内存里的,持久化靠 rdb 和 aof ,如果意外关闭,rdb 会丢失落盘间隔之间存进去的数据,aof 也有可能会丢最后几条命令,但是不至于数据完全损毁
    ThirdFlame
        2
    ThirdFlame  
       2022-10-05 17:43:45 +08:00
    没想明白为啥会损坏物理机硬件。

    最少我没遇到过由于 mysql 容器未正常关闭,影响存量数据的情况。(当时突发的更新、删除、插入操作,这种受影响很正常)
    king666wyx
        3
    king666wyx  
    OP
       2022-10-05 17:49:11 +08:00
    @boris93 连接未正常关闭,操作 io 未完成,是否会造成损毁
    king666wyx
        4
    king666wyx  
    OP
       2022-10-05 17:49:35 +08:00
    @ThirdFlame 这是目前网上主流的说法,但是具体深度一点的原因不清楚
    XiaoxiaoPu
        5
    XiaoxiaoPu  
       2022-10-05 18:04:36 +08:00
    @king666wyx 只是内容农场机翻+到处复制而已,不是什么主流的说法
    boris93
        6
    boris93  
       2022-10-05 19:00:22 +08:00 via iPhone
    @king666wyx #3
    连接是不是正常关闭跟磁盘 io 好像没啥关系
    写 rdb 和 aof 也就是那么一下子的事,正好写到半道 redis 崩了的几率小之又小,考虑这个问题不如考虑怎么搞集群搞备份
    king666wyx
        7
    king666wyx  
    OP
       2022-10-05 19:28:36 +08:00
    @boris93 崩不崩溃不是我关心的,我关心的是不是跟 mysql 一样伤磁盘
    king666wyx
        8
    king666wyx  
    OP
       2022-10-05 19:28:59 +08:00
    @XiaoxiaoPu 那主要是我们该怎么理解
    boris93
        9
    boris93  
       2022-10-05 21:10:06 +08:00 via iPhone
    @king666wyx #7 来源请求?容器异常关闭怎么会伤硬件?
    king666wyx
        10
    king666wyx  
    OP
       2022-10-05 21:16:04 +08:00
    @boris93 操作 io 的行为在进行中,未释放
    documentzhangx66
        11
    documentzhangx66  
       2022-10-06 04:37:18 +08:00   ❤️ 3
    #-------------------------
    #-------------------------
    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
        12
    king666wyx  
    OP
       2022-10-06 12:37:48 +08:00
    @documentzhangx66 mysql 本身不是有 innodb_flush_log_at_trx_commit 吗,怎么会崩溃后数据丢失也正常呢
    documentzhangx66
        13
    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
        14
    king666wyx  
    OP
       2022-10-07 17:14:58 +08:00
    @documentzhangx66 即使你说的很对,但是都是数据库层面的,我问的是基于 docker 层面的
    documentzhangx66
        15
    documentzhangx66  
       2022-10-07 17:42:48 +08:00
    @king666wyx 再仔细看看? docker 层面的问题,我在上面已经说了。
    king666wyx
        16
    king666wyx  
    OP
       2022-10-07 17:49:00 +08:00
    @documentzhangx66 那结论就是所有数据库层面的都不适用于 docker 了
    king666wyx
        17
    king666wyx  
    OP
       2022-10-07 17:52:31 +08:00
    @documentzhangx66 其实从更多层面来看,问题性应该是数据库处理机制身上而不是 docker 身上,所以还是有点不理解那些文章强行把 mysql 的问题说成 docker 的
    documentzhangx66
        18
    documentzhangx66  
       2022-10-07 21:06:59 +08:00
    @king666wyx

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

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

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

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

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

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

    金融级一般是 1 小时一个完整备份。
    julyclyde
        19
    julyclyde  
       2022-10-08 11:01:06 +08:00
    跟 unionFS 也没多大关系啊
    和下面那些层都无关的,其实只访问了最上边一层
    caotian
        20
    caotian  
       2022-10-08 16:27:14 +08:00
    我已经用 docker 跑 mysql 好几年了, 而且跑了很多个实例, 目前的观点是, 确实会有损坏的风险。
    也害怕 mysql 挂了,所以买了阿里云的数据库备份服务, 据称是可以恢复到秒的, 一直比较放心,大不了恢复一下。但是!!!有一次给服务器做了 apt upgrade, docker 有升级版本, 直接被结束 service, 升级完后, mysql 容器挂了,并且不能正常启动,有报数据库文件有损坏,当时有阿里云的数据库备份所以并不担心,于是删了容器,重建,然后用阿里云的备份来恢复却一直失败,印象中似乎是阿里云的备份服务备份了一些错误的数据,导致恢复失败。最后没办法用了当天的全量备份恢复了,还好是晚上折腾的,系统晚上没有人使用,所以全量备份的也是最新的数据。
    另外一次印象比较深的是 mysql cpu 占用太高 ecs 死机, 强制重启后, mysql 容器也是挂了, 也是通过备份恢复的。
    king666wyx
        21
    king666wyx  
    OP
       2022-10-09 22:08:14 +08:00
    @caotian 还是希望更细节了解下问题的原因,所以备份还是很重要
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2502 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 15:58 · PVG 23:58 · LAX 07:58 · JFK 10:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.