Crash Consistency on File Systems: 文件系统一致性保证 (1) Journaling File System

news2025/1/12 6:01:17

文件系统是操作系统中管理用户数据的重要模块。其中一项重要的任务就是确保用户数据的在系统突然崩溃之后,系统能够恢复出完整、一致的用户数据。本文将会分析两种流行的文件系统,Journaling File System 和 Log-structured File System是如何确保数据的一致性。本文主要参考了OSTEP的42和43章节,强烈推荐任何一位学习操作系统的同学去阅读这本教材。

什么是一致性问题

我们知道,内存的速度是远远高于磁盘,因此文件系统为了加速文件的读取,往往会使用内存页缓存一些磁盘的数据以加快文件的读写速度,而文件系统也会在适当的时机,再将脏页回写到磁盘中(即writeback操作)。这种回写操作,一般会涉及到元数据的更改(例如on-disk inode)以及文件数据的更改。一般而言,为了实现高性能,元数据的更改和文件数据的更改往往不是同步的,而是异步的。因此,如果系统突然宕机,由于它们元数据和文件数据回写的异步性,可能会引起一致性问题。

一致性问题种类

我们考虑一个简单的文件系统的on-disk结构,这个文件系统包括一个inode bitmap (8 bits,每一个bit表示一个inode),一个data bitmap (8 bits,每一个bit表示一个data block),一个inodes区域 (存放inode的磁盘区域,一共8个),一个data blocks 区域 (保存文件数据的磁盘区域,一共8个)。以及一个场景: 一个进程写入一个data block到一个空文件。

如下图所示,这个操作会首先在磁盘的free space中分配一个inode (即下图的I[v1],对应inode号是2,对应的inode bitmap也会被标记状态为已分配),然后写入一个data block (即下图的Da,对应data blocks区域的地址是4,对应的data bitmap也会被标记状态为已分配)。当文件读数据的时候,我们是通过inode找到对应的data block,所以inode需要保存对应的data block的地址建立inode-data映射,我们需要把Da的地址4写入到I[v1],请注意这个隐含的关系。因为这是这个文件的第一次更新inode,所以我们将这次更新称为v1更新,所以inode用I[v1]表示。

在这里插入图片描述
如下图所示,如果我们继续往这个文件写入一个data block的数据,那么data blocks区域肯定要更新(即Db,对应的data blocks地址是5),对应的data bitmap也要做第二次更新(即B[v2]),inode也需要记录新写入的data block的地址(即Db),因此inode也需要更新,得到I[v2]

在这里插入图片描述
如前面介绍,为了提高性能,对应inode bitmap、data bitmap、inodes、data blocks的更新都可能是异步的,文件系统无法确保它们都同时写入。而崩溃在任何时刻都可能出现,因此可能文件系统可能会出现一致性问题。我们用第二次写入作为例子,分析有哪些一致性问题:

  • 只有data block (Db) 写到磁盘中:此时虽然data block已经写入磁盘,但是inode没有更新,因此这个inode无法索引到这个data block建立inode-data映射。同时,data bitmap也没有将这个data block标记为已分配,所以这种情况下相当于这次写入操作没有发生过,文件系统可以顺利恢复一致性
  • 只有inode (I[v2]) 写到磁盘中:此时已经建立了inode-data映射,所以inode会认为它是包含data blocks区域地址为5的data block(即崩溃前的Db),但是实际上,Db没有写入到磁盘。如果不作处理,inode会从地址为5的位置读取到一个无法得知内容的data block。同时由于这个地址为5的data block处于未分配的状态(data bitmap崩溃前也没有写入磁盘),如果这个data block分配给了另外一个inode,导致两个inode共享一个data block,其中一方的更改会影响另外一个inode,从而导致一致性问题
  • 只有data bitmap (B[v2]) 写到磁盘中:这种情况下,文件系统在崩溃恢复后,会认为data blocks区域地址为5的data block是已分配的,但是实际上没有建立inode-data映射,所以inode是没有保存这个data block的,也无法索引。如果这个文件被删除,根据inode的信息也无法顺利释放地址为5的data block,从而导致了空间泄露(space leak),即地址为5的data block永远都无法被文件系统使用了。
  • inode (I[v2]) 和data bitmap (B[v2]) 写到磁盘中,但data block (Db) 没有:这种情况,我们称为metadata consistent,即文件系统从metadata的角度看是一致的,因为文件系统标记了Db已经分配,而且也可以从inode索引得到,索引页不存在两个文件共享一个data block的问题。但是唯一的问题是,inode可能会从Db中读到无法确定的数据,即虽然实现了文件系统的一致性,但是无法实现文件数据的一致性。
  • inode (I[v2]) 和data block (Db) 写到磁盘中,但data bitmap (B[v2]) 没有 :这种情况是不一致的,因为inode任务它成功分配了data block,但是bitmap却认为没有,所以是metadata inconsistent
  • data bitmap (B[v2]) 和data block (Db) 写到磁盘中,但inode (I[v2]) 没有:同上,data bitmap和inode的记录不一致,依然是metadata inconsistent。这种情况也会导致空间泄露(space leak)

接下来,我们将会探讨Journaling File System 和 Log-structured File System如何分别解决这些问题。

Journaling File System 日志文件系统

日志文件系统(Journaling File System,或者说JFS) 是一类被广泛使用的解决文件系统一致性的技术。JFS通过journaling去记录一些文件系统操作,然后再回写这些操作到磁盘的策略,实现一致性保证,使用这些技术的包括ext3/ext4,XFS等主流文件系统。Journaling的核心思想是:

在更新磁盘上的数据之前,例如更新bitmap,inode,data之前,我们先将这些操作作为日志(log),先写入到其他位置(往往是磁盘的某个特定大小的区域)。文件系统会不断写日志(log),而这些保存log的区域一般像一个数组一样将log组织起来,每一个数组单元就是一个log,文件系统在更新(write)磁盘的数据之前都会先写入到log中,所以我们也将journalling称为write-ahead log技术。

当系统崩溃时,文件系统恢复时就会检查日志记录,看看崩溃前的一刻哪些操作是完成的(成功写入到磁盘),哪些没有完成,从而可以恢复文件系统的一致性。

我们使用ext3文件系统作为例子,下图是一个ext3文件系统的on-disk结构。它比我们前面讨论的简单文件系统稍微复杂点。这里每一个group相当于前面介绍的简单文件系统的on-disk结构,也是包含了data bitmap,inode bitmap,inodes,data blocks等结构。不同之处就是它在磁盘上多分配了一个journal区域,用于保存文件操作的日志。由于文件系统包括data和metadata操作,所以它们也有相应的journaling的方法,我们分别讨论。

在这里插入图片描述

Data Journaling

我们回到最开始介绍的例子,即需要写入DbB[v2]I[v2]到磁盘的例子。前面我们的操作是让这些三个需要写入磁盘的操作,分别写入到磁盘中。那么现在,我们可以将他们打包在一起写入log (或者说journal),如下图所示。这里TxB~TxE表示一个log entry,箭头表示这个journal区域可能包含多个log entry,目前我们只使用一个log entry。

在这里插入图片描述

TxB~TxE也表示一系列操作的组成的一个事务(transaction)TxB是这个事务的头,包含这些操作需要写入到磁盘的位置信息(例如I[v2]B[v2]Db各自在磁盘的位置,一共三个blocks的地址),以及一个本次事务关联的transaction identifier (TID) 。TxE标识事务的结束位置,也包含和TxB相同的TID。我们写入log的操作称为journal write

如果这个事务被顺利写入到磁盘,那么我们可以就根据TxB记录的磁盘的三个blocks的位置信息,将I[v2]B[v2]Db各自写入到磁盘的位置,我们将这个操作称为checkpointing。如果这三个blocks都成功写入了磁盘,那么我们说这个文件系统被成功checkpointed,用于记录log的journal区域(即上图)也可以被释放,给其他操作使用。

讨论: 对于前面的例子,我们需要写入TxBI[v2]B[v2]DbTxE总共5个blocks。如果让这5个blocks一个个按顺序写入,这显然会影响性能。如果这5个blocks异步写入依然会存在一致性问题,例如TxBB[v2]DbTxE成功写入到磁盘后,系统就马上崩溃,I[v2],还没有写入。因此我们可以使用折衷的办法,异步写入TxBI[v2]B[v2]Db,等它们都成功后,再写入TxE。所以我们可以将journaling分解为3个操作:

  • Journal write:将TxB以及对应的文件操作写入到事务中,然后让它们异步写入,以及等待它们全部完成。
  • Journal Commit:写入TxE,并等待完成。完成后,我们称为这个事务是committed
  • Checkpoint:将事务中的数据,分别各自回写到各自的磁盘位置中。

Recovery恢复: 我们利用上面的三个操作去描述文件系统是如何保证一致性的。

  • 崩溃发生在Journal Commit完成前:那么文件系统可以丢掉之前写入的log。由于磁盘具体位置的bitmap,inodes,data blocks都没变,所以可以确保文件系统一致性。
  • 崩溃发生在Journal Commit后,Checkpoint之前:那么文件系统在启动时候,可以扫描所有已经commited的log,然后针对每一个log记录操作进行replay,即recovery的过程中执行Checkpoint,将log的信息回写到磁盘对应的位置。这种操作也成为redo logging
  • 崩溃发生在Checkpoint完成后:那无所谓,都已经成功回写到磁盘了,文件系统的bitmap、inodes、data blocks也能确保一致性。

Journal是如何保存在磁盘的: 如前面所说,journal区域是磁盘一段特定空间,显然它是空间是有限的,但是我们无法确定有多少写入操作会同时发生,因此文件系统一般会采用circular log去解决这个问题,即记录journal区域中每一个log entry的生成时间,当log entry不够时,则尽快Checkpoint这个log entry,以腾出空间给新的写入操作。所以journal区域需要一个journal super block去管理这些与log entry有关的元数据信息,如下图所示。这里每一个Tx1到Tx5表示都表示一个log entry。所以出了前面介绍的Journal writeJournal CommitCheckpoint操作以外,我们还多了一个free操作以释放log entry。
在这里插入图片描述

Data Journaling的开销: 经过前面的分析,我们已经得到一个完整的data journaling方案,但是这存在一个问题: 每一个data block需要写入磁盘两次 (即double write问题),使用最开始的例子即是Db要先通过Journal write写入到Journal区域,再通过Checkpoint写入到磁盘,会产生大量的开销。而且一般而言,崩溃是一个比较少出现的场景,为了严格的一致性去使用data journaling也不是非常值得的。

Metadata Journaling

回顾一开始对崩溃的场景的分析,如果inode和bitmap的写入磁盘了就可以实现metadata consistent,这可以实现文件系统的一致性。一般而言,file data的写入量会远远比metadata要大(如,写入100个data block,可能只需要更新一个inode block和一个bitmap block)。所以为了解决double write问题,文件系统可以只针对metadata做journal。以确保metadata consistent,如下图所示,Db没有写入到log当中:

在这里插入图片描述

然而,如果在事务完成前之后,Db的磁盘写入还没完成就发生崩溃,那么inode会指向一个不确定数据的data block,因为这个事务已经完成了,文件系统重启的时候会replay这个事务。这种情况下,metadata journaling虽然确保了文件系统的一致性,但是无法确保文件数据的一致性。因此有一些文件系统,如ext3/4,的journal机制会在指定的情况下,会确保data blocks (Db) 先写入到磁盘,再提交metadata journal。所以我们可以将journaling再进一步分解为5个操作:

  • data write:写入数据到磁盘的对应位置,等待它的完成 (也可以不等,看设定的模式)。
  • Journal metadata write:将TxB以及对应的文件metadata操作写入到事务中,然后让它们异步写入,以及等待它们全部完成。
  • Journal Commit:写入TxE,并等待完成。完成后,我们称为这个事务是committed
  • Checkpoint metadata:将事务中的metadata的操作相关数据,分别各自回写到各自的磁盘位置中。
  • free:释放journal区域的log entry。

在ext3/ext4中,这对应三种日志模式:

Journal Mode: 操作的metadata和file data都会写入到日志中然后提交,这是最慢的。
Ordered Mode: 只有metadata操作会写入到日志中,但是确保数据在日志提交前写入到磁盘中
Writeback Mode: 只有metadata操作会写入到日志中,且不确保数据在日志提交前写入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94572.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dataFactory连接mysql详细配置教程

场景:最近项目提出机构用户中其中一个部门下用户人数有20万,加载的时候十分缓慢,本地想重现的一下,这就需要在本地表中生成>20万的数据,搜索了网上的教程写的都是很粗略。 目录 dataFactory连接mysql配置 安装包下…

第二证券|“20cm”涨停!盘中暴涨110%,又有港股暴力拉升

A股商场今日上午窄幅动摇,电子等板块领涨。北向资金半响净买入额到达26.10亿元。 港股商场今日上午动摇也较为温和。不过,仍有个股剧烈动摇。比如浦江世界上午暴升,盘中涨幅一度超过110%。 A股窄幅动摇 电子板块领涨 今日上午A股商场全体体…

STL六大组件之算法

文章目录56、STL六大组件之遍历算法57、STL六大组件之查找算法158、STL六大组件之查找算法259、STL六大组件之统计算法60、STL六大组件之合并算法61、随机数(rand)和随机数种子(srand)的理解62、STL六大组件之随机算法(洗牌算法)6…

javaweb笔记

javaweb数据库jdbcmaven数据库 1.chart定长 2.分组查询:where>聚合函数>having 3.分页查询: select 字段列表 from limit 起始索引, 查询条目数 计算公式: 起始索引(当前页码-1)每页显示的条数 不同数据库分页查询不一样 4.like模糊查…

8种常见python运行错误,看看你中招了没?

人生苦短 我用python 对于刚入门Python的新手同学来说, 在运行代码时总免不了报错。 如何通过报错查找错误代码? 今天给大家总结了一些常见的报错类型, 每种报错都会有标有错误细节和错误行。 大家以后看到了,就更容易找出自…

使用navicat工具生成表的新增字段sql

1、在需要的表右键,设计表 2、点击【添加字段】 3、创建字段及注释,不要点【保存】和CtrlS 4、点击【SQL预览】 5、复制生成的sql语句

iframe 标签

一. 什么是 iframe 1. iframe 是 HTML元素,用于在网页中内嵌另外一个网页. 2. iframe 默认有一个宽高,存在边界. 3. iframe 是一个行内块级元素,可以通过 display 修改. 二. iframe 元素属性 1. src : 指定内联网页的地址 2. frameborder : iframe 默认有个边界,可以设置fram…

深入剖析Linux RCU原理(一)初窥门径

说明: Kernel版本:4.14ARM64处理器,Contex-A53,双核使用工具:Source Insight 3.5, Visio 1. 概述 RCU, Read-Copy-Update,是Linux内核中的一种同步机制。RCU常被描述为读写锁的替代品&#xf…

Openssl 1024bit RSA算法---公私钥获取和处理(一)

1.简介 使用OpenSSL生成公私钥文件,然后再将文件中的信息读出的操作。 由于要对设备升级,需要用到RSA算法对一部分验证信息进行加密. 2.使用OpenSSL获取公私钥 我在window系统尝试安装OpenSSL,但是安装不上,我们可以使用linux…

模式识别 第7、8章 特征的选择和提取

基本概念 问题的提出 特征→ 特征空间: 每一个特征对应特征空间的一个维度 ;特征越多,特征空间的维度越高原则:在保证分类效果的前提下用尽量少的特征来完成分类基本概念 (1)特征形成:由仪器…

如何去除图片雾化?给你推荐图片去雾怎么去除的方法

小伙伴们会不会和我一样喜欢外出爬山呢?为了留住美好记忆,我们会在途中拍照记录。但是山上很经常会有雾气,会容易导致我们拍出来的图片模糊不清。那应该怎么办呢?其实,我们只要对图片进行去雾处理就可以很好解决这个问…

[附源码]Nodejs计算机毕业设计基于的校园疫情防控管理Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置: Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分…

Web(十一)JavaScript知识训练-数学对象

1、Math.ceil(-3.14)的结果是( B)。 A、 -3.14 B、 -3 C、 -4 D、 3.14 2、Math.floor(-3.14)的结果是( C)。 A、 -3.14 B、 -3 C、 -4 D、 3.14 3、Math.round(-3.14)的结果是( B)。 A、 -3.14 B、 -3 C…

Spring Cloud Openfeign微服务接口调用与Hystrix集成实战

关于openfeign 可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务…

dataFactory向mysql批量插入测试数据

目录 第一步:准备阶段:datafactory已连接app_user的表 第二步: 点击原表app_user,其中属性界面properties中配置含义如下: 第三步:根据需要设置插入字段 第四步:设置每个字段的规则后,点击se…

病毒之Worm.Win32.AutoRun

题外话:在被奥密克戎包围的我(两个室友和我,一个低烧、一个咳嗽、就差我了,这属实是真被包围了丫)在和Worm.Win32.AutoRun决一死战… 本次Worm.Win32.AutoRun的来源: windows电脑上重装vscode,然后没有 mingw-get-setu…

浏览器兼容模式如何设置?只需要跟着下面的步骤设置

许多考生在报考教师资格证或者其他的考试报名,会遇到浏览器兼容设置的问题。与其到时急急忙忙来设置浏览器的兼容模式,不如提前设置好,免了后顾之忧。浏览器兼容模式怎么设置?一起来看看关于浏览器兼容模式的含义以及设置方式吧&a…

《Python代码审计》(1)一款超好用的代码扫描工具

1.前言 从本文开始,我将开始介绍Python源代码审计,代码审计是检查源代码中的安全缺陷,检查源代码是否存在安全隐患,或者编码不规范的地方。通常使用自动化工具或者人工审查的方式,自动化工具效率高,但是误…

【浅学Java】Linux系统中的硬连接和软连接

Linux系统中的软连接和硬连接1. 前置知识1.1 文件的存储1.2 inode——索引节点1.3 Linux系统查找文件的过程2. Linux系统中的硬连接2.1 硬连接的实现原理2.2 实现硬连接的指令3. Linux系统中的软连接3.1 软连接的实现原理3.2 实现硬连接的指令4. 软连接和硬连接的区别1. 前置知…

Java 19虚拟线程实战与性能分析

Java 19推出了新特性“虚拟线程”,类似于Go语言中的协程。它是传统线程的不同之处在于,它是一种用户模式(user-mode)的线程。 虚拟线程是由 JDK 而非操作系统提供的线程的轻量级实现: 虚拟线程是没有绑定到特定操作系…