Linux内核延迟写机制

Linux内核延迟写机制

最新项目开发的时候,发现在设备上写完文件的时候,突然掉电重启以后,数据会丢失,然后就研究了一下这个问题,是由于Linux内核延迟写机制导致了这样的情况发生。
1. 延迟写(delayed write): 传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行。 当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则 并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时, 再将该缓冲排入到输出队列,然后待其到达队首时,才进行实际的I/O操作。这种输出方式就被称为延迟写。
2. 延迟写减少了磁盘读写次数,但是却降低了文件内容的更新速度,使得欲写到文件中的数据在一段时间内并没有写到磁盘上。当系统发生故障时,这种延迟可能造成文件更新内容的丢失。为了保证磁盘上实际文件系统与缓冲区高速缓存中内容的一致性,UNIX系统提供了sync、fsync和fdatasync三个函数。
1)、sync函数
sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。通常称为update的系统守护进程会周期性地(一般每隔30秒)调用sync函数。这就保证了定期冲洗内核的块缓冲区。命令sync(1)也调用sync函数。
2)、fsync函数
fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。fsync可用于数据库这样的应用程序,这种应用程序需要确保将修改过的块立即写到磁盘上。
3)、fdatasync函数
fdatasync函数类似于fsync,但它只影响文件的数据部分。而除数据外,fsync还会同步更新文件的属性。
对于提供事务支持的数据库,在事务提交时,都要确保事务日志(包含该事务所有的修改操作以及一个提交记录)完全写到硬盘上,才认定事务提交成功并返回给应用层。

在我们的系统中,即busybox文件系统下,如果在写一个文件时,可以通过下面的命令进行同步,及时的把数据写入磁盘中:
# fsync
BusyBox v1.27.1 (2018-06-12 09:43:31 CST) multi-call binary.

Usage: fsync [-d] FILE…

Write files’ buffered blocks to disk

    -d      Avoid syncing metadata

# fsync file
如果使用#sync只是把修改过的缓冲块排入写队列当中,这时候掉电,同样会丢失数据,使用 # fsync file即可以及时写入磁盘,保护数据。

参考文章
【1】http://alinuxer.sinaapp.com/?p=147
【2】https://blog.csdn.net/younger_china/article/details/51127127

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 1 进程的组织 5 1.1 进程相关数据结构 5 1.1.1 进程的基本信息 6 1.1.2 进程状态 10 1.1.3 TASK_RUNNING状态的进程链表 11 1.1.4 进程间关系 12 1.2 Linux的线程——轻量级进程 15 1.3 进程的创建——do_fork()函数详解 19 1.4 执行进程间切换 33 1.4.1 进程切换之前的工作 33 1.4.2 进程切换实务 —— switch_to宏 37 1.4.3 __switch_to函数 39 1.5 fork与vfock系统调用的区别 42 1.6 内核线程 46 1.7 挂起状态进程的组织 49 1.7.1 等待队列头 49 1.7.2 等待队列的操作 50 1.7.3 进程资源限制 55 1.8 系统调用execve() 56 1.8.1 拷贝用户态参数 57 1.8.2 重要的数据结构 61 1.8.3 search_binary_handler函数 66 1.8.4 目标文件的装载和投入运行 69 1.8.5 库函数 92 2 中断控制 94 2.1 中断的分类 94 2.2 中断的硬件环境 95 2.2.1 外部中断请求IRQ 95 2.2.2 中断描述符表 96 2.2.3 中断和异常的硬件处理 97 2.3 中断描述符表 99 2.3.1 中断门、陷阱门及系统门 99 2.3.2 IDT的初步初始化 100 2.4 异常处理 101 2.5 中断处理 106 2.5.1 中断向量 107 2.5.2 IRQ数据结构 108 2.5.3 do_IRQ()函数 113 2.5.4 中断服务例程 115 2.5.5 IRQ线的动态分配 116 2.6 下半部分 117 2.6.1 软中断 118 2.6.2 tasklet 121 2.6.3 工作队列 122 2.7定时器中断 124 2.7.1 时钟与定时器 124 2.7.2 定时器中断相关的数据结构 127 2.7.3 定时器中断的上半部分 129 3 进程调度 138 3.1 进程调度的概念 138 3.2 进程调度的数据结构和优先级 141 3.2.1 进程的优先级 141 3.2.2 数据结构 145 3.3 调度程序所使用的函数 151 3.3.1 scheduler_tick函数 151 3.3.2 try_to_wake_up函数 156 3.3.3 recalc_task_prio函数 160 3.4 schedule()函数 163 3.4.1 直接调用 163 3.4.2 延迟调用 164 3.4.3 进程切换之前所做的工作 168 3.4.4 完成进程切换时所执行的操作 171 3.4.5 进程切换后所执行的操作 173 3.5 多处理器运行队列的平衡 175 3.5.1 调度域 176 3.5.2 rebalance_tick()函数 178 3.5.3 load_balance()函数 180 3.5.4 move_tasks()函数 183 3.6 进程退出 187 3.6.1 进程终止 187 3.6.2 进程删除 189 4 进程的并发性体现 191 4.1 内核抢占 193 4.1.1 内核抢占概念 193 4.1.2 同步技术总揽 196 4.2 每CPU变量 197 4.3 原子操作 199 4.4 优化屏障和内存壁垒 203 4.4.1 优化屏障 204 4.4.2 内存壁垒 204 4.5 自旋锁 206 4.6 读自旋锁 211 4.6.1 为读获取和释放一个锁 213 4.6.2 为获取或释放一个锁 214 4.7 顺序锁 215 4.8 RCU机制 217 4.9 信号量 219 4.9.1 获取和释放信号量 221 4.9.2 读/信号量 224 4.9.3 补充信号量 225 4.10 禁止本地中断 226 4.10.1 禁止本地中断 227 4.10.2 禁止下半部(可延迟函数) 229 4.11 一些避免竞争条件的实例 231 4.11.1 引用计数器 231 4.11.2 大内核锁 231 4.11.3 内存描述符读/信号量 232 4.11.4 slab高速缓存链表的信号量 233 4.11.5 索引节点的信号量 233 4.12 内核同步与互斥的总结 233
Linux内核中的RCU(Read-Copy-Update)机制是一种用于实现高效并发访问共享数据的技术。在RCU机制中,读操作不会被阻塞,而操作则通过延迟更新来避免对读操作的影响。然而,当某些情况下读操作被长时间阻塞时,就会发生RCU stall。下面是Linux内核中RCU stall的机制的详细介绍: 1. RCU的快速路径:在正常情况下,RCU的快速路径允许读操作不受操作的影响,从而实现高效并发访问。当一个线程进行读操作时,它会在读取共享数据之前增加一个引用计数,并在读操作完成后减少引用计数。这样,即使有其他线程正在进行操作,读操作仍然可以顺利进行。 2. 操作的延迟更新:当一个线程进行操作时,它会创建一个新的数据版本,并将更新后的数据写入新版本中。然后,它将原来的数据版本标记为废弃,并等待所有正在进行读操作的线程完成后才会释放废弃版本的内存资源。这种延迟更新的方式可以避免对读操作的影响。 3. RCU stall的触发:RCU stall通常在以下情况下触发: - 长时间的操作:当一个操作需要很长时间才能完成时,所有正在进行读操作的线程需要等待操作完成才能继续进行读操作,这可能导致RCU stall的发生。 - 频繁的操作:如果操作频繁地竞争同一资源,如数据结构或共享变量,读操作的等待时间会增加,可能导致RCU stall。 - 更新操作的阻塞:当一个更新操作阻塞了RCU的快速路径,使得其他读操作无法顺利进行时,也会引发RCU stall。 4. RCU stall的处理:当RCU stall发生时,内核会通过一些机制来尝试解决或减轻RCU stall的影响,包括: - RCU回调函数处理机制:当RCU stall发生时,内核会通过回调函数处理机制延迟执行一些需要被延迟的任务,如内存回收等,以减轻RCU stall的影响。 - RCU GP(Grace Period)的处理:GP是一个时间间隔,在这个时间间隔内,所有已经开始进行读操作的线程都可以继续执行,而不会被阻塞。内核会通过GP来确保读操作的一致性,并在GP结束后释放废弃版本的内存资源。 - RCU stall检测机制内核会定期检测是否发生了长时间的阻塞,如果检测到长时间的阻塞,会尝试唤醒被阻塞的CPU,以解决RCU stall的问题。 通过以上机制Linux内核的RCU机制可以在大多数情况下实现高效并发访问共享数据。然而,在某些特殊情况下,如长时间的操作或频繁的操作竞争,可能会引发RCU stall。内核通过回调函数处理、GP处理和RCU stall检测等机制来处理和减轻RCU stall的影响,以保证系统的性能和响应时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值