【AICon】探索八个行业创新案例,教你在教育、金融、医疗、法律等领域实践大模型技术! >>> 了解详情
写点什么

为什么数据库会丢失数据

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

评论

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

A tour of gRPC:05 - gRPC server straming 服务端流

BUG侦探

gRPC RPC protocolBuffer

ApacheCon Asia 2022 启动!7场阿里云大数据+AI议题分享等你围观

阿里云大数据AI技术

人工智能 大数据

有奖征文 | 2022 云原生编程挑战赛征稿活动开启!

阿里巴巴云原生

阿里云 云原生编程挑战赛

从0到1:基于云开发的投票小程序开发笔记

CC同学

小程序云开发 投票小程序

一文简述:SRv6基本原理

穿过生命散发芬芳

7月月更 SRv6

如何做一个好的大数据平台架构

数据社

签约计划第三季

Rust 入门指南(rustup, cargo)

王泰

rust

KubeEdge发布云原生边缘计算威胁模型及安全防护技术白皮书

华为云开发者联盟

云计算 云原生 安全

深圳哪的培训机构学习大数据开发?

小谷哥

【后端开发】Reactor 模型详解

C++后台开发

reactor 后端开发 网络模型 C/C++后台开发 C/C++开发

GIS数据漫谈(六)— 投影坐标系统

ThingJS数字孪生引擎

活动速递| Apache Doris 性能优化实战系列直播课程初公开,诚邀您来参加!

SelectDB

数据库 性能优化 数据仓库 OLAP Doris

IT远程运维是什么意思?远程运维软件哪个好?

行云管家

IT运维 远程运维 IT远程运维

应该怎么规划学习web前端培训

小谷哥

阿里云 MSE 支持 Go 语言流量防护

阿里巴巴云原生

Go 阿里云 云原生 云原生微服务

顿悟!百度强推的Redis天花板笔记,原来数据库是这样理解的

冉然学Java

分布式 redis' 技术专题合集 #java redis 底层原理

Rust 入门指南(crate 管理)

王泰

rust

不懂就问,快速成为容器服务进阶玩家!

阿里巴巴云原生

阿里云 容器 云原生 训练营

兆骑科创创新创业大赛人才引进平台,双创赛事高层次人才引进

兆骑科创凤阁

参加java培训学习建议选择

小谷哥

全链路灰度在数据库上我们是怎么做的?

阿里巴巴云原生

数据库 阿里云 微服务 云原生 全链路灰度

【干货】如何建立支持和产品之间的密切关系?

Geek_da0866

与字节、小米、移动云等企业一起揭秘 RocketMQ 实践之道

阿里巴巴云原生

阿里云 RocketMQ 云原生 峰会

在培训机构学到大数据技术

小谷哥

“工厂、构造、原型” 设计模式与 JS 继承

掘金安东尼

JavaScript 前端 7月月更

前端培训机构应该如何学习前端开发技术?

小谷哥

C#/VB.NET:在PDF中插入文本水印

Geek_249eec

C# PDF VB.NET 水印

多线程与高并发—— 源码解析 AQS 原理

王小凡

Java 程序员 AQS JVM 多线程

管理区解耦架构见过吗?能帮客户搞定大难题的

华为云开发者联盟

云计算 后端 华为云

零代码修改,教你Spring Cloud应用轻松接入CSE

华为云开发者联盟

云计算 后端 CSE

极狐GitLab Helm Registry 使用指南

极狐GitLab

git DevOps gitlab 运维 CI/CD

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