ZFS-Solaris 10的新檔案系統 (一)

Sun Solaris 10作業系統 (Solaris OS) 裡新的ZFS檔案系統於2006年6月正式推出。昇陽號稱ZFS是目前地球上最強的檔案系統,其創新的技術推翻你對檔案系統管理的概念。根據昇陽的文件它具有如下的功能。

* 管理簡單 ZFS 自動化並整合複雜的儲存管理概念,降低 80% 管理上的經常性耗用時間。
* 確實的資料完整性 ZFS 用 64 位元的總和檢查保護所有資料,能夠偵測並修正無訊資料損毀的情況。
* 無限延伸性 ZFS 是世界第一個 128 位元檔案系統,其儲存容量為 32 或 64 位元系統的 1600 萬兆倍。
* 極速效能 作業事件模型消除了傳統式發送 I/O 的順序限制,大幅提升效能。

看了這麼多,還是快開始進入我們的重點吧!要使用ZFS你得要先有一個Solaris 10的系統。不管是SPARC版或是x86版的都可以,但是一定要是Solaris 10 06/06(Update 2)這個版本以後的。再來最好有多顆硬碟,而且每顆硬碟要大於128MB(現在去那兒找比128MB還小的呀)。最後是RAM越多越好,官方說法是512MB是起碼,1G是基本。不過實際上我在VMware下只開了256MB測試也是跑的很順暢。

在一切都準備就緒後就可以開始了。首先看一下我們所安裝的Solaris版本是不是正確的。

# cat /etc/release
Solaris 10 6/06 s10x_u2wos_09a X86
Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
Use is subject to license terms.
Assembled 09 June 2006

是2006年6月的版本,不然你也可以執行zfs這個指令試看看。在我測試的環境裡,我用了6個大小都為1GB的SCSI硬碟,分別是c2t0 ~ c2t5

# echo | format
Searching for disks...done


AVAILABLE DISK SELECTIONS:
0. c0d0
/pci@0,0/pci-ide@7,1/ide@0/cmdk@0,0
1. c2t0d0
/pci@0,0/pci1000,30@10/sd@0,0
2. c2t1d0
/pci@0,0/pci1000,30@10/sd@1,0
3. c2t2d0
/pci@0,0/pci1000,30@10/sd@2,0
4. c2t3d0
/pci@0,0/pci1000,30@10/sd@3,0
5. c2t4d0
/pci@0,0/pci1000,30@10/sd@4,0
6. c2t5d0
/pci@0,0/pci1000,30@10/sd@5,0
Specify disk (enter its number): Specify disk (enter its number):

zfs標榜管理簡單所以指令也相對的少,只有二個指令。我們先介紹第一個zpool。zpool會建立一個storage pool,也會自動產生zfs 檔案系統和掛載點,並且會自動的掛載該檔案系統。如下面的例子會產生一個叫mypool的storage pool和在根目錄(/)產生mypool這個目錄

# zpool create mypool c2t0d0
# ls -ld /mypool
drwxr-xr-x 2 root sys 2 Jul 21 16:40 /mypool

這個新建的mypool大小為1GB,也就是c2t0d0的大小。讓我們在上面建個檔案試看看。

# mkfile 100m testfile
# df -k /mypool
Filesystem kbytes used avail capacity Mounted on
mypool 999424 81455 917906 9% /mypool

mypool這是一個storage pool,同時它也是一個可用的檔案系統,你可以在上面建目錄、寫入檔案,做任何在傳統的UFS檔案系統可以做的事。等等,就只是這樣子嗎?當然不是,ZFS允許你在storage pool上面再建不同的檔案系統(File System)。下個的範例會使用第二個也是最後一個ZFS相關指令 - zfs。我們會使用zfs這個指令在mypool下建了一個叫data的檔案系統,同時它也會自動地建目錄和掛載。

-bash-3.00# zfs create mypool/data
-bash-3.00# df -k
Filesystem kbytes used avail capacity Mounted on
/dev/dsk/c0d0s0 7730925 2908589 4745027 39% /
/devices 0 0 0 0% /devices
ctfs 0 0 0 0% /system/contract
proc 0 0 0 0% /proc
mnttab 0 0 0 0% /etc/mnttab
swap 561064 644 560420 1% /etc/svc/volatile
objfs 0 0 0 0% /system/object
/usr/lib/libc/libc_hwcap1.so.1
7730925 2908589 4745027 39% /lib/libc.so.1
fd 0 0 0 0% /dev/fd
swap 560452 32 560420 1% /tmp
swap 560448 28 560420 1% /var/run
mypool 999424 102449 896878 11% /mypool
mypool/data 999424 24 896878 1% /mypool/data

看到上面的輸出了嗎?如果你仔細看會發現ZFS的檔案系統和UFS不太一樣,首先是Filesystem這個欄位,傳統上我們會看到的是device的路徑,如:/dev/dsk/c0d0s0,而ZFS則為storage pool的名稱。再來看/mypool跟/mypool/data,二個的大小和可用空間都相同,分別為999424及896878。因為目前我們還沒有針對各別的空間使用做限制,所以/mypool跟/mypool/data的空間是共用的,一個用的多另外那一個就用的少。

目前已經大致介紹了storage pool和ZFS檔案系統的建立。接下來會再對storage pool的使用做更進一步的說明。

上面的範例我們建了一個叫mypool的storage pool,並且指定c2t0d0給它。回憶一下我們剛所用的指令。

-bash-3.00# zpool create mypool c2t0d0 

其中c2t0d0是一個未經solaris 格式化過的硬碟(未使用format這個指令去做過任何的處理)。而也不需要事先處理,如果指定的硬碟已經有分區的話,則整個硬碟的內容會被清除。在指定要使用的裝置時,除了用cxtxdx這種短名外,你也可以給全路徑的名稱, 如/dev/dsk/c2t0d0。這是把一整個硬碟空間都給這個storage pool使用,如果你想把已經劃好分區(slice)的硬碟中某個未使用的分區拿來用也可以,只要將裝置名稱改為cxtxdxsx就可以了。如果你有使用SVM或是VxVM也可以將所做出來的卷(volume)拿來使用。這些裝置在zfs下我們統稱為虛擬裝置(virtual device)。 下面所列的都是合法的裝置名。

c2t0d0
/dev/dsk/c2t0d0
c2t0d0s0
/dev/dsk/c2t0d0s0
/dev/md/dsk/d10
/dev/vx/dsk/datadg/vol01

除了最基本的storage pool外,其實zfs還提供了mirror和RAID-Z二種型式的storage pool。RAID-Z其實是RAID 5的一種變形,傳統的RAID 5在寫入資料時,如果遇到電力中斷有可能會造成寫入的資料並不完整。而zfs則透過將檔案系統及實體磁碟結合,並使用可變長度的跨距單位(variable-width RAID stripes),來避免這種情形的發生。
以mirror(RAID 1)的方式建立storage pool時,需要使用關鍵字mirror並且指定二個以上的虛擬裝置。而在建立RAID-Z時,則使用raidz 這個關鍵字並且指定二個以上的虛擬裝置(這裡跟RAID 5最少需使用三個磁碟不同,但可用空間都是N-1顆)。

zpool create datapool mirror c0t0d0 c0t1d0
zpool create datapool mirror c0t0d0 c0t1d0 mirror c1t0d0 c1t1d0
zpool create datapool raidz c0t0d0 c0t1d0
zpool create datapool raidz c0t0d0 c0t1d0 mirror c1t0d0 c1t1d0

當在建立storage pool時可能會出現錯誤訊息,此時可用-f的參數來強制執行。如下列所要使用的c1t0d0已經含有ufs的檔案系統,所以在建立時會出現錯誤訊息,如果你確定你真的要這麼做,那可以使用-f來強制執行。當然原先ufs檔案系統上的資料也不復存在了。

#zpool create data c1t0d0
invalid vdev specification
use '-f' to override the following errors:
/dev/dsk/c1t0d0s0 contains a ufs filesystem
#zpool create -f data c1t0d0

因為建立storage pool對磁碟資料有無法復原的破壞性。所以在做這些動作之前,請先確定你的頭腦夠清醒,並避免任何可能發生的錯誤。如果你不是很確定你的指令的正確性時,可以加上-n來做個檢查。通常最容易發生的是指定到使用中的磁碟裝置或是pool的名稱重複。

-bash-3.00# zpool create -n mypool c2t0d0
invalid vdev specification
use '-f' to override the following errors:
/dev/dsk/c2t0d0s0 is part of active ZFS pool mypool. Please see zpool(1M).

前面提到在建立storage pool時會在根目錄(/)建立一個同名的目錄以供掛載之用。可是這樣子使用很不方便,想像一下,如果我想要在/oradata下建立一個db1時那就不合需求了。其實在建立storage pool時可以手動指定掛載點,而不必一定要掛載在根目錄下面。下面的範例建立一個db1的pool並將其掛載在/oradata下。

-bash-3.00# zpool create -m /oradata/db1 db1 c2t1d0
-bash-3.00# df -k /oradata/db1
Filesystem kbytes used avail capacity Mounted on
db1 999424 24 999342 1% /oradata/db1

學會建立storage pool當然也得要知道如何把不要的storage pool殺掉。當你不再需要某個storage pool的時候便需要將該pool殺掉, 好把空間釋放出來供未來使用。在建storage pool時使用了關鍵字create,要移除時使用的關鍵字則為destroy。同樣的如果在移除時發生問題,如某個磁碟裝置出現問題,則可以加上-f來強制移除。

-bash-3.00# zpool destroy db1
-bash-3.00# zpool destroy -f db1

當pool的空間已經不夠使用的時候該怎麼辦呢?這時候zfs的好處就出來了。使用zfs你可以動態的將磁碟裝置加入某個pool裡面,該pool 的可用空間馬上就會加大,不需要umount該目錄後再mount,而且只需要一個指令。下面的範例使用zpool add的指令新增一個磁碟c2t1d0 到mypool。從二個不同的df -k的輸出可以看出來可用空間加大了1G左右(這裡的每顆硬碟大小都為1G)。

-bash-3.00# df -k /mypool
Filesystem kbytes used avail capacity Mounted on
mypool 999424 102450 794442 12% /mypool
-bash-3.00# zpool add mypool c2t1d0
-bash-3.00# df -k /mypool
Filesystem kbytes used avail capacity Mounted on
mypool 2031616 102450 1826634 6% /mypool

從上面的範例可以看出來zpool add和zpool create的指令格式一樣,而且也都可以使用-f和-n。我們再來看個範例,這個例子我們將新建一個mirror的pool然後再將它加大,你可以看到解決空間不足的問題有多簡單只要你的硬碟夠多的話。

-bash-3.00# zpool create -f testpool mirror c2t2d0 c2t3d0
-bash-3.00# df -k /testpool
Filesystem kbytes used avail capacity Mounted on
testpool 999424 24 999349 1% /testpool
-bash-3.00# zpool add testpool mirror c2t4d0 c2t5d0
-bash-3.00# df -k /testpool
Filesystem kbytes used avail capacity Mounted on
testpool 2031616 24 2031445 1% /testpool

現在有一個情況,假設我有二個Oracle的資料庫要執行,分別是DB1和db2。而我希望它們的資料是放在/oradata/db1和/oradata/db2下。這個時候可以先建一個叫oradata的storage pool,然後再建二個ZFS的檔案系統DB1和DB2分別給二個oracle的資料庫使用。 建立檔案系統使用zfs create的指令,然後接poolname/fsname看起來會像這個樣子。
zfs create poolname/fsname
下面的範例建立了一個oradata的pool並在其下建了二個檔案系統。在檔檔案系統建立時系統會一併建立目錄並掛載起來。

# zpool create oradata c2t0d0
# zfs create oradata/db1
# zfs create oradata/db2
# df -k
Filesystem kbytes used avail capacity Mounted on
oradata 999424 27 999288 1% /oradata
oradata/db1 999424 24 999288 1% /oradata/db1
oradata/db2 999424 24 999288 1% /oradata/db2

這個時候問題又來了,DBA決定把DB1改叫prod;DB2改叫test,然後prod的使用空間應該會在600MB左右;而test所需的空間不定。這個時候該如何是好?首先我們先來解決第一個問題,改名字。
ZFS的設計理念之一是簡化管理,所以當建立pool或filesystem時都不需要自行建立分割區、格式化、建立目錄、掛載、編輯/etc/vfstab, 並且重開機時系統會自動把zfs格式的檔案系統自動掛載起來。所以我們不能用傳統的方式來把/oradata/db1改成/oradata/prod,必須使用zfs rename的指令來修改。
下面的範例解決了問題一。

# zfs rename oradata/db1 oradata/prod
# zfs rename oradata/db2 oradata/test
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
oradata 136K 976M 27.5K /oradata
oradata/prod 24.5K 976M 24.5K /oradata/prod
oradata/test 24.5K 976M 24.5K /oradata/test

第二個問題要怎麼解決呢?這個時候就得要介紹一下ZFS的屬性(properties),ZFS提供了許多有用的控制屬性,如壓縮(compression)、 空間限額(quota)...等,這些屬性是可設定的,也就是說你可以透過指令來改變這些屬性的值。另外有些屬性是唯讀的,主要是ZFS一些相關的統計資料,如類型(type)、己使用空間(used)...等。現在我們要用到的是空間限額(quota)來設定二個目錄可以使用的空間。在學會怎麼設定之前,我們先要知道如何得知各屬性的值。

# zfs get
missing property argument
usage:
get [-rHp] [-o field[,field]...] [-s source[,source]...]
...

The following properties are supported:

PROPERTY EDIT INHERIT VALUES

type NO NO filesystem | volume | snapshot
creation NO NO
used NO NO
available NO NO
referenced NO NO
compressratio NO NO <1.00x>
mounted NO NO yes | no | -
origin NO NO
quota YES NO | none
reservation YES NO | none
volsize YES NO
volblocksize NO NO 512 to 128k, power of 2
recordsize YES YES 512 to 128k, power of 2
mountpoint YES YES | legacy | none
sharenfs YES YES on | off | share(1M) options
checksum YES YES on | off | fletcher2 | fletcher4 | sha256
compression YES YES on | off | lzjb
atime YES YES on | off
devices YES YES on | off
exec YES YES on | off
setuid YES YES on | off
readonly YES YES on | off
zoned YES YES on | off
snapdir YES YES hidden | visible
aclmode YES YES discard | groupmask | passthrough
aclinherit YES YES discard | noallow | secure | passthrough

Sizes are specified in bytes with standard units such as K, M, G, etc.

zfs get不加其他參數時會列出所有可用的屬性,在EDIT欄的看到NO的話就表示該屬性的值是唯讀的,YES才是可以設定的。再下一欄繼承( INHERIT)表該屬性的值會不會限制其下再建立的目錄。VALUE欄表示該屬性的可能的值。我們以
quota YES NO | none
為例,quota這個屬性是可設定的、不能繼承、值可為大小(數字)或none。
再以quota為例,我們要如何得知quota的值呢?zfs get quota oradata其中quota為屬性名,oradata為pool的名字。其中的屬性名也可以用all來取得所有的屬性。

# zfs get quota oradata
NAME PROPERTY VALUE SOURCE
oradata quota none default

# zfs get all oradata
NAME PROPERTY VALUE SOURCE
oradata type filesystem -
oradata creation Fri Aug 4 14:44 2006 -
oradata used 136K -
oradata available 976M -
oradata referenced 27.5K -
oradata compressratio 1.00x -
oradata mounted yes -
oradata quota none default
oradata reservation none default
oradata recordsize 128K default
oradata mountpoint /oradata default
oradata sharenfs off default
oradata checksum on default
oradata compression off default
oradata atime on default
oradata devices on default
oradata exec on default
oradata setuid on default
oradata readonly off default
oradata zoned off default
oradata snapdir hidden default
oradata aclmode groupmask default
oradata aclinherit secure

在瞭解ZFS的屬性後,要解決第二個問題就很簡單了。只要使用zfs set設定quota這個屬性的值就可以了。

# zfs set quota=600M oradata/prod
# zfs get quota oradata/prod
NAME PROPERTY VALUE SOURCE
oradata/prod quota 600M local

另外還有一個屬性reservation(保留空間)。在前面提到過同一個pool的空間是共用的,不管你在pool之下建了多少個zfs的檔案系統。以 oradata為例,oradata有約1G(978M)的空間可用,其下有二個檔案系統prod和test,但其實這三個總共可用的空間是1G。如果你在 /oradata/test下使用了800M,縱使你將prod的quota設定為600M,但你實際能用的就只有176M而已。為了避免這種情形,我們可以設定reservation的大小,要求系統保留一定的空間給我們使用。

# zfs set reservation=600 oradata/prod

# zfs get quota,reservation oradata/prod oradata/test
NAME PROPERTY VALUE SOURCE
oradata/prod quota 600M local
oradata/prod reservation 600M local
oradata/test quota 600M local
oradata/test reservation none default

# zfs list -r
NAME USED AVAIL REFER MOUNTPOINT
oradata 600M 376M 27.5K /oradata
oradata/prod 24.5K 900M 24.5K /oradata/prod
oradata/test 24.5K 376M 24.5K /oradata/test

觀察上面zfs list的輸出,/oradata已經使用了600M,而這600M實際上是我們保留給prod使用的。而prod最小可以使用600M的空間,如果其他空間沒被使用的話,最大可以用到900M。
下面的範例可以看出設定reservation對oradata的可用空間所產生的影響。

# zfs set reservation=100m oradata/test
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
oradata 700M 276M 27.5K /oradata
oradata/prod 24.5K 876M 24.5K /oradata/prod
oradata/test 24.5K 376M 24.5K /oradata/test

# zfs set reservation=none oradata/test
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
oradata 600M 376M 27.5K /oradata
oradata/prod 24.5K 900M 24.5K /oradata/prod
oradata/test 24.5K 376M 24.5K /oradata/test

我們來做個實驗,試著在/oradata/test下產生一個400M的檔案。但執行的結果只有376M,剛好是/oradata/test的可用空間。再看到/oradata 的可用空間從900M變成了600M正是剛剛設定好的保留大小。

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
oradata 600M 376M 27.5K /oradata
oradata/prod 24.5K 900M 24.5K /oradata/prod
oradata/test 24.5K 376M 24.5K /oradata/test

# cd /oradata/test
# mkfile 400m file1
file1: initialized 393748480 of 419430400 bytes: No space left on device

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
oradata 976M 0 27.5K /oradata
oradata/prod 24.5K 600M 24.5K /oradata/prod
oradata/test 376M 0 376M /oradata/test

一般Oracle的資料庫都會需要存放Archive log,所以我們要再建立一個目錄專來門用來放置Archive log。 因為資料特性的關係所以我們新建一個pool來給它使用。再建二個zfs並其目錄放到/oradata/prod/arch和 /oradata/test/arch。看來有點複雜的樣子,我們把資訊整理如下;
pool : archlog
zfs1 : parch
mountpoint1 : /oradata/prod/arch
zfs2 : tarch
mountpoint2 : /oradata/test/arch
有了以上的資訊後,我們就可以開始動手了。

# zpool create archlog c2t1d0
# zfs create archlog/parch
# zfs create archlog/tarch

# zfs set mountpoint=/oradata/prod/arch archlog/parch
# zfs set mountpoint=/oradata/test/arch archlog/tarch
# zfs set mountpoint=none archlog
上面的範例的解說如下;
1. 在c2t1do上建立一個叫archlog的pool
2. 建立二個zfs,parch和tarch分別給prod和test使用
3. 修改二個zfs的掛載點,使其分別掛在/oradata/prod和/oradata/test下
4. 修改archlog這個pool的掛載點,將之改為none。這有什麼影響呢?看看df的輸出你就知道了。
# df -k
oradata 999424 28 999285 1% /oradata
oradata/prod 999424 25 999285 1% /oradata/prod
oradata/test 999424 25 999285 1% /oradata/test
archlog/parch 999424 24 999267 1% /oradata/prod/arch
archlog/tarch 999424 24 999267 1% /oradata/test/arch

沒錯,將mountpoint設為none就表示這個pool(或zfs)不會被掛載起來使用,這樣做的目的可以讓目錄或掛載點的管理較為單純。
傳統上我們使用mount和umount來做檔案系統的掛載和卸載,zfs也提供了相同的參數來做同樣的事情。 對zfs的檔案系統可以使用zfs mount和zfs umount來達到相同的目的。如下面範例,

# zfs umount /oradata/test/arch
# zfs mount archlog/tarch

如果基於某些理由,你想要使用傳統的方式來掛載那也是可以的。假設DBA要把某個資料庫的資料export出來 ,所以我們需要再建一個目錄專門給他們放資料。而這個檔案系統的掛載你希望透過傳統的方式來使用。其實方法很簡單,只要將該zfs檔案系統的mointpoint改成legacy就可以了。當然你也再可以手動編輯/etc/vfstab 並讓它可以在開機時自動掛載起來。

如果你要修改vfstab的話,要注意的是zfs的內容會和傳統的UFS不太一樣。在device to mount欄的值為zfs檔案系統的名稱,如oradata、oradata/prod, /device to fsck和fsck pass這二欄的值需為-,因為fsck這個指令無法使用在zfs這種格式的檔案系統,FS type當然就是zfs囉。
下面的範例是將帶你完成上述的需求。

# zpool create oraexp c2t2d0
# zfs get mountpoint oraexp
NAME PROPERTY VALUE SOURCE
oraexp mountpoint /oraexp default
# zfs set mountpoint=legacy oraexp
# vi /etc/vfstab
#device device mount FS fsck mount mount
#to mount to fsck point type pass at boot options
oraexp - /oraexp zfs - yes -
# mkdir /oraexp
# mount /oraexp
# df -h /oraexp
Filesystem size used avail capacity Mounted on
oraexp 976M 24K 976M 1% /oraexp

過了二個小時,DBA又跑來告訴你說他資料已經export好了,希望可以用nfs分享然後就可以直接import到另一台去 。於是你心下暗罵"這個煩人的傢伙"。當然你可以使用傳統的nfs分享方式,但ZFS已經把分享變簡單了。要分享檔案 你可以直接去編輯/etc/dfs/dfstab,或是使用設定sharenfs這個屬性

# zfs set sharenfs=on oraexp
# share

怎麼沒有東西呢?當zfs的mountpoint被設成legacy時,你就無法使用zfs的指令來分享必須要先將它改回來。

# zfs set sharenfs=off oraexp
# umount /oraexp
# zfs set mountpoint=/oraexp
# zfs set sharenfs=on oraexp
# share
- /oraexp rw ""

這會兒有了吧!我們再來看一個例子,在己分享的/oraexp下再建一個zfs出來,再用share來看看發生了什麼事。

# zfs create oraexp/son
# share
- /oraexp rw ""
- /oraexp/son rw ""

我們新建了一個叫son的zfs,用share一看他也被分享出來了,可是我們並沒有要分享呀!記得前面有提到過有些屬性是可繼承的,sharenfs就是其中一個,所以新建的son繼承了父親oraexp的值,也一併的分享出來了。
當我們設定sharenfs=on時,預設分享的權限是任何人都有rw的權限。看看上面share指令輸出的結果,對系統來講這是非常不安全的設定,當你在設定時請務必注意。一般我們會針對需要存取的主機設定不同的權限,如下面範例;

# zfs set sharenfs=ro=user1,rw=user2 oraexp
# share
- /oraexp ro=user1,rw=user2 ""

要停止分享時,可以使用如下的方式。第二個指令會停掉系統上所有的分享。

# zfs unshare oraexp/son
# zfs unshare -a

在Windows下,NTFS提供了檔案系統的壓縮功能,讓可用的磁碟空間比實際上的要來的多。ZFS也有提供這樣子的功能,但個人認為在現今每單位容量的成本越來越低的情況下,這樣的功能不具有太大的實質意義。大概只會在少數的情況下會使用如此的功能。如大量的檔案需要不定時的被存取,放在磁帶嫌太慢,放在磁碟又很佔空間。這個時候選擇低價的儲存系統加上壓縮的檔案系統會是最省錢的方法,但前提是不太要求存取的速度。
ZFS的屬性有一欄是compression,預設值是off,表示不開啟壓縮功能;若要開啟則將此值設定為on,這樣子就可以了。

# zpool create mypool c2t3d0
# zfs set compression=on mypool
# cd /mypool
# mkfile 200m 200file
# mkfile 500m 500file
# df -h /mypool
Filesystem size used avail capacity Mounted on
mypool 976M 24K 976M 1% /mypool
# ls -al
total 7
drwxr-xr-x 2 root sys 4 Sep 7 09:42 .
drwxr-xr-x 39 root root 1024 Sep 7 08:53 ..
-rw------T 1 root root 209715200 Sep 7 08:55 200file
-rw------T 1 root root 524288000 Sep 7 08:56 500file
# tar -cvf etc.tar /etc/*
# ls -al
total 45650
drwxr-xr-x 2 root sys 5 Sep 7 09:45 .
drwxr-xr-x 39 root root 1024 Sep 7 08:53 ..
-rw------T 1 root root 209715200 Sep 7 08:55 200file
-rw------T 1 root root 524288000 Sep 7 08:56 500file
-rw-r--r-- 1 root root 51942912 Sep 7 09:46 etc.tar
# df -h /mypool
Filesystem size used avail capacity Mounted on
mypool 976M 22M 954M 3% /mypool

上面的例子,新建了一個pool,並且開啟壓縮功能。然後產生了一個200MB和一個500MB的空白檔案,你可以比較ls,df和du的輸出有何不同。最後又產生了一個tar檔,但實際用到的空間仍然小於三個檔案的總和。你可以自行做類似的實驗,在每次產生一個檔案後執行如下的指令,
zfs get compressratio mypool
來觀察壓縮率的變化。最後要提醒的是壓縮功能的開啟一定會損耗系統的資源,而且會隨著檔案和存取的增加一同成長。是否要使用這個功能,除非不在乎系統的反應時間,否則實在沒必要開啟。

到這裡講的也都差不多了,基本的使用應該都不成問題。Solaris 10 的ZFS確實有其特色,但我的建議是,除非經過仔細的評估和測試,否則不要輕易的將之用在重要的正式系統上。另外使用時不同性質的需求最好建立不同的pool來使用。 以oracle為例,一般的datafile、redo、temp、archive log應該要放在不同的pool上,一來因為資料性質不同,二來存取的需求不同,放在不同的pool可便於辨識和管理,並且散在不同的實體硬碟上才會有最佳的效能。
在安裝Solaris時不曉得你有沒有注意到,安裝時並沒有可以選擇/檔案系統是要用UFS或ZFS。這是限制之一,因為現在的Solaris尚不能支援以ZFS為/目錄的檔案系統,至於/usr、/var能不能使用ZFS,我就不清楚了,建議系統的目錄還是使用 UFS,頂多搭配SVM應該就很夠用了。還有一個限制是,ZFS可以像AIX的LVM(5.0之後)或VxVM一樣任意的擴充檔案系統的空間,但是如果要縮小(回收過多的)空間時就不行了。這一點就比前述的二個要遜色不少。如果一定要把空間給縮小,只能把整個pool的資料備份出來然後打掉重建,再把資料倒回去。很麻煩吧!所以在給空間或建立pool時請仔細評估所需的空間大小,以免日後多了不必要的麻煩。

留言

這個網誌中的熱門文章

Unix下為你的檔案加密

Solaris - log的管理,使用logadm