LVM va Matryoshka o'rtasida qanday umumiylik bor?

Kunning xushmuomala vaqti.
Men md RAID + LVM yordamida KVM uchun ma'lumotlarni saqlash tizimini yaratish bo'yicha amaliy tajribamni hamjamiyat bilan baham ko'rmoqchiman.

Dastur quyidagilarni o'z ichiga oladi:

  • NVMe SSD-dan md RAID 1 qurish.
  • SATA SSD va oddiy drayverlardan md RAID 6 ni yig'ish.
  • SSD RAID 1/6 da TRIM/DISCARD operatsiyasining xususiyatlari.
  • Umumiy disklar to'plamida yuklanadigan md RAID 1/6 massivini yaratish.
  • BIOS-da NVMe-ni qo'llab-quvvatlamaganda tizimni NVMe RAID 1-ga o'rnatish.
  • LVM keshini va LVM nozik foydalanish.
  • BTRFS suratlaridan foydalanish va zaxiralash uchun yuborish/qabul qilish.
  • BTRFS uslubidagi zaxira nusxalari uchun LVM nozik suratlari va thin_delta dan foydalanish.

Agar qiziqsangiz, mushukni ko'ring.

Ariza shakli

Muallif ushbu maqoladagi materiallar/misollar/kod/maslahatlar/ma'lumotlardan foydalanish yoki foydalanmaslik oqibatlari uchun javobgarlikni o'z zimmasiga olmaydi. Ushbu materialni har qanday tarzda o'qish yoki foydalanish orqali siz ushbu harakatlarning barcha oqibatlari uchun javobgarlikni o'z zimmangizga olasiz. Mumkin bo'lgan oqibatlarga quyidagilar kiradi:

  • Qovurilgan NVMe SSD'lar.
  • Yozib olish resursi to'liq ishlatilgan va SSD drayverlari ishlamay qolgan.
  • Barcha drayvlardagi barcha ma'lumotlar, shu jumladan zaxira nusxalari to'liq yo'qoladi.
  • Noto'g'ri kompyuter uskunasi.
  • Vaqt, asab va pul behuda.
  • Yuqorida sanab o'tilmagan boshqa har qanday oqibatlar.

temir

Quyidagilar mavjud edi:

Taxminan 2013 yildan beri Z87 chipsetli, Intel Core i7 / Haswell bilan to'ldirilgan anakart.

  • Protsessor 4 yadro, 8 ta ip
  • 32 GB DDR3 operativ xotira
  • 1 x 16 yoki 2 x 8 PCIe 3.0
  • 1 x 4 + 1 x 1 PCIe 2.0
  • 6 x 6 GBps SATA 3 ulagichlari

SAS adapteri LSI SAS9211-8I IT / HBA rejimiga o'tdi. RAID-ni qo'llab-quvvatlaydigan proshivka ataylab HBA proshivka bilan almashtirildi:

  1. Istalgan vaqtda ushbu adapterni tashlab yuborishingiz va uni boshqasiga almashtirishingiz mumkin.
  2. TRIM/Discard odatda disklarda ishladi, chunki... RAID mikrodasturida bu buyruqlar umuman qo'llab-quvvatlanmaydi va HBA, umuman olganda, avtobus orqali qanday buyruqlar uzatilishiga ahamiyat bermaydi.

Qattiq disklar - 8 dona HGST Travelstar 7K1000 sig'imi 1 TB bo'lgan 2.5 format faktorli, noutbuklar uchun. Ushbu drayvlar ilgari RAID 6 qatorida edi. Ular yangi tizimda ham foydalanish imkoniyatiga ega bo'ladi. Mahalliy zaxira nusxalarini saqlash uchun.

Qo'shimcha ravishda:

6 dona SATA SSD modeli Samsung 860 QVO 2TB. Ushbu SSD-lar katta hajmni talab qildi, SLC keshining mavjudligi, ishonchliligi va past narx talab qilindi. Discard/nol uchun qo'llab-quvvatlash kerak edi, bu dmesg-dagi chiziq bilan tekshiriladi:

kernel: ata1.00: Enabling discard_zeroes_data

2 dona NVMe SSD modeli Samsung SSD 970 EVO 500GB.

Ushbu SSD-lar uchun tasodifiy o'qish/yozish tezligi va sizning ehtiyojlaringiz uchun resurs hajmi muhimdir. Ular uchun radiator. Majburiy. Mutlaqo. Aks holda, birinchi RAID sinxronizatsiyasi paytida ularni qizarguncha qovuring.

PCIe 8 2x uyasiga o'rnatilgan 2 x NVMe SSD uchun StarTech PEX2M3.0E8 adapteri. Bu yana HBA, lekin NVMe uchun. U arzon adapterlardan farq qiladi, chunki u o'rnatilgan PCIe kaliti mavjudligi sababli anakartdan PCIe bifurkatsiyani qo'llab-quvvatlashni talab qilmaydi. U hatto x1 PCIe 1.0 uyasi bo'lsa ham, PCIe bilan eng qadimiy tizimda ishlaydi. Tabiiyki, tegishli tezlikda. U erda RAIDlar yo'q. Bortda o'rnatilgan BIOS mavjud emas. Shunday qilib, sizning tizimingiz sehrli ravishda NVMe bilan yuklashni o'rganmaydi, bu qurilma tufayli NVMe RAID kamroq.

Ushbu komponent faqat tizimda faqat bitta bepul 8x PCIe 3.0 mavjudligi bilan bog'liq edi va agar 2 ta bo'sh uyalar mavjud bo'lsa, uni ikki tiyinlik PEX4M2E1 yoki analoglari bilan osongina almashtirish mumkin, ularni istalgan joyda 600 ga sotib olish mumkin. rubl.

Barcha turdagi apparat yoki o'rnatilgan chipset/BIOS RAIDlaridan voz kechish, barcha ma'lumotlarni saqlab qolgan holda, SSD/HDD-dan tashqari butun tizimni to'liq almashtirish imkoniyatiga ega bo'lish uchun ataylab qilingan. Ideal holda, butunlay yangi/boshqa uskunaga o'tishda o'rnatilgan operatsion tizimni ham saqlab qolishingiz mumkin. Asosiysi, SATA va PCIe portlari mavjud. Bu jonli CD yoki yuklanadigan flesh-diskga o'xshaydi, faqat juda tez va biroz katta hajmli.

XayoliyAks holda, nima sodir bo'lishini bilasiz - ba'zida olib ketish uchun zudlik bilan butun massivni o'zingiz bilan olib ketishingiz kerak bo'ladi. Lekin men ma'lumotlarni yo'qotishni xohlamayman. Buning uchun barcha eslatib o'tilgan ommaviy axborot vositalari standart korpusning 5.25 bo'shlig'idagi slaydlarda qulay tarzda joylashgan.

Xo'sh, va, albatta, Linuxda SSD keshlashning turli usullari bilan tajriba o'tkazish uchun.

Uskuna reydlari zerikarli. Uni yoqing. U ishlaydi yoki yo'q. Va mdadm bilan har doim variantlar mavjud.

Dasturiy ta'minot

Ilgari Debian 8 Jessie EOL ga yaqin bo'lgan uskunaga o'rnatilgan edi. RAID 6 LVM bilan bog'langan yuqorida aytib o'tilgan HDD-lardan yig'ilgan. U kvm/libvirt-da virtual mashinalarni ishga tushirdi.

Chunki Muallif portativ yuklanadigan SATA/NVMe flesh-disklarini yaratish bo'yicha tegishli tajribaga ega, shuningdek, odatiy apt shablonini buzmaslik uchun maqsadli tizim sifatida Ubuntu 18.04 tanlangan, u allaqachon etarlicha barqarorlashgan, ammo hali ham 3 yilga ega. kelajakda qo'llab-quvvatlash.

Yuqorida aytib o'tilgan tizim bizga kerak bo'lgan barcha apparat drayverlarini o'z ichiga oladi. Bizga uchinchi tomon dasturlari yoki drayverlari kerak emas.

O'rnatishga tayyorgarlik

Tizimni o'rnatish uchun bizga Ubuntu Desktop Image kerak. Server tizimida qandaydir kuchli o'rnatuvchi mavjud bo'lib, u haddan tashqari mustaqillikni ko'rsatadi, uni UEFI tizim qismini disklardan biriga surish orqali o'chirib bo'lmaydi va butun go'zallikni buzadi. Shunga ko'ra, u faqat UEFI rejimida o'rnatiladi. Hech qanday variantni taklif qilmaydi.

Biz bundan mamnun emasmiz.

ΠŸΠΎΡ‡Π΅ΠΌΡƒ?Afsuski, UEFI yuklash RAID yuklash dasturi bilan juda yomon mos keladi, chunki... Hech kim bizga UEFI ESP bo'limi uchun bron qilishni taklif qilmaydi. Internetda ESP qismini USB portidagi flesh-diskga joylashtirishni taklif qiladigan retseptlar mavjud, ammo bu muvaffaqiyatsizlik nuqtasidir. 1 metadata versiyasiga ega mdadm RAID 0.9 dasturiy ta'minotidan foydalanadigan retseptlar mavjud bo'lib, ular UEFI BIOS-ning ushbu bo'limni ko'rishiga to'sqinlik qilmaydi, ammo bu BIOS yoki boshqa apparat OT ESP-ga biror narsa yozib, uni boshqasiga sinxronlashtirishni unutib qo'yadigan baxtli daqiqagacha yashaydi. oynalar.

Bundan tashqari, UEFI yuklanishi NVRAM-ga bog'liq bo'lib, u disklar bilan birga yangi tizimga o'tmaydi, chunki anakartning bir qismidir.

Shunday qilib, biz yangi g'ildirakni qayta ixtiro qilmaymiz. Bizda allaqachon vaqt sinovidan o'tgan, hozirda Legacy/BIOS yuklash deb ataladigan, UEFI-mos keluvchi tizimlarda CSM degan g'ururli nomga ega bo'lgan boboning velosipedi bor. Biz uni faqat javondan olib tashlaymiz, moylaymiz, shinalarni pompalaymiz va nam latta bilan artamiz.

Ubuntu-ning ish stoli versiyasini ham Legacy bootloader bilan to'g'ri o'rnatib bo'lmaydi, lekin bu erda, ular aytganidek, hech bo'lmaganda variantlar mavjud.

Shunday qilib, biz uskunani yig'amiz va tizimni Ubuntu Live yuklanadigan flesh-diskidan yuklaymiz. Biz paketlarni yuklab olishimiz kerak, shuning uchun biz sizga mos keladigan tarmoqni o'rnatamiz. Agar u ishlamasa, kerakli paketlarni flesh-diskga oldindan yuklashingiz mumkin.

Biz Ish stoli muhitiga o'tamiz, terminal emulyatorini ishga tushiramiz va o'chaymiz:

#sudo bash

Qanaqasiga…?Yuqoridagi chiziq sudo haqida xolivarlar uchun kanonik tetikdir. C bΠΎkatta imkoniyatlar keladi vaΠΎkatta mas'uliyat. Savol shundaki, siz buni o'zingiz qabul qila olasizmi? Ko'pchilik sudo-ni shu tarzda ishlatish hech bo'lmaganda ehtiyotkor bo'lmaydi deb o'ylashadi. Biroq:

#apt-get install mdadm lvm2 thin-provisioning-tools btrfs-tools util-linux lsscsi nvme-cli mc

Nega ZFS emas...?Biz dasturiy ta'minotni kompyuterimizga o'rnatganimizda, biz asosan ushbu dasturiy ta'minotni ishlab chiquvchilarga haydash uchun o'z uskunamizni qarzga beramiz.
Biz ushbu dasturiy ta'minotga ma'lumotlarimiz xavfsizligiga ishonganimizda, biz ushbu ma'lumotlarni qayta tiklash narxiga teng qarz olamiz, biz buni bir kun kelib to'lashimiz kerak bo'ladi.

Shu nuqtai nazardan qaraganda, ZFS Ferrari, mdadm+lvm esa ko'proq velosipedga o'xshaydi.

Subyektiv tomondan muallif Ferrari oβ€˜rniga noma’lum shaxslarga kreditga velosiped berishni ma’qul koβ€˜radi. U erda masalaning narxi yuqori emas. Huquqlar kerak emas. Yo'l harakati qoidalariga qaraganda oddiyroq. Avtoturargoh bepul. Kross-country qobiliyati yaxshiroq. Siz har doim oyoqlarni velosipedga ulashingiz mumkin va velosipedni o'z qo'llaringiz bilan ta'mirlashingiz mumkin.

Nega unda BTRFS...?Operatsion tizimni yuklash uchun bizga Legacy/BIOS GRUB-da qutidan tashqarida qo'llab-quvvatlanadigan va ayni paytda jonli suratlarni qo'llab-quvvatlaydigan fayl tizimi kerak. Biz uni /boot bo'limi uchun ishlatamiz. Bundan tashqari, muallif ushbu FS-dan / (ildiz) uchun foydalanishni afzal ko'radi, boshqa har qanday dasturiy ta'minot uchun siz LVM-da alohida bo'limlarni yaratishingiz va ularni kerakli kataloglarga o'rnatishingiz mumkinligini unutmang.

Biz ushbu FSda virtual mashinalar yoki ma'lumotlar bazalarining rasmlarini saqlamaymiz.
Ushbu FS faqat tizimni o'chirmasdan oniy tasvirlarni yaratish va keyin yuborish/qabul qilish orqali ushbu oniy tasvirlarni zaxira diskiga o'tkazish uchun ishlatiladi.

Bundan tashqari, muallif odatda minimal dasturiy ta'minotni to'g'ridan-to'g'ri apparatda saqlashni va boshqa barcha dasturiy ta'minotni virtual mashinalarda GPU va PCI-USB Xost kontrollerlarini IOMMU orqali KVM ga yo'naltirishni afzal ko'radi.

Uskunada faqat ma'lumotlarni saqlash, virtualizatsiya va zaxiralash qoladi.

Agar siz ZFS-ga ko'proq ishonsangiz, u holda, qoida tariqasida, belgilangan dastur uchun ular bir-birini almashtiradi.

Biroq, muallif ZFS, BRTFS va LVM-ga ega bo'lgan o'rnatilgan aks ettirish/RAID va ortiqcha xususiyatlarni ataylab e'tiborsiz qoldiradi.

Qo'shimcha dalil sifatida, BTRFS tasodifiy yozishni ketma-ket yozish qobiliyatiga ega, bu HDD-da oniy tasvirlar/zaxira nusxalarini sinxronlashtirish tezligiga juda ijobiy ta'sir ko'rsatadi.

Keling, barcha qurilmalarni qayta tekshiramiz:

#udevadm control --reload-rules && udevadm trigger

Keling, atrofga qaraylik:

#lsscsi && nvme list
[0:0:0:0] disk ATA Samsung SSD 860 2B6Q /dev/sda
[1:0:0:0] disk ATA Samsung SSD 860 2B6Q /dev/sdb
[2:0:0:0] disk ATA Samsung SSD 860 2B6Q /dev/sdc
[3:0:0:0] disk ATA Samsung SSD 860 2B6Q /dev/sdd
[4:0:0:0] disk ATA Samsung SSD 860 2B6Q /dev/sde
[5:0:0:0] disk ATA Samsung SSD 860 2B6Q /dev/sdf
[6:0:0:0] disk ATA HGST HTS721010A9 A3J0 /dev/sdg
[6:0:1:0] disk ATA HGST HTS721010A9 A3J0 /dev/sdh
[6:0:2:0] disk ATA HGST HTS721010A9 A3J0 /dev/sdi
[6:0:3:0] disk ATA HGST HTS721010A9 A3B0 /dev/sdj
[6:0:4:0] disk ATA HGST HTS721010A9 A3B0 /dev/sdk
[6:0:5:0] disk ATA HGST HTS721010A9 A3B0 /dev/sdl
[6:0:6:0] disk ATA HGST HTS721010A9 A3J0 /dev/sdm
[6:0:7:0] disk ATA HGST HTS721010A9 A3J0 /dev/sdn
Node SN Model Namespace Usage Format FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 S466NXXXXXXX15L Samsung SSD 970 EVO 500GB 1 0,00 GB / 500,11 GB 512 B + 0 B 2B2QEXE7
/dev/nvme1n1 S5H7NXXXXXXX48N Samsung SSD 970 EVO 500GB 1 0,00 GB / 500,11 GB 512 B + 0 B 2B2QEXE7

Diskning joylashuvi

NVMe SSD

Lekin biz ularni hech qanday tarzda belgilamaymiz. Shunga qaramay, bizning BIOS bu drayverlarni ko'rmaydi. Shunday qilib, ular butunlay RAID dasturiy ta'minotiga o'tadilar. Biz u erda bo'limlar ham yaratmaymiz. Agar siz "kanon" yoki "asosan" ga amal qilmoqchi bo'lsangiz, HDD kabi bitta katta bo'lim yarating.

SATA qattiq disk

Bu erda hech qanday maxsus narsani ixtiro qilishning hojati yo'q. Biz hamma narsa uchun bitta bo'lim yaratamiz. Biz bo'lim yaratamiz, chunki BIOS bu disklarni ko'radi va hatto ulardan yuklashga harakat qilishi mumkin. Keyinchalik bu disklarga GRUBni o'rnatamiz, shunda tizim to'satdan buni qila oladi.

#cat >hdd.part << EOF
label: dos
label-id: 0x00000000
device: /dev/sdg
unit: sectors

/dev/sdg1 : start= 2048, size= 1953523120, type=fd, bootable
EOF
#sfdisk /dev/sdg < hdd.part
#sfdisk /dev/sdh < hdd.part
#sfdisk /dev/sdi < hdd.part
#sfdisk /dev/sdj < hdd.part
#sfdisk /dev/sdk < hdd.part
#sfdisk /dev/sdl < hdd.part
#sfdisk /dev/sdm < hdd.part
#sfdisk /dev/sdn < hdd.part

Sotilgan SSD

Bu erda narsalar biz uchun qiziqarli bo'ladi.

Birinchidan, bizning drayvlarimiz 2 TB hajmga ega. Bu MBR uchun maqbul diapazonda, biz foydalanamiz. Agar kerak bo'lsa, GPT bilan almashtirilishi mumkin. GPT disklari MBR-mos keladigan tizimlarga, agar ular dastlabki 4 terabayt ichida joylashgan bo'lsa, dastlabki 2 bo'limni ko'rish imkonini beruvchi muvofiqlik qatlamiga ega. Asosiysi, ushbu disklardagi yuklash bo'limi va bios_grub bo'limi boshida bo'lishi kerak. Bu hatto GPT Legacy/BIOS drayverlaridan yuklash imkonini beradi.

Ammo bu bizning holatimizda emas.

Bu erda biz ikkita bo'lim yaratamiz. Birinchisi 1 GB hajmda bo'ladi va RAID 1 / yuklash uchun ishlatiladi.

Ikkinchisi RAID 6 uchun ishlatiladi va disk oxirida kichik ajratilmagan maydondan tashqari qolgan barcha bo'sh joyni egallaydi.

Bu belgilanmagan hudud nima?Tarmoqdagi manbalarga ko'ra, bizning SATA SSD-larimiz bortida 6 dan 78 gigabaytgacha bo'lgan o'lchamdagi dinamik ravishda kengaytiriladigan SLC keshiga ega. Drayvning ma'lumotlar varag'idagi "gigabaytlar" va "gibibaytlar" o'rtasidagi farq tufayli biz 6 gigabaytni "bepul" olamiz. Qolgan 72 gigabayt foydalanilmagan joydan ajratilgan.

Bu erda shuni ta'kidlash kerakki, bizda SLC keshi bor va bo'sh joy 4 bitli MLC rejimida band. Bu biz uchun samarali degani, har 4 gigabayt bo'sh joy uchun biz faqat 1 gigabayt SLC keshini olamiz.

72 gigabaytni 4 ga ko'paytiring va 288 gigabaytni oling. Bu disklarga SLC keshidan to'liq foydalanishga ruxsat berish uchun biz belgilamaydigan bo'sh joy.

Shunday qilib, biz jami oltita diskdan 312 gigabaytgacha SLC keshini samarali olamiz. Barcha drayverlardan 2 tasi RAID da ortiqcha uchun ishlatiladi.

Keshning bunday miqdori real hayotda kamdan-kam hollarda yozish keshga kirmaydigan vaziyatga duch kelishimizga imkon beradi. Bu QLC xotirasining eng achinarli kamchiligini juda yaxshi qoplaydi - ma'lumotlar keshni chetlab o'tib yozilganda juda past yozish tezligi. Agar sizning yuklaringiz bunga mos kelmasa, men sizga ma'lumotlar varag'idagi TBWni hisobga olgan holda SSD-ning bunday yuk ostida qancha davom etishi haqida yaxshilab o'ylab ko'rishingizni maslahat beraman.

#cat >ssd.part << EOF
label: dos
label-id: 0x00000000
device: /dev/sda
unit: sectors

/dev/sda1 : start= 2048, size= 2097152, type=fd, bootable
/dev/sda2 : start= 2099200, size= 3300950016, type=fd
EOF
#sfdisk /dev/sda < ssd.part
#sfdisk /dev/sdb < ssd.part
#sfdisk /dev/sdc < ssd.part
#sfdisk /dev/sdd < ssd.part
#sfdisk /dev/sde < ssd.part
#sfdisk /dev/sdf < ssd.part

Massivlarni yaratish

Birinchidan, biz mashina nomini o'zgartirishimiz kerak. Bu zarur, chunki xost nomi mdadm ichidagi massiv nomining bir qismidir va biror joyda biror narsaga ta'sir qiladi. Albatta, massivlarni keyinroq nomlash mumkin, ammo bu keraksiz qadamdir.

#mcedit /etc/hostname
#mcedit /etc/hosts
#hostname
vdesk0

NVMe SSD

#mdadm --create --verbose --assume-clean /dev/md0 --level=1 --raid-devices=2 /dev/nvme[0-1]n1

Nima uchun -taxmin-toza...?Massivlarni ishga tushirishdan qochish uchun. RAID 1 va 6 darajalari uchun bu amal qiladi. Agar u yangi massiv bo'lsa, hamma narsa ishga tushirilmasdan ishlashi mumkin. Bundan tashqari, yaratilgandan so'ng SSD massivini ishga tushirish TBW resursini behuda sarflashdir. Biz yig'ilgan SSD massivlarida ularni "boshlash" uchun iloji bo'lsa TRIM/DISCARD dan foydalanamiz.

SSD massivlari uchun RAID 1 DISCARD qutidan tashqarida qo'llab-quvvatlanadi.

SSD RAID 6 DISCARD massivlari uchun uni yadro moduli parametrlarida yoqishingiz kerak.

Buni faqat ushbu tizimdagi 4/5/6-darajali massivlarda ishlatiladigan barcha SSD disklar discard_zeroes_data uchun ishlaydigan qo'llab-quvvatlasagina qilish kerak. Ba'zan siz yadroga ushbu funktsiya qo'llab-quvvatlanishini aytadigan g'alati drayvlarga duch kelasiz, lekin aslida u mavjud emas yoki funksiya har doim ham ishlamaydi. Ayni paytda qo'llab-quvvatlash deyarli hamma joyda mavjud, ammo eski drayvlar va xatolarga ega proshivka mavjud. Shu sababli, RAID 6 uchun sukut bo'yicha DISCARD yordami o'chirib qo'yilgan.

Diqqat, quyidagi buyruq massivni β€œnol” bilan β€œboshlash” orqali NVMe drayverlaridagi barcha ma’lumotlarni yoβ€˜q qiladi.

#blkdiscard /dev/md0

Agar biror narsa noto'g'ri bo'lsa, qadamni belgilab ko'ring.

#blkdiscard --step 65536 /dev/md0

Sotilgan SSD

#mdadm --create --verbose --assume-clean /dev/md1 --level=1 --raid-devices=6 /dev/sd[a-f]1
#blkdiscard /dev/md1
#mdadm --create --verbose --assume-clean /dev/md2 --chunk-size=512 --level=6 --raid-devices=6 /dev/sd[a-f]2

Nega bunchalik katta...?Bo'lak o'lchamini oshirish blok o'lchamigacha bo'lgan bloklarda tasodifiy o'qish tezligiga ijobiy ta'sir ko'rsatadi. Buning sababi, tegishli o'lchamdagi yoki undan kichikroq operatsiyani butunlay bitta qurilmada bajarish mumkin. Shuning uchun barcha qurilmalardan olingan IOPS yig'iladi. Statistik ma'lumotlarga ko'ra, IO ning 99% 512K dan oshmaydi.

Har bir yozish uchun RAID 6 IOPS har doim bitta drayverning IOPS dan kam yoki unga teng. Tasodifiy o'qish sifatida IOPS bitta diskdan bir necha baravar ko'p bo'lishi mumkin va bu erda blokning o'lchami muhim ahamiyatga ega.
Muallif RAID 6 by-dizaynida yomon bo'lgan parametrni optimallashtirishga urinishning ma'nosini ko'rmaydi va buning o'rniga RAID 6 nima yaxshi ekanligini optimallashtiradi.
Biz RAID 6 ning noto'g'ri tasodifiy yozishini NVMe keshi va nozik provayderlar yordamida qoplaymiz.

Biz RAID 6 uchun DISCARD funksiyasini hali yoqmaganmiz. Shuning uchun biz hozircha bu massivni β€œboshlamaymiz”. Biz buni keyinroq, OSni o'rnatgandan so'ng qilamiz.

SATA qattiq disk

#mdadm --create --verbose --assume-clean /dev/md3 --chunk-size=512 --level=6 --raid-devices=8 /dev/sd[g-n]1

NVMe RAID-da LVM

Tezlik uchun biz ildiz fayl tizimini /dev/md1 bo'lgan NVMe RAID 0-ga joylashtirmoqchimiz.
Biroq, biz bu tezkor massivni almashtirish, metama'lumotlar va LVM-kesh va LVM-nozik metadata kabi boshqa ehtiyojlar uchun kerak bo'ladi, shuning uchun biz ushbu massivda LVM VG yaratamiz.

#pvcreate /dev/md0
#vgcreate root /dev/md0

Keling, ildiz fayl tizimi uchun bo'lim yarataylik.

#lvcreate -L 128G --name root root

Operativ xotira hajmiga ko'ra almashtirish uchun bo'lim yarataylik.

#lvcreate -L 32G --name swap root

OS o'rnatish

Umuman olganda, bizda tizimni o'rnatish uchun hamma narsa mavjud.

Ubuntu Live muhitidan tizim o'rnatish ustasini ishga tushiring. Oddiy o'rnatish. Faqat o'rnatish uchun disklarni tanlash bosqichida siz quyidagilarni ko'rsatishingiz kerak:

  • /dev/md1, - o'rnatish nuqtasi / yuklash, FS - BTRFS
  • /dev/root/root (a.k.a /dev/mapper/root-root), - o'rnatish nuqtasi / (root), FS - BTRFS
  • /dev/root/swap (a.k.a /dev/mapper/root-swap), - almashtirish bo'limi sifatida foydalaning
  • Bootloaderni /dev/sda-ga o'rnating

Ildiz fayl tizimi sifatida BTRFS ni tanlaganingizda, o'rnatuvchi avtomatik ravishda / (root) uchun "@" va /home uchun "@home" nomli ikkita BTRFS jildlarini yaratadi.

O'rnatishni boshlaylik ...

O'rnatish yuklovchini o'rnatishda xatolikni ko'rsatadigan modal dialog oynasi bilan yakunlanadi. Afsuski, siz standart vositalar yordamida ushbu dialog oynasidan chiqa olmaysiz va o'rnatishni davom ettira olmaysiz. Biz tizimdan chiqamiz va yana tizimga kiramiz va toza Ubuntu Live ish stoli bilan yakunlaymiz. Terminalni oching va yana:

#sudo bash

O'rnatishni davom ettirish uchun chroot muhitini yarating:

#mkdir /mnt/chroot
#mount -o defaults,space_cache,noatime,nodiratime,discard,subvol=@ /dev/mapper/root-root /mnt/chroot
#mount -o defaults,space_cache,noatime,nodiratime,discard,subvol=@home /dev/mapper/root-root /mnt/chroot/home
#mount -o defaults,space_cache,noatime,nodiratime,discard /dev/md1 /mnt/chroot/boot
#mount --bind /proc /mnt/chroot/proc
#mount --bind /sys /mnt/chroot/sys
#mount --bind /dev /mnt/chroot/dev

Keling, chroot-da tarmoq va xost nomini sozlaymiz:

#cat /etc/hostname >/mnt/chroot/etc/hostname
#cat /etc/hosts >/mnt/chroot/etc/hosts
#cat /etc/resolv.conf >/mnt/chroot/etc/resolv.conf

Keling, chroot muhitiga o'tamiz:

#chroot /mnt/chroot

Avvalo, biz paketlarni yetkazib beramiz:

apt-get install --reinstall mdadm lvm2 thin-provisioning-tools btrfs-tools util-linux lsscsi nvme-cli mc debsums hdparm

Keling, tizimni to'liq o'rnatmaganligi sababli egri o'rnatilgan barcha paketlarni tekshiramiz va tuzatamiz:

#CORRUPTED_PACKAGES=$(debsums -s 2>&1 | awk '{print $6}' | uniq)
#apt-get install --reinstall $CORRUPTED_PACKAGES

Agar biror narsa ishlamasa, avval /etc/apt/sources.list ni tahrirlashingiz kerak bo'lishi mumkin

TRIM/DISCARD funksiyasini yoqish uchun RAID 6 moduli parametrlarini sozlaymiz:

#cat >/etc/modprobe.d/raid456.conf << EOF
options raid456 devices_handle_discard_safely=1
EOF

Keling, massivlarimizni biroz o'zgartiramiz:

#cat >/etc/udev/rules.d/60-md.rules << EOF
SUBSYSTEM=="block", KERNEL=="md*", ACTION=="change", TEST=="md/stripe_cache_size", ATTR{md/stripe_cache_size}="32768"
SUBSYSTEM=="block", KERNEL=="md*", ACTION=="change", TEST=="md/sync_speed_min", ATTR{md/sync_speed_min}="48000"
SUBSYSTEM=="block", KERNEL=="md*", ACTION=="change", TEST=="md/sync_speed_max", ATTR{md/sync_speed_max}="300000"
EOF
#cat >/etc/udev/rules.d/62-hdparm.rules << EOF
SUBSYSTEM=="block", ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", RUN+="/sbin/hdparm -B 254 /dev/%k"
EOF
#cat >/etc/udev/rules.d/63-blockdev.rules << EOF
SUBSYSTEM=="block", ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", RUN+="/sbin/blockdev --setra 1024 /dev/%k"
SUBSYSTEM=="block", ACTION=="add|change", KERNEL=="md*", RUN+="/sbin/blockdev --setra 0 /dev/%k"
EOF

Bu nima edi..?Biz quyidagilarni amalga oshiradigan udev qoidalari to'plamini yaratdik:

  • RAID 2020 uchun blok kesh hajmini 6 yilga mos qilib belgilang. Ko'rinib turibdiki, standart qiymat Linux yaratilganidan beri o'zgarmagan va uzoq vaqt davomida etarli bo'lmagan.
  • Massivni tekshirish/sinxronizatsiya qilish uchun minimal IO ni zahiraga qo'ying. Bu sizning massivlaringiz yuk ostida abadiy sinxronizatsiya holatida qolib ketishining oldini olish uchundir.
  • Massivlarni tekshirish/sinxronlashtirish vaqtida maksimal IO ni cheklang. Bu SSD RAID-larni sinxronlashtirish/tekshirish drayverlarni qattiq qizdirmasligi uchun kerak. Bu, ayniqsa, NVMe uchun to'g'ri keladi. (Radiator haqida eslaysizmi? Men hazil qilmadim.)
  • Disklarni APM orqali mil aylanishini (HDD) to'xtatishni taqiqlang va disk kontrollerlari uchun uyqu vaqtini 7 soatga o'rnating. Agar drayvlaringiz buni qila olsa, APMni butunlay o'chirib qo'yishingiz mumkin (-B 255). Standart qiymat bilan drayvlar besh soniyadan keyin to'xtaydi. Keyin OS disk keshini tiklashni xohlaydi, disklar yana aylanadi va hamma narsa qaytadan boshlanadi. Disklarda shpindel aylanishlarining maksimal soni cheklangan. Bunday oddiy standart tsikl disklaringizni bir necha yil ichida osongina o'ldirishi mumkin. Hamma disklar bundan aziyat chekmaydi, lekin bizniki "noutbuk" bo'lib, tegishli standart sozlamalari bilan RAID mini-MAIDga o'xshaydi.
  • Oldindan o'qishni disklarga o'rnatish (aylanuvchi) 1 megabayt - ketma-ket ikkita blok/bo'lak RAID 6
  • Massivlarning o'zida o'qishni o'chirib qo'ying.

Keling, /etc/fstab ni tahrirlaymiz:

#cat >/etc/fstab << EOF
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
# file-system mount-point type options dump pass
/dev/mapper/root-root / btrfs defaults,space_cache,noatime,nodiratime,discard,subvol=@ 0 1
UUID=$(blkid -o value -s UUID /dev/md1) /boot btrfs defaults,space_cache,noatime,nodiratime,discard 0 2
/dev/mapper/root-root /home btrfs defaults,space_cache,noatime,nodiratime,discard,subvol=@home 0 2
/dev/mapper/root-swap none swap sw 0 0
EOF

Nega bunday..?UUID orqali /boot bo'limini qidiramiz. Massiv nomlanishi nazariy jihatdan o'zgarishi mumkin.

Qolgan bo'limlarni /dev/mapper/vg-lv yozuvida LVM nomlari bo'yicha qidiramiz, chunki ular bo'limlarni juda noyob tarzda aniqlaydilar.

Biz LVM uchun UUID dan foydalanmaymiz, chunki LVM hajmlarining UUID va ularning suratlari bir xil bo'lishi mumkin.Mount /dev/mapper/root-root .. ikki marta?Ha. Aynan shunday. BTRFS xususiyati. Ushbu fayl tizimi turli subvollar bilan bir necha marta o'rnatilishi mumkin.

Xuddi shu xususiyat tufayli men hech qachon faol BTRFS hajmlarining LVM suratlarini yaratmaslikni tavsiya qilaman. Qayta ishga tushirganingizda ajablanib olishingiz mumkin.

Keling, mdadm konfiguratsiyasini qayta tiklaylik:

#/usr/share/mdadm/mkconf | sed 's/#DEVICE/DEVICE/g' >/etc/mdadm/mdadm.conf

LVM sozlamalarini sozlaymiz:

#cat >>/etc/lvm/lvmlocal.conf << EOF

activation {
thin_pool_autoextend_threshold=90
thin_pool_autoextend_percent=5
}
allocation {
cache_pool_max_chunks=2097152
}
devices {
global_filter=["r|^/dev/.*_corig$|","r|^/dev/.*_cdata$|","r|^/dev/.*_cmeta$|","r|^/dev/.*gpv$|","r|^/dev/images/.*$|","r|^/dev/mapper/images.*$|","r|^/dev/backup/.*$|","r|^/dev/mapper/backup.*$|"] issue_discards=1
}
EOF

Bu nima edi..?Biz ishg'ol qilingan maydonning 90% hajmining 5% ga yetgandan so'ng, LVM yupqa hovuzlarini avtomatik ravishda kengaytirishni yoqdik.

Biz LVM keshi uchun kesh bloklarining maksimal sonini oshirdik.

Biz LVM ning LVM hajmlarini (PV) qidirishini oldini oldik:

  • LVM keshini o'z ichiga olgan qurilmalar (cdata)
  • LVM keshi yordamida keshlangan qurilmalar keshni chetlab o'tadi (_corig). Bunday holda, keshlangan qurilmaning o'zi hali ham kesh orqali tekshiriladi (faqat ).
  • LVM kesh metama'lumotlarini o'z ichiga olgan qurilmalar (cmeta)
  • nomi tasvirlar bilan VG barcha qurilmalar. Bu erda biz virtual mashinalarning diskdagi tasvirlariga ega bo'lamiz va biz hostdagi LVM mehmon OS ga tegishli hajmlarni faollashtirishini xohlamaymiz.
  • nomi zahiraga ega VG barcha qurilmalar. Bu erda biz virtual mashina tasvirlarining zaxira nusxalariga ega bo'lamiz.
  • Nomi "gpv" bilan tugaydigan barcha qurilmalar (mehmonning jismoniy hajmi)

LVM VG da boΚ»sh joy boΚ»shatishda biz DISCARD yordamini yoqdik. Ehtiyot bo'ling. Bu SSD-dagi LV-larni o'chirishni ancha vaqt talab qiladi. Bu, ayniqsa, SSD RAID 6 uchun amal qiladi. Biroq, rejaga ko'ra, biz nozik provayderdan foydalanamiz, shuning uchun bu bizga umuman to'sqinlik qilmaydi.

Keling, initramfs tasvirini yangilaymiz:

#update-initramfs -u -k all

Grubni o'rnating va sozlang:

#apt-get install grub-pc
#apt-get purge os-prober
#dpkg-reconfigure grub-pc

Qaysi disklarni tanlash kerak?Barcha sd*. Tizim har qanday ishlaydigan SATA diskidan yoki SSD-dan yuklay olishi kerak.

Nega ular os-proberni qo'shishdi..?Haddan tashqari mustaqillik va o'ynoqi qo'llar uchun.

RAIDlardan biri buzilgan holatda bo'lsa, u to'g'ri ishlamaydi. U ushbu uskunada ishlaydigan virtual mashinalarda ishlatiladigan bo'limlarda OTni qidirishga harakat qiladi.

Agar sizga kerak bo'lsa, uni tark etishingiz mumkin, lekin yuqorida aytilganlarning barchasini yodda tuting. Internetda yaramas qo'llardan qutulish uchun retseptlarni izlashni maslahat beraman.

Shu bilan biz dastlabki o'rnatishni yakunladik. Yangi o'rnatilgan operatsion tizimni qayta ishga tushirish vaqti keldi. Yuklanadigan Live CD/USBni olib tashlashni unutmang.

#exit
#reboot

Yuklash qurilmasi sifatida SATA SSD-lardan birini tanlang.

SATA SSD-da LVM

Shu nuqtada, biz allaqachon yangi OT ni ishga tushirdik, tarmoqni sozladik, apt, terminal emulyatorini ochdik va ishga tushirdik:

#sudo bash

Davom etaylik.

SATA SSD-dan massivni "boshlang":

#blkdiscard /dev/md2

Agar u ishlamasa, harakat qilib ko'ring:

#blkdiscard --step 65536 /dev/md2
SATA SSD-da LVM VG yarating:

#pvcreate /dev/md2
#vgcreate data /dev/md2

Nega boshqa VG..?Darhaqiqat, bizda allaqachon ildiz deb nomlangan VG mavjud. Nega hamma narsani bitta VGga qo'shmaysiz?

Agar VGda bir nechta PV mavjud bo'lsa, u holda VG to'g'ri faollashishi uchun barcha PV mavjud bo'lishi kerak (onlayn). Istisno LVM RAID bo'lib, biz ataylab foydalanmaymiz.

Biz haqiqatan ham RAID 6 massivlaridan birida nosozlik (o'qish ma'lumotlari yo'qolishi) bo'lsa, operatsion tizim normal ishga tushishini va muammoni hal qilish imkoniyatini berishini xohlaymiz.

Buning uchun abstraktsiyaning birinchi darajasida biz har bir jismoniy "ommaviy axborot vositalari" turini alohida VG ga ajratamiz.

Ilmiy jihatdan aytganda, turli RAID massivlari turli "ishonchlilik domenlari" ga tegishli. Siz ularni bitta VGga siqib, ular uchun qo'shimcha umumiy muvaffaqiyatsizlik nuqtasini yaratmasligingiz kerak.

LVM ning "apparat" darajasida mavjudligi bizga turli xil RAID massivlarining qismlarini turli usullar bilan birlashtirib, o'zboshimchalik bilan kesish imkonini beradi. Masalan - yugurish bir vaqtning o'zida bcache + LVM thin, bcache + BTRFS, LVM kesh + LVM thin, keshlar bilan murakkab ZFS konfiguratsiyasi yoki barchasini sinab ko'rish va solishtirish uchun boshqa do'zax aralashmasi.

"Uskuna" darajasida biz eski "qalin" LVM hajmlaridan boshqa hech narsa ishlatmaymiz. Ushbu qoidadan istisno zaxira bo'limi bo'lishi mumkin.

O'ylaymanki, shu paytga kelib, ko'plab o'quvchilar uy quradigan qo'g'irchoq haqida shubhalanishni boshladilar.

SATA HDD-dagi LVM

#pvcreate /dev/md3
#vgcreate backup /dev/md3

Yana yangi VG..?Agar biz ma'lumotlarni zahiralash uchun foydalanadigan disk massivi muvaffaqiyatsiz bo'lsa, bizning operatsion tizimimiz odatdagidek zaxiralanmagan ma'lumotlarga kirish huquqini saqlab qolgan holda normal ishlashini xohlaymiz. Shuning uchun, VG faollashtirish muammolarini oldini olish uchun biz alohida VG yaratamiz.

LVM keshini sozlash

NVMe RAID 1 da uni keshlash qurilmasi sifatida ishlatish uchun LV yarataylik.

#lvcreate -L 70871154688B --name cache root

Nega juda kam...?Gap shundaki, bizning NVMe SSD-larimiz ham SLC keshiga ega. 4-bitli MLC-da bo'sh joy egallaganligi sababli 18 gigabayt "bepul" va 3 gigabayt dinamik. Ushbu kesh tugagandan so'ng, NVMe SSD-lar keshli SATA SSD-dan tezroq bo'lmaydi. Aslida, shuning uchun biz LVM kesh qismini NVMe diskining SLC kesh hajmidan ikki baravar kattaroq qilishimiz mantiqiy emas. Amaldagi NVMe drayverlari uchun muallif 32-64 gigabayt keshni yaratishni oqilona deb hisoblaydi.

Berilgan bo'lim hajmi 64 gigabayt kesh, kesh metama'lumotlari va metadata zahirasini tashkil qilish uchun talab qilinadi.

Bundan tashqari, shuni ta'kidlaymanki, iflos tizim o'chirilgandan so'ng, LVM butun keshni iflos deb belgilaydi va yana sinxronlashtiriladi. Bundan tashqari, tizim qayta ishga tushmaguncha, bu qurilmada lvchange har safar ishlatilganda takrorlanadi. Shuning uchun, men darhol tegishli skript yordamida keshni qayta yaratishni tavsiya qilaman.

SATA RAID 6 da uni keshlangan qurilma sifatida ishlatish uchun LV yarataylik.

#lvcreate -L 3298543271936B --name cache data

Nega faqat uch terabayt..?Shunday qilib, agar kerak bo'lsa, siz boshqa ehtiyojlar uchun SATA SSD RAID 6 dan foydalanishingiz mumkin. Keshlangan bo'sh joy hajmini tizimni to'xtatmasdan dinamik ravishda oshirish mumkin. Buni amalga oshirish uchun siz keshni vaqtincha to'xtatishingiz va qayta yoqishingiz kerak, lekin LVM-keshning, masalan, bcache-dan o'ziga xos afzalligi shundaki, buni tezda amalga oshirish mumkin.

Keling, keshlash uchun yangi VG yarataylik.

#pvcreate /dev/root/cache
#pvcreate /dev/data/cache
#vgcreate cache /dev/root/cache /dev/data/cache

Keshlangan qurilmada LV yarataylik.

#lvcreate -L 3298539077632B --name cachedata cache /dev/data/cache

Bu erda biz darhol /dev/data/kesh-dagi barcha bo'sh joyni egallab oldik, shunda boshqa barcha kerakli bo'limlar darhol /dev/root/cache-da yaratildi. Agar biror narsani noto'g'ri joyda yaratgan bo'lsangiz, uni pvmove yordamida ko'chirishingiz mumkin.

Keling, keshni yaratamiz va yoqamiz:

#lvcreate -y -L 64G -n cache cache /dev/root/cache
#lvcreate -y -L 1G -n cachemeta cache /dev/root/cache
#lvconvert -y --type cache-pool --cachemode writeback --chunksize 64k --poolmetadata cache/cachemeta cache/cache
#lvconvert -y --type cache --cachepool cache/cache cache/cachedata

Nega bunday bo'laklar..?Amaliy tajribalar orqali muallif LVM kesh blokining o'lchami LVM yupqa blokining o'lchamiga to'g'ri keladigan bo'lsa, eng yaxshi natijaga erishishini aniqlashga muvaffaq bo'ldi. Bundan tashqari, o'lcham qanchalik kichik bo'lsa, konfiguratsiya tasodifiy yozib olishda shunchalik yaxshi ishlaydi.

64k - LVM thin uchun ruxsat etilgan minimal blok hajmi.

Ehtiyot bo'ling javob yozing..!Ha. Ushbu kesh turi keshlangan qurilmaga yozish sinxronizatsiyasini kechiktiradi. Bu shuni anglatadiki, agar kesh yo'qolsa, keshlangan qurilmadagi ma'lumotlarni yo'qotishingiz mumkin. Keyinchalik, muallif NVMe RAID 1 dan tashqari, ushbu xavfni qoplash uchun qanday choralar ko'rish mumkinligini aytib beradi.

Ushbu kesh turi RAID 6 ning noto'g'ri tasodifiy yozish samaradorligini qoplash uchun ataylab tanlangan.

Keling, nima borligini tekshiramiz:

#lvs -a -o lv_name,lv_size,devices --units B cache
LV LSize Devices
[cache] 68719476736B cache_cdata(0)
[cache_cdata] 68719476736B /dev/root/cache(0)
[cache_cmeta] 1073741824B /dev/root/cache(16384)
cachedata 3298539077632B cachedata_corig(0)
[cachedata_corig] 3298539077632B /dev/data/cache(0)
[lvol0_pmspare] 1073741824B /dev/root/cache(16640)

Faqat [cachedata_corig] /dev/data/cache-da joylashgan bo'lishi kerak. Agar biror narsa noto'g'ri bo'lsa, pvmove-dan foydalaning.

Agar kerak bo'lsa, bitta buyruq bilan keshni o'chirib qo'yishingiz mumkin:

#lvconvert -y --uncache cache/cachedata

Bu onlayn tarzda amalga oshiriladi. LVM shunchaki keshni disk bilan sinxronlashtiradi, uni o'chiradi va cachedata_corig nomini keshdataga o'zgartiradi.

LVM nozik o'rnatilmoqda

Keling, LVM yupqa metadata uchun qancha joy kerakligini taxmin qilaylik:

#thin_metadata_size --block-size=64k --pool-size=6terabytes --max-thins=100000 -u bytes
thin_metadata_size - 3385794560 bytes estimated metadata area size for "--block-size=64kibibytes --pool-size=6terabytes --max-thins=100000"

4 gigabaytgacha yaxlitlash: 4294967296B

Ikkiga ko'paytiring va LVM PV metama'lumotlari uchun 4194304B qo'shing: 8594128896B
NVMe RAID 1 da LVM yupqa metama'lumotlarini va ularning zaxira nusxasini joylashtirish uchun alohida bo'lim yarataylik:

#lvcreate -L 8594128896B --name images root

Nima uchun..?Bu erda savol tug'ilishi mumkin: agar u hali ham NVMe-da keshlangan bo'lsa va tezda ishlasa, LVM nozik metama'lumotlarini nima uchun alohida joylashtirish kerak.

Bu erda tezlik muhim bo'lsa-da, bu asosiy sababdan uzoqdir. Gap shundaki, kesh muvaffaqiyatsizlik nuqtasidir. Unga biror narsa yuz berishi mumkin va agar LVM yupqa metadata keshlangan bo'lsa, bu hamma narsaning butunlay yo'qolishiga olib keladi. To'liq metama'lumotlarsiz nozik hajmlarni yig'ish deyarli imkonsiz bo'ladi.

Meta-ma'lumotlarni alohida keshlanmagan, ammo tezkor hajmga ko'chirish orqali biz kesh yo'qolishi yoki buzilishi holatlarida metama'lumotlarning xavfsizligini kafolatlaymiz. Bunday holda, keshni yo'qotish natijasida etkazilgan barcha zararlar ingichka hajmlar ichida lokalizatsiya qilinadi, bu esa tiklash jarayonini kattalik buyurtmalari bilan soddalashtiradi. Yuqori ehtimollik bilan bu zararlar FS jurnallari yordamida tiklanadi.

Bundan tashqari, agar ilgari yupqa hajmning surati olingan bo'lsa va undan keyin kesh kamida bir marta to'liq sinxronlashtirilgan bo'lsa, LVM thin-ning ichki dizayni tufayli kesh yo'qolgan taqdirda suratning yaxlitligi kafolatlanadi. .

Keling, nozik ta'minot uchun javobgar bo'lgan yangi VG yarataylik:

#pvcreate /dev/root/images
#pvcreate /dev/cache/cachedata
#vgcreate images /dev/root/images /dev/cache/cachedata

Keling, hovuz yarataylik:

#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T images/thin-pool
Nima uchun -Z yUshbu rejim aslida nimaga mo'ljallanganiga qo'shimcha ravishda - bo'sh joyni qayta taqsimlashda bitta virtual mashinadan ma'lumotlarning boshqa virtual mashinaga oqib ketishini oldini olish uchun - nolga qo'shimcha ravishda 64k dan kichik bloklarda tasodifiy yozish tezligini oshirish uchun qo'llaniladi. Yupqa hajmning oldindan ajratilmagan maydoniga 64k dan kam bo'lgan har qanday yozish keshda 64K qirrali bo'ladi. Bu keshlangan qurilmani chetlab o'tib, operatsiyani to'liq kesh orqali bajarishga imkon beradi.

Keling, LVlarni mos keladigan PVlarga o'tkazamiz:

#pvmove -n images/thin-pool_tdata /dev/root/images /dev/cache/cachedata
#pvmove -n images/lvol0_pmspare /dev/cache/cachedata /dev/root/images
#pvmove -n images/thin-pool_tmeta /dev/cache/cachedata /dev/root/images

Keling, tekshiramiz:

#lvs -a -o lv_name,lv_size,devices --units B images
LV LSize Devices
[lvol0_pmspare] 4294967296B /dev/root/images(0)
thin-pool 274877906944B thin-pool_tdata(0)
[thin-pool_tdata] 274877906944B /dev/cache/cachedata(0)
[thin-pool_tmeta] 4294967296B /dev/root/images(1024)

Sinovlar uchun nozik hajm yarataylik:

#lvcreate -V 64G --thin-pool thin-pool --name test images

Sinov va monitoring uchun paketlarni o'rnatamiz:

#apt-get install sysstat fio

Haqiqiy vaqtda bizning saqlash konfiguratsiyasining xatti-harakatlarini shunday kuzatishingiz mumkin:

#watch 'lvs --rows --reportformat basic --quiet -ocache_dirty_blocks,cache_settings cache/cachedata && (lvdisplay cache/cachedata | grep Cache) && (sar -p -d 2 1 | grep -E "sd|nvme|DEV|md1|md2|md3|md0" | grep -v Average | sort)'

Biz konfiguratsiyani shu tarzda sinab ko'rishimiz mumkin:

#fio --loops=1 --size=64G --runtime=4 --filename=/dev/images/test --stonewall --ioengine=libaio --direct=1
--name=4kQD32read --bs=4k --iodepth=32 --rw=randread
--name=8kQD32read --bs=8k --iodepth=32 --rw=randread
--name=16kQD32read --bs=16k --iodepth=32 --rw=randread
--name=32KQD32read --bs=32k --iodepth=32 --rw=randread
--name=64KQD32read --bs=64k --iodepth=32 --rw=randread
--name=128KQD32read --bs=128k --iodepth=32 --rw=randread
--name=256KQD32read --bs=256k --iodepth=32 --rw=randread
--name=512KQD32read --bs=512k --iodepth=32 --rw=randread
--name=4Kread --bs=4k --rw=read
--name=8Kread --bs=8k --rw=read
--name=16Kread --bs=16k --rw=read
--name=32Kread --bs=32k --rw=read
--name=64Kread --bs=64k --rw=read
--name=128Kread --bs=128k --rw=read
--name=256Kread --bs=256k --rw=read
--name=512Kread --bs=512k --rw=read
--name=Seqread --bs=1m --rw=read
--name=Longread --bs=8m --rw=read
--name=Longwrite --bs=8m --rw=write
--name=Seqwrite --bs=1m --rw=write
--name=512Kwrite --bs=512k --rw=write
--name=256write --bs=256k --rw=write
--name=128write --bs=128k --rw=write
--name=64write --bs=64k --rw=write
--name=32write --bs=32k --rw=write
--name=16write --bs=16k --rw=write
--name=8write --bs=8k --rw=write
--name=4write --bs=4k --rw=write
--name=512KQD32write --bs=512k --iodepth=32 --rw=randwrite
--name=256KQD32write --bs=256k --iodepth=32 --rw=randwrite
--name=128KQD32write --bs=128k --iodepth=32 --rw=randwrite
--name=64KQD32write --bs=64k --iodepth=32 --rw=randwrite
--name=32KQD32write --bs=32k --iodepth=32 --rw=randwrite
--name=16KQD32write --bs=16k --iodepth=32 --rw=randwrite
--name=8KQD32write --bs=8k --iodepth=32 --rw=randwrite
--name=4kQD32write --bs=4k --iodepth=32 --rw=randwrite
| grep -E 'read|write|test' | grep -v ioengine

Ehtiyotkorlik bilan! Manba!Ushbu kod har biri 36 soniya davomida ishlaydigan 4 xil testni o'tkazadi. Sinovlarning yarmi yozib olish uchun. 4 soniyada NVMe-da ko'p narsalarni yozib olishingiz mumkin. soniyasiga 3 gigabaytgacha. Shunday qilib, har bir yozish testi sizdan 216 gigabaytgacha SSD resursini iste'mol qilishi mumkin.

O'qish va yozish aralashmi?Ha. O'qish va yozish testlarini alohida bajarish mantiqan. Bundan tashqari, barcha keshlar sinxronlashtirilganligini ta'minlash mantiqan to'g'ri keladi, shunda ilgari qilingan yozuv o'qishga ta'sir qilmaydi.

Natijalar birinchi ishga tushirishda va undan keyingilarida sezilarli darajada farq qiladi, chunki kesh va ingichka hajm to'ldiriladi, shuningdek, tizim oxirgi ishga tushirish paytida to'ldirilgan keshlarni sinxronlashtira oldimi yoki yo'qmi.

Boshqa narsalar qatorida, men suratga olingan allaqachon to'liq nozik hajmda tezlikni o'lchashni tavsiya qilaman. Muallif birinchi suratni yaratgandan so'ng darhol tasodifiy yozishlar qanday keskin tezlashishini kuzatish imkoniga ega bo'ldi, ayniqsa kesh hali to'liq to'ldirilmaganda. Bu yozishda nusxa ko'chirish semantikasi, kesh va ingichka hajm bloklarini tekislash va RAID 6 ga tasodifiy yozish RAID 6 dan tasodifiy o'qishga, keyin esa keshga yozishga aylanishi tufayli sodir bo'ladi. Bizning konfiguratsiyamizda RAID 6 dan tasodifiy o'qish yozishdan ko'ra 6 martagacha (massivdagi SATA SSD-lar soni) tezroq. Chunki Sigir uchun bloklar nozik hovuzdan ketma-ket ajratiladi, keyin yozuv, ko'pincha, ketma-ketlikka aylanadi.

Bu xususiyatlarning ikkalasi ham sizning foydangiz uchun ishlatilishi mumkin.

β€œMuvofiq” suratlarni keshlash

Kesh shikastlanishi/yo'qolishi holatlarida ma'lumotlarning yo'qolishi xavfini kamaytirish uchun muallif bu holda ularning yaxlitligini kafolatlash uchun snapshotlarni aylantirish amaliyotini joriy qilishni taklif qiladi.

Birinchidan, ingichka hajmli metama'lumotlar keshlanmagan qurilmada joylashganligi sababli, metama'lumotlar izchil bo'ladi va mumkin bo'lgan yo'qotishlar ma'lumotlar bloklari ichida izolyatsiya qilinadi.

Quyidagi oniy tasvirni aylantirish sikli kesh yo'qolgan taqdirda suratlar ichidagi ma'lumotlarning yaxlitligini kafolatlaydi:

  1. nomli har bir nozik jild uchun .keshlangan nomli surat yarating.
  2. Keling, migratsiya chegarasini o'rtacha yuqori qiymatga o'rnatamiz: #lvchange --quiet --cachesettings "migration_threshold=16384" cache/cachedata
  3. Loopda biz keshdagi iflos bloklar sonini tekshiramiz: #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' biz nolga erishgunimizcha. Agar nol juda uzoq vaqt davomida etishmayotgan bo'lsa, u keshni vaqtincha yozish rejimiga o'tkazish orqali yaratilishi mumkin. Biroq, bizning SATA va NVMe SSD massivlarining tezlik xususiyatlarini, shuningdek, ularning TBW resursini hisobga olgan holda, siz kesh rejimini o'zgartirmasdan tezda lahzani qo'lga kiritishingiz mumkin yoki sizning uskunangiz butun resursni to'liq iste'mol qiladi. bir necha kun. Resurs cheklovlari tufayli tizim, qoida tariqasida, har doim 100% yozish yukidan past bo'la olmaydi. 100% yozish yuki ostida bo'lgan NVMe SSD'larimiz resursni to'liq tugatadi 3-4 kun. SATA SSD-lar faqat ikki baravar uzoq davom etadi. Shuning uchun, biz yukning katta qismi o'qishga ketadi deb taxmin qilamiz va bizda yozish uchun o'rtacha yuk bilan birlashtirilgan juda yuqori faollikning nisbatan qisqa muddatli portlashlari mavjud.
  4. Biz nolni ushlaganimiz (yoki qilganimiz) bilanoq, biz .cached nomini .committed deb o'zgartiramiz. Qadimgi .majburiy o'chiriladi.
  5. Majburiy emas, agar kesh 100% to'lgan bo'lsa, u skript orqali qayta yaratilishi mumkin, shuning uchun uni tozalaydi. Yarim bo'sh kesh bilan tizim yozishda ancha tezroq ishlaydi.
  6. Migratsiya chegarasini nolga o'rnating: #lvchange --quiet --cachesettings "migration_threshold=0" cache/cachedata Bu vaqtinchalik keshni asosiy media bilan sinxronlashdan saqlaydi.
  7. Keshda juda ko'p o'zgarishlar to'planguncha kutamiz #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' yoki taymer o'chadi.
  8. Yana takrorlaymiz.

Nima uchun migratsiya chegarasi bilan bog'liq qiyinchiliklar...?Gap shundaki, haqiqiy amaliyotda "tasodifiy" yozuv aslida mutlaqo tasodifiy emas. Agar biz 4 kilobayt o'lchamdagi sektorga biror narsa yozgan bo'lsak, keyingi bir necha daqiqada bir xil yoki qo'shni (+-32K) sektorlardan biriga rekord qo'yish ehtimoli katta.

Migratsiya chegarasini nolga o'rnatish orqali biz SATA SSD-da yozish sinxronizatsiyasini qoldiramiz va keshdagi bitta 64K blokga bir nechta o'zgarishlarni jamlaymiz. Bu SATA SSD resursini sezilarli darajada tejaydi.

Kod qayerda..?Afsuski, muallif o'zini bash skriptlarini ishlab chiqishda etarli darajada malakali emas deb hisoblaydi, chunki u 100% o'zini o'zi o'rgatadi va "google" tomonidan boshqariladigan rivojlanishni qo'llaydi, shuning uchun u qo'lidan chiqadigan dahshatli kodni hech kim ishlatmasligi kerak deb hisoblaydi. boshqa.

O'ylaymanki, ushbu sohadagi mutaxassislar, agar kerak bo'lsa, yuqorida tavsiflangan barcha mantiqlarni mustaqil ravishda tasvirlashlari va, ehtimol, muallif harakat qilganidek, uni tizimli xizmat sifatida chiroyli tarzda loyihalashtira oladilar.

Bunday oddiy suratni aylantirish sxemasi bizga nafaqat doimiy ravishda SATA SSD-da to'liq sinxronlashtirilgan bitta suratga ega bo'lish imkonini beradi, balki bizga thin_delta yordam dasturidan foydalanib, u yaratilgandan keyin qaysi bloklar o'zgartirilganligini aniqlashga va shu bilan zararni lokalizatsiya qilishga imkon beradi. tiklanishni sezilarli darajada soddalashtiradigan asosiy hajmlar .

libvirt/KVM da TRIM/DISCARD

Chunki ma'lumotlarni saqlash libvirt bilan ishlaydigan KVM uchun ishlatiladi, keyin bizning VMlarimizni nafaqat bo'sh joy egallashga, balki endi kerak bo'lmagan narsalarni ham bo'shatishga o'rgatish yaxshi fikr bo'lar edi.

Bu virtual disklarda TRIM/DISCARD qo'llab-quvvatlashiga taqlid qilish orqali amalga oshiriladi. Buning uchun siz kontroller turini virtio-scsi ga o'zgartirishingiz va xml ni tahrirlashingiz kerak.

#virsh edit vmname
<disk type='block' device='disk'>
<driver name='qemu' type='raw' cache='writethrough' io='threads' discard='unmap'/>
<source dev='/dev/images/vmname'/>
<backingStore/>
<target dev='sda' bus='scsi'/>
<alias name='scsi0-0-0-0'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>

<controller type='scsi' index='0' model='virtio-scsi'>
<alias name='scsi0'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</controller>

Mehmon operatsion tizimlaridan bunday DISCARDlar LVM tomonidan to'g'ri qayta ishlanadi va bloklar keshda ham, nozik hovuzda ham to'g'ri bo'shatiladi. Bizning holatlarimizda, bu, asosan, keyingi suratni o'chirishda kechiktirilgan holda sodir bo'ladi.

BTRFS zaxira nusxasi

bilan tayyor skriptlardan foydalaning ekstremal ehtiyot va o'z xavf-xatarida. Muallif ushbu kodni o'zi va faqat o'zi uchun yozgan. Ishonchim komilki, ko'plab tajribali Linux foydalanuvchilari shunga o'xshash vositalarga ega va boshqalarnikini nusxalashning hojati yo'q.

Zaxira qurilmasida ovoz balandligini yarataylik:

#lvcreate -L 256G --name backup backup

Keling, uni BTRFS da formatlaymiz:

#mkfs.btrfs /dev/backup/backup

Keling, o'rnatish nuqtalarini yaratamiz va fayl tizimining ildiz bo'limlarini o'rnatamiz:

#mkdir /backup
#mkdir /backup/btrfs
#mkdir /backup/btrfs/root
#mkdir /backup/btrfs/back
#ln -s /boot /backup/btrfs
# cat >>/etc/fstab << EOF

/dev/mapper/root-root /backup/btrfs/root btrfs defaults,space_cache,noatime,nodiratime 0 2
/dev/mapper/backup-backup /backup/btrfs/back btrfs defaults,space_cache,noatime,nodiratime 0 2
EOF
#mount -a
#update-initramfs -u
#update-grub

Keling, zaxiralash uchun kataloglarni yarataylik:

#mkdir /backup/btrfs/back/remote
#mkdir /backup/btrfs/back/remote/root
#mkdir /backup/btrfs/back/remote/boot

Keling, zaxira skriptlari uchun katalog yarataylik:

#mkdir /root/btrfs-backup

Keling, skriptni nusxalaymiz:

Ko'p qo'rqinchli bash kodi. O'zingizning xavf-xataringiz ostida foydalaning. Muallifga jahl bilan xat yozmang...#cat >/root/btrfs-backup/btrfs-backup.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

SCRIPT_FILE="$(realpath $0)"
SCRIPT_DIR="$(dirname $SCRIPT_FILE)"
SCRIPT_NAME="$(basename -s .sh $SCRIPT_FILE)"

LOCK_FILE="/dev/shm/$SCRIPT_NAME.lock"
DATE_PREFIX='%Y-%m-%d'
DATE_FORMAT=$DATE_PREFIX'-%H-%M-%S'
DATE_REGEX='[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
BASE_SUFFIX=".@base"
PEND_SUFFIX=".@pend"
SNAP_SUFFIX=".@snap"
MOUNTS="/backup/btrfs/"
BACKUPS="/backup/btrfs/back/remote/"

function terminate ()
{
echo "$1" >&2
exit 1
}

function wait_lock()
{
flock 98
}

function wait_lock_or_terminate()
{
echo "Wating for lock..."
wait_lock || terminate "Failed to get lock. Exiting..."
echo "Got lock..."
}

function suffix()
{
FORMATTED_DATE=$(date +"$DATE_FORMAT")
echo "$SNAP_SUFFIX.$FORMATTED_DATE"
}

function filter()
{
FORMATTED_DATE=$(date --date="$1" +"$DATE_PREFIX")
echo "$SNAP_SUFFIX.$FORMATTED_DATE"
}

function backup()
{
SOURCE_PATH="$MOUNTS$1"
TARGET_PATH="$BACKUPS$1"
SOURCE_BASE_PATH="$MOUNTS$1$BASE_SUFFIX"
TARGET_BASE_PATH="$BACKUPS$1$BASE_SUFFIX"
TARGET_BASE_DIR="$(dirname $TARGET_BASE_PATH)"
SOURCE_PEND_PATH="$MOUNTS$1$PEND_SUFFIX"
TARGET_PEND_PATH="$BACKUPS$1$PEND_SUFFIX"
if [ -d "$SOURCE_BASE_PATH" ] then
echo "$SOURCE_BASE_PATH found"
else
echo "$SOURCE_BASE_PATH File not found creating snapshot of $SOURCE_PATH to $SOURCE_BASE_PATH"
btrfs subvolume snapshot -r $SOURCE_PATH $SOURCE_BASE_PATH
sync
if [ -d "$TARGET_BASE_PATH" ] then
echo "$TARGET_BASE_PATH found out of sync with source... removing..."
btrfs subvolume delete -c $TARGET_BASE_PATH
sync
fi
fi
if [ -d "$TARGET_BASE_PATH" ] then
echo "$TARGET_BASE_PATH found"
else
echo "$TARGET_BASE_PATH not found. Synching to $TARGET_BASE_DIR"
btrfs send $SOURCE_BASE_PATH | btrfs receive $TARGET_BASE_DIR
sync
fi
if [ -d "$SOURCE_PEND_PATH" ] then
echo "$SOURCE_PEND_PATH found removing..."
btrfs subvolume delete -c $SOURCE_PEND_PATH
sync
fi
btrfs subvolume snapshot -r $SOURCE_PATH $SOURCE_PEND_PATH
sync
if [ -d "$TARGET_PEND_PATH" ] then
echo "$TARGET_PEND_PATH found removing..."
btrfs subvolume delete -c $TARGET_PEND_PATH
sync
fi
echo "Sending $SOURCE_PEND_PATH to $TARGET_PEND_PATH"
btrfs send -p $SOURCE_BASE_PATH $SOURCE_PEND_PATH | btrfs receive $TARGET_BASE_DIR
sync
TARGET_DATE_SUFFIX=$(suffix)
btrfs subvolume snapshot -r $TARGET_PEND_PATH "$TARGET_PATH$TARGET_DATE_SUFFIX"
sync
btrfs subvolume delete -c $SOURCE_BASE_PATH
sync
btrfs subvolume delete -c $TARGET_BASE_PATH
sync
mv $SOURCE_PEND_PATH $SOURCE_BASE_PATH
mv $TARGET_PEND_PATH $TARGET_BASE_PATH
sync
}

function list()
{
LIST_TARGET_BASE_PATH="$BACKUPS$1$BASE_SUFFIX"
LIST_TARGET_BASE_DIR="$(dirname $LIST_TARGET_BASE_PATH)"
LIST_TARGET_BASE_NAME="$(basename -s .$BASE_SUFFIX $LIST_TARGET_BASE_PATH)"
find "$LIST_TARGET_BASE_DIR" -maxdepth 1 -mindepth 1 -type d -printf "%fn" | grep "${LIST_TARGET_BASE_NAME/$BASE_SUFFIX/$SNAP_SUFFIX}.$DATE_REGEX"
}

function remove()
{
REMOVE_TARGET_BASE_PATH="$BACKUPS$1$BASE_SUFFIX"
REMOVE_TARGET_BASE_DIR="$(dirname $REMOVE_TARGET_BASE_PATH)"
btrfs subvolume delete -c $REMOVE_TARGET_BASE_DIR/$2
sync
}

function removeall()
{
DATE_OFFSET="$2"
FILTER="$(filter "$DATE_OFFSET")"
while read -r SNAPSHOT ; do
remove "$1" "$SNAPSHOT"
done < <(list "$1" | grep "$FILTER")

}

(
COMMAND="$1"
shift

case "$COMMAND" in
"--help")
echo "Help"
;;
"suffix")
suffix
;;
"filter")
filter "$1"
;;
"backup")
wait_lock_or_terminate
backup "$1"
;;
"list")
list "$1"
;;
"remove")
wait_lock_or_terminate
remove "$1" "$2"
;;
"removeall")
wait_lock_or_terminate
removeall "$1" "$2"
;;
*)
echo "None.."
;;
esac
) 98>$LOCK_FILE

EOF

Hatto nima qiladi..?BTRFS snapshotlarini yaratish va BTRFS yuborish/qabul qilish yordamida ularni boshqa FSga nusxalash uchun oddiy buyruqlar toΚ»plamini oΚ»z ichiga oladi.

Birinchi ishga tushirish nisbatan uzoq davom etishi mumkin, chunki... Boshida barcha ma'lumotlar nusxalanadi. Keyingi ishga tushirishlar juda tez bo'ladi, chunki... Faqat o'zgarishlar nusxalanadi.

Biz cronga joylashtirgan yana bir skript:

Yana bash kodi#cat >/root/btrfs-backup/cron-daily.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

SCRIPT_FILE="$(realpath $0)"
SCRIPT_DIR="$(dirname $SCRIPT_FILE)"
SCRIPT_NAME="$(basename -s .sh $SCRIPT_FILE)"

BACKUP_SCRIPT="$SCRIPT_DIR/btrfs-backup.sh"
RETENTION="-60 day"
$BACKUP_SCRIPT backup root/@
$BACKUP_SCRIPT removeall root/@ "$RETENTION"
$BACKUP_SCRIPT backup root/@home
$BACKUP_SCRIPT removeall root/@home "$RETENTION"
$BACKUP_SCRIPT backup boot/
$BACKUP_SCRIPT removeall boot/ "$RETENTION"
EOF

Nima qiladi..?Zaxira FS da sanab o'tilgan BTRFS jildlarining qo'shimcha suratlarini yaratadi va sinxronlashtiradi. Shundan so'ng, u 60 kun oldin yaratilgan barcha rasmlarni o'chiradi. Ishga tushgandan so'ng, sanab o'tilgan jildlarning sanali suratlari /backup/btrfs/back/remote/ pastki kataloglarida paydo bo'ladi.

Keling, kodni bajarish huquqlarini beraylik:

#chmod +x /root/btrfs-backup/cron-daily.sh
#chmod +x /root/btrfs-backup/btrfs-backup.sh

Keling, uni tekshiramiz va uni cronga qo'yamiz:

#/usr/bin/nice -n 19 /usr/bin/ionice -c 3 /root/btrfs-backup/cron-daily.sh 2>&1 | /usr/bin/logger -t btrfs-backup
#cat /var/log/syslog | grep btrfs-backup
#crontab -e
0 2 * * * /usr/bin/nice -n 19 /usr/bin/ionice -c 3 /root/btrfs-backup/cron-daily.sh 2>&1 | /usr/bin/logger -t btrfs-backup

LVM nozik zaxira nusxasi

Keling, zaxira qurilmada nozik hovuz yarataylik:

#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T backup/thin-pool

Keling, ddrescue ni o'rnatamiz, chunki ... skriptlar ushbu vositadan foydalanadi:

#apt-get install gddrescue

Skriptlar uchun katalog yaratamiz:

#mkdir /root/lvm-thin-backup

Keling, skriptlarni nusxalaymiz:

Ichkarida juda ko'p janjal ...#cat >/root/lvm-thin-backup/lvm-thin-backup.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

SCRIPT_FILE="$(realpath $0)"
SCRIPT_DIR="$(dirname $SCRIPT_FILE)"
SCRIPT_NAME="$(basename -s .sh $SCRIPT_FILE)"

LOCK_FILE="/dev/shm/$SCRIPT_NAME.lock"
DATE_PREFIX='%Y-%m-%d'
DATE_FORMAT=$DATE_PREFIX'-%H-%M-%S'
DATE_REGEX='[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
BASE_SUFFIX=".base"
PEND_SUFFIX=".pend"
SNAP_SUFFIX=".snap"
BACKUPS="backup"
BACKUPS_POOL="thin-pool"

export LVM_SUPPRESS_FD_WARNINGS=1

function terminate ()
{
echo "$1" >&2
exit 1
}

function wait_lock()
{
flock 98
}

function wait_lock_or_terminate()
{
echo "Wating for lock..."
wait_lock || terminate "Failed to get lock. Exiting..."
echo "Got lock..."
}

function suffix()
{
FORMATTED_DATE=$(date +"$DATE_FORMAT")
echo "$SNAP_SUFFIX.$FORMATTED_DATE"
}

function filter()
{
FORMATTED_DATE=$(date --date="$1" +"$DATE_PREFIX")
echo "$SNAP_SUFFIX.$FORMATTED_DATE"
}

function read_thin_id {
lvs --rows --reportformat basic --quiet -othin_id "$1/$2" | awk '{print $2}'
}

function read_pool_lv {
lvs --rows --reportformat basic --quiet -opool_lv "$1/$2" | awk '{print $2}'
}

function read_lv_dm_path {
lvs --rows --reportformat basic --quiet -olv_dm_path "$1/$2" | awk '{print $2}'
}

function read_lv_active {
lvs --rows --reportformat basic --quiet -olv_active "$1/$2" | awk '{print $2}'
}

function read_lv_chunk_size {
lvs --rows --reportformat basic --quiet --units b --nosuffix -ochunk_size "$1/$2" | awk '{print $2}'
}

function read_lv_size {
lvs --rows --reportformat basic --quiet --units b --nosuffix -olv_size "$1/$2" | awk '{print $2}'
}

function activate_volume {
lvchange -ay -Ky "$1/$2"
}

function deactivate_volume {
lvchange -an "$1/$2"
}

function read_thin_metadata_snap {
dmsetup status "$1" | awk '{print $7}'
}

function thindiff()
{
DIFF_VG="$1"
DIFF_SOURCE="$2"
DIFF_TARGET="$3"
DIFF_SOURCE_POOL=$(read_pool_lv $DIFF_VG $DIFF_SOURCE)
DIFF_TARGET_POOL=$(read_pool_lv $DIFF_VG $DIFF_TARGET)

if [ "$DIFF_SOURCE_POOL" == "" ] then
(>&2 echo "Source LV is not thin.")
exit 1
fi

if [ "$DIFF_TARGET_POOL" == "" ] then
(>&2 echo "Target LV is not thin.")
exit 1
fi

if [ "$DIFF_SOURCE_POOL" != "$DIFF_TARGET_POOL" ] then
(>&2 echo "Source and target LVs belong to different thin pools.")
exit 1
fi

DIFF_POOL_PATH=$(read_lv_dm_path $DIFF_VG $DIFF_SOURCE_POOL)
DIFF_SOURCE_ID=$(read_thin_id $DIFF_VG $DIFF_SOURCE)
DIFF_TARGET_ID=$(read_thin_id $DIFF_VG $DIFF_TARGET)
DIFF_POOL_PATH_TPOOL="$DIFF_POOL_PATH-tpool"
DIFF_POOL_PATH_TMETA="$DIFF_POOL_PATH"_tmeta
DIFF_POOL_METADATA_SNAP=$(read_thin_metadata_snap $DIFF_POOL_PATH_TPOOL)

if [ "$DIFF_POOL_METADATA_SNAP" != "-" ] then
(>&2 echo "Thin pool metadata snapshot already exist. Assuming stale one. Will release metadata snapshot in 5 seconds.")
sleep 5
dmsetup message $DIFF_POOL_PATH_TPOOL 0 release_metadata_snap
fi

dmsetup message $DIFF_POOL_PATH_TPOOL 0 reserve_metadata_snap
DIFF_POOL_METADATA_SNAP=$(read_thin_metadata_snap $DIFF_POOL_PATH_TPOOL)

if [ "$DIFF_POOL_METADATA_SNAP" == "-" ] then
(>&2 echo "Failed to create thin pool metadata snapshot.")
exit 1
fi

#We keep output in variable because metadata snapshot need to be released early.
DIFF_DATA=$(thin_delta -m$DIFF_POOL_METADATA_SNAP --snap1 $DIFF_SOURCE_ID --snap2 $DIFF_TARGET_ID $DIFF_POOL_PATH_TMETA)

dmsetup message $DIFF_POOL_PATH_TPOOL 0 release_metadata_snap

echo $"$DIFF_DATA" | grep -E 'different|left_only|right_only' | sed 's/</"/g' | sed 's/ /"/g' | awk -F'"' '{print $6 "t" $8 "t" $11}' | sed 's/different/copy/g' | sed 's/left_only/copy/g' | sed 's/right_only/discard/g'

}

function thinsync()
{
SYNC_VG="$1"
SYNC_PEND="$2"
SYNC_BASE="$3"
SYNC_TARGET="$4"
SYNC_PEND_POOL=$(read_pool_lv $SYNC_VG $SYNC_PEND)
SYNC_BLOCK_SIZE=$(read_lv_chunk_size $SYNC_VG $SYNC_PEND_POOL)
SYNC_PEND_PATH=$(read_lv_dm_path $SYNC_VG $SYNC_PEND)

activate_volume $SYNC_VG $SYNC_PEND

while read -r SYNC_ACTION SYNC_OFFSET SYNC_LENGTH ; do
SYNC_OFFSET_BYTES=$((SYNC_OFFSET * SYNC_BLOCK_SIZE))
SYNC_LENGTH_BYTES=$((SYNC_LENGTH * SYNC_BLOCK_SIZE))
if [ "$SYNC_ACTION" == "copy" ] then
ddrescue --quiet --force --input-position=$SYNC_OFFSET_BYTES --output-position=$SYNC_OFFSET_BYTES --size=$SYNC_LENGTH_BYTES "$SYNC_PEND_PATH" "$SYNC_TARGET"
fi

if [ "$SYNC_ACTION" == "discard" ] then
blkdiscard -o $SYNC_OFFSET_BYTES -l $SYNC_LENGTH_BYTES "$SYNC_TARGET"
fi
done < <(thindiff "$SYNC_VG" "$SYNC_PEND" "$SYNC_BASE")
}

function discard_volume()
{
DISCARD_VG="$1"
DISCARD_LV="$2"
DISCARD_LV_PATH=$(read_lv_dm_path "$DISCARD_VG" "$DISCARD_LV")
if [ "$DISCARD_LV_PATH" != "" ] then
echo "$DISCARD_LV_PATH found"
else
echo "$DISCARD_LV not found in $DISCARD_VG"
exit 1
fi
DISCARD_LV_POOL=$(read_pool_lv $DISCARD_VG $DISCARD_LV)
DISCARD_LV_SIZE=$(read_lv_size "$DISCARD_VG" "$DISCARD_LV")
lvremove -y --quiet "$DISCARD_LV_PATH" || exit 1
lvcreate --thin-pool "$DISCARD_LV_POOL" -V "$DISCARD_LV_SIZE"B --name "$DISCARD_LV" "$DISCARD_VG" || exit 1
}

function backup()
{
SOURCE_VG="$1"
SOURCE_LV="$2"
TARGET_VG="$BACKUPS"
TARGET_LV="$SOURCE_VG-$SOURCE_LV"
SOURCE_BASE_LV="$SOURCE_LV$BASE_SUFFIX"
TARGET_BASE_LV="$TARGET_LV$BASE_SUFFIX"
SOURCE_PEND_LV="$SOURCE_LV$PEND_SUFFIX"
TARGET_PEND_LV="$TARGET_LV$PEND_SUFFIX"
SOURCE_BASE_LV_PATH=$(read_lv_dm_path "$SOURCE_VG" "$SOURCE_BASE_LV")
SOURCE_PEND_LV_PATH=$(read_lv_dm_path "$SOURCE_VG" "$SOURCE_PEND_LV")
TARGET_BASE_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_BASE_LV")
TARGET_PEND_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_PEND_LV")

if [ "$SOURCE_BASE_LV_PATH" != "" ] then
echo "$SOURCE_BASE_LV_PATH found"
else
echo "Source base not found creating snapshot of $SOURCE_VG/$SOURCE_LV to $SOURCE_VG/$SOURCE_BASE_LV"
lvcreate --quiet --snapshot --name "$SOURCE_BASE_LV" "$SOURCE_VG/$SOURCE_LV" || exit 1
SOURCE_BASE_LV_PATH=$(read_lv_dm_path "$SOURCE_VG" "$SOURCE_BASE_LV")
activate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
echo "Discarding $SOURCE_BASE_LV_PATH as we need to bootstrap."
SOURCE_BASE_POOL=$(read_pool_lv $SOURCE_VG $SOURCE_BASE_LV)
SOURCE_BASE_CHUNK_SIZE=$(read_lv_chunk_size $SOURCE_VG $SOURCE_BASE_POOL)
discard_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
sync
if [ "$TARGET_BASE_LV_PATH" != "" ] then
echo "$TARGET_BASE_LV_PATH found out of sync with source... removing..."
lvremove -y --quiet $TARGET_BASE_LV_PATH || exit 1
TARGET_BASE_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_BASE_LV")
sync
fi
fi
SOURCE_BASE_SIZE=$(read_lv_size "$SOURCE_VG" "$SOURCE_BASE_LV")
if [ "$TARGET_BASE_LV_PATH" != "" ] then
echo "$TARGET_BASE_LV_PATH found"
else
echo "$TARGET_VG/$TARGET_LV not found. Creating empty volume."
lvcreate --thin-pool "$BACKUPS_POOL" -V "$SOURCE_BASE_SIZE"B --name "$TARGET_BASE_LV" "$TARGET_VG" || exit 1
echo "Have to rebootstrap. Discarding source at $SOURCE_BASE_LV_PATH"
activate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
SOURCE_BASE_POOL=$(read_pool_lv $SOURCE_VG $SOURCE_BASE_LV)
SOURCE_BASE_CHUNK_SIZE=$(read_lv_chunk_size $SOURCE_VG $SOURCE_BASE_POOL)
discard_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
TARGET_BASE_POOL=$(read_pool_lv $TARGET_VG $TARGET_BASE_LV)
TARGET_BASE_CHUNK_SIZE=$(read_lv_chunk_size $TARGET_VG $TARGET_BASE_POOL)
TARGET_BASE_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_BASE_LV")
echo "Discarding target at $TARGET_BASE_LV_PATH"
discard_volume "$TARGET_VG" "$TARGET_BASE_LV"
sync
fi
if [ "$SOURCE_PEND_LV_PATH" != "" ] then
echo "$SOURCE_PEND_LV_PATH found removing..."
lvremove -y --quiet "$SOURCE_PEND_LV_PATH" || exit 1
sync
fi
lvcreate --quiet --snapshot --name "$SOURCE_PEND_LV" "$SOURCE_VG/$SOURCE_LV" || exit 1
SOURCE_PEND_LV_PATH=$(read_lv_dm_path "$SOURCE_VG" "$SOURCE_PEND_LV")
sync
if [ "$TARGET_PEND_LV_PATH" != "" ] then
echo "$TARGET_PEND_LV_PATH found removing..."
lvremove -y --quiet $TARGET_PEND_LV_PATH
sync
fi
lvcreate --quiet --snapshot --name "$TARGET_PEND_LV" "$TARGET_VG/$TARGET_BASE_LV" || exit 1
TARGET_PEND_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_PEND_LV")
SOURCE_PEND_LV_SIZE=$(read_lv_size "$SOURCE_VG" "$SOURCE_PEND_LV")
lvresize -L "$SOURCE_PEND_LV_SIZE"B "$TARGET_PEND_LV_PATH"
activate_volume "$TARGET_VG" "$TARGET_PEND_LV"
echo "Synching $SOURCE_PEND_LV_PATH to $TARGET_PEND_LV_PATH"
thinsync "$SOURCE_VG" "$SOURCE_PEND_LV" "$SOURCE_BASE_LV" "$TARGET_PEND_LV_PATH" || exit 1
sync

TARGET_DATE_SUFFIX=$(suffix)
lvcreate --quiet --snapshot --name "$TARGET_LV$TARGET_DATE_SUFFIX" "$TARGET_VG/$TARGET_PEND_LV" || exit 1
sync
lvremove --quiet -y "$SOURCE_BASE_LV_PATH" || exit 1
sync
lvremove --quiet -y "$TARGET_BASE_LV_PATH" || exit 1
sync
lvrename -y "$SOURCE_VG/$SOURCE_PEND_LV" "$SOURCE_BASE_LV" || exit 1
lvrename -y "$TARGET_VG/$TARGET_PEND_LV" "$TARGET_BASE_LV" || exit 1
sync
deactivate_volume "$TARGET_VG" "$TARGET_BASE_LV"
deactivate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
}

function verify()
{
SOURCE_VG="$1"
SOURCE_LV="$2"
TARGET_VG="$BACKUPS"
TARGET_LV="$SOURCE_VG-$SOURCE_LV"
SOURCE_BASE_LV="$SOURCE_LV$BASE_SUFFIX"
TARGET_BASE_LV="$TARGET_LV$BASE_SUFFIX"
TARGET_BASE_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_BASE_LV")
SOURCE_BASE_LV_PATH=$(read_lv_dm_path "$SOURCE_VG" "$SOURCE_BASE_LV")

if [ "$SOURCE_BASE_LV_PATH" != "" ] then
echo "$SOURCE_BASE_LV_PATH found"
else
echo "$SOURCE_BASE_LV_PATH not found"
exit 1
fi
if [ "$TARGET_BASE_LV_PATH" != "" ] then
echo "$TARGET_BASE_LV_PATH found"
else
echo "$TARGET_BASE_LV_PATH not found"
exit 1
fi
activate_volume "$TARGET_VG" "$TARGET_BASE_LV"
activate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
echo Comparing "$SOURCE_BASE_LV_PATH" with "$TARGET_BASE_LV_PATH"
cmp "$SOURCE_BASE_LV_PATH" "$TARGET_BASE_LV_PATH"
echo Done...
deactivate_volume "$TARGET_VG" "$TARGET_BASE_LV"
deactivate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
}

function resync()
{
SOURCE_VG="$1"
SOURCE_LV="$2"
TARGET_VG="$BACKUPS"
TARGET_LV="$SOURCE_VG-$SOURCE_LV"
SOURCE_BASE_LV="$SOURCE_LV$BASE_SUFFIX"
TARGET_BASE_LV="$TARGET_LV$BASE_SUFFIX"
TARGET_BASE_LV_PATH=$(read_lv_dm_path "$TARGET_VG" "$TARGET_BASE_LV")
SOURCE_BASE_LV_PATH=$(read_lv_dm_path "$SOURCE_VG" "$SOURCE_BASE_LV")

if [ "$SOURCE_BASE_LV_PATH" != "" ] then
echo "$SOURCE_BASE_LV_PATH found"
else
echo "$SOURCE_BASE_LV_PATH not found"
exit 1
fi
if [ "$TARGET_BASE_LV_PATH" != "" ] then
echo "$TARGET_BASE_LV_PATH found"
else
echo "$TARGET_BASE_LV_PATH not found"
exit 1
fi
activate_volume "$TARGET_VG" "$TARGET_BASE_LV"
activate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
SOURCE_BASE_POOL=$(read_pool_lv $SOURCE_VG $SOURCE_BASE_LV)
SYNC_BLOCK_SIZE=$(read_lv_chunk_size $SOURCE_VG $SOURCE_BASE_POOL)

echo Syncronizing "$SOURCE_BASE_LV_PATH" to "$TARGET_BASE_LV_PATH"

CMP_OFFSET=0
while [[ "$CMP_OFFSET" != "" ]] ; do
CMP_MISMATCH=$(cmp -i "$CMP_OFFSET" "$SOURCE_BASE_LV_PATH" "$TARGET_BASE_LV_PATH" | grep differ | awk '{print $5}' | sed 's/,//g' )
if [[ "$CMP_MISMATCH" != "" ]] ; then
CMP_OFFSET=$(( CMP_MISMATCH + CMP_OFFSET ))
SYNC_OFFSET_BYTES=$(( ( CMP_OFFSET / SYNC_BLOCK_SIZE ) * SYNC_BLOCK_SIZE ))
SYNC_LENGTH_BYTES=$(( SYNC_BLOCK_SIZE ))
echo "Synching $SYNC_LENGTH_BYTES bytes at $SYNC_OFFSET_BYTES from $SOURCE_BASE_LV_PATH to $TARGET_BASE_LV_PATH"
ddrescue --quiet --force --input-position=$SYNC_OFFSET_BYTES --output-position=$SYNC_OFFSET_BYTES --size=$SYNC_LENGTH_BYTES "$SOURCE_BASE_LV_PATH" "$TARGET_BASE_LV_PATH"
else
CMP_OFFSET=""
fi
done
echo Done...
deactivate_volume "$TARGET_VG" "$TARGET_BASE_LV"
deactivate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
}

function list()
{
LIST_SOURCE_VG="$1"
LIST_SOURCE_LV="$2"
LIST_TARGET_VG="$BACKUPS"
LIST_TARGET_LV="$LIST_SOURCE_VG-$LIST_SOURCE_LV"
LIST_TARGET_BASE_LV="$LIST_TARGET_LV$SNAP_SUFFIX"
lvs -olv_name | grep "$LIST_TARGET_BASE_LV.$DATE_REGEX"
}

function remove()
{
REMOVE_TARGET_VG="$BACKUPS"
REMOVE_TARGET_LV="$1"
lvremove -y "$REMOVE_TARGET_VG/$REMOVE_TARGET_LV"
sync
}

function removeall()
{
DATE_OFFSET="$3"
FILTER="$(filter "$DATE_OFFSET")"
while read -r SNAPSHOT ; do
remove "$SNAPSHOT"
done < <(list "$1" "$2" | grep "$FILTER")

}

(
COMMAND="$1"
shift

case "$COMMAND" in
"--help")
echo "Help"
;;
"suffix")
suffix
;;
"filter")
filter "$1"
;;
"backup")
wait_lock_or_terminate
backup "$1" "$2"
;;
"list")
list "$1" "$2"
;;
"thindiff")
thindiff "$1" "$2" "$3"
;;
"thinsync")
thinsync "$1" "$2" "$3" "$4"
;;
"verify")
wait_lock_or_terminate
verify "$1" "$2"
;;
"resync")
wait_lock_or_terminate
resync "$1" "$2"
;;
"remove")
wait_lock_or_terminate
remove "$1"
;;
"removeall")
wait_lock_or_terminate
removeall "$1" "$2" "$3"
;;
*)
echo "None.."
;;
esac
) 98>$LOCK_FILE

EOF

Nima qiladi...?Yupqa suratlarni manipulyatsiya qilish va thin_delta orqali olingan ikkita ingichka surat o'rtasidagi farqni ddrescue va blkdiscard yordamida boshqa blokli qurilmaga sinxronlashtirish uchun buyruqlar to'plamini o'z ichiga oladi.

Biz cronga joylashtirgan yana bir skript:

Bir oz ko'proq janjal#cat >/root/lvm-thin-backup/cron-daily.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

SCRIPT_FILE="$(realpath $0)"
SCRIPT_DIR="$(dirname $SCRIPT_FILE)"
SCRIPT_NAME="$(basename -s .sh $SCRIPT_FILE)"

BACKUP_SCRIPT="$SCRIPT_DIR/lvm-thin-backup.sh"
RETENTION="-60 days"

$BACKUP_SCRIPT backup images linux-dev
$BACKUP_SCRIPT backup images win8
$BACKUP_SCRIPT backup images win8-data
#etc

$BACKUP_SCRIPT removeall images linux-dev "$RETENTION"
$BACKUP_SCRIPT removeall images win8 "$RETENTION"
$BACKUP_SCRIPT removeall images win8-data "$RETENTION"
#etc

EOF

Nima qiladi...?Ro'yxatdagi nozik jildlarning zaxira nusxalarini yaratish va sinxronlashtirish uchun oldingi skriptdan foydalanadi. Skript oxirgi sinxronizatsiyadan keyingi o'zgarishlarni kuzatish uchun zarur bo'lgan ro'yxatdagi jildlarning nofaol suratlarini qoldiradi.

Ushbu skript zaxira nusxalarini yaratish kerak bo'lgan nozik jildlar ro'yxatini ko'rsatib, tahrir qilinishi kerak. Berilgan ismlar faqat tasvirlash uchun. Agar xohlasangiz, barcha hajmlarni sinxronlashtiradigan skript yozishingiz mumkin.

Keling, huquqlarni beraylik:

#chmod +x /root/lvm-thin-backup/cron-daily.sh
#chmod +x /root/lvm-thin-backup/lvm-thin-backup.sh

Keling, uni tekshiramiz va uni cronga qo'yamiz:

#/usr/bin/nice -n 19 /usr/bin/ionice -c 3 /root/lvm-thin-backup/cron-daily.sh 2>&1 | /usr/bin/logger -t lvm-thin-backup
#cat /var/log/syslog | grep lvm-thin-backup
#crontab -e
0 3 * * * /usr/bin/nice -n 19 /usr/bin/ionice -c 3 /root/lvm-thin-backup/cron-daily.sh 2>&1 | /usr/bin/logger -t lvm-thin-backup

Birinchi ishga tushirish uzoq davom etadi, chunki... nozik hajmlar barcha ishlatilgan bo'sh joyni nusxalash orqali to'liq sinxronlashtiriladi. LVM yupqa metama'lumotlari tufayli biz qaysi bloklar amalda ekanligini bilamiz, shuning uchun faqat aslida ishlatilgan ingichka hajmli bloklar nusxalanadi.

LVM yupqa metama'lumotlari orqali o'zgartirish kuzatuvi tufayli keyingi ishga tushirishlar ma'lumotlarni bosqichma-bosqich nusxalaydi.

Keling, nima bo'lganini ko'rib chiqaylik:

#time /root/btrfs-backup/cron-daily.sh
real 0m2,967s
user 0m0,225s
sys 0m0,353s

#time /root/lvm-thin-backup/cron-daily.sh
real 1m2,710s
user 0m12,721s
sys 0m6,671s

#ls -al /backup/btrfs/back/remote/*
/backup/btrfs/back/remote/boot:
total 0
drwxr-xr-x 1 root root 1260 ΠΌΠ°Ρ€ 26 09:11 .
drwxr-xr-x 1 root root 16 ΠΌΠ°Ρ€ 6 09:30 ..
drwxr-xr-x 1 root root 322 ΠΌΠ°Ρ€ 26 02:00 .@base
drwxr-xr-x 1 root root 516 ΠΌΠ°Ρ€ 6 09:39 [email protected]
drwxr-xr-x 1 root root 516 ΠΌΠ°Ρ€ 6 09:39 [email protected]
...
/backup/btrfs/back/remote/root:
total 0
drwxr-xr-x 1 root root 2820 ΠΌΠ°Ρ€ 26 09:11 .
drwxr-xr-x 1 root root 16 ΠΌΠ°Ρ€ 6 09:30 ..
drwxr-xr-x 1 root root 240 ΠΌΠ°Ρ€ 26 09:11 @.@base
drwxr-xr-x 1 root root 22 ΠΌΠ°Ρ€ 26 09:11 @home.@base
drwxr-xr-x 1 root root 22 ΠΌΠ°Ρ€ 6 09:39 @[email protected]
drwxr-xr-x 1 root root 22 ΠΌΠ°Ρ€ 6 09:39 @[email protected]
...
drwxr-xr-x 1 root root 240 ΠΌΠ°Ρ€ 6 09:39 @[email protected]
drwxr-xr-x 1 root root 240 ΠΌΠ°Ρ€ 6 09:39 @[email protected]
...

#lvs -olv_name,lv_size images && lvs -olv_name,lv_size backup
LV LSize
linux-dev 128,00g
linux-dev.base 128,00g
thin-pool 1,38t
win8 128,00g
win8-data 2,00t
win8-data.base 2,00t
win8.base 128,00g
LV LSize
backup 256,00g
images-linux-dev.base 128,00g
images-linux-dev.snap.2020-03-08-10-09-11 128,00g
images-linux-dev.snap.2020-03-08-10-09-25 128,00g
...
images-win8-data.base 2,00t
images-win8-data.snap.2020-03-16-14-11-55 2,00t
images-win8-data.snap.2020-03-16-14-19-50 2,00t
...
images-win8.base 128,00g
images-win8.snap.2020-03-17-04-51-46 128,00g
images-win8.snap.2020-03-18-03-02-49 128,00g
...
thin-pool <2,09t

Buning qo'g'irchoqlar uyasiga qanday aloqasi bor?

Katta ehtimol bilan, LVM LV mantiqiy hajmlari boshqa VGlar uchun LVM PV jismoniy hajmlari bo'lishi mumkinligini hisobga olsak. LVM qo'g'irchoqlar kabi rekursiv bo'lishi mumkin. Bu LVM ga o'ta moslashuvchanlikni beradi.

PS

Keyingi maqolada biz uy ish stollari, uy Interneti va P2P tarmoqlaridan foydalangan holda bir nechta qit'alarda ortiqcha bo'lgan geo-tarqatilgan saqlash / vm klasterini yaratish uchun asos sifatida bir nechta shunga o'xshash mobil saqlash tizimlari / KVM dan foydalanishga harakat qilamiz.

Manba: www.habr.com

a Izoh qo'shish