linux 2行数据为一条记录 该如何操作这一条记录_Linux 日志文件系统原来是这样工作的...

d5ccd3dd9a6235ff074004814203f2ea.png

文件系统要解决的一个关键问题是怎样防止掉电或系统崩溃造成数据损坏,在此类意外事件中,导致文件系统损坏的根本原因在于写文件不是原子操作,因为写文件涉及的不仅仅是用户数据,还涉及元数据(metadata)包括 Superblock、inode bitmap、inode、data block bitmap等,所以写操作无法一步完成,如果其中任何一个步骤被打断,就会造成数据的不一致或损坏。

举一个简化的例子,我们对一个文件进行写操作,要涉及以下步骤:

  1. 从data block bitmap中分配一个数据块;

  2. 在inode中添加指向数据块的指针;

  3. 把用户数据写入数据块。

  • 如果步骤2完成了,3未完成,结果是数据损坏,因为该文件认为数据块是自己的,但里面的数据其实是垃圾;

  • 如果步骤2完成了,1未完成,结果是元数据不一致,因为该文件已经把数据块据为己有,然而文件系统却还认为该数据块未分配、随后又可能会把该数据块分配给别的文件、造成数据覆盖;

  • 如果步骤1完成了、2未完成,结果就是文件系统分配了一个数据块,但是没有任何文件用到这个数据块,造成空间浪费;

  • 如果步骤3完成了,2未完成,结果就是用户数据写入了硬盘数据块中,但白写了,因为文件不知道这个数据块是自己的。

日志文件系统(Journal File System)就是为解决上述问题而诞生的。

它的原理是在进行写操作之前,把即将进行的各个步骤(称为transaction)事先记录下来,保存在文件系统上单独开辟的一块空间上,这就是所谓的日志(journal),也被称为write-ahead logging,日志保存成功之后才进行真正的写操作、把文件系统的元数据和用户数据写进硬盘(称为checkpoint),这样万一写操作的过程中掉电,下次挂载文件系统之前把保存好的日志重新执行一遍就行了(术语叫做replay),避免了前述的数据损坏场景。

有人问如果保存日志的过程中掉电怎么办?最初始的想法是把一条日志的数据一次性写入硬盘,相当于一个原子操作,然而这并不可行,因为硬盘通常以512字节为单位进行操作,日志数据一超过512字节就不可能一次性写入了。所以实际上是这么做的:给每一条日志设置一个结束符,只有在日志写入成功之后才写结束符,如果一条日志没有对应的结束符就会被视为无效日志,直接丢弃,这样就保证了日志里的数据是完整的。

一条日志在它对应的写操作完成之后就没用了,占用的硬盘空间就可以释放。保存日志的硬盘空间大小是有限的,被循环使用,所以日志也被称为circular log。

至此可以总结一下日志文件系统的工作步骤了:

  1. Journal write : 把transaction写入日志中;

  2. Journal commit : 在一条日志保存好之后,写入结束符;

  3. Checkpoint : 进行真正的写操作,把元数据(metadata)和用户数据(user data)写入文件系统;

  4. Free : 回收日志占用的硬盘空间。

以上方式把用户数据(user data)也记录在日志中,称为Data Journaling,Linux EXT3文件系统就支持这种方式,这种方式存在效率问题:

就是每一个写操作涉及的元数据(metadata)和用户数据(user data)实际上都要在硬盘上写两次,一次写在日志里,一次写在文件系统上。元数据倒也罢了,用户数据通常比较大,拷贝几个GB的电影文件也要乘以2实在是降低了效率。

一个更高效的方式是Metadata Journaling,不把用户数据(user data)记录在日志中,它防止数据损坏的方法是先写入用户数据(user data)、再写日志,即在上述”Journal write”之前先写用户数据,这样就保证了只要日志是有效的,那么它对应的用户数据也是有效的,一旦发生掉电故障,最坏的结果也就是最后一条日志没记完,那么对应的用户数据也会丢,效果与Data Journaling丢弃日志一样,重要的是文件系统的一致性和完整性是有保证的。

Metadata Journaling又叫Ordered Journaling,大多数文件系统都采用这种方式。像Linux EXT3文件系统也是可以选择Data Journaling还是Ordered Journaling的。

参考资料:
Crash Consistency: FSCK and Journaling

来源:http://linuxperf.com/?p=153

提高软件的可靠性和效率,是每个 IT 人的使命

GOPS 2019 · 深圳站,4.12-13,不要错过软件工程的第三次革命

7e5239acb0019a87acb0180795084afa.png

0059bd728a907716f2f5da7a3d11c819.png

点击,访问大会官网

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

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

相关文章

[vue] v-for循环中key有什么作用?

[vue] v-for循环中key有什么作用? 四个字: 性能优化,简述: 让vue在更新数据的时候可以更有针对性的个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

JMeter - 如何创建可重用和模块化测试脚本

概述: 我的应用程序几乎没有业务关键流程,我们可以从中提出不同的业务工作流程。当我试图在JMeter中提出性能测试脚本时,我需要找到一些方法来创建可重用/模块化的测试脚本。这样我就可以创建不同的工作流程。 对于Ex: 让我们考虑…

请求支付宝渠道报错:40006,Insufficient Permissions,ISV权限不足

错误描述: 申请的是支付宝2.0产品(如何区分支付宝产品是1.0还是2.0),请求支付宝渠道时,报错: {"code":"40006","msg":"Insufficient Permissions","sub_code…

dll放在unity哪个文件夹下_unity中调用dll文件总结

unity中调用dll文件总结根据收集的资料,对unity中调用dll文件进行总结,目前常用的两种,在给出vs中封装dll文件的步骤。一、调用c#中的dll文件1.1封装dll文件首先新建一个项目然后创建一个类库,例如命名为Csharpusing System;using…

[vue] watch和计算属性有什么区别?

[vue] watch和计算属性有什么区别? 一个是侦听属性,一个是计算属性 2.一个是为了应对复杂的逻辑计算,一个是对数据的变化作出反应 3.一个是只有当缓存改变时才执行,一个是只要从新渲染就会执行 4.一个有缓存,一个没有…

如何将阿里云的数据库备份RDS文件在本地恢复

1.首先把RDS文件下载到本地,我的备份文件3.5G(下载时间6分钟); 压缩包: hins2448103_data_20180127044633.tar.gz 2.解压下载的RDS压缩包: tar -xzvf hins2448103_data_20180127044633.tar.gz 解压完是一个一个的数据库文件夹…

idea中lombok的使用

1.安装插件 在File-Setting-Plugins-Browse Repostitories中搜索Lombok Plugin插件安装 安装完成先别急着重启,继续设置,在File-Setting-Build, Execution, Deployment-Compiler-Annotation Processors中点击Enable annotation processors 确定后重启ide…

是隐极电机_资料 | 发电机定子绕组端部动态特性试验详解

一、试验目的大型汽轮发电机运行过程中,定子端部受二倍工频(100Hz)的电磁激振力。如果定子端部的模态接近100Hz,将发生谐振,从而可能因振幅过大而发生结构松动、磨损、绝缘损坏等现象,甚至断裂等故障,严重威胁机组的安…

[vue] 为什么data属性必须声明为返回一个初始数据对应的函数呢?

[vue] 为什么data属性必须声明为返回一个初始数据对应的函数呢? 对象为引用类型,当重用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返…

Mac系统xampp环境下安装redis和phpredis

一、安装redis服务 通过homebrew安装redis sudo brew install redis 安装Homebrew mac下redis简单命令 1.安装命令 brew install redis 2.启动Redis命令 redis-server /usr/local/etc/redis.conf 3.停止redis server服务 redis-cli shutdown 4.退出redis server服务 C…

[导入]在C++ Builder3下实现程序自动运行的方法

文章来源:http://blog.csdn.net/nm/archive/2000/08/10/4403.aspx 转载于:https://www.cnblogs.com/zhaoxiaoyang2/archive/2000/08/10/816562.html

[vue] 说说你对keep-alive的理解是什么?

[vue] 说说你对keep-alive的理解是什么? keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在页面渲染完毕后不会被渲染成一个DOM元素个人简介 我是歌谣,欢迎…

Problem01 不死神兔

题目:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... …

中动态路径加载_GOT段在linux系统中实现代码动态加载的作用和其他段的说明

上一节我们看到,当程序想调用系统函数时,在编译阶段无法确认被调用函数所在的虚拟地址。因此必须有机制让程序在运行过程中,在调用系统API的时候有办法去确定所调用的系统函数对应的入口地址,这就是代码运行时对应动态加载的过程。…

构件化软件生产

前面提到的是个人理想,那个是远景的。近期能够触摸到的就是构件化的软件生产了。先摘抄一句我非常喜欢的话:“软件工厂一定不是源代码拼装起来的,而是目标代码拼装出来的。就像零件生产一样,给你一个螺丝就可以拧上,而…

[vue] 你有写过自定义组件吗?

[vue] 你有写过自定义组件吗? 写过,随便说点组件的引入问题、注册问题、传值问题吧个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

GitLab结合Eclipse的简单使用 - 20190211

需求: 移动端的值班经理视图调用了三个接口,需要在移动段的应用下加上三个接口的路由,分别是: /xxx-mvc/dutyView/getProviderSysDeal /xxx-mvc/dutyView/getSysAlarmData /xxx-mvc/dutyView/getSysStaffInfo package com.xxx.xxx…

单片机shell命令_MCU调试大法:使用串口实现简单shell功能

MCU调试大法:使用串口实现简单shell功能[复制链接]MCU程序调试方法有很多,比如软/硬件仿真、添加数据打印等。像Keil MDK就支持不少单片机的软件仿真,在没有拿到单片机的情况下,就可以先仿真调试部分功能,查看代码逻辑…

Google Desktop 果然

<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />如果是真的&#xff0c;那么果然可怕&#xff0c;还好没有安装&#xff0c;诸位有安装和使用的有没有如下的体验&#xff1f; http://blogs.salon.com/0001561/categories/visual…

[vue] 怎么在vue中使用插件?

[vue] 怎么在vue中使用插件&#xff1f; npm 安装 然后再main.js 引入 最后 vue.use(插件名)个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题