搜尋
首頁運維linux運維從 lsof 開始,深入理解 Linux 虛擬檔案系統


背景

有有時會出現這樣的情況,磁碟空間顯示已經被佔滿,但是在檢視磁碟的具體檔案佔用情況時,發現磁碟仍有很大的空餘空間。
1.執行<span style="font-size: 15px;">df</span>#指令查看磁碟使用情況,發現磁碟已經滿了。
-bash-4.2$ df -ThFilesystem     Type      Size  Used Avail Use% Mounted on/dev/vda1      ext4       30G    30G 0         100% /devtmpfs       devtmpfs  489M     0  489M   0% /devtmpfs          tmpfs     497M     0  497M   0% /dev/shmtmpfs          tmpfs     497M   50M  447M  11% /runtmpfs          tmpfs     497M     0  497M   0% /sys/fs/cgroup


2.執行du 指令查看各個目錄的磁碟佔用情況,把各個目錄檔案的大小相加,發現並沒有佔滿磁碟,有10多G空間莫名失蹤。


-bash-4.2$ du -h --max-depth=1 /home16M    /home/logs11G    /home/serverdog11G    /home


#
3.为何会出现这样的情况呢?
因为虽然文件已被删除,但是一些进程仍然打开这些文件,因此其占用的磁盘空间并没有被释放。执行<span style="font-size: 15px;">lsof</span> 命令显示打开已删除的文件。将有问题的进程重启(或,清空),磁盘空间就会得到释放。
-bash-4.2# lsof | grep deletemysqld     2470         mysql    4u      REG              253,1           0     523577 /var/tmp/ibfTeQFn (deleted)mysqld     2470         mysql    5u      REG              253,1           0     523579 /var/tmp/ibaHcIdW (deleted)mysqld     2470         mysql    6u      REG              253,1           0     523581 /var/tmp/ibLjiALu (deleted)mysqld     2470         mysql    7u      REG              253,1           0     523585 /var/tmp/ibCFnzTB (deleted)mysqld     2470         mysql   11u      REG              253,1           0     523587 /var/tmp/ibCjuqva (deleted)

那么,Linux 的文件系统,到底为什么这么设计呢?要了解这些,就要先弄清楚并不容易,下面将从一些基本概念入手,一步步将这些梳理清楚:
  • 什么是虚拟文件系统(VFS:virtual filesystem)?

  • 什么是通用文件模型?

    • 超级块对象(superblock object)

    • 索引节点对象(inode object)

    • 文件对象(file object)

    • 目录项对象(dentry object)

    • 文件的概念

  • 文件的表达

    • 内存表达

    • 磁盘表达

  • 目录树的构建

    • 軟體連結vs 硬連結

  • #檔& 磁碟管理

    • 索引節點狀態

  • 檔& 行程管理

    • 作業:

      ##開啟&刪除

虛擬檔案系統(virtual filesystem)
下圖顯示了Linux 作業系統中負責檔案管理的基本元件。上半區域為使用者模式,下半區域為核心模式。應用程式使用標準庫libc來存取文件,庫將請求映射到系統調用,以便進入內核模式。

從 lsof 開始,深入理解 Linux 虛擬檔案系統

#######
所有與檔案相關的操作的入口都是虛擬檔案系統(VFS),而非特定的額檔案系統(如Ext3、ReiserFS和NFS)。 VFS 提供了系統函式庫和特定檔案系統之間的介面。因此,VFS 不僅充當抽象層,而且實際上它提供了一個檔案系統的基本實現,可以由不同的實作來使用和擴展。因此,要了解檔案系統是如何運作的,就要先了解VFS 。

通用檔案模型

VFS 的主要想法在於引入了一個通用檔案模型(common file model)。通用檔案模型由以下物件類型組成:

超級區塊物件(superblock object)

記憶體:檔案系統安裝時創建,存放檔案系統的相關資訊
磁碟:對應於存放在磁碟上的檔案系統控制區塊(filesystem control block)

索引節點物件( inode object)

##記憶體:存取時創建,存放關於具體檔案的一般資訊(

inode 結構磁碟:對應於存放在磁碟上的檔案控制區塊(file control block)
每個索引節點物件都有索引節點號,唯一標識檔案系統的檔案

檔案物件(file object)

#記憶體:開啟檔案時創建,存放開啟檔案與行程之間進行互動的有關資訊(file 結構
開啟檔案訊息,僅當進程存取檔案期間存在於內核記憶體中。

目錄項目物件(dentry object)

#記憶體:目錄項目一旦被讀入內存,VFS就會將其轉換成dentry 結構的目錄項目物件
磁碟:特定檔案系統以特定的方式儲存在磁碟上
存放目錄項目(即,檔案名稱)與對應檔案進行連結的有關資訊

目錄樹

綜合來說,Linux 的根檔案系統(system's root filessystem) 是核心啟動mount的第一個文件系統。核心程式碼映像檔保存在根檔案系統中,而係統引導啟動程式會在根檔案系統掛載之後,從中把一些基本的初始化腳本和服務等載入到記憶體中去運行(檔案系統和核心是完全獨立的兩個部分)。其他檔案系統,則後續透過腳本或命令作為子檔案系統安裝在已安裝檔案系統的目錄上,最終形成整個目錄樹。

start_kernel   vfs_caches_init     mnt_init       init_rootfs     // 注册rootfs文件系统      init_mount_tree // 挂载rootfs文件系统   …   rest_init   kernel_thread(kernel_init, NULL, CLONE_FS);

就单个文件系统而言,在文件系统安装时,创建超级块对象;沿树查找文件时,总是首先从初识目录的中查找匹配的目录项,以便获取相应的索引节点,然后读取索引节点的目录文件,转化为dentry对象,再检查匹配的目录项,反复执行以上过程,直至找到对应的文件的索引节点,并创建索引节点对象。

软链接 vs 硬链接

软链接是一个普通的文件,其中存放的是另外一个文件的路径名。硬链接则指向同一个索引节点,硬链接数记录在索引节点对象的 i_nlink 字段。当<span style="font-size: 15px;color: rgb(68, 68, 68);">i_nlink</span>字段为零时,说明没有硬链接指向该文件。

文件 & 进程管理

下图是一个简单示例,说明进程是怎样与文件进行交互。三个不同进程打开同一个文件,每个进程都有自己的文件对象,其中两个进程使用同一个硬链接(每个硬链接对应一个目录对象),两个目录项对象都指向同一个 索引节点对象。

從 lsof 開始,深入理解 Linux 虛擬檔案系統

索引节点的数据又由两部分组成:内存数据和磁盘数据。Linux 使用 Write back 作为索引节点的数据一致性策略。对于索引节点的数据,当文件被打开时,才会加载索引节点到内存;当不再被进程使用,则从内存踢出;如果中间有更新,则需要把数据写回磁盘。
*  "in_use" - valid inode, i_count > 0, i_nlink > 0*  "dirty"  - as "in_use" but also dirty*  "unused" - valid inode, i_count = 0

索引節點是否仍在使用,是透過 <span style="font-size: 15px;">open()</span> 和 <span style="font-size: 15px;">close ()</span> 作業建立和銷毀檔案對象,檔案物件透過索引節點提供的 <span style="font-size: 15px;">iget</span> 和  <span style="font-size: 15px;">#iput</span>  更新索引節點的i_count字段,以完成使用計數。 open 操作使得 i_count 加一, close 操作使得 i_count 減一。在 close 操作時判斷索引節點是否釋放,如果 i_count = 0,則表示不再有進程引用,將會從記憶體釋放。

檔案& 磁碟管理

檔案與磁碟管理連結最緊密的操作,莫過於<span style="font-size: 15px;">touch </span><span style="font-size: 15px;">rm</span>操作,而特別以後者最為關鍵。透過strace(或 dtruss),查看 rm 的實際的系統呼叫

#
# dtruss rm tmp...geteuid(0x0, 0x0, 0x0)         = 0 0ioctl(0x0, 0x4004667A, 0x7FFEE06F09C4)         = 0 0lstat64("tmp\0", 0x7FFEE06F0968, 0x0)         = 0 0access("tmp\0", 0x2, 0x0)         = 0 0unlink("tmp\0", 0x0, 0x0)         = 0 0

可以发现 rm 实际是通过 unlink 完成的。unlink代表删除目录项,以及减少其索引节点的计数。由通用文件模型可知,父目录本身同样是一个文件,也就意味着目录项是其文件数据的一部分。删除目录项等价于从父目录的文件中删除数据,也就意味着首先要打开父目录的文件。那么,删除操作即可理解为:

  1. 删除命令(一个进程)使用 open 操作获得父目录文件对象

  2. 通过 <span style="font-size: 15px;color: rgb(68, 68, 68);">iget</span> 增加 目录文件的索引节点对象计数

  3. 读取目录文件数据

  • 将目录文件数据转化为目录项对象

  • 由于目录项包含文件的索引节点,类似的,需要通过 iget 增加文件的索引节点对象计数

  • 删除目录的目录项

  • 减少文件索引节点对象的硬链接计数i_nlink

  • 通过 <span style="font-size: 15px;color: rgb(68, 68, 68);">iput</span> 结束对文件索引节点对象的操作,使用计数 i_count 减一

    • 判断i_count是否为零,如果为零,则释放内存

    • 然后,判断i_nlink是否为零,如果为零,则释放磁盘空间

  • 通过 iput 结束对目录索引节点对象的操作。

  • 總結

    回頭來看遇到的問題,其實可以從兩個角度來理解:

    索引與資料

    檔案系統與檔案、磁碟管理與檔案、行程管理與文件,最核心的都是檔案的索引,而不是檔案的資料。把資料和索引分開是理解檔案系統的關鍵。


    從 lsof 開始,深入理解 Linux 虛擬檔案系統

    快取策略

    由於作業系統使用Write back的策略,意味著只有先釋放內存,才有可能釋放磁碟。

    Why lsof ?

    從上面的模型可以很清楚的理解,因為目錄已經沒有索引到文件了,但是打開文件還有索引到文件,所以不能立刻釋放磁碟空間。
    為什麼 lsof 可以找到已刪除未釋放的檔案?
    lsof,顧名思義:list open files,該命令的原則就是查找開啟檔案的列表,因此可以找到已刪除未釋放的檔案。
#

以上是從 lsof 開始,深入理解 Linux 虛擬檔案系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:Linux中文社区。如有侵權,請聯絡admin@php.cn刪除
Linux中的維護模式:何時以及為什麼使用它Linux中的維護模式:何時以及為什麼使用它Apr 25, 2025 am 12:15 AM

使用Linux維護模式的時機和原因:1)系統啟動問題時,2)進行重大系統更新或升級時,3)執行文件系統維護時。維護模式提供安全、控制的環境,確保操作的安全性和效率,減少對用戶的影響,並增強系統的安全性。

Linux:基本命令和操作Linux:基本命令和操作Apr 24, 2025 am 12:20 AM

Linux中不可或缺的命令包括:1.ls:列出目錄內容;2.cd:改變工作目錄;3.mkdir:創建新目錄;4.rm:刪除文件或目錄;5.cp:複製文件或目錄;6.mv:移動或重命名文件或目錄。這些命令通過與內核交互執行操作,幫助用戶高效管理文件和系統。

Linux操作:管理文件,目錄和權限Linux操作:管理文件,目錄和權限Apr 23, 2025 am 12:19 AM

在Linux中,文件和目錄管理使用ls、cd、mkdir、rm、cp、mv命令,權限管理使用chmod、chown、chgrp命令。 1.文件和目錄管理命令如ls-l列出詳細信息,mkdir-p遞歸創建目錄。 2.權限管理命令如chmod755file設置文件權限,chownuserfile改變文件所有者,chgrpgroupfile改變文件所屬組。這些命令基於文件系統結構和用戶、組系統,通過系統調用和元數據實現操作和控制。

Linux中的維護模式是什麼?解釋了Linux中的維護模式是什麼?解釋了Apr 22, 2025 am 12:06 AM

MaintenancemodeInuxisAspecialBootenvironmentforforcalsystemmaintenancetasks.itallowsadMinistratorStoperFormTaskSlikerSettingPassingPassingPasswords,RepairingFilesystems,andRecoveringFrombootFailuresFailuresFailuresInamInimAlenimalenimalenrenmentrent.ToEnterMainterMainterMaintErmaintErmaintEncemememodeBoode,Interlecttheboo

Linux:深入研究其基本部分Linux:深入研究其基本部分Apr 21, 2025 am 12:03 AM

Linux的核心組件包括內核、文件系統、Shell、用戶空間與內核空間、設備驅動程序以及性能優化和最佳實踐。 1)內核是系統的核心,管理硬件、內存和進程。 2)文件系統組織數據,支持多種類型如ext4、Btrfs和XFS。 3)Shell是用戶與系統交互的命令中心,支持腳本編寫。 4)用戶空間與內核空間分離,確保系統穩定性。 5)設備驅動程序連接硬件與操作系統。 6)性能優化包括調整系統配置和遵循最佳實踐。

Linux體系結構:揭示5個基本組件Linux體系結構:揭示5個基本組件Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

Linux操作:利用維護模式Linux操作:利用維護模式Apr 19, 2025 am 12:08 AM

Linux的維護模式可以通過GRUB菜單進入,具體步驟為:1)在GRUB菜單中選擇內核並按'e'編輯,2)在'linux'行末添加'single'或'1',3)按Ctrl X啟動。維護模式提供了一個安全環境,適用於系統修復、重置密碼和系統升級等任務。

Linux:如何進入恢復模式(和維護)Linux:如何進入恢復模式(和維護)Apr 18, 2025 am 12:05 AM

進入Linux恢復模式的步驟是:1.重啟系統並按特定鍵進入GRUB菜單;2.選擇帶有(recoverymode)的選項;3.在恢復模式菜單中選擇操作,如fsck或root。恢復模式允許你以單用戶模式啟動系統,進行文件系統檢查和修復、編輯配置文件等操作,幫助解決系統問題。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境