数据库管理系统在今天已经是软件的重要组成部分,开源的 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 - 写入和落盘

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

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

总结

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

  • 运维人员在配置和运维时极有可能因为操作失误导致数据丢失;
  • 数据库依赖的底层磁盘发生硬件错误,导致数据无法恢复;
  • 数据库系统支持的功能非常多而且复杂,数据没有及时落盘就可能造成数据丢失;

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

  • 除了文中列出的数据丢失事故,还有哪些数据库或者云服务商丢失过数据?
  • Redis 的 RDB 和 AOF 机制什么时候会将数据落盘?
  • 数据成功写入数据库究竟应该如何定义?

数据错误循环冗余检查是什么意思_数据库为什么会丢失数据相关推荐

  1. 数据错误循环冗余检查是什么意思_为什么数据库会丢失数据?今天我就来跟你掰扯掰扯

    这份分布式一致性算法文档,足够你解决分布式系统 80% 核心问题​zhuanlan.zhihu.com 从远程办公到简历被拒,再到斩获阿里offer,这份PDF功不可没​zhuanlan.zhihu. ...

  2. 数据错误循环冗余检查是什么意思_“DCS系统组态”是什么意思?其步骤方法又有哪些?...

    "DCS系统组态"是什么意思? DCS组态通俗来讲就是就是控制回路程序. 控制回路通常是针对模拟量的控制来说,一个控制器根据一个输入量,按照一定的规则和算法来决定一个输出量,这样, ...

  3. java安装报错循环冗余检查_SQLSERVER2012备份日志报错:”读取失败: 23(数据错误(循环冗余检查)。)”...

    SQLSERVER2012备份日志报错:"读取失败: 23(数据错误(循环冗余检查).)" 问题: SQLSERVER2012数据库,8月6日的LOG自动备份出现问题,之前备份一直 ...

  4. 移动磁盘显示无法访问数据错误(循环冗余检查)的文件恢复方法

    数据错误(循环冗余检查)说明这个盘的文件系统结构损坏了.在平时如果数据不重要,那么可以直接格式化就能用了.但是有的时候里面的数据很重要,那么就必须先恢复出数据再格式化.具体恢复方法可以看正文了解(不格 ...

  5. G盘数据错误循环冗余检查的资料找到方案

    移动磁盘打不开数据错误循环冗余检查,是因为这个I盘的文件系统内部结构损坏导致的.要恢复里面的数据就必须要注意,这个盘不能格式化,否则数据会进一步损坏.具体的恢复方法看正文 工具/软件:AuroraDa ...

  6. 移动硬盘数据错误循环冗余检查要如何寻回文件

    数据错误循环冗余检查说明这个盘的文件系统结构损坏了.在平时如果数据不重要,那么可以直接格式化就能用了.但是有的时候里面的数据很重要,那么就必须先恢复出数据再格式化.具体恢复方法可以看正文了解(不格式化 ...

  7. oracle数据错误循环冗余检查,oracle数据库坏块修复 oracle数据库数据错误(循环冗余检查)...

    前一段在某客户的系统中,就遇到了硬盘故障导致的数据库问题,仅仅是一个扇区损坏,碰巧位于数据文件上,就导致了如下错误: Mon Jun 13 09:14:10 2011 Errors in file f ...

  8. mysql数据库插入数据语法_数据库请求:插入数据(INSERT)

    MySQL中, INSERT 语句用来向数据表中插入数据.可以一次性插入一条或多条数据. 语法: SQL中通过 INSERT INTO 命令向数据表中插入数据.下面是通用语法: INSERT INTO ...

  9. mysql批量删除数据库_数据库实现批量删除数据的操作方法(代码实例)

    本篇文章就给大家介绍数据库实现批量删除数据的操作方法.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助.package com.mescs.baseinfo.utils; import ...

最新文章

  1. FPGA加载bit文件可以工作,加载mcs不能工作的原因
  2. 大战设计模式【16】—— 桥接模式
  3. jstack命令案例分析:对wait的线程没有调用notify()导致程序无法停止
  4. 【Java学习笔记五】Java异常处理
  5. linux c计算两个int相除求百分比的实现
  6. workbench提示工作负载高度不平衡_功率因数负载组
  7. oracle insert 触发器无效_分享一个超实用的Zabbix监控Oracle用户无效对象手册
  8. uniac是哪一代计算机的代表,Saint-Uniac
  9. ASP.NET Google Maps Javascript API V3 实战基础篇一检测用户位置
  10. java 链表反转_面试必备 | 不可不会的反转链表
  11. Maven—Eclipse如何创建Maven项目
  12. 这4款适合原型图的软件,产品经理都说好
  13. p6spy的使用和配置
  14. 公司、办公司内如何限制上外网因特网、只能连内网局域网 - 注册表工具软件、批处理办法 - 注册表转换成批处理BAT,批处理如何修改注册表
  15. access是用来干什么的_access是干什么用的
  16. 雷电网络 微支付通道
  17. excel使用教程_汉字资料如何进行数据分析?Excel中医学汉字资料转化为数字资料视频教程——If/Iserror/Find函数的结合使用...
  18. 微信小程序 java四六级英语学习助手系统app
  19. 短视频怎么获得高流量?简单小技巧,让你的短视频被更多人看到
  20. 建模simulink - xpc函数参数处理

热门文章

  1. 江西应用技术职业学院宿舍计算机,江西应用技术职业学院宿舍条件,宿舍几人间环境好不好(图片)...
  2. 人民日报:在线教育首先要教育“在线”
  3. 阴阳师2017 7服务器维护,阴阳师6月16日服务器维护更新内容公告
  4. SpringCloud源码探析(三)-Nacos集群搭建与配置管理
  5. 高级软件工程作业2-1
  6. DEseq2和edgeR的安装问题记录
  7. speeding up your web site 前端性能优化规则(二)
  8. 海康威视连接阿里云视频监控并sdk开发
  9. Python处理图像
  10. 再谈云原生时代的系统软件,创造一个开放、无锁定、低成本的技术体系