3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別

概述

最近有朋友問硬鏈接與軟鏈接之間的區別,說總感覺很容易混淆,剛好之前沒這塊內容,所以今天抽空整理了下。


一、從inode瞭解Linux文件系統

硬鏈接與軟鏈接是Linux文件系統中的一個重要概念,其涉及文件系統中的索引節點 (index node 又稱 inode),而索引節點對象是 Linux 虛擬文件系統 (VFS) 的四個基本概念之一。

在 Linux 系統中查看 inode 號可使用命令 stat 或 ls -i(若是 AIX 系統,則使用命令 istat)。

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別


二、Linux的文件與目錄

UNIX 系統中除進程之外的一切皆是文件,而Linux保持了這一特性。為了便於文件的管理,Linux還引入了目錄(有時亦被稱為文件夾)這一概念。目錄使文件可被分類管理,且目錄的引入使Linux的文件系統形成一個層級結構的目錄樹。

Linux與其他類 UNIX 系統一樣並不區分文件與目錄:目錄是記錄了其他文件名的文件。使用命令 mkdir 創建目錄時,若期望創建的目錄的名稱與現有的文件名(或目錄名)重複,則會創建失敗。

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別


三、硬鏈接與軟鏈接的聯繫與區別

文件都有文件名與數據,這在Linux上被分成兩個部分:用戶數據 (user data) 與元數據 (metadata)。

用戶數據,即文件數據塊 (data block),數據塊是記錄文件真實內容的地方;而元數據則是文件的附加屬性,如文件大小、創建時間、所有者等信息。

在 Linux 中,元數據中的 inode 號(inode 是文件元數據的一部分但其並不包含文件名,inode 號即索引節點號)才是文件的唯一標識而非文件名。文件名僅是為了方便人們的記憶和使用,系統或程序通過 inode 號尋找正確的文件數據塊。

下圖展示了程序通過文件名獲取文件內容的過程。

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別

在Linux系統中查看inode號可使用命令stat 或 ls -i(若是 AIX 系統,則使用命令istat)。使用命令 mv 移動文件 ,其結果不影響文件的用戶數據及 inode 號,文件移動前後 inode 號均為:1573119 ,操作如下:

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別

為解決文件的共享使用,Linux系統引入了兩種鏈接:硬鏈接 (hard link)軟鏈接(又稱符號鏈接,即soft link或symbolic link)。

鏈接為Linux系統解決了文件的共享使用,還帶來了隱藏文件路徑、增加權限安全及節省存儲等好處。若一個inode號對應多個文件名,則稱這些文件為硬鏈接。換言之,硬鏈接就是同一個文件使用了多個別名。

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別

軟鏈接的訪問

簡單來說,就是有多個文件名對應到同一個inode號碼,注意,是多個文件名,不是多個文件。一般來說,使用硬連接(hard link)設置連接文件,磁盤的空間與inode的數目是不會變的,它只是在某個目錄下的block多寫入一個關聯數據而已,既不會耗用inode也不會耗用block數量。硬鏈接可由命令link或ln創建。

由於硬鏈接是有著相同inode號僅文件名不同的文件,因此硬鏈接存在以下幾點特性:

文件有相同的 inode 及 data block;
只能對已存在的文件進行創建;
不能交叉文件系統進行硬鏈接的創建;
不能對目錄進行創建,只可對文件創建;
刪除一個硬鏈接文件並不影響其他有相同 inode 號的文件。

軟鏈接與硬鏈接不同,若文件用戶數據塊中存放的內容是另一文件的路徑名的指向,則該文件就是軟連接。軟鏈接就是一個普通文件,只是數據塊內容有點特殊。軟鏈接有著自己的 inode 號以及用戶數據塊。因此軟鏈接的創建與使用沒有類似硬鏈接的諸多限制:

  • 軟鏈接有自己的文件屬性及權限等;
  • 可對不存在的文件或目錄創建軟鏈接;
  • 軟鏈接可交叉文件系統;
  • 軟鏈接可對文件或目錄創建;
  • 創建軟鏈接時,鏈接計數 i_nlink 不會增加;
  • 刪除軟鏈接並不影響被指向的文件,但若被指向的原文件被刪除,則相關軟連接被稱為死鏈接(即 dangling link,若被指向路徑文件被重新創建,死鏈接可恢復為正常的軟鏈接)。

測試操作:

# 可對不存在的文件創建軟鏈接;
$ ln -s old.file soft.link
$ ls -liF
total 0
789467 lrwxrwxrwx 1 root root 8 Sep 1 18:00 soft.link -> old.file

# 由於被指向的文件不存在,此時的軟鏈接soft.link就是死鏈接;
$ cat soft.link
cat: soft.link: No such file or directory

# 創建被指向的文件old.file,soft.link恢復成正常的軟鏈接;
$ echo "This is an original file_A" >> old.file
$ cat soft.link
This is an original file_A

# 對不存在的目錄創建軟鏈接;
$ ln -s old.dir soft.link.dir
$ mkdir -p old.dir/test
$ tree . -F --inodes
.
├── [ 789497] old.dir/
│ └── [ 789498] test/
├── [ 789495] old.file
├── [ 789495] soft.link -> old.file
└── [ 789497] soft.link.dir -> old.dir/

當然軟鏈接的用戶數據也可以是另一個軟鏈接的路徑,其解析過程是遞歸的。但需注意:軟鏈接創建時原文件的路徑指向使用絕對路徑較好。使用相對路徑創建的軟鏈接被移動後該軟鏈接文件將成為一個死鏈接。


四、利用硬鏈接原理秒刪MySQL大文件

原理:硬鏈接基礎,當多個文件共同指向同一inode、inode鏈接數N>1、刪除任何一個文件都是巨快。因為、此時刪除的僅僅是指向inode的指針,而當N=1時、則不一樣了、此時刪除的文件相關的所有數據塊、所以慢。

測試:

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別

這裡可以發現stock.ibd的INODES屬性變成了2;

下面繼續來刪表。

mysql> show table status like 'stock'\G 
*************************** 1. row ***************************
Name: stock
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 49916863
Avg_row_length: 356
Data_length: 17799577600
Max_data_length: 0
Index_length: 1025507328
Data_free: 4194304
Auto_increment: NULL
Create_time: 2019-03-18 14:55:08
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.23 sec)

mysql> drop table stock ;
Query OK, 0 rows affected (0.99 sec)

1秒不到就刪除完成; 也就是DROP TABLE不用再HANG這麼久了。但table是刪除了,數據文件還在,所以你還需要最後數據文件給刪除。

$ ll 
total 19096666112
-rw-r–r– 2 mysql mysql 19096666112 Apr 15 09:55 stock.id.hdlk

$ rm stock.id.hdlk

最後一步刪除原始大文件也可以選擇rsync來刪除、比rm快多了:rsync秒刪大文件。

$ rsync --delete-before -avH --progress --stats DEST SRC

解釋:當SRC和DEST性質都為文件【f】時,意思是清空文件內容而不是刪除文件。當SRC和DEST性質都為目錄【d】時,意思是刪除該目錄下的所有文件,使其變為空目錄。rsync實際上用的就是替換原理,處理速度相當快,處理幾個G的文件也就是秒級的事、比rm要快很多倍;缺點就是對磁盤io的佔用較高、業務高峰或要暫避。


3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別

從使用的角度講,軟鏈接與硬鏈接兩者沒有任何區別,都與正常的文件訪問方式一樣,支持讀寫,如果是可執行文件的話也可以直接執行。區別在底層原理上,即:

  • 硬鏈接: 與普通文件沒什麼不同,inode 都指向同一個文件在硬盤中的區塊
  • 軟鏈接: 保存了其代表的文件的絕對路徑,是另外一種文件,在硬盤上有獨立的區塊,訪問時替換自身路徑。

後面會分享更多Linux方面的內容,感興趣的朋友可以關注一下~

3分鐘讓你明白“軟鏈接”和“硬鏈接”之間的區別


分享到:


相關文章: