به طور دورهای، برای انتقال به مرکز توزیع مرکزی، با شرکتهای بزرگ مختلف، عمدتاً در سن پترزبورگ و مسکو، برای یک موقعیت DevOps مصاحبه میکنم. من متوجه شدم که بسیاری از شرکت ها (بسیاری از شرکت های خوب، به عنوان مثال Yandex) دو سوال مشابه می پرسند:
- inode چیست;
- به چه دلایلی می توانید خطای نوشتن دیسک دریافت کنید (یا به عنوان مثال: چرا ممکن است فضای دیسک شما تمام شود، ماهیت یکسان است).
همانطور که اغلب اتفاق می افتد، مطمئن بودم که این موضوع را به خوبی می دانم، اما به محض اینکه شروع به توضیح کردم، شکاف هایی در دانش آشکار شد. برای اینکه دانش خود را نظام مند کنم، شکاف ها را پر کنم و دیگر خود را خجالت ندهم، این مقاله را می نویسم، شاید برای شخص دیگری مفید باشد.
من از پایین شروع می کنم، یعنی. از یک هارد دیسک (ما درایوهای فلش، SSD و سایر چیزهای مدرن را کنار می گذاریم؛ برای مثال، اجازه دهید هر درایو قدیمی 20 یا 80 گیگ را در نظر بگیریم، زیرا اندازه بلوک در آنجا 512 بایت است).
هارد دیسک نمی داند چگونه بایت به بایت فضای خود را آدرس دهی کند؛ به طور مشروط به بلوک ها تقسیم می شود. شماره گذاری بلوک از 0 شروع می شود. (این LBA نامیده می شود، جزئیات در اینجا:
همانطور که از شکل مشخص است، من بلوک های LBA را به عنوان سطح HDD تعیین کردم. به هر حال، می توانید ببینید که دیسک شما چه اندازه بلوکی دارد مانند این:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512
سطح بالا یک پارتیشن است، یکی برای کل دیسک (دوباره برای سادگی). اغلب از دو نوع نشانه گذاری پارتیشن استفاده می شود: msdos و gpt. بر این اساس، msdos یک فرمت قدیمی است که از دیسکهای تا 2 ترابایت پشتیبانی میکند، gpt فرمت جدیدی است که میتواند تا 1 زتابایت بلوک 512 بایتی را آدرسدهی کند. در مورد ما، ما یک پارتیشن از نوع msdos داریم، همانطور که از شکل مشخص است، پارتیشن با بلوک شماره 1 شروع می شود، در حالی که صفر برای MBR استفاده می شود.
در پارتیشن اول که یک فایل سیستم ext2 ایجاد کردم، اندازه بلوک پیش فرض آن 4096 بایت است که در شکل نیز منعکس شده است. شما می توانید اندازه بلوک سیستم فایل را به صورت زیر مشاهده کنید:
root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: a600bf40-f660-41f6-a3e6-96c303995479
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 65536
Block count: 261888
Reserved block count: 13094
Free blocks: 257445
Free inodes: 65525
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 63
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
Filesystem created: Fri Aug 2 15:02:13 2019
Last mount time: n/a
Last write time: Fri Aug 2 15:02:14 2019
Mount count: 0
Maximum mount count: -1
Last checked: Fri Aug 2 15:02:13 2019
Check interval: 0 (<none>)
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Default directory hash: half_md4
Directory Hash Seed: c0155456-ad7d-421f-afd1-c898746ccd76
پارامتر مورد نیاز ما "اندازه بلوک" است.
حال قسمت جالب این است که چگونه فایل /home/serp/testfile را بخوانیم؟ یک فایل شامل یک یا چند بلوک سیستم فایل است که داده های آن در آن ذخیره می شود. با دانستن نام فایل، چگونه آن را پیدا کنیم؟ کدام بلوک ها را باید بخوانم؟
اینجاست که inode ها به کار می آیند. سیستم فایل ext2fs دارای یک "جدول" است که حاوی اطلاعات برای همه inode ها است. تعداد inode ها در مورد ext2fs هنگام ایجاد سیستم فایل تنظیم می شود. ما به اعداد مورد نیاز در پارامتر "Inode count" خروجی tune2fs نگاه می کنیم، یعنی. ما 65536 قطعه داریم. inode حاوی اطلاعاتی است که ما نیاز داریم: لیستی از بلوک های سیستم فایل برای فایلی که به دنبال آن هستیم. چگونه شماره inode یک فایل مشخص را پیدا کنیم؟
نام و شماره inode مربوطه در دایرکتوری موجود است و دایرکتوری در ext2fs نوع خاصی از فایل است. همچنین شماره ایند مخصوص به خود را دارد. برای شکستن این دایره باطل، یک عدد inode "ثابت" "2" به دایرکتوری ریشه اختصاص داده شد. بیایید به محتویات inode شماره 2 نگاه کنیم:
root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs: stat <2>
Inode: 2 Type: directory Mode: 0755 Flags: 0x0
Generation: 0 Version: 0x00000000:00000002
User: 0 Group: 0 Size: 4096
File ACL: 0 Directory ACL: 0
Links: 3 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x5d43cb51:16b61bcc -- Fri Aug 2 16:34:09 2019
atime: 0x5d43c247:b704301c -- Fri Aug 2 15:55:35 2019
mtime: 0x5d43cb51:16b61bcc -- Fri Aug 2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fri Aug 2 15:02:14 2019
Size of extra inode fields: 28
BLOCKS:
(0):579
TOTAL: 1
همانطور که می بینید، دایرکتوری مورد نیاز ما در بلوک شماره 579 قرار دارد. در آن شماره گره را برای پوشه خانه پیدا می کنیم، و به همین ترتیب در زنجیره ادامه می دهیم تا در دایرکتوری serp شماره گره فایل درخواستی را مشاهده کنیم. اگر ناگهان کسی بخواهد بررسی کند که آیا شماره صحیح است و آیا اطلاعات لازم وجود دارد یا خیر، دشوار نیست. ما انجام می دهیم:
root@ubuntu:/# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 records in
1+0 records out
4096 bytes (4,1 kB) copied, 0,000184088 s, 22,3 MB/s
root@ubuntu:/# hexdump -c /home/serp/dd_image
در خروجی می توانید نام فایل های موجود در دایرکتوری را بخوانید.
بنابراین من به سوال اصلی می رسم: "به چه دلایلی ممکن است خطای ضبط رخ دهد؟"
به طور طبیعی، اگر هیچ بلوک رایگانی در سیستم فایل باقی نماند، این اتفاق می افتد. در این صورت چه می توان کرد؟ علاوه بر واضح "حذف هر چیزی غیر ضروری"، باید به خاطر داشته باشید که در سیستم های فایل ext2,3،4 و 13094 چیزی به نام "تعداد بلوک های رزرو شده" وجود دارد. اگر به لیست بالا نگاه کنید، ما "XNUMX" چنین بلوک هایی را داریم. این بلوک ها فقط توسط کاربر ریشه قابل نوشتن هستند. اما اگر نیاز به حل سریع مشکل دارید، به عنوان یک راه حل موقت می توانید آنها را در دسترس همه قرار دهید و در نتیجه فضای خالی ایجاد کنید:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)
آن ها به طور پیش فرض، شما 5 درصد از فضای دیسک را برای نوشتن در دسترس ندارید، و با توجه به حجم دیسک های مدرن، این می تواند صدها گیگابایت باشد.
چه چیز دیگری می تواند باشد؟ همچنین ممکن است بلوک های رایگان وجود داشته باشد، اما گره دیگری وجود نداشته باشد. این معمولاً زمانی اتفاق میافتد که تعداد زیادی فایل در سیستم فایل خود داشته باشید که کوچکتر از اندازه بلوک سیستم فایل هستند. با توجه به اینکه 1 inode روی 1 فایل یا دایرکتوری صرف می شود و در کل ما (برای یک سیستم فایل معین) 65536 داریم - وضعیت بیش از حد واقعی است. این را می توان به وضوح از خروجی دستور df مشاهده کرد:
serp@ubuntu:~$ df -hi
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 493K 480 492K 1% /dev
tmpfs 493K 425 493K 1% /run
/dev/xvda1 512K 240K 273K 47% /
none 493K 2 493K 1% /sys/fs/cgroup
none 493K 2 493K 1% /run/lock
none 493K 1 493K 1% /run/shm
none 493K 2 493K 1% /run/user
/dev/xvdc1 320K 4,1K 316K 2% /var
/dev/xvdb1 64K 195 64K 1% /home
/dev/xvdh1 4,0M 3,1M 940K 78% /var/www
serp@ubuntu:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 2,0G 4,0K 2,0G 1% /dev
tmpfs 395M 620K 394M 1% /run
/dev/xvda1 7,8G 2,9G 4,6G 39% /
none 4,0K 0 4,0K 0% /sys/fs/cgroup
none 5,0M 0 5,0M 0% /run/lock
none 2,0G 0 2,0G 0% /run/shm
none 100M 0 100M 0% /run/user
/dev/xvdc1 4,8G 2,6G 2,0G 57% /var
/dev/xvdb1 990M 4,0M 919M 1% /home
/dev/xvdh1 63G 35G 25G 59% /var/www
همانطور که به وضوح در پارتیشن /var/www قابل مشاهده است، تعداد بلوک های آزاد در سیستم فایل و تعداد گره های آزاد بسیار متفاوت است.
اگر اینودها تمام شود، هیچ طلسمی به شما نمی گویم، زیرا ... هیچ کدام وجود ندارد (اگر اشتباه می کنم، به من اطلاع دهید). بنابراین برای پارتیشن هایی که فایل های کوچک در آنها تکثیر می شوند، باید سیستم فایل را هوشمندانه انتخاب کنید. به عنوان مثال، btrfs inodes نمی تواند پایان یابد، زیرا در صورت لزوم، موارد جدید به صورت پویا ایجاد می شوند.
منبع: www.habr.com