写点什么

为什么数据库会丢失数据

  • 2020-02-28
  • 本文字数:2773 字

    阅读完需:约 9 分钟

为什么数据库会丢失数据

数据库管理系统在今天已经是软件的重要组成部分,开源的 MySQL、PostgreSQL 以及商业化的 Oracle 等数据库已经随处可见,几乎所有的服务都需要依赖数据库管理系统存储数据。



图 1 - 数据库


数据库不会丢失数据听起来像是理所当然的事情,持久化能力也应该是数据库的最基本保障,但是在这个复杂的世界上想要保证数据不丢失是很困难的。在今天,我们能找到很多数据库出现问题导致数据丢失的例子:


  • MongoDB 在过去很长的一段时间都不能保证持久性,很容易就会丢失数据1

  • RocksDB DeleteRange 功能导致的数据丢失问题2

  • 腾讯云硬盘故障,导致创业公司线上生产数据完全丢失的问题3


无论是开源数据库还是云服务商提供的服务,都有可能发生数据丢失的。本文将数据库丢失数据的原因归结到以下的几个方面,我们将详细展开介绍这些原因:


  • 人为因素导致的运维和配置错误是数据库丢失数据的首要原因;

  • 数据库存储数据使用的磁盘损坏导致数据丢失;

  • 数据库的功能和实现复杂,数据没有及时刷入磁盘就有丢失的风险;

人为错误

人为错误是造成数据丢失的首要原因。在腾讯云数据丢失事故中,我们会发现,虽然事故的起因是硬件故障,但是最终导致数据完整性受损的还是运维人员的不当操作:


第一是正常数据搬迁流程默认开启数据校验,开启之后可以有效发现并规避源端数据异常,保障搬迁数据正确性,但是运维人员为了加速完成搬迁任务,违规关闭了数据校验;

第二是正常数据搬迁完成之后,源仓库数据应保留 24 小时,用于搬迁异常情况下的数据恢复,但是运维人员为了尽快降低仓库使用率,违规对源仓库进行了数据回收。


减少人为错误的最好方式是将数据的备份和运维等操作标准化,使用自动化的流程处理涉及数据安全的操作,这样才能降低人为干预带来的风险。


对于软件工程师来说,我们应该敬畏生产环境,谨慎地在生产环境执行一切操作,认识到所有的操作都可能对线上正在运行的服务产生影响,这样才能降低类似问题发生的概率。

硬件错误

我们在 为什么基础服务不应该高可用 一文中曾经介绍过任何一个线上的服务能够正常运行都是极其偶然的,只要时间拉的足够长,我们就没有办法保证服务 100% 的可用性4。磁盘等硬件如果使用的时间足够长,很有可能会发生损坏,根据 Google 论文中的数据,5 年内硬盘的年平均故障率(Annualized Failure Rates,AFR)为 8.6%5


2018 年,腾讯云数据损坏事故的起因就是磁盘静默错误(Silent data corruption)6导致的单副本数据错误。磁盘静默错误是没有被磁盘固件或者宿主操作系统发现的错误,包括以下情况:电缆松了、电源供给不可靠、外部震动、网络引起的数据丢失等问题。


正是因为磁盘的数据损坏非常常见,所以我们需要数据冗余的方式保证磁盘在发生不可修复读错误(Unrecoverable Read Error)时能够恢复磁盘数据。独立冗余磁盘阵列(Redundant Array of Independent Disks,RAID)是一种能够将多个物理磁盘组合成一个逻辑磁盘的数据存储虚拟化技术,它能够增加数据冗余并提高性能7



图 2 - RAID 三大策略


RAID 主要使用分割(Striping)、镜像(Mirroring)和奇偶校验(Parity)三大策略管理磁盘中的数据,我们这里举几个简单的例子:


  • RAID 0 使用了数据分割技术,但是没有镜像和奇偶校验。它对磁盘上的数据几乎不进行任何的保护,任意一块磁盘磁盘损坏都意味着其中的数据无法恢复,但是因为不存在冗余,所以它也会提供较好的性能;

  • RAID 1 使用了数据镜像的功能,但是没有奇偶校验和数据分割。所有的数据都会写入两个相同的磁盘,两个磁盘都能对外提供数据读取的服务。这种方式降低了磁盘的使用率,但是能够提高读取性能并提供备份;


RAID 使用的分割和镜像策略与分布式数据库中的分片(Partition)和副本(Replication)比较相似,分割和分片将数据切分后分配到不同的磁盘或者机器,而镜像和副本的作用都是复制数据。


很多现代的操作系统都会提供基于软件的 RAID 实现,一些云服务厂商也会使用自研的文件系统或者冗余备份机制:


  • Google 使用 Google 文件系统管理文件,它以块的方式存储文件并且通过主服务管理所有的文件块8

  • Microsoft 在 Azure 中使用擦除编码的方式计算冗余数据9


硬件错误在生产环境中很常见,我们只有通过数据冗余和校验才能降低数据丢失的可能性,但是增加冗余的方式也只能不断降低数据丢失的概率,不能 100% 的避免。

实现复杂

数据库管理系统最终会将数据存储在磁盘上,对于很多数据库来说,数据落到磁盘上就意味着持久化完成了。磁盘作为数据库系统的下层,磁盘能够稳定存储数据是数据库能够持久化数据的基础。



图 3 - 数据库依赖磁盘


很多人都误认为使用 write 就能将数据写入到磁盘上,然而这是错误的。函数 write 不仅不能保证数据写入磁盘,有的实现甚至都不能保证目标空间保留给了写入的数据10。一般情况下,对文件的 write 只会更新内存中的页缓存,这些页缓存不会立刻刷入磁盘,操作系统的 flusher 内核线程会在满足以下条件时将数据落盘11


  • 空闲内存下降到了特定的阈值,需要释放脏页占用的内存空间;

  • 脏数据持续了一定时间,最老的数据就会被写入磁盘;

  • 用户进程执行 sync 或者 fsync 系统调用;


如果我们想要将数据立刻刷入磁盘,就需要在执行 write 后立刻调用 fsync 等函数12,当 fsync 等函数返回后,数据库才会通知调用方数据已经成功写入。



图 4 - 写入和落盘


writefsync 在数据库管理系统中非常重要,它们是提供持久性保证的核心方法,一些开发者对 write 的理解错误写出错误的代码就会导致数据丢失。


除了持久化的特性之外,数据库可能还需要提供 ACID(Atomicity, Consistency, Isolation, Durability)或者 BASE(Basically Available, Soft state, Eventual consistency)的保证,有些数据库还会提供分片、副本以及分布式事务等复杂功能,这些功能的引入也增加了数据库系统的复杂性,而随着程序复杂性的增加,出现问题的可能性也随之增长。

总结

数据库管理系统是软件工程中最复杂、最重要的系统之一,几乎所有服务的正常运行都建立在数据库不会丢失数据的假设上。然而因为如下所示的原因,数据库不能完全保证数据的安全:


  • 运维人员在配置和运维时极有可能因为操作失误导致数据丢失;

  • 数据库依赖的底层磁盘发生硬件错误,导致数据无法恢复;

  • 数据库系统支持的功能非常多而且复杂,数据没有及时落盘就可能造成数据丢失;


一旦发生数据丢失的事故,造成的影响就会非常大,我们在使用数据库存储核心业务数据时也不能完全信任数据库的稳定性,可以考虑使用热备以及快照等方式容灾。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:


  • 除了文中列出的数据丢失事故,还有哪些数据库或者云服务商丢失过数据?

  • Redis 的 RDB 和 AOF 机制什么时候会将数据落盘?

  • 数据成功写入数据库究竟应该如何定义?


本文转载自 Draveness 技术网站。


原文链接:https://draveness.me/whys-the-design-database-data-loss


2020-02-28 17:19995

评论

发布
暂无评论
发现更多内容

上手体验TailwindCSS

小鑫同学

8月月更

【Vite】配置HTTPS&自签名证书

小鑫同学

8月月更

小程序|炎炎夏日、清爽一夏、头像大换装

小鑫同学

8月月更

阿里最新468页Spring Boot企业级项目开发实战手册好强啊,Github获星30000+

Java面试那些事儿

Java 编程 程序员 面试 架构师

开源一夏 | 在 STM32L051 上使用 RT-Thread (五、无线温湿度传感器 之 完结篇)(附源码)

矜辰所致

开源 RT-Thread 8月月更 STM32L051

时序数据无处不在

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

教你从创建数据表到实现最基础增删改查的实现全过程,小白也能轻松学会【带附件】

CRMEB

介绍16个让你的代码变漂亮的属性

小鑫同学

8月月更

大数据训练营1期 毕业总结

张大彪

一个 SAP 开发工程师在 SAP 德国总部出差的见闻系列 1:出差 ≠ 公费旅游

汪子熙

SAP abap 8月月更 开发工程师 思爱普

95后阿里P7晒出工资单:狠补了这个,真香...

退休的汤姆

Java、 面经 社招 秋招 阿里、

SAP 电商云 Spartacus UI 里的 ASM 模块启用的前置条件

汪子熙

angular SAP SAP UI5 Spartacus 8月月更

兆骑科创高层次人才引进服务平台,双创服务,投融资对接

兆骑科创凤阁

你必须知道的Java泛型

自然

Java core 8月月更

【全干】从零搞定微信SDK授权

小鑫同学

8月月更

基于STM32F103设计的智能门锁(支持多种开锁解锁方式)

DS小龙哥

8月月更

flex 布局(弹性布局 / 弹性盒子)一直没学明白,看完这篇文章我彻底懂了

CRMEB

秋招大厂字节上午 10:00 面试,10:09 就出来了 ,问的实在是太...

退休的汤姆

Java、 面经 社招 Java工程师 秋招

望繁信科技受邀参加中国智慧财务国际峰会

望繁信科技

有了这 14 个技巧,让你玩转 Spring MVC

TimeFriends

8月月更

强烈推荐一款超好用的开源电商系统!!!

CRMEB

Go-Excelize API源码阅读(十五)——SetSheetViewOptions

Regan Yue

Go 开源 源码 8月日更 8月月更

数据,不能只讲大道理

水滴

数据中台 数据规范 数据化转型

了解布隆过滤器

自然

Java core 8月月更

带你体验一次类型编程实践

小鑫同学

8月月更

京东8年资深架构师为你解析:Kafka源码解析实战。为你解忧

Java编程日记

Java 编程 程序员 架构师 面经

惊艳!阿里巴巴最新发布Java系统架构师+开发应用面试突击宝典

Java编程日记

Java 编程 程序员 面试 架构师

开源一夏 | 单片机系统中实用的按键驱动(STM32、51都适用)

矜辰所致

开源 8月月更 按键驱动

阿里大佬耗时一年整理的Java面试常考题,GitHub点赞33K+

Java面试那些事儿

Java 编程 程序员 面试 架构师

腾讯 X 广东省计算机学会,推动数据库产学研发展

科技热闻

兆骑科创创新创业高层次人才引进,以赛引才,线上直播路演

兆骑科创凤阁

为什么数据库会丢失数据_大数据_Draveness_InfoQ精选文章