QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

为什么数据库会丢失数据

  • 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:191114

评论

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

cdc 同步到 s3 的故障

TiDB 社区干货传送门

迁移 管理与运维 故障排查/诊断 新版本/特性发布

【文章】精选实践汇总1

TiDB 社区干货传送门

实践案例

TiDB at ZaloPay Infrastructure & Lesson Learned

TiDB 社区干货传送门

使用pd-recover 恢复pd 多数节点故障的场景

TiDB 社区干货传送门

管理与运维 故障排查/诊断

TiDB 多Socket 服务器性能扩展问题分析

TiDB 社区干货传送门

性能调优 性能测评

TUG 技术大咖圆桌讨论:如何评判一个数据架构的好坏

TiDB 社区干货传送门

数据库架构选型

端到端的实时计算:TiDB + Flink 最佳实践

TiDB 社区干货传送门

实践案例

【文章】精选实践汇总2

TiDB 社区干货传送门

实践案例

通过 BR 完成不同 K8s 的 TiDB 集群的数据恢复

TiDB 社区干货传送门

故障排查/诊断

数据库选型中的非技术因素

TiDB 社区干货传送门

数据库架构选型

TiKV 集群部署 注意事项

TiDB 社区干货传送门

Chaos Mesh 助力 Apache APISIX 提升稳定性

TiDB 社区干货传送门

实践案例

TiDB 集群的可用性详解及 TiKV Label 规划

TiDB 社区干货传送门

TiDB 底层架构

实时 AP、分库分表、大数据应用,TiDB 在虎牙直播是怎么用的?

TiDB 社区干货传送门

实践案例

多种方式告诉你如何计算DM同步数据到TiDB的延时时间

TiDB 社区干货传送门

管理与运维

5.0 新特性试用体验之 Clustered Index

TiDB 社区干货传送门

实践案例 TiDB 底层架构 版本测评 新版本/特性发布 性能测评

写冲突场景下的悲观/乐观事务模型选择

TiDB 社区干货传送门

实践案例

Flink + TiDB,体验实时数仓之美

TiDB 社区干货传送门

实践案例

TiDB 优化之消失的统计信息

TiDB 社区干货传送门

实践案例

【TiDB 最佳实践系列】开发 Java 应用使用 TiDB 的最佳实践

TiDB 社区干货传送门

实践案例

【TiDB 最佳实践系列】TiDB 高并发写入常见热点问题及规避方法

TiDB 社区干货传送门

实践案例

如何在 TiDB 上高效运行序列号生成服务

TiDB 社区干货传送门

管理与运维

tiup目录冲突检测不健全导致的节点被destroy问题以及解决

TiDB 社区干货传送门

某业务升级5.0解决慢SQL问题

TiDB 社区干货传送门

实践案例 故障排查/诊断

SQL只是CRUD?

TiDB 社区干货传送门

TiDB 底层架构

【TiDB DevCon 2020】金融专题论坛演讲视频汇总

TiDB 社区干货传送门

raft:分布式一致性算法笔记

TiDB 社区干货传送门

TiDB 底层架构

关于 TiDB 性能优化的一些思考

TiDB 社区干货传送门

性能调优

JQ 入门教程

TiDB 社区干货传送门

TiDB 底层架构

PD模块梳理

TiDB 社区干货传送门

TiDB 底层架构

一次热点问题排查经历

TiDB 社区干货传送门

故障排查/诊断

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