در کنار فایل سیستمهای معروفی چون ReiserFS، EXT2/3/4، XFS و … از سال 2007 فایل سیستم دیگری هم به نام BTRFS شروع به توسعه یافت که قابلیتهای ویژه ای را به همراه دارد و بسیاری از کارهایی که با کمک LVM قابل انجام است را می توان با استفاده از آن انجام داد. با کمک این فایل سیستم، می توان چندین دیسک مختلف را بدون انجام پارتیشن بندی کنار هم قرار داد و با کمک آنها، فضای واحدی را ایجاد نمود. همچنین می توان حجم این فضا را به صورت انلاین، کم یا زیاد نمود و مهمتر آنکه، با استفاده از این فایل سیستم،می توان در دو سطح metadata و data در مورد striping و mirroring سیاستهایی را اعمال کرد از دیگر قابلیتهای این فایل سیستم، ایجاد subvolume و snapshot می باشد.
در ادامه این متن، به شیوه استفاده و مدیریت این فایل سیستم و همچنین بعضی از قابلیتهای آن خواهیم پرداخت.
ایجاد فایل سیستم
در ابتدا سه دیسک sdc، sdd و sde را به سیستم اضافه می کنیم که هر کدام فضایی معادل 1GB دارند:
[root@ol7 ~]# fdisk -l /dev/sdc /dev/sdd /dev/sde
Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sdd: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sde: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
با کمک دستور mkfs، فایل سیستم این سه دیسک را BTRFS تعیین می کنیم:
[root@ol7 ~]# mkfs.btrfs /dev/sdc /dev/sdd /dev/sde
btrfs-progs v4.9.1
See http://btrfs.wiki.kernel.org for more information.
Label: (null)
UUID: 779f1682-5800-44f2-81d8-812cd5e8045b
Node size: 16384
Sector size: 4096
Filesystem size: 3.00GiB
Block group profiles:
Data: RAID0 307.12MiB
Metadata: RAID1 153.56MiB
System: RAID1 8.00MiB
SSD detected: no
Incompat features: extref
Number of devices: 3
Devices:
ID SIZE PATH
1 1.00GiB /dev/sdc
2 1.00GiB /dev/sdd
3 1.00GiB /dev/sde
همانطور که در خروجی دستور قابل مشاهده است، سطح افزونگی برای metadata برابر با RAID1 می باشد و همچنین با تنظیم RAID0 برای data، صرفا striping برای آن انجام خواهد شد و از افزونگی در این لایه، خبری نخواهد بود. با این تنظیمات، اطلاعات مربوط به metadata، در دو مکان نوشته خواهد شد که با خراب شدن یکی از انها، به نقطه دیگر رجوع خواهد شد.
Mount کردن فضای BTRFS
همانطور که ملاحظه کردید، سه دیسک را با فایل سیستم BTRFS فرمت کردیم حال برای mount کردن این فضا به یک پوشه، چه باید کرد؟ کدام دیسک را باید به پوشه مورد نظر map کنیم؟ برای پاسخ به این سوال، از دستور blkid کمک می گیریم:
[root@ol7 ~]# blkid /dev/sdc
/dev/sdc: UUID=“881fe4c6-b695-46fa-9579-62d535512aa2” UUID_SUB=”df2cc3f2-4e37-470a-a624-416188c921b5″ TYPE=”btrfs”
[root@ol7 ~]# blkid /dev/sdd
/dev/sdd: UUID=“881fe4c6-b695-46fa-9579-62d535512aa2” UUID_SUB=”b3e8c7c7-31a2-408c-bdcb-7a8e7d6f2b55″ TYPE=”btrfs”
[root@ol7 ~]# blkid /dev/sde
/dev/sde: UUID=“881fe4c6-b695-46fa-9579-62d535512aa2” UUID_SUB=”52ed2250-a785-492d-bfa2-aa9e2d626fbe” TYPE=”btrfs”
همانطور که می بینید، هر سه دیسک، UUID یکسانی دارند پس برای انجام عملیات mount، می توانیم از UUID و یا اسامی هر کدام از این دیسکها استفاده کنیم:
[root@ol7 ~]# mkdir /btrfs1
[root@ol7 ~]# mount /dev/sdd /btrfs1
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc 3.0G 17M 2.6G 1% /btrfs1
نکته 1: استفاده از دستور df و du برای این نوع از فایل سیستم که از RAID در سطح metadata و data استفاده می کند، همیشه اطلاعات درستی را ارائه نخواهد کرد و بهتر است برای مشاهده فضای مصرفی این دسته از فضاها، از دستور زیر استفاده شود:
[root@ol7 ~]# btrfs filesystem df /btrfs1
نکته 2: با دستور زیر هم می توان uuid و دیگر مشخصات دیسکها را مشاهده کرد:
[root@ol7 ~]# btrfs filesystem show
Label: none uuid: 66e73097-0765-4b84-bbe0-ef87a335204b
Total devices 3 FS bytes used 112.00KiB
devid 1 size 1.00GiB used 20.00MiB path /dev/sdc
devid 2 size 1.00GiB used 0.00B path /dev/sdd
devid 3 size 1.00GiB used 0.00B path /dev/sde
تنظیم سطح افزونگی
برای تنظیم سطح mirroring و striping به شیوه دلخواه، می توانیم از دو سوییچ m برای metadata و d برای data استفاده کنیم برای مثال، با دستور زیر، سطح افزونگی برای data برابر با RAID1 تنظیم خواهد شد:
[root@ol7 ~]# mkfs.btrfs -f -d RAID1 /dev/sdc /dev/sdd /dev/sde
قسمتی از خروجی این دستور:
Block group profiles:
Data: RAID1 153.56MiB
Metadata: RAID1 153.56MiB
System: RAID1 8.00MiB
نکته: سوییچ f در دستور بالا، به معنی force می باشد و در صورت وجود فایل سیستم بر روی هر کدام از این دیسکها، بازنویسی بر روی ان انجام خواهد شد.
با این تنظیمات، فضای زیادی برای انجام افزونگی در سطح data از بین خواهد رفت:
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc 1.5G 17M 1015M 2% /btrfs1
همچنین با دستور زیر و با استفاده از عبارت single، می توان از mirroring و striping در دو لایه data و metadata صرفنظر کرد:
[root@ol7 ~]# mkfs.btrfs -f -d single -m single /dev/sdc /dev/sdd /dev/sde
قسمتی از خروجی این دستور:
Data: single 8.00MiB
Metadata: single 8.00MiB
System: single 4.00MiB
با این تنظیمات، بیشترین میزان فضای مصرفی، در دسترس خواهد بود:
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc 3.0G 17M 2.8G 1% /btrfs1
نکته: زمانی که تنها از یک دیسک استفاده می شود، به صورت پیش فرض، اطلاعات مربوط به metadata در دو نقطه از دیسک نوشته خواهد شد مگر انکه از عبارت single در زمان اجرای دستور mkfs استفاده شود.
بعد از ایجاد فایل سیستم، کماکان امکان تغییر سیاستها در مورد mirroring و striping وجود دارد. برای مثال، در صورتی که سطح افزونگی را برای data و metadata برابر با single قرار داده باشیم، می توانیم با کمک دستور زیر، به صورت آنلاین، سطح هر دو را به RAID1 تغییر دهیم:
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sde 3.0G 17M 2.8G 1% /btrfs1
[root@ol7 ~]# btrfs balance start -dconvert=raid1 -mconvert=raid1 /btrfs1
Done, had to relocate 4 out of 4 chunks
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sde 1.5G 17M 767M 3% /btrfs1
حذف و اضافه انلاین دیسک
یکی از قابلیتهای فایل سیستم BTRFS، حذف و اضافه انلاین دیسک می باشد. در ادامه قصد داریم دیسک sdf را به btrfs1/ اضافه کنیم. قبل از اضافه کردن دیسک، با دو دستور زیر، حجم مصرفی فعلی btrfs1/ را بررسی می کنیم:
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc 3.0G 517M 2.3G 19% /btrfs1
[root@ol7 ~]# btrfs filesystem df /btrfs1
Data, single: total=736.00MiB, used=500.25MiB
System, single: total=32.00MiB, used=16.00KiB
Metadata, single: total=256.00MiB, used=624.00KiB
GlobalReserve, single: total=16.00MiB, used=0.00B
با دستور زیر، دیسک sdf را به btrfs/ اضافه می کنیم:
[root@ol7 ~]# btrfs device add /dev/sdf /btrfs1
با اضافه کردن این فضا، فضای مصرفی دیسک را بررسی می کنیم:
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc 4.0G 517M 3.3G 14% /btrfs1
دستور زیر نشان می دهد که هنوز اطلاعاتی به دیسک sdf منتقل نشده است و اصطلاحا، دیسکها بالانس نیستند:
[root@ol7 ~]# btrfs filesystem show
Label: none uuid: 66e73097-0765-4b84-bbe0-ef87a335204b
Total devices 4 FS bytes used 500.81MiB
devid 1 size 1.00GiB used 340.00MiB path /dev/sdc
devid 2 size 1.00GiB used 256.00MiB path /dev/sdd
devid 3 size 1.00GiB used 320.00MiB path /dev/sde
devid 4 size 1.00GiB used 0.00B path /dev/sdf
نکته:برخلاف Oracle ASM که بعد از اضافه کردن دیسک؛ به صورت خودکار rebalancing را انجام می داد، در این نوع از فایل سیستم، باید به صورت دستی این کار انجام شود:
[root@ol7 ~]# btrfs filesystem balance /btrfs1
WARNING:
Full balance without filters requested. This operation is very
intense and takes potentially very long. It is recommended to
use the balance filters to narrow down the balanced data.
Use ‘btrfs balance start –full-balance’ option to skip this
warning. The operation will start in 10 seconds.
Use Ctrl-C to stop it.
10 9 8 7 6 5 4 3 2 1
Starting balance without any filters.
Done, had to relocate 6 out of 6 chunks
با انجام rebalancing به صورت دستی، مجددا وضیعت دیسکها را بررسی می کنیم:
[root@ol7 ~]# btrfs filesystem show
Label: none uuid: 66e73097-0765-4b84-bbe0-ef87a335204b
Total devices 4 FS bytes used 500.75MiB
devid 1 size 1.00GiB used 416.00MiB path /dev/sdc
devid 2 size 1.00GiB used 32.00MiB path /dev/sdd
devid 3 size 1.00GiB used 256.00MiB path /dev/sde
devid 4 size 1.00GiB used 416.00MiB path /dev/sdf
در ادامه قصد داریم دیسک sdc را بصورت انلاین از btrfs1/ حذف کنیم:
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdc 4.0G 17M 3.8G 1% /btrfs1
[root@ol7 ~]# btrfs device delete /dev/sdc /btrfs1
[root@ol7 ~]# df -h /btrfs1
Filesystem Size Used Avail Use% Mounted on
/dev/sdd 3.0G 17M 2.8G 1% /btrfs1
کاهش و افزایش اندازه دیسکها
در زمان استفاده از فایل سیستم BTRFS، می توان اندازه دیسکها را کاهش و یا در صورت امکان، افزایش داد. برای تغییر اندازه دیسکها، در صورتی که تنها از یک دیسک استفاده می کنیم، صرفا ذکر نام پوشه کافی می باشد ولی در صورتی که از چندین دیسک استفاده می کنیم، باید نام دیسک را هم مشخص کنیم.
برای مثال، btrfs2/ تنها یک دیسک با نام sdg را شامل می شود:
[root@ol7 ~]# mkfs.btrfs /dev/sdg
[root@ol7 ~]# mkdir /btrfs2
[root@ol7 ~]# mount /dev/sdg /btrfs2
پس می توان بدون ذکر نام دیسک، اندازه btrfs2/ را تغییر داد:
[root@ol7 ~]# btrfs filesystem resize -500m /btrfs2
Resize ‘/btrfs2’ of ‘-500m’
حال اگر بخواهیم فضای btrfs1/ که از دیسکهای مختلفی تشکیل می شود را تغییر دهیم، باید شماره دیسک را هم مشخص کنیم:
[root@ol7 ~]# btrfs filesystem show
Label: none uuid: bdf0974b-8562-4934-adcb-63fc100b467f
Total devices 3 FS bytes used 192.00KiB
devid 1 size 1.00GiB used 20.00MiB path /dev/sde
devid 2 size 1.00GiB used 256.00MiB path /dev/sdf
devid 3 size 1.00GiB used 0.00B path /dev/sdg
برای کم کردن 500M از حجم دیسک sdf می توان از دستور زیر استفاده کرد:
[root@ol7 ~]# btrfs filesystem resize 2:-500m /btrfs1
Resize ‘/btrfs1’ of ‘2:-500m’
[root@ol7 ~]# btrfs filesystem show
Label: none uuid: bdf0974b-8562-4934-adcb-63fc100b467f
Total devices 3 FS bytes used 192.00KiB
devid 1 size 1.00GiB used 20.00MiB path /dev/sde
devid 2 size 524.00MiB used 256.00MiB path /dev/sdf
devid 3 size 1.00GiB used 0.00B path /dev/sdg
نکته: در صورت عدم تعیین شماره دیسک، عدد مورد نظر، از حجم کلی دیسک شماره 1 کسر خواهد شد.
تبدیل ext2/3/4 به btrfs
در این قسمت قصد داریم تا فایل سیستم دیسک sdg که برابر با ext4 می باشد را به btrfs تغییر دهیم.برای انجام این تبدیل، ابتدا باید دیسک را از حالت mount خارج کنیم:
[root@ol7 ~]# umount /myext4
بعد از ان، دستور fsck را روی این دیسک اجرا کنیم:
[root@ol7 ~]# fsck -f /dev/sdg
fsck from util-linux 2.23.2
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdg: 12/65536 files (0.0% non-contiguous), 12956/262144 blocks
نهایتا تبدیل را انجام می دهیم:
[root@ol7 ~]# btrfs-convert /dev/sdg
create btrfs filesystem:
blocksize: 4096
nodesize: 16384
features: extref (default)
creating ext2 image file
creating btrfs metadatacopy inodes [o] [ 0/ 12]
ایجاد و مدیریت snapshot
در محیط BTRFS، ایجاد snapshot در سطح subvolume امکان پذیر می باشد پس قبل از ایجاد snapshot، باید با مفهوم subvolume آشنا باشیم.
در فایل سیستم BTRFS، می توان subvolumeهای متعددی را ایجاد نمود و آنها را مستقل از فایل سیستم اصلی، در حالت mount قرار داد. به عبارت دیگر، می توان بر روی یک دیسک، فایل سیستمهای متعددی را ایجاد کرد.
برای نمونه، subvolumeای به نام subvol1 را در زیر پوشه btrfs1/ ایجاد می کنیم:
[root@ol7 ~]# btrfs subvolume create /btrfs1/subvol1
Create subvolume ‘/btrfs1/subvol1’
[root@ol7 btrfs1]# ls -l
drwxr-xr-x 1 root root 0 Oct 14 11:00 subvol1
با دستور زیر، خواهیم دید که به این subvolume، شماره یکتا تخصیص داده شده است:
[root@ol7 ~]# btrfs subvolume list /btrfs1
ID 257 gen 8 top level 5 path subvol1
برای انجام تست، دو فایل را در این پوشه ایجاد می کنیم:
[root@ol7 ~]# dd if=/dev/zero of=/btrfs1/subvol1/myfile1 bs=500M count=2
2+0 records in
2+0 records out
1048576000 bytes (1.0 GB) copied, 1.65437 s, 634 MB/s
[root@ol7 ~]# echo “my name is usef.” > /btrfs1/subvol1/myfile2
[root@ol7 btrfs1]# cd /btrfs1/subvol1/
[root@ol7 subvol1]# ls -lih
257 -rw-r–r– 1 root root 1000M Oct 14 11:01 myfile1
258 -rw-r–r– 1 root root 11 Oct 14 11:01 myfile2
حال قصد داریم این subvolume را هم در حالت mount قرار دهیم:
[root@ol7 ~]# mount -o subvolid=257 /dev/sde /btrfs1
mount: /dev/sde is already mounted or /btrfs1 busy
/dev/sde is already mounted on /btrfs1
همانطور که می بینید، دستور با خطا متوقف شد! برای اجرای بدون خطای این دستور، ابتدا باید btrfs1/ را در حالت umount قرار داد:
[root@ol7 ~]# umount /btrfs1
[root@ol7 ~]# mount -o subvolid=257 /dev/sde /btrfs1
فضای مصرفی مربوط به این subvolume را با دستورات زیر مشاهده می کنید:
[root@ol7 ~]# df -h /btrfs1/
Filesystem Size Used Avail Use% Mounted on
/dev/sde 2.0G 1018M 826M 56% /btrfs1
[root@ol7 btrfs1]# btrfs filesystem df /btrfs1
Data, single: total=1.62GiB, used=1000.56MiB
System, single: total=4.00MiB, used=16.00KiB
Metadata, single: total=216.00MiB, used=1.17MiB
GlobalReserve, single: total=16.00MiB, used=0.00B
با اجرای این دستورات، subvol1 در حالت mount قرار گرفته و اطلاعات ان در دسترس خواهد بود:
[root@ol7 btrfs1]# ls -lih
257 -rw-r–r– 1 root root 1000M Oct 14 11:01 myfile1
258 -rw-r–r– 1 root root 11 Oct 14 11:01 myfile2
حال می توانیم از subvol1 اسنپ شات تهیه کنیم، قبل از اجرای دستور مربوطه، مجددا btrfs1/ را در حالت mount قرار می دهیم:
[root@ol7 ~]# umount /btrfs1
[root@ol7 ~]# mount /dev/sde /btrfs1
قبل از ایجاد snapshot، مجددا فضای مصرفی را مورد بررسی قرار می دهیم تا تاثیر snapshot را بر این فضا مشخص کنیم:
[root@ol7 ~]# df -h /btrfs1/
Filesystem Size Used Avail Use% Mounted on
/dev/sde 2.0G 1018M 826M 56% /btrfs1
در نهایت با دستور زیر، snapshot را ایجاد می کنیم:
[root@ol7 ~]# btrfs subvolume snapshot /btrfs1/subvol1 /btrfs1/subvol1-snapshot
Create a snapshot of ‘/btrfs1/subvol1’ in ‘/btrfs1/subvol1-snapshot’
فضای مصرفی btrfs1/ بدون تغییر مانده است:
[root@ol7 ~]# df -h /btrfs1/
Filesystem Size Used Avail Use% Mounted on
/dev/sde 2.0G 1018M 826M 56% /btrfs1
[root@ol7 ~]# btrfs filesystem df /btrfs1
Data, single: total=1.62GiB, used=1000.56MiB
System, single: total=4.00MiB, used=16.00KiB
Metadata, single: total=216.00MiB, used=1.19MiB
GlobalReserve, single: total=16.00MiB, used=0.00B
همچنین دستور زیر نشان می دهد که شماره inode فایلهای موجود در snapshot، برابر با شماره ان در subvol1 می باشد پس تا اینجا صرفا یک hard linkای از این فایلها ایجاد شده است:
[root@ol7 ~]# cd /btrfs1/subvol1-snapshot/
[root@ol7 subvol1-snapshot]# ls -ilh
257 -rw-r–r– 1 root root 1000M Oct 14 11:01 myfile1
258 -rw-r–r– 1 root root 11 Oct 14 11:01 myfile2
حال قصد داریم تغییری در فایل اصلی ایجاد کنیم و بعد از ان، شماره inode این فایلها را با هم مقایسه کنیم:
[root@ol7 subvol1]# ls -ilh myfile2
258 -rw-r–r– 1 root root 11 Oct 14 11:01 myfile2
[root@ol7 subvol1]# echo “my name is vahid.”>> myfile2
[root@ol7 subvol1]# ls -ilh myfile2
258 -rw-r–r– 1 root root 29 Oct 14 11:09 myfile2
همانطور که می بینید، کماکان تغییری در شماره inode فایل ایجاد نشده است! همچنین اگر فایل myfile1 را حذف کنیم، فضایی ازاد نخواهد شد:
[root@ol7 ~]# rm -rf /btrfs1/subvol1/myfile1
[root@ol7 ~]# df -h /btrfs1/
Filesystem Size Used Avail Use% Mounted on
/dev/sde 2.0G 1018M 826M 56% /btrfs1
[root@ol7 ~]# btrfs filesystem df /btrfs1
Data, single: total=1.62GiB, used=1000.56MiB
System, single: total=4.00MiB, used=16.00KiB
Metadata, single: total=216.00MiB, used=1.19MiB
GlobalReserve, single: total=16.00MiB, used=0.00B
برای برگرداندن فایل myfile1 باید subvol1-snapshot را در حالت mount قرار داد:
[root@ol7 ~]# btrfs subvolume list /btrfs1
ID 257 gen 20 top level 5 path subvol1
ID 266 gen 18 top level 5 path subvol1-snapshot
[root@ol7 ~]# umount /btrfs1
[root@ol7 ~]# mount -o subvolid=266 /dev/sde /btrfs1
[root@ol7 ~]# cd /btrfs1/
[root@ol7 btrfs1]# ls -ilh
257 -rw-r–r– 1 root root 1000M Oct 14 11:01 myfile1
258 -rw-r–r– 1 root root 11 Oct 14 11:01 myfile2
نکته: انجام عملیات snapshot با سرعت بالا و با مصرف فضای بسیار کم انجام می شود.
فشرده سازی
فایل سیستم BTRFS فشرده سازی را هم پشتیبانی می کند و می توان به کمک این قابلیت، به صورت خودکار، فشرده سازی را برای بهینه سازی عملیات i/o انجام داد. این کار با دو الگوریتم lzo و zlib قابل انجام است.
فشرده سازی با روش zlib:
[root@ol7 ~]# mount -o compress=zlib /dev/sde /btrfs1
فشرده سازی با روش lzo:
[root@ol7 ~]# mount -o compress=lzo /dev/sde /btrfs1
با فعال کردن این قابلیت، فشرده سازی برای اطلاعات جدید انجام خواهد شد.