Tere!
Soovin jagada kogukonnaga praktilisi kogemusi KVM-i andmesalvestussĂŒsteemi ĂŒlesehitamisest, kasutades md RAID + LVM-i.
Programmis on:
- md RAID 1 koostamine NVMe SSD-dest.
- md RAID 6 koostamine SATA SSD-dest ja tavalisest kettast.
- TRIM/DISCARD funktsiooni eripÀra SSD RAID 1/6-s.
- KĂ€ivitava md RAID 1/6 massiivi loomine ĂŒldiste ketaste kogumiga.
- SĂŒsteemi installimine NVMe RAID 1-le ilma NVMe toe olemasoluta BIOS-is.
- LVM cache ja LVM thin kasutamine.
- BTRFS-i snapshotide ja send/receive kasutamine varukoopiate tegemiseks.
- LVM thin snapshotide ja thin_delta kasutamine BTRFS-i stiilis varukoopiate tegemiseks.
Kui see huvitab, palun vaata edasi.
TÔend
Autor ei vastuta selle artikli materjalide/nÀidete/koodi/nÔuannete/andmete kasutamisest vÔi mitte kasutamisest tulenevate tagajÀrgede eest. Lugedes vÔi muul viisil seda materjali kasutades vÔtaksite enda kanda kÔik nende tegevuste tagajÀrjed. TagajÀrgedeks vÔivad olla:
- KĂŒpsetatud krĂ”bedaks NVMe SSD-d.
- SSD-mÀluseadmest tÀielikult ammendatud kirjutamisressurss ja rikkeilmumine.
- Kogu andmete kaotus kÔikidel salvestusseadmetel, sealhulgas varukoopiatel.
- Defektsed arvutitooted.
- Kulutatud aeg, nÀrvid ja raha.
- Igasugused muud tagajĂ€rjed, mida ei ole ĂŒlal loetletud.
Riistvara
Olime omandanud:
Emaplaat, mis on toodetud kuskil 2013. aastal Z87 kiibistikuga koos Intel Core i7 / Haswell-iga.
- Protsessor 4 tuuma ja 8 vooga.
- 32 gigabaiti DDR3 RAM-i.
- 1 x 16 vÔi 2 x 8 PCIe 3.0.
- 1 x 4 + 1 x 1 PCIe 2.0.
- 6 x 6 GBps SATA 3 pesad.
SAS-adapter LSI SAS9211-8I on uuendatud IT/HBA reĆŸiimi. RAID-toe tarkvara asendati tahtlikult HBA tarkvaraga, et:
- Saaksin igal ajal selle adapteri vÀlja vahetada ja asendada selle mingi muu esimese ettejuhtuva adapteriga.
- TRIM/DISCARD töötas kettadel normaalselt, kuna RAID-tarkvaras ei toetata neid kĂ€ske ĂŒldse, kuid HBA ei hooli, millised kĂ€sud bussil edastatakse.
KĂ”vakettad â 8 tk HGST Travelstar 7K1000, 1 TB suuruses 2.5-tollise vormitegija nagu sĂŒlearvutitel. Need kettad olid varem RAID 6 massiivis. Uues sĂŒsteemis on neil samuti kasutust, et salvestada lokaalseid varukoopiaid.
Lisaks soetati:
6 tk SATA SSD-d mudelist Samsung 860 QVO 2TB. Nendelt SSD-delt nĂ”uti suurt mahtu, SLC vahemĂ€lu olemasolu, soovitav oli usaldusvÀÀrsus ja madal hind. Kohustuslik oli discard/zero toete olemasolu, mida kontrollitakse dmesgâi rida jĂ€rgi:
kernel: ata1.00: Aktiveerimine discard_zeroes_data
2 tĂŒkki NVMe SSD mudelilt Samsung SSD 970 EVO 500GB.
Nende SSD-de jaoks on oluline juhuslike lugemise/kirjutamise kiirus ja ressurss teie vajadustele. Radiaator nende jaoks. HĂ€davajalik. TĂ”eliselt hĂ€davajalik. Vastasel juhul â kĂŒpsetate need Ă€ra kohe RAID-sĂŒnkroonimise ajal.
StarTech PEX8M2E2 adapter 2 x NVMe SSD jaoks, mis paigaldatakse PCIe 3.0 8x pesasse. See on jĂ€lle lihtsalt HBA, aga NVMe jaoks. Erineb odavatest adapteritest PCIe bifurcation'i toe nĂ”udmise puudumise tĂ”ttu emaplaadilt, tĂ€nu sisseehitatud PCIe lĂŒlitile. Töötab isegi kĂ”ige vanemas sĂŒsteemis, kus on PCIe, isegi kui see oleks x1 PCIe 1.0 pesa. Loomulikult vastava kiirusaga. RAID-e seal ei ole. Integratsiooni BIOS-i ei ole. Nii et teie sĂŒsteem ei Ă”pi maagiliselt NVMe-lt kĂ€ivituma ja kindlasti ei tee see NVMe RAID-i tĂ€nu sellele seadmele.
See komponent oli tingitud ainult ĂŒhest vabast 8x PCIe 3.0 pesast sĂŒsteemis ja kui oleks kaks vaba pesa, saaks selle hĂ”lpsasti asendada kahe odava PEX4M2E1-ga vĂ”i analoogidega, mida saab osta igalt poolt alates 600 rubla.
ErakĂ€iguga loobuti igasugustest riistvaralistest vĂ”i emaplaadi/BIOSe integreeritud RAID-idest, et oleks vĂ”imalik tĂ€ielikult asendada kogu sĂŒsteem, vĂ€lja arvatud SSD/HDD, sĂ€ilitades kĂ”ik andmed. Ideaalis nii, et saaks isegi paigaldatud operatsioonisĂŒsteemi sĂ€ilitada uuele/teisele riistvarale ĂŒlemisel. Peamine, et oleks SATA ja PCIe portid. See on nagu live CD vĂ”i kĂ€ivitatav USB, vaid vĂ€ga kiire ja veidi mahukas.
HuumorTeate, kuidas see vahel on â vahel tuleb kogu massiiv kiiresti kaasa vĂ”tta. Ja andmeid ei taha kaotada. Selleks on kĂ”ik mainitud kandjad mugavalt paigutatud 5.25 standardse korpuse sahtlitesse.
Ja muidugi katsetamiseks erinevate SSD vahemÀlu meetoditega Linuxis.
Riistvarased RAID-id on igavad. LĂŒlitate sisse. See kas töötab vĂ”i ei. Aga mdadm-iga on alati variandid.
Push-teated
Varem oli riistvaras paigaldatud Debian 8 Jessie, mis on peaaegu EOL. Koostati RAID 6 ĂŒlalmainitud HDD-de paarist LVM-iga. Sellel töötasid virtuaalmasinaid kvm/libvirt.
Kuna autoril on sobiv kogemus portatiivsete laadimis-SATA/NVMe mĂ€lupulkade loomiseks ning et mitte rikkuda tuttavat apt-malli, valiti sihtsĂŒsteemiks Ubuntu 18.04, mis on juba piisavalt stabiilne, kuid omab siiski veel 3 aasta toetust.
Mainitud sĂŒsteemis on olemas kĂ”ik vajalikud riistvara draiverid kohe vĂ€lja pakutud. Me ei vaja mingeid kolmandate osapoolte tarkvara ega draivereid.
Paigaldamise ettevalmistus
SĂŒsteemi paigaldamiseks on meil vaja Ubuntu Desktop Images. Serveriversioonil on mingisugune tuumne paigaldaja, mis nĂ€itab liialt suurt iseseisvust, pannes UEFI sĂŒsteemiosa automaatselt ĂŒhte kandidaatide ketast, rikkudes kogu ilu. Seega installitakse see ainult UEFI reĆŸiimis. Alternatiive ei pakuta.
See meid ei rahulda.
Miks?Kahjuks on UEFI laadimine ÀÀrmiselt halvasti kooskĂ”las lauaarvuti tarkvaraliselt RAID-iga, kuna UEFI ESP jaotise jaoks ei pakuta mingit varundust. Internetis on retsepte, mis soovitavad paigutada ESP jaotise mĂ€lupulgale USB-porti, kuid see on rikkepunkt. On retsepte, mis kasutavad tarkvaralist mdadm RAID 1 versiooni 0.9 metaandmetega, mis ei takista UEFI BIOS-il seda jaotist nĂ€gemast, kuid see elab kuni Ă”nneliku hetkeni, mil BIOS vĂ”i mĂ”ni muu OS riistvaral kirjutab ESP-le, unustades sĂŒnhroniseerida teised peeglid.
Lisaks sĂ”ltub UEFI laadimine NVRAM-ist, mis ei liigu koos ketastega uude sĂŒsteemi, kuna see on osa emaplaadist.
Nii et me ei hakka uut jalgratast leiutama. Meil on juba valmis, aastate jooksul proovitud vanakooli jalgratas, mida tĂ€napĂ€eval tuntakse Legacy/BIOS kĂ€ivitamisena, kuid selle uhke nimega CSM UEFI ĂŒhilduvates sĂŒsteemides. Me lihtsalt vĂ”tame selle riiulilt, mÀÀrime kokku, pumpame rehvid ĂŒles ja puhastame niiske lapiga.
Ubuntu töölauaversioon ei oska ka korralikult Legacy laadijaga paigalduda, kuid nagu öeldakse, siin on vÀhemalt valikud olemas.
Nii et kogume riistvara ja laadime sĂŒsteemi Ubuntu Live laadimismĂ€lupulgalt. Me peame pakette allalaadima, seega seadistame vĂ”rgu, mis teile tööle hakkab. Kui see ei toimi â vajalikud paketid saab eelnevalt mĂ€lupulgale laadida.
Siseneme töölauakeskkonda, kÀivitame terminali emulatori ja alustame:
#sudo bash
KuidasâŠ?Ălalolev rida on kanonisest vallandav tegur sudo vaidlustest. Alustame.ilotkaSuurem vastutusega kaasneb ka suurem vastutus. KĂŒsimus on, kas suudate selle endale vĂ”tta. Paljud arvavad, et sudo kasutamine sellisel viisil on vĂ€hemalt ettevaatamatu. Kuid:ilotkaMiks mitte ZFSâŠ?

#apt-get install mdadm lvm2 thin-provisioning-tools btrfs-tools util-linux lsscsi nvme-cli mc
Kui me installime tarkvara oma arvutisse, rendime pÔhimÔtteliselt oma riistvara selle tarkvara arendajatele.Kui usaldame seda tarkvara oma andmete kaitsmiseks, vÔtame omale laenu, mis vastab nende andmete taastamise maksumusele, mille eest tuleb kunagi tasuda.
Sellest vaatenurgast on ZFS nagu Ferrari, kuid mdadm+lvm sarnaneb rohkem jalgrattaga.
Subjektiivselt eelistab autor laenata tundmatutele isikutele laenatud jalgratta, mitte Ferrarit. Seal on ka kĂŒsimus madalam hind. Pole vajadust Ă”iguste jĂ€rele. Lihtsam liiklusreeglite jĂ€rgimine. Parkimine on tasuta. LĂ€bivus on parem. Jalgrattale saab alati jalad kĂŒlge panna ning tasuks jalgratast saab ka ise parandada.
Miks siis BTRFS�
KĂ€itusĂŒsteemi laadimiseks vajame failisĂŒsteemi, mis toetab Legacy/BIOS GRUB-i kastis ja samal ajal toetab elus snapshots. Kasutame seda /boot jagu jaoks. Lisaks eelistab autor kasutada seda failisĂŒsteemi ka / (juurkataloog) jaoks, unustamata, et igasugusele muule tarkvarale vĂ”ib luua eraldi lĂ”ike LVM-iga ja paigaldada need vajalikesse kataloogidesse.Ei pilte
, ei andmebaase me sellel failisĂŒsteemil hoidma ei hakka. virtuaalmasinateSeda failisĂŒsteemi kasutatakse ainult sĂŒsteemi hetkeseisude loomiseks ilma selle vĂ€ljalĂŒlitamiseta ja nende hetkeseisude jĂ€rgneks edastamiseks varukoopiaketale send/receive abil.
Lisaks eelistab autor hoida otse riistvaral minimaalset tarkvara ja kÀivitada kogu muu tarkvara virtuaalmasinates, kasutades selliseid lahendusi nagu GPU ja PCI-USB host-kontrollerite edastamine KVM-i kaudu IOMMU abil.
Riistvarale jÀÀb ainult â andmete salvestamine, virtualiseerimine ja varundamine.
Kui usaldad rohkem ZFS-i, siis on pÔhimÔtteliselt nende kasutamine sarnane.
Siiski, autor ignoreerib teadlikult ZFS-s, BTRFS-is ja LVM-is olemasolevaid peegeldamise / RAID ja ĂŒleliigsete funktsioone.
Siiski autor ignoreerib teadlikult ZFS, BRTFS ja LVM-i sisseehitatud peegeldamis- ja ĂŒleliigsuse funktsioone.
BTRFS-l on lisafunktsioon, mis muudab juhuslikud kirjutused jĂ€rjestikusteks, mis omakorda parandab varundamise ja ĂŒlesvĂ”tmise kiirus HDD-l.
Skaneerime kÔik seadmed uuesti:
#udevadm control --reload-rules && udevadm trigger
Uurime ĂŒmber:
#lsscsi && nvme list
[0:0:0:0] ketas ATA Samsung SSD 860 2B6Q /dev/sda
[1:0:0:0] ketas ATA Samsung SSD 860 2B6Q /dev/sdb
[2:0:0:0] ketas ATA Samsung SSD 860 2B6Q /dev/sdc
[3:0:0:0] ketas ATA Samsung SSD 860 2B6Q /dev/sdd
[4:0:0:0] ketas ATA Samsung SSD 860 2B6Q /dev/sde
[5:0:0:0] ketas ATA Samsung SSD 860 2B6Q /dev/sdf
[6:0:0:0] ketas ATA HGST HTS721010A9 A3J0 /dev/sdg
[6:0:1:0] ketas ATA HGST HTS721010A9 A3J0 /dev/sdh
[6:0:2:0] ketas ATA HGST HTS721010A9 A3J0 /dev/sdi
[6:0:3:0] ketas ATA HGST HTS721010A9 A3B0 /dev/sdj
[6:0:4:0] ketas ATA HGST HTS721010A9 A3B0 /dev/sdk
[6:0:5:0] ketas ATA HGST HTS721010A9 A3B0 /dev/sdl
[6:0:6:0] ketas ATA HGST HTS721010A9 A3J0 /dev/sdm
[6:0:7:0] ketas ATA HGST HTS721010A9 A3J0 /dev/sdn
SÔlm SN Mudel Nimi Kasutamine Formaat 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
Diskide jaotamine
NVMe SSD
Me ei hakka neid kuidagi jaotama. Igal juhul ei jĂ”ua meie BIOS nende mĂ€luseadmeteni. Nii et need lĂ€hevad tĂ€ielikult tarkvara RAID-i. Isegi jaotusi me seal ei loo. Kui soovid âreetmeâ vĂ”i âprintsiibinaâ â loo ĂŒks suur jaotus nagu HDD-l.
SATA HDD
Siin ei ole eriliselt midagi vĂ€lja mĂ”elda. Loome ĂŒhe jaotuse kĂ”igile. Jaotuse loome, sest need diskid on BIOSis nĂ€htavad ja vĂ”ivad isegi proovida sĂŒsteemi laadida. Hiljem paigaldame neist diskidest GRUB-i, et sĂŒsteem saaks ootamatult kĂ€ima.
#cat >hdd.part << EOF
silt: dos
silt-id: 0x00000000
seade: /dev/sdg
ĂŒksus: sektorid
/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
SATA SSD
Siin on meil kÔige huvitavam.
Esiteks, meie mĂ€luseadmed on suurusega 2 TB. See on MBR-i jaoks lubatud, mida me ka kasutame. Vajadusel vĂ”ib asendada GPT-ks. GPT diskidel on ĂŒhilduvuskihid, mis vĂ”imaldavad MBR-ĂŒhilduvatel sĂŒsteemidel nĂ€ha esimesi 4 jaotust, kui need asuvad esimeses 2 terabaidis. Peamine on, et alglaadimise jaotus ja bios_grub jaotus oleksid nende diskide alguses. See vĂ”imaldab isegi GPT diskilt Legacy/BIOS laadimist.
Kuid see ei ole meie juhtum.
Siin loome kaks jaotust. Esimene jaotus on suurusega 1 GB ja seda kasutatakse RAID 1 /boot-iks.
Teine jaotus kasutatakse RAID 6 jaoks ja hĂ”ivab kogu ĂŒlejÀÀnud vaba ruumi, vĂ€lja arvatud vĂ€ike jaotamata ala, mis jÀÀb seadme lĂ”ppu.
Mis on see jaotamata ala?VĂ”rgus olevate allikate kohaselt on meie SATA SSD-del dĂŒnaamiliselt laiendatav SLC vahemĂ€lu suurusega 6 kuni 78 gigabaidi. 6 gigabaidi saame âtasutaâ mĂ€luseadme tehniliste andmete âgigabaitideâ ja âgibibaitideâ erinevuse tĂ”ttu. ĂlejÀÀnud 72 gigabaidi eraldatakse kasutamata ruumi tĂ”ttu.
Siinkohal on oluline mĂ€rkida, et meil on SLC vahemĂ€lu, kuid ruum on hĂ”ivatud 4 bitti MLC reĆŸiimis. See tĂ€hendab, et iga 4 gigabaidi vaba ruumi puhul saame vaid 1 gigabaidi SLC vahemĂ€lu.
Korrutame 72 gigabaidi neljaga ja saame 288 gigabaidi. Just see on see vaba ruum, mida me ei hakka jaotama, et vÔimaldada mÀluseadmetel tÀielikult kasutada SLC vahemÀlu.
Seega saame tĂ”husalt kuni 312 gigabaidi SLC vahemĂ€lu kuuest mĂ€luseadmest. Kahest mĂ€luseadmest kaks kasutatakse RAID-is ĂŒleliigsete elementide jaoks.
Selline kogus vahemĂ€lu vĂ”imaldab meil vĂ€ga harva otsepraktikas kokku puutuda olukorraga, kus kirjutamine ei toimu vahemĂ€lus. See kompenseerib ÀÀrmiselt hĂ€sti kĂ”ige kurvemad QLC mĂ€lu puudused â ÀÀrmiselt madal kirjutamiskiirus, kui andmed kirjutatakse vahemĂ€lust mööda. Kui teie koormused sellele ei vasta, soovitan tĂ”siselt mĂ”elda, kui kaua teie SSD-d sellise koormuse all töötavad, arvestades TBW tehnikaspetsifikatsioone.
#cat >ssd.part << EOF
silt: dos
silt-id: 0x00000000
seade: \/dev\/sda
ĂŒksus: sektorid
/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
Massiivide loomine
Alustuseks peame masina ĂŒmber nimetama. Seda on vaja, kuna hosti nimi on osa massiivi nimest, kuski mdadm sees, ja see mĂ”jutab mingil mÀÀral. Massiive vĂ”ib muidugi hiljem ĂŒmber nimetada, kuid see on liigsed toimingud.
#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
Miks âassume-cleanâŠ?Kuna massiivide initsialiseerimine ei ole vajalik. RAID 1 ja 6 tasemete puhul on see lubatud. KĂ”ik vĂ”ib töötada ka ilma initsialiseerimiseta, kui see on uus massiiv. Veelgi enam, SSD massiivi initsialiseerimine loomisel on TBW ressursi raiskamine. Me kasutame TRIM/DISCARD seal, kus vĂ”imalik, kokku pandud SSD massiivide âinitsialiseerimiseksâ.
SSD RAID 1 massiivide puhul on DISCARD kohe toetatud.
SSD RAID 6 massiivide puhul tuleb DISCARD seadistada tuuma mooduli parameetrites.
Seda tasub teha ainult siis, kui kĂ”ik SSD-d, mida kasutatakse tasemete 4/5/6 massiivides, toetavad discard_zeroes_data. MĂ”nikord satub kummalisi seadmeid, mis teatavad tuumale selle funktsiooni toimest, kuid tegelikkuses seda ei ole vĂ”i funktsioon ei toimi alati. Praegu on tugi praktiliselt kĂ”ikjal olemas, kuid vanade seadmete ja vigaste pĂŒsivara puhul on siiski juhtumeid. SeetĂ”ttu on RAID 6 jaoks DISCARD vaikimisi vĂ€lja lĂŒlitatud.
TĂ€helepanu, jĂ€rgmine kĂ€sk hĂ€vitab kĂ”ik andmed NVMe mĂ€luseadmetel, âinitsialiseeridesâ massiivi ânullideksâ.
#blkdiscard /dev/md0
Kui midagi lÀks valesti, proovige nÀidata sammu.
#blkdiscard --step 65536 /dev/md0
SATA 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
Miks nii suurâŠ?Chunk-size suurendamine mĂ”jutab positiivselt juhusliku lugemise kiiruseni chunk-size kaasaarvatud. See juhtub, kuna vastava suurusega vĂ”i vĂ€iksema operatsiooni saab tĂ€ielikult teostada ĂŒhes seadmes. SeetĂ”ttu summeeritakse kĂ”ikide seadmete IOPS. Statistika kohaselt ei ĂŒleta 99% IO-d 512K.
RAID 6 kirjutus-IOPS on alati vĂ€hem vĂ”i vĂ”rdne ĂŒhe seadme IOPS-iga. Samas vĂ”ib juhuslik lugemine olla mitu korda kĂ”rgem kui ĂŒhel seadmel, ja siin on ploki suurus vĂ”tmetĂ€htsusega.
Autor ei nÀe mÔtet optimeerida parameetrit, mis on RAID 6 puhul algselt halb, ja selle asemel optimeerib ta seda, kus RAID 6 end hÀsti nÀitab.
Halba juhuslikku kirjutamist RAID 6 kompenseerime NVMe vahemÀluga ja Ôhukese provisionimise trikkidega.
Me ei ole veel lubanud DISCARD RAID 6 jaoks. Seega ei hakka me seda massiivi "kĂ€ivitama" praegu. Teeme seda hiljem, - pĂ€rast operatsioonisĂŒsteemi installimist.
SATA HDD
#mdadm --create --verbose --assume-clean /dev/md3 --chunk-size=512 --level=6 --raid-devices=8 /dev/sd[g-n]1
LVM NVMe RAID-il
Kiirusest lÀhtuvalt soovime paigutada juur-FS NVMe RAID 1 peale, mille aadress on /dev/md0.
Kuid seda kiiret massiivi vajame veel muudeks vajadusteks, nagu vahetus, metaandmed ja LVM-vahemÀlu ning LVM-Ôhuke metaandmed, seetÔttu loome sellel massiivil LVM VG.
#pvcreate /dev/md0
#vgcreate root /dev/md0
Loome jaotuse juur-FS jaoks.
#lvcreate -L 128G --name root root
Loome vahetusjaotuse, mille suurus on sama, mis RAM-i.
#lvcreate -L 32G --name swap root
OperatsioonisĂŒsteemi installimine
KokkuvĂ”ttes on meil kĂ”ik vajalikud, et sĂŒsteemi installida.
KĂ€ivitame sĂŒsteemi installimisviisardi Ubuntu Live keskkonnast. Tavaline installatsioon. Ainult, et installimise ajal ketaste valimisel tuleb jĂ€rgmist mĂ€rkida:
- /dev/md1, â ŃĐŸŃĐșа ĐŒĐŸĐœŃĐžŃĐŸĐČĐ°ĐœĐžŃ /boot, ЀХ â BTRFS
- /dev/root/root (a.k.a /dev/mapper/root-root), â ŃĐŸŃĐșа ĐŒĐŸĐœŃĐžŃĐŸĐČĐ°ĐœĐžŃ / (ĐșĐŸŃĐ”ĐœŃ), ЀХ â BTRFS
- /dev/root/swap (a.k.a /dev/mapper/root-swap), â ĐžŃĐżĐŸĐ»ŃĐ·ĐŸĐČаŃŃ ĐșаĐș ŃазЎДл ĐżĐŸĐŽĐșаŃĐșĐž
- KĂ€ivitaja installige /dev/sda peale
Kui valitakse BTRFS juur-FS-ina, siis loob installija automaatselt kaks BTRFS-mahtu nimedega "@" juur (/)-le ja "@home" /home jaoks.
KĂ€ivitame installiâŠ
Installimine lĂ”peb moodsa dialoogiboksiga, mis teavitab installimise kĂ€ivitaja tĂ”rkest. Kahjuks ei saa sellest dialoogist normaalselt lahkuda ja jĂ€tkata installimist. Logime sĂŒsteemist vĂ€lja ja logime uuesti sisse, jĂ”udes puhtale Ubuntu Live töölauale. Avame terminali ja uuesti:
#sudo bash
Loome chroot keskkonna, et jÀtkata installimist:
#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
Seame vÔrgu ja hostinime chrootis:
#cat /etc/hostname >/mnt/chroot/etc/hostname
#cat /etc/hosts >/mnt/chroot/etc/hosts
#cat /etc/resolv.conf >/mnt/chroot/etc/resolv.conf
Siseneme chroot keskkonda:
#chroot /mnt/chroot
Esimese asjana installime paketid:
apt-get install --reinstall mdadm lvm2 thin-provisioning-tools btrfs-tools util-linux lsscsi nvme-cli mc debsums hdparm
Kontrollime ja parandame kÔik paketid, mis on valesti paigaldatud lÔpetamata installimise tÔttu:
#CORRUPTED_PACKAGES=$(debsums -s 2>&1 | awk '{print $6}' | uniq)
#apt-get install --reinstall $CORRUPTED_PACKAGES
Kui midagi lÀks valesti, vÔib tekkida vajadus enne seda muuta /etc/apt/sources.list:
Parandame RAID 6 mooduli seadeid TRIM/DISCARD lubamiseks:
#cat >/etc/modprobe.d/raid456.conf << EOF
valikud raid456 seadmed_kĂ€sitlema_hĂŒlgamine_turvaliselt=1
EOF
Veidi seadistame meie massiive:
#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
Mis see oli..?Oleme loonud ĐœĐ°Đ±ĐŸŃ udev reegleid, mis teevad jĂ€rgmist:
- Seada 2020. aasta jaoks sobivat RAID 6 plokkide vahemÀlu suurust. T vaikimisi vÀÀrtus ei tundu olevat muutunud alates Linuxi loomise ajast ning ei ole juba pikka aega olnud sobiv.
- Reserveerige minimaalselt I/O-d, kui kontrollite/sĂŒnkroonite massiive. See on vajalik, et teie massiivid ei takerduks igavese sĂŒnkroniseerimise seisundisse koormuse all.
- Piirake maksimum I/O-d, kui kontrollite/sĂŒnkroonite massiive. See on vajalik, et SSD RAID-i sĂŒnkroniseerimine/kontroll ei kĂ”rvetaks teie mĂ€luseadmeid. See on eriti aktuaalne NVMe puhul. (Kas mĂ€letate jahutusradiaatorit? Ma ei naljatanud.)
- Keelake APM-l kettadelt spindli peatumise lubamine (HDD) ja seadke kettade kontrollerite puhkuse ajaline piir 7 tunniks. Kui teie kettad seda toetavad, vĂ”ite APM-i tĂ€iesti vĂ€lja lĂŒlitada (-B 255). Vaikimisi peatavad kettad oma pöörlemise viie sekundi jooksul. Siis soovib operatsioonisĂŒsteem kettaketti tĂŒhjendada, kettad hakkavad uuesti pöörlema ja kĂ”ik kordub. Kettadel on piiratud maksimaalne spindli pöörde arv. Selline lihtne tsĂŒkkel vaikimisi vĂ”ib kergesti teie kettad mĂ”ne aasta jooksul Ă€ra tappa. KĂ”ik kettad ei kannata seda, kuid meie
- Seadke pöörlevate ketaste readahead 1 megabaidiks â kaks jĂ€rjestikust plokki/RAID 6 chunk.
- Keelake readahead ise massiivides.
Tegime muudatused /etc/fstab:
#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
Miks nii..?Otsime /boot partitsiooni UUID jÀrgi, kuna massiivide nimetused vÔivad teoreetiliselt muutuda.
Otsime ĂŒlejÀÀnud partitsioone LVM nimede jĂ€rgi kujul /dev/mapper/vg-lv, kuna need tuvastavad partitsioonid piisavalt unikaalselt.
Ărge kasutage UUID-d LVM jaoks, kuna LVM mahutite ja nende varukoopiate UUID-d vĂ”ivad kattuda.Kas mĂ€letame /dev/mapper/root-root'i kaks korda..?Jah. Just nii. BTRFS eripĂ€ra. Seda failisĂŒsteemi saab mountida mitu korda erinevate subvol'idega.
Selle sama eripĂ€ra tĂ”ttu soovitan mitte luua LVM varukoopiaid aktiivsetest BTRFS mahutitest. VĂ”ite saada ĂŒllatuse pĂ€rast taaskĂ€ivitamist.
Genereerime mdadm konfiguratsiooni uuesti:
#/usr/share/mdadm/mkconf | sed 's/#DEVICE/DEVICE/g' >/etc/mdadm/mdadm.conf
Korrigeerime LVM seadeid:
#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
Mis see oli..?Oleme lĂŒlitanud LVM thin basseinide automaatse laienemise sisse, kui kasutatud ruum ulatub 90% mahust, suurendades mahtu 5% vĂ”rra.
Oleme suurendanud LVM cache maksimaalset vahemÀlu plokkide arvu.
Oleme LVM-le keelanud otsimise LVM mahtude (PV) peale:
- seadmetes, mis sisaldavad LVM cache (cdata)
- seadmetes, mis on LVM cache'iga vahele lĂŒlitatud (<lv_name>_corig). Sellegipoolest skannitakse vahepeal kĂ€tkist seadet lĂ€bi vahecache'i (lihtsalt <lv_name>).
- seadmetes, mis sisaldavad LVM cache metainformatsiooni (cmeta)
- kĂ”ikides seadmetes VG, mille nimi on images. Siin on meil virtuaalmasinate diskipildid, ja me ei soovi, et LVM hostis aktiveeriks kĂŒlalisoperatsioonisĂŒsteemile kuuluvad mahud.
- kÔikides seadmetes VG, mille nimi on backup. Siin on meil virtuaalmasinate piltide varukoopiad.
- kÔikides seadmetes, mille nimi lÔpeb sÔnadega «gpv» (guest physical volume)
Oleme lĂŒlitanud DISCARD toetuse sisse, kui vabastame ruumi LVM VG-s. Olge ettevaatlik. See muudab LV eemaldamise SSD-l piisavalt ajaliseks. Eriti kehtib see SSD RAID 6 puhul. Kuid plaanis on kasutada thin provisioning'it, seega ei sega see meid ĂŒldse.
Uuendame initramfs'i pilti:
#update-initramfs -u -k all
Paigaldame ja konfigureerime grub'i:
#apt-get install grub-pc
#apt-get purge os-prober
#dpkg-reconfigure grub-pc
Milliseid kettaid valida?KĂ”iki, mis on sd*. SĂŒsteem peaks olema suuteline kĂ€ivituma mis tahes töötavast SATA ketast vĂ”i SSD-st.
Miks me os-prober'i kinni panime..?Liigne iseseisvus ja ulakad kÀed.
See ei tööta korralikult, kui ĂŒks RAID on degradatsioonis. See proovib otsida OS-i osadest, mida kasutatakse virtuaalmasinates, mis töötavad selle riistvara peal.
Kui see on teile vajalik, vÔite selle jÀtta, kuid pidage meeles kÔiki eelnevalt loetletud asju. Soovitan otsida internetist retsepte, kuidas vabaneda ulakatest kÀtest.
Sellega lĂ”petasime algse installi. On aeg taaskĂ€ivitada Ă€sja paigaldatud operatsioonisĂŒsteemi. Ărge unustage eemaldada kĂ€ivitatavat Live CD/USB-d.
#exit
#reboot
KĂ€ivitusseadmeks valime mis tahes SATA SSD.
LVM SATA SSD-l
Selleks ajaks oleme juba kĂ€ivitanud uue operatsioonisĂŒsteemi, seadistanud vĂ”rgu, apt, avanud terminali emulaatori ja kĂ€ivitanud:
#sudo bash
JĂ€tkame.
«Algatame» SATA SSD massiivi:
#blkdiscard /dev/md2
Kui ei toimi, siis proovime:
#blkdiscard --step 65536 /dev/md2
Loome LVM VG SATA SSD-l:
#pvcreate /dev/md2
#vgcreate data /dev/md2
Miks veel ĂŒks VG..?TĂ”epoolest, meil on juba VG nimega root. Miks mitte lisada kĂ”ik ĂŒhte VG?
Kui VG-l on mitu PV-d, peavad kÔik need PV-d olema kohal (veebis), et VG-d Ôigesti aktiveerida. Erandiks on LVM RAID, mida me sihikindlalt ei kasuta.
Tahame vĂ€ga, et RAID 6 massiivi andmete kadumise (loe: andmete kaotuse) korral saaks operatsioonisĂŒsteem sujuvalt kĂ€ivituda ja annaks meile vĂ”imaluse probleem lahendada.
Selleks isoleerime me esimesel abstraktsioonitasemel iga fĂŒĂŒsilise "kandja" tĂŒĂŒbi eraldi VG-sse.
Teaduslikult öeldes kuuluvad erinevad RAID massiivid erinevatesse "usaldusdomÀÀnidesse". Ei ole mĂ”istlik luua neile tĂ€iendavat ĂŒhest rikekohta, koondades need ĂŒhte VG-sse.
LVM olemasolu "riistvaratasemel" vÔimaldab meil jagada erinevaid RAID massiive erinevalt ning neid kuju kombineerida. NÀiteks - kÀivitada samal ajal bcache + LVM thin, bcache + BTRFS, LVM cache + LVM thin, keeruline ZFS konfigureerimine vahemÀllu vÔi mÔni muu segane segu, et kÔik see proovida ja vÔrrelda.
Riistvaratasemel ei kasuta me midagi muud kui hÀid ja vanu "paksu" LVM-volume. Erandiks reeglist vÔib olla varukoopia jagu.
MÔtlen, et selleks ajaks on paljud lugejad juba hakanud midagi kahtlustama matroƥka osas.
LVM SATA HDD-l
#pvcreate /dev/md3
#vgcreate backup /dev/md3
JĂ€lle uus VG..?Tahame vĂ€ga, et meie varukoopia andmeid sisaldava ketta massiivi rikke korral saaks meie operatsioonisĂŒsteem jĂ€tkata sujuvalt töötamist, hoides samas ligipÀÀsu mitte-varukoopia andmetele. SeetĂ”ttu, et vĂ€ltida VG aktiveerimise probleeme, loome eraldi VG.
LVM vahemÀlu seadistamine
Loome LV NVMe RAID 1-l, et kasutada seda vahemÀlu seadmena.
#lvcreate -L 70871154688B --name cache root
Miks nii vĂ€heâŠ?Asi on selles, et meie NVMe SSD-del on samuti SLC vahemĂ€lu. 4 gigabaiti "tasuta" ja 18 gigabaiti dĂŒnaamiliselt vabastatud ruumi, mis on hĂ”ivatud 3-bit MLC. PĂ€rast seda vahemĂ€lu ammendumist ei saa NVMe SSD-d palju kiiremini kui meie SATA SSD vahemĂ€luga. Just sellepĂ€rast ei ole mĂ”tet luua LVM vahemĂ€lu jagu mĂ€rkimisvÀÀrselt suurem kui kaks korda NVMe salvestusseadmest SLC vahemĂ€lu maht. Kasutatavate NVMe salvestusseadmete puhul peab autor mĂ”istlikuks luua 32-64 gigabaiti vahemĂ€lu.
Esitatud jagu on vajalik 64 gigabaiti vahemÀlu organiseerimiseks, vahemÀlude metateabe salvestamiseks ja metateabe varukoopia loomiseks.
Lisaks mĂ€rgin, et pĂ€rast sĂŒsteemi ebaĂ”iget vĂ€ljalĂŒlitamist mĂ€rgib LVM kogu vahemĂ€lu rĂ€pasena ja sĂŒnkroniseerib selle uuesti. Veelgi enam, see kordub iga kord, kui kasutate lvchange selle seadme peal kuni jĂ€rgmise sĂŒsteemi taaskĂ€ivitamiseni. SeetĂ”ttu soovitan vahemĂ€lu kohe vastava skripti abil ĂŒmber luua.
Loome LV SATA RAID 6, et kasutada seda vahemÀluna.
#lvcreate -L 3298543271936B --name cache data
Miks just kolm terabaiti?..Et vajadusel saaks kasutada SATA SSD RAID 6 teisteks vajadusteks. VahemĂ€lu suurust saab dĂŒnaamiliselt suurendada, ilma et sĂŒsteem peatuks. Selleks on vajalik vahemĂ€lu ajutiselt peatada ja uuesti sisse lĂŒlitada, kuid LVM-cache'i eripĂ€ra vĂ”rreldes nĂ€iteks bcache'iga on see, et seda saab teha ilma sĂŒsteemi seiskamata.
Loome uue VG vahemÀluks.
#pvcreate /dev/root/cache
#pvcreate /dev/data/cache
#vgcreate cache /dev/root/cache /dev/data/cache
Loome LV vahemÀluseadmel.
#lvcreate -L 3298539077632B --name cachedata cache /dev/data/cache
Siin kasutasime kohe kogu vabast ruumist /dev/data/cache, et kĂ”ik muud vajalikud jaotised luuakse kohe /dev/root/cache. Kui teil on midagi valesti koha peal, saate selle pvmove abil ĂŒmber paigutada.
Loome ja aktiveerime vahemÀlu:
#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
Miks selline chunksize..?Praktiliste katsetuste kÀigus suudeti autoril vÀlja selgitada, et parim tulemus saavutatakse, kui LVM cache ploki suurus vastab LVM thin ploki suurusele. Sel juhul, mida vÀiksem on suurus, seda paremini nÀitab konfiguratsioon juhusliku kirjutamise korral.
64k on minimaalne ploki suurus, mis on lubatud LVM thin jaoks.
Olge ettevaatlik writeback..!Jah. See vahemĂ€lu tĂŒĂŒp lĂŒkkab kirjutamise sĂŒnkroniseerimise vahemĂ€luga seadmele. See tĂ€hendab, et kui vahemĂ€lu on kadunud, vĂ”ib kaotada andmeid vahemĂ€lu seadmes. Hiljem rÀÀgib autor, millised meetmed, peale NVMe RAID 1, on vĂ”imalikud selle riski kompenseerimiseks.
See vahemĂ€lu tĂŒĂŒp on valitud teadlikult, et kompenseerida RAID 6 madalat tulemuslikkust juhusliku kirjutamise korral.
Kontrollime, mida oleme saavutanud:
#lvs -a -o lv_name,lv_size,devices --units B cache
LV LSize seadmed
[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)
/dev/data/cache peavad olema ainult [cachedata_corig]. Kui midagi on valesti, kasutage pvmove.
VahemĂ€lu saab vajadusel ĂŒhe kĂ€suga keelata:
#lvconvert -y --uncache cache/cachedata
See toimub reaalajas. LVM sĂŒnkroniseerib lihtsalt vahemĂ€lu kettale, eemaldab selle ja nimetab cachedata_corig uuesti cachedata'ks.
LVM thin seadistamine
Hinnanguliselt hindame, kui palju ruumi vajame LVM thin metadate jaoks:
#thin_metadata_size --block-size=64k --pool-size=6terabytes --max-thins=100000 -u bytes
thin_metadata_size - 3385794560 baitsi hinnanguline metaandmete piirkonna suurus "--block-size=64kibibytes --pool-size=6terabytes --max-thins=100000"
Ămardame 4 gigabaidini: 4294967296B
Korrutame kahega ja liidame 4194304B LVM PV metaandmete jaoks: 8594128896B
Loome eraldi jaotuse NVMe RAID 1-s, et paigaldada sinna LVM thin metaandmed ja nende varukoopia:
#lvcreate -L 8594128896B --name images root
Miks..?Siin vĂ”ib tekkida kĂŒsimus, miks paigutada LVM thin metaandmed eraldi, kui need siiski vahemĂ€lus salvestatakse ja töötavad kiiresti.
Kiirus on kĂŒll oluline, kuid mitte peamine pĂ”hjus. Asi on selles, et vahemĂ€lu on rikke punkt. See vĂ”ib rikke korral vĂ€lja kukkuda ja kui LVM thin metaandmed on vahemĂ€lu salvestatud, toob see kaasa kogu kaotuse. Ilma tĂ€iuslike metaandmeteta on Ă”hukeste mahtude taastamine praktiliselt vĂ”imatu.
Kandudes metaandmed eraldi, mitte vahemĂ€lusse, kuid kiiresse mahtu, tagame metaandmete turvalisuse, juhul kui vahemĂ€lu kaob vĂ”i kahjustub. Sellisel juhul jÀÀvad vahemĂ€lu kadumise tĂ”ttu tekkinud kahjustused Ă”hukeste mahtude piiridesse, mis lihtsustab taastamisprotsessi oluliselt. Suure tĂ”enĂ€osusega saab neid kahjustusi taastada failisĂŒsteemi logide abil.
Veelgi enam, kui varem on tehtud hetkepilt Ă”hukesest mahust ja pĂ€rast seda on vahemĂ€lu vĂ€hemalt ĂŒks kord tĂ€ielikult sĂŒnkroonitud, siis tĂ€nu LVM thin sisemistele tunnustele tagatakse hetkpildi terviklikkus vahemĂ€lu kadumise korral.
Loome uue VG, mis vastutab thin-provisioning'i eest:
#pvcreate /dev/root/images
#pvcreate /dev/cache/cachedata
#vgcreate images /dev/root/images /dev/cache/cachedata
Loome basseini:
#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T images/thin-pool
Miks -Z yLisaks sellele, milleks see reĆŸiim on ette nĂ€htud - ei lase andmetel ĂŒhest virtuaalsest masinast teise lekkida ruumi jaotamisel, kasutatakse nullimist ka juhuslike kirjutuste kiiruse suurendamiseks, kui plokkide suurus on vĂ€iksem kui 64k. Igany kirjutamine, mis on alla 64k varem mitte-eraldatud valdkonnas Ă”hukeses mahus, muudetakse 64K-s, mis on joondatud vahemĂ€lu piiriga. See vĂ”imaldab tĂ€ita operatsiooni tĂ€ielikult vahemĂ€lu kaudu, mööda vahemĂ€lus vĂ€lja antud seadmest.
Kandume LV vastavatesse PV-desse:
#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
Kontrollime:
#lvs -a -o lv_name,lv_size,devices --units B images
LV LSize seadmed
[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)
Loome Ôhukese mahuti katsetamiseks:
#lvcreate -V 64G --thin-pool thin-pool --name test images
Paigaldame paketid testimiseks ja jÀlgimiseks:
#apt-get install sysstat fio
Nii on vÔimalik jÀlgida meie salvestusseadmete konfiguratsiooni kÀitumist reaalajas:
#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)'
Nii on vÔimalik meie konfiguratsiooni katsetada:
#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
Oht! Ressurss!See kood kĂ€ivitab 36 erinevat testi, millest igaĂŒks kestab 4 sekundi. Pool testidest on kirjutamiste testid. 4 sekundi jooksul saab NVMe-l kirjutada vĂ€ga palju. Kuni 3 gigabitti sekundis. Seega vĂ”ib iga kirjutamiste testide kĂ€ivitamine kasutada teie SSD-st kuni 216 gigabaiti ressurssi.
Lugemine ja kirjutamine vaheldumisi?Jah. Lugemise ja kirjutamise testide kĂ€ivitamine on mĂ”ttekas eraldi. Veelgi enam, on mĂ”ttekas veenduda, et kĂ”ik vahemĂ€lud on sĂŒnkroonitud, et eelneval kirjutamisel ei oleks lugemisele mĂ”ju.
Tulemused erinevad oluliselt esimesel kĂ€ivitamisel ja edasistel, sĂ”ltuvalt vahemĂ€lude tĂ€itmisest ja Ă”hukese keti tĂ€iuslikkusest, samuti sellest, kas sĂŒsteem on jĂ”udnud sĂŒnkroonida eelnevalt tĂ€idetud vahemĂ€lud.
Lisaks soovitan mÔÔta kiirus juba tÀidetud Ôhukesel kettal, millelt just tehti snapshot. Autor on kogenud, et juhuslik kirjutamine kiireneb dramaatiliselt kohe pÀrast esimese snapshot'i loomist, eriti kui vahemÀlu pole veel tÀielikult tÀidetud. See toimub copy-on-write kirjutamise semantika tÔttu, vahemÀlu ja Ôhukese keti plokkide joondumise tÔttu ning selle tÔttu, et juhuslik kirjutamine RAID 6-l muutub juhuslikuks lugemiseks koos hilisema kirjutamisega vahemÀllu. Meie konfiguratsioonis on juhuslik lugemine RAID 6-l kuni 6 korda (SATA SSD-de arv maatriksis) kiirem kui kirjutamine. Kuna CoW plokid eraldatakse jÀrjestikku Ôhukesest reservist, muutub kirjutamine valdavalt jÀrjestikuseks.
MÔlemat nendest omadustest saab soodsalt kasutada.
VahemÀlu "koherentsete" snapshot'id
Andmete kaotsimineku riski vÀhendamiseks vahemÀlu kahjustumise/kaotuse korral soovitab autor rakendada snapshot'ide rotatsiooni praktikat, mis tagab nende terviklikkuse.
Esiteks, kuna Ôhukeste keti metaandmed asuvad mitte-vahemÀlus seadmes, on metaandmed terved ja vÔimalike kaotuste tagajÀrjed piirduvad andmeplokkidega.
JĂ€rgmine snapshot'ide rotatsiooni tsĂŒkkel tagab andmete terviklikkuse snapshot'ides, juhul kui vahemĂ€lu on kaotatud:
- Igale Ă”hukesele ketale nimega <ĐžĐŒŃ> loome snapshot'i nimega <ĐžĐŒŃ>.cached
- Seame ĂŒlekande lĂ€vise mĂ”istlikult kĂ”rgele vÀÀrtusele:
#lvchange --quiet --cachesettings "migration_threshold=16384" cache/cachedata - TsĂŒklis kontrollime vahemĂ€lu rĂ€pane plokkide arvu:
#lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}'kuni, kuni ei ole nulli, on vĂ”imalik ajutiselt luua see, muutes vahemĂ€lu writethrough reĆŸiimiks. Kuid arvestades meie SATA ja NVMe SSD-de kiirusomadusi ning nende TBW ressursse, suudate kas piisavalt kiiresti hetke tabada ilma vahemĂ€lu reĆŸiimi muutmata vĂ”i teie riistvara kulutab oma ressursid mĂ”ne pĂ€evaga Ă€ra. Ressursipiirangute tĂ”ttu ei suuda sĂŒsteem pĂ”himĂ”tteliselt pidevalt olla 100% kirjutamise koormusel. Meie NVMe SSD-d kulutavad oma ressursid 100% kirjutamise koormuse all tĂ€ielikult Ă€ra 3-4 pĂ€eva. SATA SSD-d elavad aga vaid kaks korda kauem. SeetĂ”ttu eeldame, et enamus koormusest on lugemine ja kirjutamine â suhteliselt lĂŒhiajalised kĂ”rge aktiivsusega puhangud koos keskmise madala koormusega. - Niipea kui olete (vĂ”i olete teinud) nulli â nimetage .cached ĂŒmber .committed. Eemaldame vana .committed.
- Valikuliselt, kui vahemĂ€lu on 100% tĂ€is, saab selle skripti abil uuesti luua, puhastades sellega. Osaliselt tĂŒhja vahemĂ€luga töötab sĂŒsteem kirjutamise osas palju kiiremini.
- Seame migreerimise kĂŒnnise nullile:
#lvchange --quiet --cachesettings "migration_threshold=0" cache/cachedataSee keelab ajutiselt vahemĂ€lu sĂŒnkroniseerimise pĂ”hikandjale. - Ootame, kuni vahemĂ€lus koguneb piisavalt muudatusi
#lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}'vÔi töötaks taimer. - Kordame uuesti.
Miks sellised raskused migreerimise kĂŒnnisegaâŠ?Asi on selles, et reaalses praktikas ei ole "juhuslik" kirjutamine tegelikult pĂ€ris juhuslik. Kui me kirjutame midagi 4 kilobaiti suurusesse sektorisse, on suur tĂ”enĂ€osus, et jĂ€rgmise paari minuti jooksul tehakse kirjutamine sellesse vĂ”i ĂŒheks naaber (+- 32K) sektoriks.
Seades migreerimise kĂŒnnise nullile, lĂŒkkame SATA SSD-le kirjutamise sĂŒnkroniseerimise edasi ja kogume mitu muudatust ĂŒhe 64K ploki jaoks vahemĂ€lus. Nii sÀÀstame mĂ€rgatavalt SATA SSD ressursse.
Aga koodi kuskil..?Kahjuks peab autor end bash-skriptide arendamisel ebakompetentseks, kuna on 100% isehakanud ja praktiseerib "google"-pÔhist arendust, seega arvab, et see hirmuÀratav kood, mis tema kÀest vÀlja tuleb, ei peaks keegi teine kasutama.
Arvan, et asja professionaalid saavad vajadusel kogu ĂŒlaltoodud loogika iseseisvalt luua ja vĂ”ib-olla isegi ilusasti systemd teenuse vormis kujundada, nagu autor seda ĂŒritas.
Sarnane lihtne snapshotide rotatsiooni skeem vĂ”imaldab meil mitte ainult pidevalt omada ĂŒhte tĂ€ielikult sĂŒnkroniseeritud SATA SSD snapshotit, vaid ka thanks utiliidi thin_delta kaudu teada saada, millised plokid on pĂ€rast selle loomist muutunud, ja seelĂ€bi lokaliseerida kahjustusi peamistel mahtudel, muutes taastamise kordades lihtsamaks.
TRIM/DISCARD libvirt/KVM-s
Kuna andmete salvestamine kasutatakse KVM-i libvirt'i halduses, oleks hea Ôpetada meie VM-id mitte ainult tasuta ruumi vÔtmist, vaid ka vabastama enam mittevajalikku.
Seda tehakse TRIM/DISCARD toe simuleerimise kaudu virtuaalsetes diskides. Selleks tuleb muuda kontrolleri tĂŒĂŒp virtio-scsi-ks ja redigeerida xml.
#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'/>
</disk>
<controller type='scsi' index='0' model='virtio-scsi'>
<alias name='scsi0'/>
</controller>
Sellised DISCARD'id kĂŒlgplaadilt OS-ide poolt töödeldakse Ă”igesti LVM-i poolt, ja plokid vabastatakse Ă”igesti nii vahemĂ€lus kui ka Ă”hukeses basseinis. Meie puhul toimub see peamiselt viivitusega, kui kustutatakse jĂ€rgmine snapshot.
BTRFS varundamine
Kasuta valmis skripte ÀÀrmise ettevaatlikkuse ja oma riski ja vastutuse all. Autor kirjutas selle koodi ise ja vaid enda tarbeks. Olen kindel, et paljudel kogenud Linuxi kasutajatel on sarnased lahendused olemas, ja ei ole vaja teiste omi kopeerida.
Loome maht reserveeritud seadmes:
#lvcreate -L 256G --name backup backup
Formateerime BTRFS-ks:
#mkfs.btrfs /dev/backup/backup
Loome mountimispunktid ja monteerime failisĂŒsteemi juuralamid:
#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
Loome varukoopiate katalooge:
#mkdir /backup/btrfs/back/remote
#mkdir /backup/btrfs/back/remote/root
#mkdir /backup/btrfs/back/remote/boot
Loome skriptide varukoopiate jaoks katalooge:
#mkdir /root/btrfs-backup
Kopeerime skripti:
Palju kohutavat bash-koodi. Kasuta oma riski ja ohuga. Autorile vihaste kirjade saatmine ei ole vajalik...#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" ]
siis
echo "$SOURCE_BASE_PATH leitud"
muul juhul
echo "$SOURCE_BASE_PATH Fail not found, luuakse $SOURCE_PATH snapshot $SOURCE_BASE_PATH"
btrfs subvolume snapshot -r $SOURCE_PATH $SOURCE_BASE_PATH
sync
if [ -d "$TARGET_BASE_PATH" ]
siis
echo "$TARGET_BASE_PATH leitud, ei ĂŒhti allikaga... eemaldatakse..."
btrfs subvolume delete -c $TARGET_BASE_PATH
sync
fi
fi
if [ -d "$TARGET_BASE_PATH" ]
siis
echo "$TARGET_BASE_PATH leitud"
muul juhul
echo "$TARGET_BASE_PATH ei leitud. SĂŒnkroniseerimine $TARGET_BASE_DIR"
btrfs send $SOURCE_BASE_PATH | btrfs receive $TARGET_BASE_DIR
sync
fi
if [ -d "$SOURCE_PEND_PATH" ]
siis
echo "$SOURCE_PEND_PATH leitud, eemaldatakse..."
btrfs subvolume delete -c $SOURCE_PEND_PATH
sync
fi
btrfs subvolume snapshot -r $SOURCE_PATH $SOURCE_PEND_PATH
sync
if [ -d "$TARGET_PEND_PATH" ]
siis
echo "$TARGET_PEND_PATH leitud, eemaldatakse..."
btrfs subvolume delete -c $TARGET_PEND_PATH
sync
fi
echo "Saatmine $SOURCE_PEND_PATH $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/\
}
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"
sift
case "$COMMAND" in
"--help")
echo "Abi"
;;
"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 "TĂŒhine.."
;;
esac
) 98>$LOCK_FILE
EOF
Mida see teeb..?Sisaldab lihtsate kĂ€skude kogumit BTRFS snapshotide loomiseks ja nende kopeerimiseks teise failisĂŒsteemi BTRFS send/receive kaudu.
Esimene kÀivitus vÔib vÔtta suhteliselt kaua aega, kuna alguses kopeeritakse kÔik andmed. Edasised kÀivitamised on vÀga kiired, kuna kopeeritakse ainult muudatused.
Veel ĂŒks skript, mille lisame cron'i:
Veel veidi bash-koodi#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 pÀeva"
$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
Mida see teeb..?Loob ja sĂŒnkroniseerib backup failisĂŒsteemis inkrementeerseid snapshot'e loetletud BTRFS-volume'ide jaoks. PĂ€rast seda eemaldab kĂ”ik snapshot'id, mis on loodud 60 pĂ€eva tagasi. KĂ€ivitamise jĂ€rel ilmuvad alakaustades /backup/btrfs/back/remote/ kuupĂ€eva jĂ€rgsed snapshot'id loetletud mahtudest.
Anname koodile kÀivitamisÔiguse:
#chmod +x /root/btrfs-backup/cron-daily.sh
#chmod +x /root/btrfs-backup/btrfs-backup.sh
Kontrollime ja lisame cron'i:
#/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 thin varundamine
Loome Ôhukese basseini varukoopiale:
#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T backup/thin-pool
Kasutame ddrescue, kuna skriptid kasutavad seda tööriista:
#apt-get install gddrescue
Loome skriptide jaoks katalooge:
#mkdir /root/lvm-thin-backup
Kopeerime skripte:
Palju bash'i sees...#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" == "" ]
siis
(>&2 echo "Allika LV ei ole Ôhuke.")
exit 1
fi
if [ "$DIFF_TARGET_POOL" == "" ]
siis
(>&2 echo "Siht LV ei ole Ôhuke.")
exit 1
fi
if [ "$DIFF_SOURCE_POOL" != "$DIFF_TARGET_POOL" ]
siis
(>&2 echo "Allika ja siht LVs kuuluvad erinevatele Ôhukestele basseinidele.")
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" != "-" ]
siis
(>&2 echo "Ăhukese basseini metadata snapshot juba eksisteerib. Eeldame, et see on aegunud. Vabastame metadata snapshot 5 sekundi pĂ€rast.")
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" == "-" ]
siis
(>&2 echo "Ăhukese basseini metadata snapshot'i loomine ebaĂ”nnestus.")
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" ]
siis
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" ]
siis
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" != "" ]
siis
echo "$DISCARD_LV_PATH leitud"
muul juhul
echo "$DISCARD_LV ei leidu $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" != "" ]
siis
echo "$SOURCE_BASE_LV_PATH found"
muul juhul
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" != "" ]
siis
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" != "" ]
siis
echo "$TARGET_BASE_LV_PATH found"
muul juhul
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" != "" ]
siis
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" != "" ]
siis
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" != "" ]
siis
echo "$SOURCE_BASE_LV_PATH found"
muul juhul
echo "$SOURCE_BASE_LV_PATH not found"
exit 1
fi
if [ "$TARGET_BASE_LV_PATH" != "" ]
siis
echo "$TARGET_BASE_LV_PATH found"
muul juhul
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" != "" ]
siis
echo "$SOURCE_BASE_LV_PATH found"
muul juhul
echo "$SOURCE_BASE_LV_PATH not found"
exit 1
fi
if [ "$TARGET_BASE_LV_PATH" != "" ]
siis
echo "$TARGET_BASE_LV_PATH found"
muul juhul
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"
muul juhul
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"
sift
case "$COMMAND" in
"--help")
echo "Abi"
;;
"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 "TĂŒhine.."
;;
esac
) 98>$LOCK_FILE
EOF
Mida see teebâŠ?Sisaldab kĂ€skude komplekti, et manipuleerida Ă”hukeste koopiatega ja sĂŒnkroonida erinevusi kahe Ă”hukese snĂ€piga, kasutades thin_delta, teisele blokeeringule ddrescue ja blkdiscardiga.
Veel ĂŒks skript, mille lisame cron'i:
Veel veidi bash'i#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 pÀeva"
$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
Mida see teebâŠ?Kasutab eelmist skripti, et luua ja sĂŒnkroonida varukoopiaid loetletud Ă”hukestest mahutest. Skript jĂ€tab loetletud mahtude tarvis mittetegevad snĂ€pid, mida on vaja viimase sĂŒnkroonimise muudatuste jĂ€lgimiseks.
Seda skripti tuleb muuta, esitades loetelu Ă”hukestest mahutest, mille jaoks varukoopiaid luua. Antud nimetused on ainult nĂ€itlikud. Soovi korral vĂ”ib kirjutada skripti, mis sĂŒnkroonib kĂ”ik mahud.
Anname Ôigused:
#chmod +x /root/lvm-thin-backup/cron-daily.sh
#chmod +x /root/lvm-thin-backup/lvm-thin-backup.sh
Kontrollime ja lisame cron'i:
#/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
Esimene kĂ€ivitamine saab olema pikk, kuna Ă”hukesed mahud sĂŒnkroonitakse tĂ€ielikult kogu kasutatud ruumi kopeerimise kaudu. TĂ€nu LVM thin metainfodele teame, millised plokid on tegelikult kasutuses, seega kopeeritakse ainult tegelikult kasutatud plokid Ă”hukestest mahutest.
JÀrgmised kÀivitamised kopeerivad andmeid inkrementaalselt, tÀnu muudatuste jÀlgimisele LVM thin metainfo kaudu.
Vaatame, mis vÀlja tuli:
#time /root/btrfs-backup/cron-daily.sh
reaalne 0m2,967s
kasutaja 0m0,225s
sĂŒsteem 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 mÀr 26 09:11 .
drwxr-xr-x 1 root root 16 mÀr 6 09:30 ..
drwxr-xr-x 1 root root 322 mÀr 26 02:00 .@base
drwxr-xr-x 1 root root 516 mÀr 6 09:39 .@snap.2020-03-06-09-39-37
drwxr-xr-x 1 root root 516 mÀr 6 09:39 .@snap.2020-03-06-09-39-57
...
/backup/btrfs/back/remote/root:
total 0
drwxr-xr-x 1 root root 2820 mÀr 26 09:11 .
drwxr-xr-x 1 root root 16 mÀr 6 09:30 ..
drwxr-xr-x 1 root root 240 mÀr 26 09:11 @.@base
drwxr-xr-x 1 root root 22 mÀr 26 09:11 @home.@base
drwxr-xr-x 1 root root 22 mÀr 6 09:39 @home.@snap.2020-03-06-09-39-35
drwxr-xr-x 1 root root 22 mÀr 6 09:39 @home.@snap.2020-03-06-09-39-57
...
drwxr-xr-x 1 root root 240 mÀr 6 09:39 @.@snap.2020-03-06-09-39-26
drwxr-xr-x 1 root root 240 mÀrts 6 09:39 @.@snap.2020-03-06-09-39-56
...
#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
Miks on siin matroĆĄkad?
TĂ”enĂ€oliselt seetĂ”ttu, et loogilised LVM LV mahud vĂ”ivad olla fĂŒĂŒsilised LVM PV mahud teistele VG-dele. LVM vĂ”ib olla rekursiivne, nagu matroĆĄkad. See annab LVM-ile erakordse paindlikkuse.
P.S.
JÀrgmises artiklis proovime kasutada mitmeid sarnaseid mobiilseid SAN/KVM-d, et luua geojagatud storage/VM-klastrit, mis varundatakse mitmel kontinendil koduste lauaarvutite, koduse interneti ja P2P-vÔrkude kaudu.
Allikas: habr.com
