天天看點

Linux伺服器出現:No space left on device的解決方法 及 linux inode, block區域講解Linux伺服器出現:No space left on device的解決方法    簡單了解Linux的inode與block

Linux伺服器出現:No space left on device的解決方法_運維_DRACOYU的部落格-CSDN部落格

https://blog.csdn.net/chanbo8205/article/details/85229453

Linux伺服器出現:No space left on device的解決方法

報錯資訊:

2016-06-02 23:56:26 [com.thinkive.server.logger.TradeLogger]-[ERROR]

java.io.IOException: No space left on device

at java.io.FileOutputStream.writeBytes(Native Method)

at java.io.FileOutputStream.write(FileOutputStream.java:282)

at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)

at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)

at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)

at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)

at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)

at com.thinkive.server.logger.TradeLogger$LoggerThread.flushLogFile(TradeLogger.java:404)

at com.thinkive.server.logger.TradeLogger$LoggerThread.run(TradeLogger.java:322)

伺服器磁盤不足,df -h 一下,var下正常,還有剩餘,發現問題沒有,到後來顯示大量的No space left on device:

/var明明還有很大的空間,為什麼就提示“沒有足夠的空間”了呢?結果用到了df -i指令檢視磁盤的節點發現如下圖:

節點100%了.

這個時候使用者可以先看下日志檔案是否太多,如果是日志檔案占用大量的inodes可以臨時釋放清理下過期的日志。

以下是檢查inodes滿的某一種情況,僅供參考:

檢視原來是crontab裡面定時執行的句子裡沒有加 > /dev/null 2>&1,系統中cron執行的程式有輸出内容,輸出内容會以郵件形式發給cron的使用者,而sendmail沒有啟動是以就産生了很大零碎的檔案:

cd /var/spool/clientmqueue/  進入這個目錄,删掉這些沒用的檔案,用ls 檢視一下,結果是沒有反應,檔案太多,于是就用到了這個指令:ls |xargs rm -rf 可以分批的處理删除檔案

操作到該步驟,可以根據較大目錄的檔案占用情況,臨時轉移部分檔案到占用磁盤較小的目錄中。

最近這兩天登陸伺服器,發現用 wget 下載下傳檔案的時候提示“No space left on device”,而且連使用 tab 鍵進行補全時也會提示該錯誤。

之前遇到過一次這種問題,是由于磁盤空間被占滿了,導緻無法建立新檔案。正常情況下,删除一些檔案來釋放空間,即可解決該問題。

當我使用 df 指令檢視分區情況時,結果如下:

# df -h

Filesystem Size Used Avail Use% Mounted on

/dev/vda1 29G 29G 0 100% /

udev  10M 0 10M 0% /dev

tmpfs  101M 232K 100M 1% /run

tmpfs  5.0M 0 5.0M 0% /run/lock

tmpfs  405M 0 405M 0% /run/shm

看到這裡,我以為磁盤真的被 100% 占用了,于是就檢視了各目錄的占用情況:

# du -sh /*

8.8M /bin

30M /boot

0 /dev

5.3M /etc

24K /home

0 /initrd.img

205M /lib

4.0K /lib64

16K /lost+found

8.0K /media

4.0K /mnt

4.0K /opt

0 /proc

2.5G /root

232K /run

5.2M /sbin

8.0K /srv

0 /sys

4.0K /tmp

2.6G /usr

1.8G /var

0 /vmlinuz

很明顯,總共的磁盤占用完全不到 10G,磁盤理論上并未被占滿。

這種情況下,很可能是小檔案過多,導緻 inode 急劇增加,消耗完 inode 區域的空間。

如果真是如此,那麼即使磁盤空間有剩餘,但由于無法建立新的 inode 來存儲檔案的元資訊,也就無法建立新檔案。

是以,我用 df 指令進行驗證:

# df -ih

Filesystem Inodes IUsed IFree IUse% Mounted on

/dev/vda1 1.9M 299K 1.6M 17% /

udev  123K 299 123K 1% /dev

tmpfs  126K 249 125K 1% /run

tmpfs  126K 4 126K 1% /run/lock

tmpfs  126K 2 126K 1% /run/shm

可以看到,inode 區域隻被占用了一小部分,還有大量的空間未使用,是以也不是 inode 區域被占滿的問題。

到了這裡,我的内心是非常郁悶的。這個問題直接導緻了Apache、MySql以及其它的一些服務均無法啟動,伺服器已經基本沒法使用了,然而原因卻撲朔迷離。

最後,伺服器提供商告訴我另一種可能的情況,就是有些檔案删除時還被其它程序占用,此時檔案并未真正删除,隻是标記為 deleted,隻有程序結束後才會将檔案真正從磁盤中清除。

于是我通過 lsop 指令檢視了被程序占用中的檔案:

# lsof | grep deleted

mysqld 1952 2982 mysql 5u REG  254,1  0 127 /tmp/ibzMEe4z (deleted)

mysqld 1952 2982 mysql 6u REG  254,1  0 146 /tmp/ibq6ZFge (deleted)

mysqld 1952 2982 mysql 10u REG  254,1  0 150 /tmp/ibyNHH8y (deleted)

apache2 2869  root 9u REG  254,1  0 168 /tmp/.ZendSem.2w14iv (deleted)

apache2 2869  root 10w REG  0,16  0 11077 /run/lock/apache2/rewrite-map.2869 (deleted)

...

python 3102  root 1w REG  254,1 22412342132 264070 /var/log/nohup.out (deleted)

終于找到了罪魁禍首,原來是在背景運作的 Python 腳本,源源不斷地将輸出儲存到 /var/log/nohup.out 檔案中,檔案大小居然達到了20G+!

前階段在背景運作腳本之後,就沒再管過它。估計是我在 Python 運作過程中删掉了 nothup.out 檔案,由于該檔案被占用,是以隻能先标記為 deleted,而未真正删除,最後導緻磁盤爆滿。

這次的教訓提醒了我,不能将任務簡單放到背景就放任不管,特别是使用 nohup 指令時,所有的輸出都會被不斷地添加到同一個檔案中,如果該程序不會自己終止,就可能導緻輸出檔案占滿整個磁盤。

=============================================================================

=============================================================================

=============================================================================

簡單了解Linux的inode與block - 苦逼運維 - 部落格園

https://www.cnblogs.com/diantong/p/10504513.html

簡單了解Linux的inode與block

Linux常見檔案系統類型:ext3(CentOS5),ext4(CentOS6),xfs(CentOS7)

Windows常見檔案系統類型:FAT32,NTFS

(1).inode的内容

1)inode包含檔案的元資訊,具體來說有以下内容:

         檔案的位元組數

         檔案擁有者的User ID

         檔案的Group ID

         檔案的讀、寫、執行權限

         檔案的時間戳,共有三個:ctime指inode上次檔案屬性變動的時間,例如:chmod +x a.sh;mtime指檔案内容上次變動的時間,例如:echo aa >> a.sh或vim a.sh;atime值檔案上次打開的時間,例如:cat a.sh。

         連結數,即有多少檔案名指向這個inode

         檔案資料block的位置

2)我們可以用stat指令,檢視某個檔案的inode資訊:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

[[email protected] ~]# stat /etc/passwd

檔案:

"/etc/passwd"

大小:2257       塊:8          IO 塊:4096   普通檔案

裝置:803h/2051d   Inode:17324457    硬連結:1

權限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)

環境:system_u:object_r:passwd_file_t:s0

最近通路:2019-03-08 11:00:01.672759577 +0800

最近更改:2019-02-13 16:19:23.303395879 +0800

最近改動:2019-02-13 16:19:23.305395782 +0800

建立時間:-

[[email protected] ~]# echo $LANG      

//檢視目前語言

zh_CN.UTF-8

[[email protected] ~]# en_US.UTF-8"

//語言臨時轉為英文

[[email protected] ~]# stat /etc/passwd

File: ‘/etc/passwd’

Size: 2257        Blocks: 8          IO Block: 4096   regular file

Device: 803h/2051d  Inode: 17324457    Links: 1

Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Context: system_u:object_r:passwd_file_t:s0

Access: 2019-03-08 11:00:01.672759577 +0800

Modify: 2019-02-13 16:19:23.303395879 +0800

Change: 2019-02-13 16:19:23.305395782 +0800

Birth: -

[[email protected] ~]# ll /etc/passwd  

//ll其實就是檢視檔案的inode資訊

-rw-r--r--. 1 root root 2257 Feb 13 16:19 /etc/passwd   

//ll檢視到的時間是ctime時間

3)測試ctime,mtime和atime

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

[[email protected] ~]# touch a.txt

[[email protected] ~]# stat a.txt

File: ‘a.txt’

Size: 0           Blocks: 0          IO Block: 4096   regular empty file

Device: 803h/2051d  Inode: 34042450    Links: 1

Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:admin_home_t:s0

Access: 2019-03-08 14:24:17.272886924 +0800

Modify: 2019-03-08 14:24:17.272886924 +0800

Change: 2019-03-08 14:24:17.272886924 +0800

Birth: -

[[email protected] ~]# date -s 

"2019-03-07 14:29:49"

//修改系統時間

Thu Mar  7 14:29:49 CST 2019

[[email protected] ~]# chmod +x a.txt

[[email protected] ~]# stat a.txt  

//可以看到’ chmod +x a.txt’修改了ctime

File: ‘a.txt’

Size: 0           Blocks: 0          IO Block: 4096   regular empty file

Device: 803h/2051d  Inode: 34042450    Links: 1

Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:admin_home_t:s0

Access: 2019-03-08 14:24:17.272886924 +0800

Modify: 2019-03-08 14:24:17.272886924 +0800

Change: 2019-03-07 14:30:32.246910417 +0800

Birth: -

[[email protected] ~]# echo aa >> a.txt

[[email protected] ~]# stat a.txt  

//可以看到’ echo aa >> a.txt’修改了mtime和ctime

File: ‘a.txt’

Size: 3           Blocks: 8          IO Block: 4096   regular file

Device: 803h/2051d  Inode: 34042450    Links: 1

Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:admin_home_t:s0

Access: 2019-03-08 14:24:17.272886924 +0800

Modify: 2019-03-07 14:31:19.164728344 +0800

Change: 2019-03-07 14:31:19.164728344 +0800

Birth: -

[[email protected] ~]# vim a.txt

//添加了一行bbb

[[email protected] ~]# stat a.txt  

//可以看到’ vim a.txt’修改了atime,ctime和mtime

File: ‘a.txt’

Size: 7           Blocks: 8          IO Block: 4096   regular file

Device: 803h/2051d  Inode: 34729170    Links: 1

Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:admin_home_t:s0

Access: 2019-03-07 14:32:42.604862498 +0800

Modify: 2019-03-07 14:32:42.604862498 +0800

Change: 2019-03-07 14:32:42.605945804 +0800

Birth: -

[[email protected] ~]# cat a.txt

aa

bbb

[[email protected] ~]# stat a.txt  

//可以看到’ cat a.txt’修改了atime

File: ‘a.txt’

Size: 7           Blocks: 8          IO Block: 4096   regular file

Device: 803h/2051d  Inode: 34729170    Links: 1

Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:admin_home_t:s0

Access: 2019-03-07 14:34:27.525217232 +0800

Modify: 2019-03-07 14:32:42.604862498 +0800

Change: 2019-03-07 14:32:42.605945804 +0800

Birth: -

  由此可見,黑客是可以通過修改時間,再植入木馬,防止被find找到。

4)inode的大小

         Inode也會消耗硬碟空間,是以硬碟格式化時,作業系統自動将檔案分成兩個區域。一個是資料區,用于存放檔案資料;另一個是inode區,用于存放inode所包含的資訊。

         每個inode節點的大小一般是128位元組或256位元組。Inode節點的總數在格式化時就給定,一般是1KB或2KB或4KB就設定一個inode。如果一塊1GB的硬碟,每個inode節點的大小為128位元組,每1KB就設定一個inode,那麼inode區的大小就會達到128MB,占整個硬碟的12.8%。(是以block可以設定的大一點)

5)inode号

         每個inode都有一個号碼,作業系統用inode号來識别不同的檔案。

         Unix/Linux系統内部不是用檔案名,而使用inode号來識别檔案。對于系統來說,檔案名隻是iode号便于識别的别名。表面上使用者是通過檔案名打開檔案,實際上系統内部分成三個步驟:首先,系統找到這個檔案名對應的inode号;其次通過inode号擷取inode資訊;最後根據inode資訊找到檔案資料所在的block,讀出資料。

         可以使用’ls -i [filename]’快速檢視檔案的inode号:

1

2

[[email protected] ~]# ls -i a.txt

34729170 a.txt

  在Unix/Liunx系統中,目錄也是一種檔案。目錄檔案的結構非常簡單,即使一系列目錄項的清單。每個目錄項由所包含檔案的檔案名以及該檔案名對應的inode号組成。

  可以使用’ls -id [directory]’快速檢視目錄的inode号:

1

2

[[email protected] ~]# ls -id /etc

16777281 /etc

  另外可以使用’df -i’檢視每個磁盤分區的inode總數和已經使用的數量

1

2

3

4

5

6

7

8

9

10

11

12

[[email protected] ~]# df -i

檔案系統         Inode 已用(I) 可用(I) 已用(I)% 挂載點

/dev/sda3      8912384  193509 8718875       3% /

devtmpfs        249583     408  249175       1% /dev

tmpfs           253514       1  253513       1% /dev/shm

tmpfs           253514     966  252548       1% /run

tmpfs           253514      16  253498       1% /sys/fs/cgroup

/dev/sda1       524288     359  523929       1% /boot

/dev/sr0             0       0       0        - /mnt

tmpfs           253514       6  253508       1% /run/user/42

tmpfs           253514      17  253497       1% /run/user/1000

tmpfs           253514       1  253513       1% /run/user/0

  注意:由于每個檔案都必須有一個inode号,是以有可能發生inode已用光,但硬碟未存滿的情況。這時就無法在硬碟上建立新的檔案。

6)inode的特殊作用

  有時檔案名有特殊字元或亂碼,無法正常修改或删除,可以通過inode号來進行操作。執行個體:

1

2

3

4

5

6

7

8

9

10

11

12

13

[[email protected] ~]$ mkdir Dir

[[email protected] ~]$ cd Dir/

[[email protected] Dir]$ touch 學習  \\建立一個中文的檔案名

[[email protected] Dir]$ ls

學習

[[email protected] Dir]$ en_US.gbk"

  \\臨時調整一下編碼,使得檔案名變為亂碼

[[email protected] Dir]$ ls

??????

[[email protected] Dir]$ ls -i  \\看一下該檔案的inode号

407062 ??????<br>\\删除還可以使用

"find . -inum 407062 -delete"

(沒有提示)以及

"find . -inum 407062 | xargs -i rm {}"

<br>\\修改類似

[[email protected] Dir]$ find . -inum 407062 -exec rm -i {} \;

rm: remove regular empty file 

'./\345\255\246\344\271\240'

? y

[[email protected] Dir]$ ls

  移動或重命名檔案,隻改變檔案名,inode沒影響。

  使用vim修改檔案内容後,inode會發生改變。執行個體:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

[[email protected] ~]$ touch File

[[email protected] ~]$ ls -i File

52016344 File

[[email protected] ~]$ vim File<br>

//增加一行aaaaa

[[email protected] ~]$ ls -i File  

//inode号改變了

52016202 File

[[email protected] ~]$ echo bbbbb>>File  

//追加一行bbbbb

[[email protected] ~]$ ls -i File  

//inode号沒變

52016202 File

[[email protected] ~]$ cat File

aaaaa

bbbbb

[[email protected] ~]$ ls -i File

52016202 File

[[email protected] ~]$ cat > File <<EOF  

//重寫File

> ccccc

> ddddd

> EOF

[[email protected] ~]$ ls -i File  

//inode号還是沒變

52016202 File

  我一開始還懷疑會不會是我位元組沒有寫滿一個block,但我用cat寫了20416個位元組,結果inode号還是沒變。我估計echo追加和cat重寫都不改變inode号。

(2).block的内容

         block是真正存儲資料的地方。block是檔案系統中的最小存儲機關,扇區是磁盤中的最小存儲機關。

         注意:Linux下叫block,Windows下叫簇。

1)  Windows如何修改簇的大小

  可以右鍵一個分區,點選格式化會出現如下視窗:

Linux伺服器出現:No space left on device的解決方法 及 linux inode, block區域講解Linux伺服器出現:No space left on device的解決方法    簡單了解Linux的inode與block

這裡的配置設定單元大小就是設定簇的大小。

2)  Block或簇的大小對系統的影響

  簇或block調大時,節約了尋址時間,速度變快,但浪費空間;簇和block調小時,節約空間,但尋址時間變長,速度變慢。

  說明:為什麼簇或block調大會浪費空間?這是因為一個檔案會占用多個簇或block來存放。目前一個簇或block放不下時,就會占用下一個簇或block,到最後如果産生不足以占用一個完整的簇或block時,仍然會占用一個完整的簇或block,就會浪費這個簇或block剩下的空間。

         如果有一個2T的硬碟,可以前1.5T使用4K的簇或block,後0.5G使用64K的簇或block,這樣可以改善機械硬碟越到最後速度越慢的問題。

3)  Linux下檢視block的大小以及修改方式

  檢視block的大小

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[[email protected] ~]# file -s /dev/sdb1   

//把block或裝置當做普通檔案看待

/dev/sdb1: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)

[[email protected] ~]# xfs_info /dev/sdb1

xfs_info: /dev/sdb1 

is

not a mounted XFS filesystem 

//居然需要先挂載

[[email protected] ~]# ls /

bin   dev   etc   lib    media  opt   root  sbin  srv  tmp  

var

boot  dump  home  lib64  mnt    proc  run   sdb1  sys  usr

[[email protected] ~]# mkdir /sdb1

mkdir: 無法建立目錄

"/sdb1"

: 檔案已存在

[[email protected] ~]# mount /sdb1 /dev/sdb1

mount: /sdb1 不是一個塊裝置

[[email protected] ~]# mount /dev/sdb1 /sdb1/

[[email protected] ~]# xfs_info /dev/sdb1

meta-data=/dev/sdb1              isize=512    agcount=4, agsize=65536 blks

=                       sectsz=512   attr=2, projid32bit=1

=                       crc=1        finobt=0 spinodes=0

data     =                       bsize=4096   blocks=262144, imaxpct=25

=                       sunit=0      swidth=0 blks

naming   =version 2              bsize=4096   ascii-ci=0 ftype=1

log      =

internal

bsize=4096   blocks=2560, version=2

=                       sectsz=512   sunit=0 blks, lazy-count=1

realtime =none                   extsz=4096   blocks=0, rtextents=0

  注意:xfs_info隻能用于xfs的檔案系統,如果是ext4或ext3請使用tune2fs

  修改block的大小,就需要用到mkfs.xfs格式化指令,需要格式化分區

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[[email protected] ~]# umount /sdb1

[[email protected] ~]# mkfs -t xfs -b size=2048 /dev/sdb1

mkfs.xfs: /dev/sdb1 appears to contain an existing filesystem (xfs).

mkfs.xfs: Use the -f option to force overwrite.

[[email protected] ~]# mkfs -t xfs -b size=2048 -f /dev/sdb1

meta-data=/dev/sdb1              isize=512    agcount=4, agsize=131072 blks

=                       sectsz=512   attr=2, projid32bit=1

=                       crc=1        finobt=0, sparse=0

data     =                       bsize=2048   blocks=524288, imaxpct=25

=                       sunit=0      swidth=0 blks

naming   =version 2              bsize=4096   ascii-ci=0 ftype=1

log      =

internal

log           bsize=2048   blocks=5120, version=2

=                       sectsz=512   sunit=0 blks, lazy-count=1

realtime =none                   extsz=4096   blocks=0, rtextents=0

  注意:mkfs.xfs就是mkfs –t xfs的簡寫。

繼續閱讀