写点什么

为什么数据库会丢失数据

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

评论

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

为什么西门子、美的等企业这样进行架构升级,看看改造效果就知道了

TDengine

数据库 tdengine 开源 时序数据库

手写JavaScript常见5种设计模式

helloworld1024fd

JavaScript

关于我在学习LFU的时候,在开源项目捡了个漏这件事

why技术

Java 面试 算法

三十分钟入门基础Go(Java小子版)

京东科技开发者

Java php Go nil 企业号 2 月 PK 榜

2023最新Java面试手册(性能优化+微服务架构+并发编程+开源框架)

小小怪下士

Java 程序员 面试 金三银四

试试 MyBatis 流式查询,很强!!!

Steven

细说react源码中的合成事件

flyzz177

React

React-Hooks源码深度解读

goClient1992

React

从源码角度看React-Hydrate原理

flyzz177

React

【等保要求】等保要求堡垒机审计日志保留多久?

行云管家

等保 堡垒机 等级保护

为实现跨境文件高速传输,镭速传输都用了哪些技术

镭速

StarRocks获评「2022 中国开源社区健康案例」!

StarRocks

数据库 开源

百度前端必会手写面试题整理

helloworld1024fd

JavaScript

看透react源码之感受react的进化

goClient1992

React

PMR 提取视频特征,理解上下文

Zilliz

GaussDB(DWS)性能调优:indexscan导致的性能问题识别与优化

华为云开发者联盟

数据库 后端 华为云 企业号 2 月 PK 榜 华为云开发者联盟

深入react源码看setState究竟做了什么?

flyzz177

React

阿里IM技术分享(十):深度揭密钉钉后端架构的单元化演进之路

JackJiang

转角遇到爱,资源中心系统和图数据库

鲸品堂

技术 图数据库 企业号 2 月 PK 榜

StarRocks 企业行|走进 58 同城,探索极速统一 3.0 时代的企业实践

StarRocks

数据库

手写现代前端框架diff算法-前端面试进阶

helloworld1024fd

JavaScript

升级到JDK17和Spring Boot 2.7.8

xiaoboey

Spring Cloud Spring Boot

React源码分析(一)Fiber

goClient1992

React

企业级数据平台为什么要“可观测”? | StartDT Hackathon

奇点云

数据平台 可观测 云数据 黑客马拉松 奇点云

喜讯:行云绽放荣获国家高新技术企业证书

行云管家

高新企业 高新技术 高新

IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf

JackJiang

倒带ChunJun,同心前行|2022年度回顾&2023年共建规划

袋鼠云数栈

开源

ChatGPT类AI软件供应链的安全及合规风险

墨菲安全

代码安全检测 墨菲安全 软件供应链安全 ChatGPT

深度使用国产Bg-Tinkle数据库客户端—太赞了,居然还集成chatGPT AI生成SQL

非喵鱼

Java MySQL 数据库 国产软件 Tinkle

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