為什麼文件刪除了但磁碟空間沒有釋放?

来源:https://www.cnblogs.com/edisonfish/archive/2023/03/18/17229472.html
-Advertisement-
Play Games

案例現象 這天,監控系統發來一條告警消息,內容說某台伺服器根目錄磁碟占用空間達到閾值,超過百分之八十了 登上伺服器,df -Th 看一下,發現磁碟空間確實不夠用了 進入到根目錄,然後 du -sh * 可以看到,var 目錄下的磁碟空間已經占用了 75G 既然如此,刪除 var 目錄下一些占空間較大 ...


案例現象

這天,監控系統發來一條告警消息,內容說某台伺服器根目錄磁碟占用空間達到閾值,超過百分之八十了

 

登上伺服器,df -Th 看一下,發現磁碟空間確實不夠用了

 

 

 

 

進入到根目錄,然後 du -sh *

 

 

 

可以看到,var 目錄下的磁碟空間已經占用了 75G

 

 

既然如此,刪除 var 目錄下一些占空間較大的數據文件即可

 

 

繼續定位到占用空間較大的是 /var/log 目錄

 

最後排查到 /var/log/nginx/access_log這個文件占了 66G

 

這個文件是 Nginx 產生的訪問日誌文件,從日誌大小來看,一方面沒有做日誌切割,另一方面很久沒有清理這個文件

 

基本能夠判斷是這個文件造成的告警,執行如下刪除操作

 

 刪除完畢,我們再看下系統磁碟空間

 

 

 

咦?根分區空間怎麼還沒有釋放,不是刪除了文件了嗎?

 

案例現象

一般來講,很少出現刪除了文件但磁碟空間不釋放的現象

 

但是如果出現了,就要考慮到以下兩種情況:

  1. 文件被某一進程鎖定了

  2. 有進程一直在向這個文件寫數據

 

為什麼文件被進程占用之後刪除不會釋放磁碟空間呢?

 

我們來學習一下 Linux 的文件存儲結構

 

在 Linux 中,文件存儲在硬碟上,硬碟的最小存儲單位是扇區(Sector),然而扇區只有 512位元組大小,如果每次都讀寫這麼小的單位效率一定很低

 

 

 

 

所以當操作系統從硬碟讀取數據的時候,不會一個個扇區的地去讀取,而是一次性連續讀取多個扇區,即一次性讀取一個”塊“(block)

 

由多個 sector 組成的 block ,是文件存取的最小單位

 

block 常見大小的是 4KB,即連續 8 個 sector 組成一個 block

 

 

 

既然文件數據都存儲在 block 中,那麼我們指定讀取某個文件數據的時候,操作系統就需要知道這個文件存儲在哪個 block 上

 

而文件的數據存放位置信息被存放到了 inode 上,inode 中文名叫索引節點

 

我要打開 1.txt 這個文件並讀取內容,會經過以下步驟

1、系統根據文件名(1.txt)找到對應的 inode 號

2、通過 inode 號獲取到 inode 信息

3、根據 inode 信息找到文件數據所在的 block ,讀出數據

 

 

除了文件的數據存放信息,文件的創建者、文件的大小、文件的屬性等文件的元信息都被存儲到了 inode 上

 

文件元信息包含以下內容(可以通過 stat 命令查看)

  • 文件的位元組數

  • 文件擁有者的 User ID

  • 文件擁有者的 User ID

  • 文件擁有者的 User ID

  • 文件的時間戳

  • 鏈接數,即有多少文件名指向這個inode

  • 數據block的位置

 

inode 跟數據一樣會消耗硬碟空間,所以硬碟格式化的時候,系統自動將硬碟分成2個區域:

  • 一個是數據區,存放文件數據

  • 另一個是 inode 區,存放 inode 所包含的信息,即文件元信息

 

簡單來說在 Linux 下,文件由指針部分(inode)和數據部分(data)組成

 

在瞭解了文件的存儲結構之後,我們來看下對文件執 rm 行刪除操作之後,這兩個部分會發生什麼

 

文件被刪除的時候,文件對應的 inode 就被刪除掉了,而文件的數據部分在 inode 被清除掉之後,就會被覆蓋並寫入新的內容

 

但是如果文件在刪除的時候是被打開的(有一個進程正在使用該文件,文件被進程鎖定或者有進程一直在向這個文件寫數據等)狀態,那麼進程依舊可以讀取該文件,系統就會認為該文件的磁碟空間一直被占用

 

之所以出現刪除 access_log 文件後空間沒有釋放,是因為 nginx 進程還在一直向這個文件寫入內容

 

雖然刪除了 access_log 文件,但是由於 nginx 進程鎖定,文件的 inode 並沒有清除掉,而由於 inode 沒有清除,系統內核就認為文件並未刪除,這才出現空間不釋放的情況

 

解決問題

既然有了定位的思路,我們就來看看是不是有進程一直在向 access_log 文件寫數據

 

我們使用 lsof 命令

 

 

 

可以看到 /var/log/nginx/access_log被進程 nginx 鎖定,而且 nginx 進程一直在往這個文件寫數據,現在文件大小已經 68G 了

 

由此可見,這個文件就是導致系統根目錄空間耗盡的罪魁禍首,而最後一列的 deleted 狀態表示這個文件已經被刪除

 

但由於進程還在一直往裡面寫數據,導致磁碟空間並未釋放

 

  • 方法一

刪除掉日誌文件之後,重啟 nginx 進程或者重啟系統讓操作系統來回收磁碟空間

 

 

 

但是在生產環境下一般不建議重啟服務或者重啟系統

 

萬一齣問題了,這個鍋可背不起

 

 

  • 方法二(推薦)

像這種進程不停對文件寫數據的操作,如果你想要清空磁碟空間,推薦的辦法是線上清空這個文件

 

 

通過這種方法,磁碟空間不僅可以馬上釋放,也可以保證進程能夠一直往文件里寫數據

 

 


感謝閱讀,喜歡作者就動動小手[一鍵三連],這是我寫作最大的動力


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.在自己電腦中找到Viual Studio Installer這樣一個文件,我自己的是在"C:\ProgramData\Microsoft\Windows\Start Menu\Programs"路徑下 若是找不到,也可以下載一個"everything"工具進行搜索,(這個比windows自帶的文 ...
  • #[EF Core] EF Core Code-First 移除外鍵 —— 重寫SQL生成器 使用EF Core時最煩的就是生成的某些 SQL 其實並不是你想要的結果,例如外鍵約束等等。 一個最簡單的例子就是,因為EF Core會根據導航屬性生成外鍵約束等原因,導致很多開發者拋棄了更易維護的Code ...
  • 1、OpenGL有多個標準,如Open ES是為了移動設備,目前通常使用OpenTK.Graphics.OpenGL4對應OpenGL4.x版本,2010年是OpenGL分割領,之前是3版本,之後都是4版本,目前最新4.6,更新頻率不高 2、OpenGL的著色語言GLSL,對應的文件擴展名.vert ...
  • 最近寫了一個demo:demo的github地址 一. 簡單介紹 1. Server端 它是一個WebApi服務,把它當成一個黑盒就行了。 2. MiddleServer端 是重點,它是一個WebApi服務,包含一個GetValues介面和一個Query2介面。 Query2介面是一個簡單的介面。 ...
  • Watchtower 是一個用於自動更新 Docker 容器的工具。它可以監視 Docker Hub 或私有倉庫中的鏡像,併在發現新的鏡像版本時自動更新容器。 ...
  • (文章目錄) 01、首先配置文件地址改了 地址為 ` /etc/NetworkManager/system-connections/網卡名 ` 網卡名可以使用 ip a查看,紅框中就是網卡名 網卡名 ls命令可以看到有以下配置文件 ` es160.nmconnection ` vi編輯 ` [con ...
  • 一、共用記憶體是什麼 在Linux系統中,共用記憶體是一種IPC(進程間通信)方式,它可以讓多個進程在物理記憶體中共用一段記憶體區域。 這種共用記憶體區域被映射到多個進程的虛擬地址空間中,使得多個進程可以直接訪問同一段物理記憶體區域中的數據,從而實現進程間的高速數據交換和通信。 二、共用記憶體的原理 共用記憶體基於 ...
  • 前騰訊工程師,經歷過大廠,也經歷過創業! 我已奔四,但我還在持續學習,持續成長! 我非常樂意把我的經驗和心得分享給你! 我是阿銘,關註我,和我一起成長為技術大牛! ↓↓↓↓↓ 關於DevOps這個概念,可能100個人能給出100個說法,這是因為每個人所接觸到的環境有所差異,不同的公司要解決的問題自然 ...
一周排行
    -Advertisement-
    Play Games
  • 最近做項目過程中,使用到了海康相機,官方只提供了C/C++的SDK,沒有搜尋到一個合適的封裝了的C#庫,故自己動手,簡單的封裝了一下,方便大家也方便自己使用和二次開發 ...
  • 前言 MediatR 是 .NET 下的一個實現消息傳遞的庫,輕量級、簡潔高效,用於實現進程內的消息傳遞機制。它基於中介者設計模式,支持請求/響應、命令、查詢、通知和事件等多種消息傳遞模式。通過泛型支持,MediatR 可以智能地調度不同類型的消息,非常適合用於領域事件處理。 在本文中,將通過一個簡 ...
  • 前言 今天給大家推薦一個超實用的開源項目《.NET 7 + Vue 許可權管理系統 小白快速上手》,DncZeus的願景就是做一個.NET 領域小白也能上手的簡易、通用的後臺許可權管理模板系統基礎框架。 不管你是技術小白還是技術大佬或者是不懂前端Vue 的新手,這個項目可以快速上手讓我們從0到1,搭建自 ...
  • 第1章:WPF概述 本章目標 瞭解Windows圖形演化 瞭解WPF高級API 瞭解解析度無關性概念 瞭解WPF體繫結構 瞭解WPF 4.5 WPF概述 ​ 歡迎使用 Windows Presentation Foundation (WPF) 桌面指南,這是一個與解析度無關的 UI 框架,使用基於矢 ...
  • 在日常開發中,並不是所有的功能都是用戶可見的,還在一些背後默默支持的程式,這些程式通常以服務的形式出現,統稱為輔助角色服務。今天以一個簡單的小例子,簡述基於.NET開發輔助角色服務的相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 第3章:佈局 本章目標 理解佈局的原則 理解佈局的過程 理解佈局的容器 掌握各類佈局容器的運用 理解 WPF 中的佈局 WPF 佈局原則 ​ WPF 視窗只能包含單個元素。為在WPF 視窗中放置多個元素並創建更貼近實用的用戶男面,需要在視窗上放置一個容器,然後在這個容器中添加其他元素。造成這一限制的 ...
  • 前言 在平時項目開發中,定時任務調度是一項重要的功能,廣泛應用於後臺作業、計劃任務和自動化腳本等模塊。 FreeScheduler 是一款輕量級且功能強大的定時任務調度庫,它支持臨時的延時任務和重覆迴圈任務(可持久化),能夠按秒、每天/每周/每月固定時間或自定義間隔執行(CRON 表達式)。 此外 ...
  • 目錄Blazor 組件基礎路由導航參數組件參數路由參數生命周期事件狀態更改組件事件 Blazor 組件 基礎 新建一個項目命名為 MyComponents ,項目模板的交互類型選 Auto ,其它保持預設選項: 客戶端組件 (Auto/WebAssembly): 最終解決方案裡面會有兩個項目:伺服器 ...
  • 先看一下效果吧: isChecked = false 的時候的效果 isChecked = true 的時候的效果 然後我們來實現一下這個效果吧 第一步:創建一個空的wpf項目; 第二步:在項目裡面添加一個checkbox <Grid> <CheckBox HorizontalAlignment=" ...
  • 在編寫上位機軟體時,需要經常處理命令拼接與其他設備進行通信,通常對不同的命令封裝成不同的方法,擴展稍許麻煩。 本次擬以特性方式實現,以兼顧維護性與擴展性。 思想: 一種命令對應一個類,其類中的各個屬性對應各個命令段,通過特性的方式,實現其在這包數據命令中的位置、大端或小端及其轉換為對應的目標類型; ...