数据库的持久化(durability)
来源:互联网 发布:国家网络应急中心 编辑:程序博客网 时间:2024/05/17 11:59
转自 : NoSQL Fan blog
以前对数据安全性这一部分有一定的了解,不够深刻,这篇文章里面写的很详细。
虽然是针对 redis的持久化的详解,但是前面一部分还是比较通用的。
==============
本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是最大的,于是他写了一篇长文来对Redis的持久化进行了系统性的论述。文章非常长,也很值得一看,NoSQLFan将主要内容简述成本文。
什么是持久化,简单来讲就是将数据放到断电后数据不会丢失的设备中。也就是我们通常理解的硬盘上。
写操作的流程
首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程。
- 客户端向服务端发送写操作(数据在客户端的内存中)
- 数据库服务端接收到写请求的数据(数据在服务端的内存中)
- 服务端调用write(2) 这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)
- 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)
- 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)
故障分析
写操作大致有上面5个流程,下面我们结合上面的5个流程看一下各种级别的故障。
- 当数据库系统故障时,这时候系统内核还是OK的,那么此时只要我们执行完了第3步,那么数据就是安全的,因为后续操作系统会来完成后面几步,保证数据最终会落到磁盘上。
- 当系统断电,这时候上面5项中提到的所有缓存都会失效,并且数据库和操作系统都会停止工作。所以只有当数据在完成第5步后,机器断电才能保证数据不丢失,在上述四步中的数据都会丢失。
通过上面5步的了解,可能我们会希望搞清下面一些问题:
- 数据库多长时间调用一次write(2),将数据写到内核缓冲区
- 内核多长时间会将系统缓冲区中的数据写到磁盘控制器
- 磁盘控制器又在什么时候把缓存中的数据写到物理介质上
对于第一个问题,通常数据库层面会进行全面控制。而对第二个问题,操作系统有其默认的策略,但是我们也可以通过POSIX API提供的fsync系列命令强制操作系统将数据从内核区写到磁盘控制器上。对于第三个问题,好像数据库已经无法触及,但实际上,大多数情况下磁盘缓存是被设置关闭的。或者是只开启为读缓存,也就是写操作不会进行缓存,直接写到磁盘。建议的做法是仅仅当你的磁盘设备有备用电池时才开启写缓存。
数据损坏
所谓数据损坏,就是数据无法恢复,上面我们讲的都是如何保证数据是确实写到磁盘上去,但是写到磁盘上可能并不意味着数据不会损坏。比如我们可能一次写请求会进行两次不同的写操作,当意外发生时,可能会导致一次写操作安全完成,但是另一次还没有进行。如果数据库的数据文件结构组织不合理,可能就会导致数据完全不能恢复的状况出现。
这里通常也有三种策略来组织数据,以防止数据文件损坏到无法恢复的情况:
- 第一种是最粗糙的处理,就是不通过数据的组织形式保证数据的可恢复性。而是通过配置数据同步备份的方式,在数据文件损坏后通过数据备份来进行恢复。实际上MongoDB在不开启journaling日志,通过配置Replica Sets时就是这种情况。
- 另一种是在上面基础上添加一个操作日志,每次操作时记一下操作的行为,这样我们可以通过操作日志来进行数据恢复。因为操作日志是顺序追加的方式写的,所以不会出现操作日志也无法恢复的情况。这也类似于MongoDB开启了journaling日志的情况。
- 更保险的做法是数据库不进行老数据的修改,只是以追加方式去完成写操作,这样数据本身就是一份日志,这样就永远不会出现数据无法恢复的情况了。实际上CouchDB就是此做法的优秀范例。
- 数据库的持久化(durability)
- 数据库事务的处理 (ACID(Atomic/Consistency/Isolation/Durability))
- 关系型数据库管理系统:事务处理Durability(持久性)的实现
- nosql的持久性(Durability)
- spring的持久化数据库访问
- 数据库持久化的深入理解
- 数据库结合Spring的各种持久化
- 分布式内存数据库---Redis的持久化
- Mesos:数据库使用的持久化卷
- SpringSecurity【用户+权限的数据库持久化】
- NoSql数据库之Redis的持久化
- 支持持久化的内存数据库-----Redis
- SqlPersistenceService持久化数据库
- ActiveMQ 数据库持久化
- iOS持久化(数据库)
- SqlPersistenceService持久化数据库
- 数据库持久化框架
- HIBERNATE - 符合Java习惯的关系数据库持久化
- 常用的高级Linux shell命令
- setsockopt设置socket状态
- XCode 4 的调试定位技巧
- 关于GVIM
- linux下获取时间的若干函数(z)
- 数据库的持久化(durability)
- @Html.DropdownList用法
- .NET C#获取当前网页地址
- 递归算法先序遍历二叉树
- ST测试
- Android cts测试命令
- LTE中的SRB--承载
- C#实现100万条数据导入SQL SERVER数据库仅用4秒 (附源码)
- Lambda表达式