Tere pÀevast.
Soovin jagada kogemust KVM-i andmesalvestussĂŒsteemi ehitamisel, kasutades md RAID + LVM-i.
Kavas on:
- MD RAID 1 kogumine NVMe SSD-dest.
- MD RAID 6 kogumine SATA SSD-dest ja tavalisest kettadest.
- TRIM/DISCARD funktsiooni omadused SSD RAID 1/6 korral.
- KĂ€ivitava md RAID 1/6 massiivi loomine eri kettade komplektist.
- SĂŒsteemi installimine NVMe RAID 1-le, kui BIOS ei toeta NVMe-d.
- LVM cache ja LVM thin kasutamine.
- BTRFS-i kohe ja send/receive kasutamine varundamiseks.
- LVM thin kohe ja thin_delta kasutamine BTRFS-i stiilis varundamiseks.
Kui see huvi pakub, palun vaata edasi.
MĂ€rkus
Autor ei vastuta mingite tagajÀrgede eest, mis tulenevad kÀesoleva artikli materjalide/nÀidete/koodi/nÔuannete/andmete kasutamisest vÔi mitte kasutamisest. KÀesolevat materjali lugedes vÔi mis tahes viisil kasutades vÔtate enda kanda kÔik selle tegevuse tagajÀrjed. VÔimalike tagajÀrgede hulka kuuluvad:
- KĂŒpsetatud kuni krĂ”beda NVMe SSD.
- Kirjutusressurss on tÀielikult vÀlja kulutatud ja SSD-d lÔhkemised.
- KÔigi andmete, sealhulgas varukoopiate tÀielik kaotus kÔikidel kettadel.
- Vigane arvutiraud.
- Kulutatud aeg, nÀrvid ja raha.
- Iga muud tagajÀrjed, mida ei ole eespool loetletud.
Riistvara
Oli saadaval:
Emaplaat, mis on toodetud umbes 2013. aastal Z87 kiibistiku pÔhjal koos Intel Core i7 / Haswell protsessoriga.
- 4 tuuma, 8 lÔime protsessor.
- 32 GB DDR3 operatiivmÀlu.
- 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 porti.
SAS adapter LSI SAS9211-8I, mis on vilkuma IT / HBA reĆŸiimi. RAID'i toe pĂŒsivara on tahtlikult asendatud HBA pĂŒsivara, et:
- Saaks igal hetkel selle adapteri vÀlja visata ja asendada mistahes teise, mis ette jÀÀb.
- TRIM/Discard töötab kĂ”vaketastega normaalselt, kuna RAID pĂŒsivara ei toeta neid kĂ€ske ĂŒldse, aga HBA ei ole sisuliselt tĂ€htis, milliseid kĂ€ske bussil edastada.
KĂ”vakettad â 8 tĂŒkki HGST Travelstar 7K1000, mille maht on 1 TB 2.5-tollises formaat, nagu sĂŒlearvutitele. Need kettad olid varem RAID 6 mahus. Uues sĂŒsteemis leiavad nad samuti kasutust kohalike varukoopiate sĂ€ilitamiseks.
Lisaks oli lisatud:
6 tĂŒkki SATA SSD mudeleid Samsung 860 QVO 2TB. Need SSD-d nĂ”udsid suurt mahtu, SLC vahemĂ€lu olemasolu, soovitav oli usaldusvÀÀrsus ja madal hind. Oluline oli, et oleks tugi discard/zero, mida kontrollitakse dmesg rea jĂ€rgi:
kernel: ata1.00: Lubatakse discard_zeroes_data
2 tĂŒkki NVMe SSD mudeleid Samsung SSD 970 EVO 500GB.
Nende SSD-de puhul on oluline juhuslike lugemise/kirjutamise kiirus ja nende tööea sobivus. Radiaator tuleb kindlasti lisada. Absoluutselt. Ilma selleta â jĂ€tate nad esimese RAID sĂŒnkroniseerimise ajal rabedaks.
StarTech PEX8M2E2 adapter 2 x NVMe SSD jaoks PCIe 3.0 8x pesasse. See on jĂ€llegi lihtsalt HBA, kuid NVMe jaoks. Erineb odavatest adapteritest, kuna ei nĂ”ua PCIe bifurcationi toe olemasolu emaplaadilt tĂ€nu sisseehitatud PCIe lĂŒlitile. Töötab isegi kĂ”ige vanemas sĂŒsteemis, kus on PCIe, isegi kui see on x1 PCIe 1.0 pesa. Loomulikult, vastava kiirusaga. Seal ei ole RAID-e. Sisseehitatud BIOS-i pole. Seega ei Ă”pi teie sĂŒsteem maagiliselt kĂ€ivituma NVMe-lt ja veel vĂ€hem tegema NVMe RAID-i tĂ€nu sellele seadmele.
See komponent on tingitud ainult ĂŒhest vabas 8x PCIe 3.0 pesast sĂŒsteemis ning leides 2 vaba pesaga, on see hĂ”lpsasti asendatav kahe odava PEX4M2E1 vĂ”i sarnasega, mida saab osta igalt poolt alates 600 rubla.
TavapĂ€raste raudvarade vĂ”i kiibisti/BIOSe RAIDide kasutamisest loobumine tehti teadlikult, et vĂ”imaldada sĂŒsteemi tĂ€ielikku asendamist, vĂ€lja arvatud SSD/HDD, sĂ€ilitades kĂ”ik andmed. Ideaalselt, et vĂ”iks sĂ€ilitada isegi installitud operatsioonisĂŒsteemi ĂŒleminekul tĂ€iesti uuele/teisele riistvarale. Peamine on, et seal oleks SATA ja PCIe pesad. See on nagu live CD vĂ”i kĂ€ivitatav USB, ainult et vĂ€ga kiire ja veidi mahukam.
HuviJa tead, kuidas on â vahel on hĂ€da tekkinud, et tuleb kogu maht endaga kaasa vĂ”tta. Andmeid ei taha kaotada. Selleks on kĂ”ik nimetatud seadmed mugavalt paigutatud 5.25 standardkorpuse radadele.
No ja loomulikult eksperimenteerimiseks erinevate SSD vahemÀlu meetoditega Linuxis.
Riistvara RAID on igav. LĂŒlitad sisse. See kas töötab vĂ”i ei tööta. Aga mdadmiga on alati erinevad vĂ”imalused.
Tarkvara
Varasemal riistvaral oli paigaldatud Debian 8 Jessie, mis on peaaegu EOL. Oli kokku pandud RAID 6 eelmainitud HDD-dega koos LVM-iga. Sellega töötasid virtuaalmasinatele kvm/libvirt.
Kuna autoril on sobiv kogemus kaasaskantavate SATA/NVMe alglaadimise flashide loomisel ja et mitte katkestada tuttavat apt-malli, valiti sihthĂ€rkesĂŒsteemiks Ubuntu 18.04, mis on juba piisavalt stabiliseerunud, kuid millel on veel 3 aastat tuge tulevikus.
Mainitud sĂŒsteemis on kĂ”ik vajalikud riistvarajuhid juba kastist vĂ€lja. Me ei vaja mingeid kolmandate osapoolte tarkvara ega juhte.
Paigaldamiseks ettevalmistamine
SĂŒsteemi paigaldamiseks vajame Ubuntu Desktop Image'i. Serveri sĂŒsteemil on mingi hull paigaldaja, mis kĂ€itub ĂŒleliia iseseisvalt, pannes kindlasti UEFI sĂŒsteemi osa ĂŒhele diskile, rikkudes kogu ilu. Seega installitakse see ainult UEFI reĆŸiimis. KĂ”ik variandid, mida ei pakuta.
See ei sobi meile.
Miks?Kahjuks on UEFI laadimine ÀÀrmiselt halvasti ĂŒhilduv kĂ€ivitusprogrammi RAID-iga, kuna keegi ei paku meile UEFI ESP jao varundamist. Internetis on retsepte, mis soovitavad asendada ESP jao mĂ€lupulgaga USB-porti, kuid see on tĂ”rkepunkt. On ka retsepte, mis kasutavad tarkvaralist mdadm RAID 1 metaandmete versiooniga 0.9, mis ei sega UEFI BIOS-il seda jao nĂ€gemist, kuid see kestab kuni Ă”nneliku hetkeni, mil BIOS vĂ”i muu operatsioonisĂŒsteem riistvaral kirjutab midagi ESP-sse, unustades sĂŒnkroniseerida teiste peeglitega.
Lisaks sĂ”ltub UEFI laadimine NVRAM-ist, mis ei rĂ€nda koos diskidega uude sĂŒsteemi, kuna see on osa emaplaadist.
Seega ei hakka me uut jalgratast leiutama. Meil on juba olemas korralik, aastate jooksul tĂ”estatud vana jalgratas, mida praegu nimetatakse Legacy/BIOS laadimiseks, uhkelt nimega CSM UEFI-ĂŒhilduvates sĂŒsteemides. Me lihtsalt vĂ”tame selle riiulilt, mÀÀrime, pumpame rehvid ja pĂŒhime niiske lapiga puhtaks.
Ubuntu töölauaversioon ei oska samuti korralikult Legacy laadijaga installida, kuid nagu öeldakse, vÀhemalt on valikud olemas.
Nii et kogume riistvara ja laadime sĂŒsteemi Ubuntu Live kĂ€ivitatavalt USB-lt. Me peame alla laadima paketid, seega seadistame vĂ”rgu, mis teil tööle hakkas. Kui see ei hakka tööle, siis vajalikud paketid saab USB-le eelnevalt laadida.
Siseneme Desktopi keskkonda, kÀivitame terminali emulaatori ja lÀhme edasi:
#sudo bash
KuidasâŠ?Ălalolev rida on kanoniline vallandaja sudo teemaliste vaidluste jaoks. Suuremate vĂ”imalustega tuleb ka suurem vastutus. KĂŒsimus on selles, kas suudate selle endale vĂ”tta. Paljud arvavad, et sudo sellel viisil kasutamine on vĂ€hemalt ettevaatlik.oMiks mitte ZFSâŠ?oKui me installime tarkvara oma arvutisse, siis pĂ”himĂ”tteliselt laename oma riistvara selle tarkvara arendajatelt.

#apt-get install mdadm lvm2 thin-provisioning-tools btrfs-tools util-linux lsscsi nvme-cli mc
Kui me usaldame selle tarkvara oma andmete turvalisuse, siis vÔtame laenu, mis on vÔrdne nende andmete taastamise maksumusega, mida me peame kunagi tagasi maksma.Selle nurga alt on ZFS nagu Ferrari, samas kui mdadm+lvm sobib rohkem jalgrattaks.
Kui me usaldame selle tarkvara oma andmete kaitsmisse, siis vÔtame me laenu, mis on vÔrdne nende andmete taastamise maksumusega, mille eest tuleb kunagi tasuda.
Sellelt seisukohalt on ZFS nagu Ferrari, samas kui mdadm+lvm meenutab rohkem jalgratast.
Subjektiivne autor eelistab laenata tundmatutele isikutele laenatud jalgratta, mitte Ferrarit. Seal ei ole hind ka kĂ”rge. Ei ole vaja Ă”igusi. Lihtsam on KTT. Parkimine on tasuta. LĂ€bivus on parem. Jalgrattale saab alati jalad kĂŒlge panna ja seda saab ka omal kĂ€el parandada.
Miks siis BTRFSâŠ?KĂ€ivitamiseks vajame operatsioonisĂŒsteemile sobivat failisĂŒsteemi, mis toetab Legacy/BIOS GRUB-i kohe ja toetab samal ajal elusfotode tegemist. Kasutame seda /boot jao jaoks. Peale selle eelistab autor kasutada seda failisĂŒsteemi / (juure) jaoks, unustamata mĂ€rkida, et muud tarkvara jaoks saab luua eraldi jaotised LVM-is ning neid vajalikesse kataloogidesse monteerida.
Me ei hoia selles failisĂŒsteemis ei pilte virtuaalmasinad, ega andmebaase.
Seda failisĂŒsteemi kasutatakse ainult sĂŒsteemi hetkede loomiseks ilma seda vĂ€lja lĂŒlitamata, millele jĂ€rgneb nende hetkede ĂŒlekandmine varukoopiadiskile kasutades send/receive.
Lisaks eeltoodule eelistab autor hoida minimaalset tarkvara otse riistvaral ja kĂ€itada kogu ĂŒlejÀÀnud tarkvara virtuaalmasinates, kasutades selliseid lahendusi nagu GPU ja PCI-USB hostkontrollerite suunamine KVM-i kaudu IOMMU kaudu.
Riistvarale jÀÀvad ainult â andmete salvestamine, virtualiseerimine ja varundamine.
Kui usaldate rohkem ZFS-i, siis pÔhimÔtteliselt on need mÀÀratud rakendusele omavahel asendatavad.
Siiski ignoreerib autor teadlikult ZFS-i, BTRFS-i ja LVM-i sisseehitatud peegelduse / RAID-i ja ĂŒleliigsuse funktsioone.
Lisaks on BTRFS-l kalduvus muuta juhuslik kirjutamine jĂ€rjestikuseks, mis mĂ”jutab vĂ€ga positiivselt varukoopiate / snapshotide sĂŒnkroniseerimise kiirus HDD-l.
Skaneerime kÔik seadmed uuesti:
#udevadm control --reload-rules && udevadm trigger
Vaata ĂŒmber:
#lsscsi && nvme list
[0:0:0:0] kettaseade ATA Samsung SSD 860 2B6Q /dev/sda
[1:0:0:0] kettaseade ATA Samsung SSD 860 2B6Q /dev/sdb
[2:0:0:0] kettaseade ATA Samsung SSD 860 2B6Q /dev/sdc
[3:0:0:0] kettaseade ATA Samsung SSD 860 2B6Q /dev/sdd
[4:0:0:0] kettaseade ATA Samsung SSD 860 2B6Q /dev/sde
[5:0:0:0] kettaseade ATA Samsung SSD 860 2B6Q /dev/sdf
[6:0:0:0] kettaseade ATA HGST HTS721010A9 A3J0 /dev/sdg
[6:0:1:0] kettaseade ATA HGST HTS721010A9 A3J0 /dev/sdh
[6:0:2:0] kettaseade ATA HGST HTS721010A9 A3J0 /dev/sdi
[6:0:3:0] kettaseade ATA HGST HTS721010A9 A3B0 /dev/sdj
[6:0:4:0] kettaseade ATA HGST HTS721010A9 A3B0 /dev/sdk
[6:0:5:0] kettaseade ATA HGST HTS721010A9 A3B0 /dev/sdl
[6:0:6:0] kettaseade ATA HGST HTS721010A9 A3J0 /dev/sdm
[6:0:7:0] kettaseade ATA HGST HTS721010A9 A3J0 /dev/sdn
SÔlm SN Mudel Nimi Kasutamine Vorming 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
Aga me ei hakka neid kuidagi jaotama. Igatahes ei nĂ€e meie BIOS neid mĂ€lusid. Nii et need lĂ€hevad tĂ€ielikult tarkvaras RAID-i. Isegi jaotusi ei hakka seal looma. Kui tahate 'kanoniga' vĂ”i 'pĂ”himĂ”tteliselt' â looge ĂŒks suur jaotus, nagu HDD-l.
SATA HDD
Siin ei ole vaja midagi eriti leiutada. Loome ĂŒhe sektsiooni kĂ”igile. Sektsioon loomine on vajalik, kuna BIOS nĂ€eb neid kettaid ja vĂ”ib isegi proovida nendelt kĂ€ivituskorraldust teha. Paigaldame hiljem neile ketastele GRUB-i, et sĂŒsteem saaks seda ootamatult teha.
#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 on meie mĂ€luseadmed suurusega 2 TB. See on MBR-i jaoks lubatud, millega me ka kasutame. Vajadusel saab vahetada GPT vastu. GPT ketaste jaoks on olemas ĂŒhilduvustase, mis vĂ”imaldab MBR-ĂŒhilduvatel sĂŒsteemidel nĂ€ha esimest 4 sektsiooni, kui need asuvad esimeses 2 terabaidis. Peamine on, et kĂ€ivitussektsioon ja sektsioon bios_grub oleksid nende ketaste alguses. See vĂ”imaldab isegi teha Legacy/BIOS kĂ€ivitust GPT ketastelt.
Kuid see ei ole meie juhtum.
Siin loome kaks sektsiooni. Esimene on suurusega 1 GB ja kasutatakse RAID 1 /boot jaoks.
Teine kasutatakse RAID 6 jaoks ja hĂ”lmab kogu ĂŒlejÀÀnud vaba ruumi, vĂ€lja arvatud vĂ€ike jaotamata ala ketta lĂ”pus.
Mis see jaotamata ala on?VĂ”rgustiku allikate kohaselt on meie SATA SSD-de koostisosadeks dĂŒnaamiliselt laiendatav SLC vahemĂ€lu, mille suurus on vahemikus 6 kuni 78 gigabaiti. 6 gigabaiti saame âtasutaâ tĂ€nu erinevustele âgigabaitideâ ja âgibibaitideâ vahel seadme tehnilistes omadustes. ĂlejÀÀnud 72 gigabaiti eraldatakse kasutamata ruumi pĂ”hjal.
Siinkohal tuleb mĂ€rkida, et vahemĂ€lu on meil SLC ja ruumi kasutatakse 4 bitti MLC reĆŸiimis. See tĂ€hendab, et iga 4 gigabaiti vabast ruumist saame ainult 1 gigabaiti SLC vahemĂ€lust.
Korrutame 72 gigabaiti neljaga ja saame 288 gigabaiti. See on see vaba ruum, mida me ei mÀrgista, et lubada andmekandjatel SLC vahemÀlu tÀielikult kasutada.
Nii saame kokku efektiivselt kuni 312 gigabaiti SLC vahemÀlu kokku kuuest andmekandjast. Kahest andmekandjast kasutatakse RAID-i kaudu liigse koormuse tagamiseks.
Selline vahemĂ€lu maht vĂ”imaldab meil ÀÀrmiselt harva kogeda olukorda, kus kirjutamine ei toimu vahemĂ€lus. See kompenseerib suurepĂ€raselt kĂ”ige kurvema QLC mĂ€lu puuduse â ÀÀrmiselt madal kirjutamiskiirus, kui andmed kirjutatakse vahemĂ€lust mööda. Kui teie koormused sellega ei sobi, siis soovitan tĂ”siselt mĂ”elda, kui kaua teie SSD-d sellise koormuse all kestavad, arvestades TBW-d tehnilises dokumentatsioonis.
#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 nime muutma. Seda on vaja, sest hostinimi on osa massiivi nimest kuskil mdadm-is ja mĂ”jutab midagi. Muidugi on massiive hiljem vĂ”imalik ka ĂŒmber nimetada, kuid see on ebavajalik tegevus.
#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 see ei initsialiseeri massiive. 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. Kasutame TRIM/DISCARD-i nii palju kui vÔimalik kogutud SSD massiivides nende 'initsialiseerimiseks'.
SSD RAID 1 massiivide puhul toetatakse DISCARD-i vÀlja kastist.
SSD RAID 6 massiivide puhul tuleb DISCARD aktiveerida tuumamooduli seadetes.
Seda tuleks teha ainult siis, kui kĂ”ik SSD-d, mis on kasutusel 4/5/6 taseme massiivides, toetavad tĂ€ielikult discard_zeroes_data funktsiooni. MĂ”nikord esineb kummalisi seadmeid, mis teavitavad tuumast selle funktsiooni toetamisest, kuid tegelikult seda ei toimu vĂ”i see ei toimi alati. Hetkel on toetus peaaegu igal pool olemas, kuid vanad seadmed ja vigaste pĂŒsivara esinemine on ikka veel probleemiks. Sellest tulenevalt on RAID 6 puhul DISCARD tugi vaikimisi vĂ€lja lĂŒlitatud.
TÀhelepanu, jÀrgmine kÀsk hÀvitab kÔik andmed NVMe seadmetel, 'algatades' massiivi 'nullidega'.
#blkdiscard /dev/md0
Kui midagi lÀks valesti, proovige tÀpsustada 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 kiirus, kuni chunk-size-ni. See juhtub, kuna ĂŒks sellise suurusega vĂ”i vĂ€iksem opsioon saab tĂ€ielikult teostada ĂŒhel seadmel. SeetĂ”ttu summeeruvad IOPS kĂ”ikidelt seadmetelt. Statistika kohaselt ei ĂŒleta 99% IO-d 512K.
RAID 6 IOPS kirjutamisel alati ĂŒhe ketta IOPS on vĂ€iksem vĂ”i vĂ”rdne. Samas vĂ”ib juhuslik lugemine IOPS olla mitmeid kordi suurem kui ĂŒhe ketta oma, kusjuures ploki suurusel on vĂ”tmeroll.
Autor ei nÀe mÔtet proovida optimeerida parameetrit, mis on RAID 6 disainispetsiifiliselt halb, ja selle asemel optimeerib ta seda, milles RAID 6 end hÀsti nÀitab.
Halva juhusliku kirjutamise RAID 6 kompenseerime NVMe vahemÀlu ja thin-provisioning nipidega.
Me ei ole veel RAID 6 jaoks DISCARDâi lisanud. Seega ei hakka me seda massiivi 'algatama'. 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Àhtudes tahame paigutada juurkatalooge NVMe RAID 1, mis on /dev/md0.
Kuid me vajame seda kiiret massiivi ka muude vajaduste jaoks, nagu swap, metaandmed ja LVM-cache vahemÀlu ja LVM-thin metaandmed, seetÔttu loome sellel massiivil LVM VG.
#pvcreate /dev/md0
#vgcreate root /dev/md0
Loomine juurkatalooge jaoks.
#lvcreate -L 128G --name root root
Loomine vahetusfailile, mille suurus on vÔrreldav töötavate mÀlude suurusega.
#lvcreate -L 32G --name swap root
OperatsioonisĂŒsteemi installimine
KokkuvĂ”ttes on meil kĂ”ik vajalik sĂŒsteemi installimiseks.
KĂ€ivitame sĂŒsteemi installimise wizard'i Ubuntu Live keskkonnast. Tavaline installatsioon. Ainult ketaste valimise etapis tuleb mĂ€rkida jĂ€rgmist:
- /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 installimine /dev/sda-le
Kui valite BTRFS-i juureks failisĂŒsteemiks, loob installer automaatselt kaks BTRFS-ruumi nimega "@" juure (/), ja "@home" /home jaoks.
KĂ€ivitame installimiseâŠ
Installimine lĂ”peb dialoogakna ilmumisega, mis teatab kĂ€ivitaja installimise veast. Kahjuks ei Ă”nnestu selle dialooge tavapĂ€raste meetoditega sulgeda ja installimist jĂ€tkata. Logime sĂŒsteemist vĂ€lja ja logime uuesti sisse, sisenedes puhtale Ubuntu Live töölauale. Avame terminali ja kirjutame taas:
#sudo bash
Loome chroot keskkonna, et installimist jÀtkata:
#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 chrootis vÔrgu ja hosti nime:
#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
Esmalt paigaldame vajalikud 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 vale installimise tÔttu valesti paigaldatud:
#CORRUPTED_PACKAGES=$(debsums -s 2>&1 | awk '{print $6}' | uniq)
#apt-get install --reinstall $CORRUPTED_PACKAGES
Kui midagi ei tööta, peate vÔib-olla enne seda redigeerima /etc/apt/sources.list faili.
Parandame RAID 6 mooduli seadistused, et lubada TRIM/DISCARD:
#cat >/etc/modprobe.d/raid456.conf << EOF
valikud raid456 seadmed_haldavad_hÀvitamist_turvaliselt=1
EOF
Meie massiivid saavad veidi seadistust:
#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 komplekti udev reegleid, mis teevad jÀrgmist:
- Seada sobiva 2020. aasta RAID 6 blokki vahemÀlu suuruse. Tundub, et vaikevÀÀrtust ei ole muudetud alates Linuxi loomise ajast ja see ei ole ammu enam adekvaatne.
- Broneerige kontrollide/sĂŒnkroniseerimiste ajal minimaalne IO koormus. See on vajalik, et teie massiivid ei jÀÀks koormuse all igavese sĂŒnkroniseerimise olekusse.
- Piirake kontrollide/sĂŒnkroniseerimiste ajal maksimaalne IO koormus. See on vajalik, et sĂŒnkroniseerimine/kontroll SSD RAID-ide mitte kuumaks kĂŒpsetaks teie seadmeid. Eriti oluline NVMe puhul. (Kas mĂ€letate jahutusplekk? Ma ei naljanud.)
- APM-i kaudu on keelatud kĂ”vaketastel peatada spindli pöörlemine (HDD) ja seadistada ketaskontrollide unereĆŸiimi timeout 7 tunniks. APM-i vĂ”ib tĂ€ielikult vĂ€lja lĂŒlitada, kui teie kettad seda toetavad (-B 255). Vaikimisi peatatakse kettad viie sekundi pĂ€rast. Siis soovib operatsioonisĂŒsteem kettade vahemĂ€lu tĂŒhjendada, kettad pöörduvad taas ja kĂ”ik kordub. Kettadel on maksimaalne spindli pöörlemiste arv piiratud. Selline lihtne tsĂŒkkel vaikimisi vĂ”ib teie kettad kahe aastaga kergesti kahjustada. See ei mĂ”juta kĂ”iki kettaid, kuid meie "sĂŒlearvutite" puhul, kus vaikeseaded teevad RAID-ist kummalise mini-MAID-i.
- Seadistage pöörlevatel kĂ”vaketastel readahead 1 megabaiti â kaks jĂ€rjestikust plokki/chunki RAID 6 jaoks.
- Keelake readahead ise RAID-mahtudes.
Toimetame /etc/fstab faili:
#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..?Kandame /boot partitsiooni UUID jÀrgi, kuna massiivide nimed vÔivad teoreetiliselt muutuda.
ĂlejÀÀnud partitsioone otsime LVM nimede kaudu, jĂ€rgides sĂŒntaksit /dev/mapper/vg-lv, kuna need identifitseerivad partitsioone piisavalt unikaalselt.
Ărge kasutage UUID-d LVM jaoks, kuna LVM mahtude ja nende snapshotide UUID-d vĂ”ivad kattuda.Kuidas kaks korda mountida /dev/mapper/root-root..?Jah. Just nii. BTRFS-i eripĂ€ra. Seda failisĂŒsteemi saab mountida mitu korda erinevate subvol'idega.
Selle sama eripĂ€ra tĂ”ttu soovitan alati vĂ€ltida aktiivsete BTRFS mahtude LVM snapshotide loomist. VĂ”ite pĂ€rast taaskĂ€ivitamist ĂŒllatuda.
Regenerime mdadm konfiguratsiooni:
#/usr/share/mdadm/mkconf | sed 's/#DEVICE/DEVICE/g' >/etc/mdadm/mdadm.conf
Korrigeerime LVM seaded:
#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 lubanud automaatse LVM thin basseinide laiendamise, kui kohandatud ruum on 90% ja see laieneb 5% vÔrra.
Oleme suurendanud LVM cache'i jaoks maksimaalset vahemÀlu plokkide arvu.
Oleme keelanud LVM-il otsida LVM mahtusid (PV) jÀrgmistes seadmetes:
- seadmetes, mis sisaldavad LVM cache'i (cdata)
- seadmetes, mida on LVM cache'i kaudu vahemÀllu salvestatud (selge _corig). Samuti skaneeritakse vahemÀllu salvestatud seade siiski vahemÀlu kaudu (lihtsalt ).
- seadmetes, mis sisaldavad LVM cache'i metadata (cmeta)
- kĂ”ikides seadmetes, mis on VG nimega images. Siin hoitakse meie virtuaalmasinate kettapilte, ning me ei soovi, et LVM hostis aktiveeriks kĂŒlg-OS-i kuuluvad mahud.
- kÔigis VG seadmetes, mille nimeks on backup. Siia salvestame virtuaalmasinate pildid.
- kÔigis seadmetes, mille nimi lÔpeb 'gpv' (guest physical volume)
Oleme lisanud DISCARD toe tĂŒhjendamiseks vaba ruumi LVM VG-s. Olge ettevaatlikud. See muudab LV kustutamise SSD-l piisavalt kaua kestvaks. Eriti kehtib see SSD RAID 6 puhul. Siiski plaanime kasutada thin provisioning-d, seega ei tohiks see meid segada.
Uuendame initramfs pilti:
#update-initramfs -u -k all
Paigaldame ja konfigureerime grub:
#apt-get install grub-pc
#apt-get purge os-prober
#dpkg-reconfigure grub-pc
Milliseid kettaid valida?KĂ”ik, mis on sd*. SĂŒsteem peab suutma kĂ€ivituda mistahes töötavast SATA ketast vĂ”i SSD-st.
Miks os-prober maha suruti..?Liialt iseseisvuse ja sahkerdamise pÀrast.
See ei tööta korralikult, kui ĂŒks RAID on degradeerunud. Ta pĂŒĂŒab otsida OS-i osadest, mis on kasutusel virtuaalmasinates, mis töötavad selle riistvara peal.
Kui see on vajalik, vÔite jÀtta, kuid pidage meeles eespool mainitut. Soovitan otsida internetist retsepte, kuidas sahkerdamisest vabaneda.
Selle lĂ”petame esialgse installimise. On aeg taaskĂ€ivitada just installitud operatsioonisĂŒsteemi. Ăra unusta eemaldada kĂ€ivitatavat Live CD/USB-d.
#exit
#reboot
KĂ€ivitusseadmeks valime ĂŒkskĂ”ik millise SATA SSD.
LVM SATA SSD-l
Selleks ajaks oleme juba sisse loginud uude operatsioonisĂŒsteemi, seadnud ĂŒles vĂ”rgu, apt, avanud terminali emulaatori ja jooksutanud:
#sudo bash
JĂ€tkame.
«Initsialiseerime» massiivi SATA SSD-lt:
#blkdiscard /dev/md2
Kui see ei toimi, siis proovime:
#blkdiscard --step 65536 /dev/md2
Loome SATA SSD-l LVM VG:
#pvcreate /dev/md2
#vgcreate data /dev/md2
Miks veel ĂŒks VG..?TĂ”epoolest, meil on juba VG nimega root. Miks mitte kĂ”ik ĂŒhte VG lisada?
Kui VG-l on mitu PV-d, siis nende Ôigeks aktiveerimiseks peavad kÔik PV-d olema kohal (online). Erandiks on LVM RAID, mida me sihipÀraselt ei kasuta.
Me soovime vĂ€ga, et RAID 6 massiivi mis tahes tĂ”rke korral (loe andmete kaotust) kĂ€ivituks operatsioonisĂŒsteem tavapĂ€raselt ja annaks meile vĂ”imaluse probleem lahendada.
Selleks, abstraktsiooni esimesel tasemel, isoleerime iga fĂŒĂŒsilise "kandja" tĂŒĂŒbi eraldi VG-sse.
Teaduslikult öeldes kuuluvad erinevad RAID massiivid erinevatesse "usaldusdomÀÀnidesse". Ei tasu luua neile lisaks ĂŒhiseid tĂ”rke-kohti, surudes kĂ”ik ĂŒhte VG-sse.
LVM-i olemasolu âraudiâ tasemel vĂ”imaldab meil erinevate RAID-massiivide osi meelevaldselt jagada, neid omavahel kombineerides. NĂ€iteks, et kĂ€ivitada samal ajal bcache + LVM thin, bcache + BTRFS, LVM cache + LVM thin, keeruline ZFS konfiguratsioon kĂ€ivitusfailidega vĂ”i mis tahes muu segadus, et seda kĂ”ike testida ja vĂ”rrelda.
âRaudiâ tasemel ei kasuta me midagi muud kui vanade head âpaksudeâ LVM-mahtude algandmeid. Erandiks sellest reeglist vĂ”ib olla tagavarakoopia eraldi osa.
Ma arvan, et paljud lugejad on juba hakanud midagi kahtlustama seoses matrooshkaga.
LVM SATA HDD-l
#pvcreate /dev/md3
#vgcreate backup /dev/md3
JĂ€lle uus VG..?Me tahame tĂ”eliselt, et kui diskimassiiv, mida kasutame andmete varundamiseks, ebaĂ”nnestub, siis meie operatsioonisĂŒsteem jĂ€tkaks tööd normaalselt, samal ajal sĂ€ilitades pÀÀsu mittevarundatud andmetele. SeetĂ”ttu, et vĂ€ltida VG aktiveerimise probleeme, loome eraldi VG.
LVM cache'i seadistamine
Loome LV NVMe RAID 1-l, et kasutada seda vahemÀluseadmest.
#lvcreate -L 70871154688B --name cache root
Miks on nii vÀhe...?As it turns out, our NVMe SSDs also feature SLC cache. There are 4 gigabytes of 'free' cache and 18 gigabytes of dynamic cache due to the free space occupied in 3-bit MLC. Once this cache is exhausted, NVMe SSDs won't be much faster than our SATA SSDs with cache. For this reason, there is no point in making the LVM cache partition significantly larger than twice the size of the SLC cache of the NVMe drive. For the NVMe drives we use, it is reasonable to create a cache of 32-64 gigabytes.
The specified partition size is necessary to organize 64 gigabytes of cache, along with the placement of cache metadata and a backup of that metadata.
Additionally, I would note that after a dirty shutdown, LVM will mark the entire cache as dirty and will need to resynchronize. Moreover, this will recur with every use of lvchange on this device until a new system reboot. Therefore, I recommend recreating the cache immediately with the appropriate script.
We will create an LV on SATA RAID 6 to use it as a caching device.
#lvcreate -L 3298543271936B --name cache data
Why only three terabytes..?Ettevalmistamiseks, et vajadusel saaks kasutada SATA SSD RAID 6 mĂ”nede muude vajaduste jaoks. VahemĂ€lu suurust saab dĂŒnaamiliselt suurendada, töö kĂ€igus, ilma sĂŒsteemi tööseisakut. Selleks tuleb 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 töö kĂ€igus.
Loome uue VG vahemÀluks.
#pvcreate /dev/root/cache
#pvcreate /dev/data/cache
#vgcreate cache /dev/root/cache /dev/data/cache
Loome LV vahemÀlus.
#lvcreate -L 3298539077632B --name cachedata cache /dev/data/cache
Siin kasutasime koheselt kogu vaba ruumi /dev/data/cache, et kÔik muud vajalikud osade loomised toimuksid otse /dev/root/cache. Kui midagi on loodud valele kohale, saab selle liikuda pvmove abil.
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 katsete kÀigus avastas autor, et parima tulemuse saavutamiseks peab LVM cache'i ploki suurus olema sama kui LVM thin'i ploki suurus. Samal ajal, mida vÀiksem on suurus, seda paremini töötab konfiguratsioon juhuslike kirjutuste korral.
64k on minimaalne ploki suurus, mis on lubatud LVM thin'i jaoks.
Ole ettevaatlik writeback..!Jah. See tĂŒĂŒp vahemĂ€lu lĂŒkkab kirje sĂŒnkroniseerimise vahemĂ€lus hoidmise seadmele edasi. See vĂ”ib pĂ”hjustada andmete kaotuse vahemĂ€lu kaotamise korral. Hiljem rÀÀgib autor, milliseid meetmeid, vĂ€lja arvatud NVMe RAID 1, saab vĂ”tta riski kompenseerimiseks.
See tĂŒĂŒp vahemĂ€lu on valitud teadlikult, et kompenseerida RAID 6 madalat jĂ”udlust juhuslikul kirjutamisel.
Kontrollime, mis meil tuli vÀlja:
#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 peab sisaldama ainult [cachedata_corig]. Kui midagi on valesti, kasutage pvmove.
VahemĂ€lu saab vajadusel ĂŒhe kommandiga vĂ€lja lĂŒlitada:
#lvconvert -y --uncache cache/cachedata
See toimub online. LVM sĂŒnkroniseerib lihtsalt vahemĂ€lu kettale, eemaldab selle ja nimetab cachedata_corig tagasi cachedata-ks.
LVM thin seadistamine
Hinnatakse, kui palju ruumi vajame LVM thin metaandmete jaoks:
#thin_metadata_size --block-size=64k --pool-size=6terabytes --max-thins=100000 -u bytes
thin_metadata_size - 3385794560 baitsi hinnanguline metaandmeala suurus "--block-size=64kibibytes --pool-size=6terabytes --max-thins=100000"
Ămardame 4 gigabaidini: 4294967296B
Korrutame kahega ja lisame 4194304B LVM PV metaandmete jaoks: 8594128896B
Loome NVMe RAID 1 eraldi partitsiooni, et salvestada 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 on ikkagi vahemĂ€lus ja töötavad kiiresti.
Kuigi kiirus on siin oluline, ei ole see peamine pĂ”hjus. Asi on selles, et vahemĂ€lu on rikke punkt. Sellega vĂ”ib midagi juhtuda ja kui LVM thin metaandmed on vahemĂ€lus, siis vĂ”ib see viia kĂ”igi andmete tĂ€ieliku kadumiseni. Ilma tervete metaandmeteta on Ă”hukeste mahtude ĂŒlesehitamine peaaegu vĂ”imatu.
Kandes metaandmed eraldi mitte-vahemĂ€lustatud, kuid kiirele mahule, tagame metaandmete sĂ€ilimise vahemĂ€lu kaotuse vĂ”i kahjustumise korral. Sel juhul lokaliseeritakse kĂ”ik kahjustused, mis tulenevad vahemĂ€lu kaotusest, vaid Ă”hukestesse mahtudesse, mis lihtsustab taastamisprotseduuri oluliselt. Suure tĂ”enĂ€osusega saab need kahjustused taastada failisĂŒsteemi logide abil.
Veelgi enam, kui on eelnevalt tehtud hetkeseis Ă”hukesest mahust, ja pĂ€rast seda on vĂ€hemalt ĂŒks kord vahemĂ€lu tĂ€ielikult sĂŒnkroonitud, siis, arvestades LVM thin sisemisi omadusi, on hetkeseisu terviklikkus tagatud vahemĂ€lu kaotuse korral.
Loome uue VG, mis vastutab Ôhukese pakkumise 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 mĂ”eldud â et vĂ€ltida andmete lekkimist ĂŒhelt virtuaalmasinalt teisele ruumi ĂŒmberjaotamisel â kasutatakse zeroing tĂ€iendavalt vĂ€iksema kui 64k blokis juhusliku kirjutamise kiirusest suurema tĂ”hususe saavutamiseks. Iga vĂ€hem kui 64k kirjutis varem mittejaotatud Ă”hukesesse mahuti alasse muudetakse 64K pĂŒhendatuks vahemĂ€lu piirides. See vĂ”imaldab protsessil tĂ€ielikult lĂ€bi vahemĂ€lu toimumist, vĂ€ltides vahemĂ€lu seadme kasutamist.
Liigume LV vastavatele PV-dele:
#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)
Ôhuke bassein 274877906944B thin-pool_tdata(0)
[thin-pool_tdata] 274877906944B /dev/cache/cachedata(0)
[thin-pool_tmeta] 4294967296B /dev/root/images(1024)
Loome katsetamiseks Ôhukese mahuti:
#lvcreate -V 64G --thin-pool thin-pool --name test images
Paigaldame katse- ja jÀlgimispaketid:
#apt-get install sysstat fio
Nii saab jÀlgida oma salvestusseadme 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 saab testida oma konfiguratsiooni:
#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 sekundit. Pool teste on kirjutamistest. 4 sekundi jooksul suudab NVMe kirjutada vĂ€ga palju. Kuni 3 gigabaiti sekundis. Seega vĂ”ivad iga kirjutamiskatse kĂ€ivitamine neelata teie SSD ressursse kuni 216 gigabaiti.
Lugemine ja kirjutamine segamini?Jah. Testid lugemise ja kirwriting jaoks on mĂ”ttekas teostada eraldi. Veelgi enam, on mĂ”istlik veenduda, et kĂ”ik vahemĂ€lud on sĂŒnkroniseeritud, et varem tehtud kirje ei mĂ”juta lugemist.
Tulemused erinevad oluliselt esimese kĂ€ivitamise ja jĂ€rgnevate vahel, kuna vahemĂ€lu tĂ€itub ja Ă”huke maht areneb, ning olenevalt sellest, kas sĂŒsteem on suutnud sĂŒnkroniseerida vahemĂ€lud, mis tĂ€ideti eelmisel kĂ€ivitamisel.
Lisaks soovitan mÔÔta kiirus juba tÀidetud Ôhukeselt mahult, millest just tehti hetkeseis. Autor on mÀrganud, kuidas juhuslik kirjutamine kiireneb pÀrast esimesena tehtud hetkeseisu loomist, eriti kui vahemÀlu ei ole veel tÀielikult tÀidetud. See toimub tÀnu copy-on-write kirjutamise semantikale, vahemÀlu ja Ôhukese mahu blokki tasandamisele, ning sellele, et juhuslik kirjutamine RAID 6-l muutub juhuslikuks lugemiseks RAID 6-l koos jÀrgneva kirjutamisega vahemÀllu. Meie konfiguratsioonis on juhuslik lugemine RAID 6-l kuni 6 korda (SATA SSD-de arv maatriksis) kiirem kui kirjutamine. Kuna CoW jaoks blokeeritakse blokid jÀrjestikku Ôhukesest basseinist, siis kirjutamine, enamasti, muutub ka jÀrjestikuseks.
MÔlemaid neid omadusi saab kasulikult kasutada.
Vahehoidla «koherentsete» snÀpƥottide
Andmekao riski vÀhendamiseks vahehoidla kahjustamise vÔi kaotamise korral soovitab autor rakendada snÀpƥottide vahetamise praktikat, mis tagab nende terviklikkuse sel juhul.
Esiteks, kuna peene mahtude metaandmed asuvad vahehoidmata seadmes, on metaandmed terved ja vÔimalikud kaotused isoleeritakse andmeplokkidesse.
JĂ€rgmine snĂ€pĆĄottide vahetamise tsĂŒkkel garanteerib andmete terviklikkuse snĂ€pĆĄottides ka vahehoidla kadumise korral:
- KĂ€itage iga peene mahu jaoks nimega <ĐžĐŒŃ> snĂ€pĆĄott nimega <ĐžĐŒŃ>.cached
- Seame migreerimislÀvendi mÔistlikult kÔrgele vÀÀrtusele:
#lvchange --quiet --cachesettings "migration_threshold=16384" cache/cachedata - TsĂŒklis kontrollime mÀÀratud plokkide arvu vahehoidlas:
#lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}'kuni saame nulli. Kui nulli pole liiga kaua, saab selle ajutiselt luua, viies vahemĂ€lu writethrough reĆŸiimi. Siiski, arvestades meie SATA ja NVMe SSD-de kiirusnĂ€itajaid ning nende TBW ressursse, suudate kas piisavalt kiiresti Ă”igel hetkel tabada ilma vahemĂ€lu reĆŸiimi muutmata vĂ”i teie riistvara tarbib kogu oma ressursi Ă€ra vaid mĂ”ne pĂ€evaga. Ressursi piirangute tĂ”ttu ei suuda sĂŒsteem pidevalt pĂŒsida 100% kirjutuskoormusel. Meie NVMe SSD-d kulutavad oma ressursid tĂ€ieliku 100% kirjutuskoormuse all 3-4 pĂ€eva. SATA SSD-d elavad vaid kaks korda kauem. SeetĂ”ttu oletame, et suurem osa koormusest on lugemine, ja kirjutamine on meil â suhteliselt lĂŒhikesed kĂ”rge aktiivsuse perioodid, millega kaasnevad madalad koormused keskmiselt. - Niipea kui oleme nulli saanud (vĂ”i loonud) â muudame <nimi>.cached nimeks <nimi>.committed. Eemaldame vana <nimi>.committed.
- Valikuline: kui vahemĂ€lu on 100% tĂ€is, saab seda skripti abil uuesti luua, andes seelĂ€bi tĂŒhjendamise. Osaliselt tĂŒhja vahemĂ€luga töötab sĂŒsteem kirjutamisel palju kiiremini.
- Seame migreerimise lÀvendi nulliks:
#lvchange --quiet --cachesettings "migration_threshold=0" cache/cachedataSee on ajutiselt keelatud sĂŒnkroonida vahemĂ€lu peamisele kandjale. - Ootame, kuni vahemĂ€lus koguneb piisavalt muudatusi.
#lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}'vÔi kuni taimer kÀivitub. - Kordame uuesti.
Miks need keerukused migration thresholdiga�Asi on selles, et reaalses praktikas ei ole 'juhuslik' kirjutamine tegelikult tÀiesti juhuslik. Kui me kirjutame midagi 4 kilobaidi suurusesse sektorisse, on suur tÔenÀosus, et jÀrgmise paari minuti jooksul tehakse kirjutamine sellesse vÔi mÔnda naaber (+- 32K) sektorisse.
Seades migration threshold nulli, lĂŒkkame SATA SSD-l kirjutamise sĂŒnkroonimist edasi ja kogume vahemĂ€lus mitu 64K ploki muudatust. Sellega sÀÀstame oluliselt SATA SSD ressurssi.
Aga kus on kood..?Kahjuks peab autor end bash skriptide arendamisel piisavalt mittekompetentseks, kuna on 100% iseÔppija ja praktik, kes jÀrgib 'google'-pÔhist arendust, seetÔttu arvab ta, et see kohutav kood, mis tema kÀest tuleb, ei ole kedagi teist vÀÀrt kasutada.
Usun, et professionaalid suudavad vajadusel kogu eeltoodud loogika ise ĂŒles ehitada ja vĂ”ib-olla isegi ilusasti systemd teenusena kujundada, nagu autor ĂŒritas teha.
Selline lihtne snapshotide rotatsiooni skeem vĂ”imaldab meil mitte ainult hoida ĂŒhte tĂ€ielikult sĂŒnkroonitud SATA SSD snapshotit, vaid ka kasutada utiliiti thin_delta, et teada saada, millised plokid on pĂ€rast selle loomist muutunud, hĂ”lbustades seelĂ€bi pĂ”hitomide vigade paikamist ja taastamist.
TRIM/DISCARD libvirt/KVM
Kuna andmesalvestus on mÔeldud KVM jaoks, mis töötab libvirt'i alt, oleks hea Ôpetada meie VM-e mitte ainult kasutama vaba ruumi, vaid ka vabastama juba ebavajaliku.
See saavutatakse TRIM/DISCARD toe emuleerimise teel virtuaalsetes ketastes. Selleks tuleb muuta kontrolleri tĂŒĂŒpi virtio-scsi 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'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</controller>
Delikud DISCARD'id kĂŒlgvĂ”rkudest töödeldakse LVM-iga korrektselt ja blokid vabastatakse Ă”igesti nii vahemĂ€lus kui ka Ă”hukeses mahus. Meie puhul toimub see peamiselt viivitusega, kui eemaldatakse jĂ€rgmine snapshot.
BTRFS varukoopia
Kasutame valmis skripte ÀÀrmise ettevaatlikkusega ja oma riski ja vastutusega. Autor kirjutas selle koodi ise ja ainult enda tarbeks. Olen kindel, et paljudel kogenud Linuxi kasutajatel on olemas sarnased lahendused ja teiste kopeerimine pole vajalik.
Loome mahu varuseadmel:
#lvcreate -L 256G --name backup backup
Formateerime BTRFS-ks:
#mkfs.btrfs /dev/backup/backup
Loome mount-punktid ja mountime FS-i juurosakonnad:
#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 varukoopiaideks kataloogid:
#mkdir /backup/btrfs/back/remote
#mkdir /backup/btrfs/back/remote/root
#mkdir /backup/btrfs/back/remote/boot
Loome varukoopiate skriptide katalooge:
#mkdir /root/btrfs-backup
Kopeerime skripti:
Palju kohutavat bash-koodi. Kasutada omal riskil. Autorile ei saada raevukaid kirju...#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 "Ootan lukku..."
wait_lock || terminate "Luku saamine ebaÔnnestus. VÀljumine..."
echo "Lukk saadud..."
}
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 leitud"
muud
echo "$SOURCE_BASE_PATH Faili ei leitud, luues $SOURCE_PATH jaoks $SOURCE_BASE_PATH snapshot'i"
btrfs subvolume snapshot -r $SOURCE_PATH $SOURCE_BASE_PATH
sync
if [ -d "$TARGET_BASE_PATH" ]
then
echo "$TARGET_BASE_PATH leitud, allika jaotusest vÀljas... eemaldatakse..."
btrfs subvolume delete -c $TARGET_BASE_PATH
sync
fi
fi
if [ -d "$TARGET_BASE_PATH" ]
then
echo "$TARGET_BASE_PATH leitud"
muud
echo "$TARGET_BASE_PATH ei leitud. SĂŒnkroonimine $TARGET_BASE_DIR'iga"
btrfs send $SOURCE_BASE_PATH | btrfs receive $TARGET_BASE_DIR
sync
fi
if [ -d "$SOURCE_PEND_PATH" ]
then
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" ]
then
echo "$TARGET_PEND_PATH leitud, eemaldatakse..."
btrfs subvolume delete -c $TARGET_PEND_PATH
sync
fi
echo "Saadan $SOURCE_PEND_PATH $TARGET_PEND_PATH'ile"
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"
nihke
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
Mida see ĂŒldse teeb..?Sisaldab rida lihtsaid kĂ€ske BTRFS snapshot'ide loomiseks ja nende edastamiseks teisele failisĂŒsteemile BTRFS send/receive'i kaudu.
Esimene kÀivitamine vÔib olla suhteliselt aeglane, kuna alguses kopeeritakse kÔik andmed. Edasi kÀivitamised on vÀga kiired, kuna kopeeritakse vaid muudatused.
Veel ĂŒks skript, mille paneme cron'i:
Veidi rohkem 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ĂŒnkroneerib varukoopiate failisĂŒsteemis sisemisi BTRFS mahutite inkrementaalseid pilte. PĂ€rast seda eemaldab kĂ”ik 60 pĂ€eva tagasi loodud pildid. PĂ€rast kĂ€ivitamist ilmuvad kaustades /backup/btrfs/back/remote/ kuupĂ€evalised pildid loetletud mahutitest.
Anname koodile Ôigused tÀitmiseks:
#chmod +x /root/btrfs-backup/cron-daily.sh
#chmod +x /root/btrfs-backup/btrfs-backup.sh
Kontrollime ja lisame croni:
#/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 Ôhukese varukoopia
Loome Ôhukese basaari varukoopia seadmes:
#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T backup/thin-pool
Paigaldame ddrescue, kuna skriptid kasutavad seda tööriista:
#apt-get install gddrescue
Loome skriptide kausta:
#mkdir /root/lvm-thin-backup
Kopeerime skriptid:
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 "Ootan lukku..."
wait_lock || terminate "Luku saamine ebaÔnnestus. VÀljumine..."
echo "Lukk saadud..."
}
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 "Allikas LV ei ole Ôhuke.")
exit 1
fi
if [ "$DIFF_TARGET_POOL" == "" ]
then
(>&2 echo "Siht LV ei ole Ôhuke.")
exit 1
fi
if [ "$DIFF_SOURCE_POOL" != "$DIFF_TARGET_POOL" ]
then
(>&2 echo "Allika ja sihtrĂŒhmad kuuluvad erinevatesse Ă”hukestesse basseinidesse.")
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 "Ăhukese basseini metainformatsiooni hetkeseis juba eksisteerib. Eeldame, et see on aegunud. Vabastame metainformatsiooni hetkeseisu 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" == "-" ]
then
(>&2 echo "Ăhukese basseini metainformatsiooni hetkeseisu 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" ]
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"
muud
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"
muud
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 ei ĂŒhtinud allikaga... eemaldamine..."
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 leitud"
muud
echo "$TARGET_VG/$TARGET_LV ei leitud. Loome tĂŒhja mahuti."
lvcreate --thin-pool "$BACKUPS_POOL" -V "$SOURCE_BASE_SIZE"B --name "$TARGET_BASE_LV" "$TARGET_VG" || exit 1
echo "Peame uuesti kÀivitama. Loovutame allika $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 "Loovutame sihtkohta $TARGET_BASE_LV_PATH"
discard_volume "$TARGET_VG" "$TARGET_BASE_LV"
sync
fi
if [ "$SOURCE_PEND_LV_PATH" != "" ]
then
echo "$SOURCE_PEND_LV_PATH leitud eemaldamine..."
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 leitud eemaldamine..."
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 "SĂŒnkroniseerimine $SOURCE_PEND_LV_PATH $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"
muud
echo "$SOURCE_BASE_LV_PATH ei leitud"
exit 1
fi
if [ "$TARGET_BASE_LV_PATH" != "" ]
then
echo "$TARGET_BASE_LV_PATH leitud"
muud
kui "$TARGET_BASE_LV_PATH" ei leidu
exit 1
fi
aktiveeri_maht "$TARGET_VG" "$TARGET_BASE_LV"
activate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
vÔrdlemine "$SOURCE_BASE_LV_PATH" ja "$TARGET_BASE_LV_PATH"
vÔrdle "$SOURCE_BASE_LV_PATH" "$TARGET_BASE_LV_PATH"
Valmis...
deactivate_volume "$TARGET_VG" "$TARGET_BASE_LV"
deactivate_volume "$SOURCE_VG" "$SOURCE_BASE_LV"
}
funktsioon resĂŒnkroonimine()
{
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"
muud
echo "$SOURCE_BASE_LV_PATH ei leitud"
exit 1
fi
if [ "$TARGET_BASE_LV_PATH" != "" ]
then
echo "$TARGET_BASE_LV_PATH leitud"
muud
kui "$TARGET_BASE_LV_PATH" ei leidu
exit 1
fi
aktiveeri_maht "$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)
sĂŒnkroniseerimine "$SOURCE_BASE_LV_PATH" «"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 "SĂŒnkroniseerimine $SYNC_LENGTH_BYTES baiti alguses $SYNC_OFFSET_BYTES $SOURCE_BASE_LV_PATH-st $TARGET_BASE_LV_PATH-le"
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"
muud
CMP_OFFSET=""
fi
done
Valmis...
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
eemalda "$SNAPSHOT"
done < <(list "$1" "$2" | grep "$FILTER")
}
(
COMMAND="$1"
nihke
case "$COMMAND" in
"--help")
echo "Help"
;;
"suffix")
suffix
;;
"filter")
filter "$1"
;;
"backup")
wait_lock_or_terminate
varunda "$1" "$2"
;;
"list")
loetle "$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
eemalda "$1"
;;
"removeall")
wait_lock_or_terminate
eemalda kÔik "$1" "$2" "$3"
;;
*)
echo "None.."
;;
esac
) 98>$LOCK_FILE
EOF
Mida see teebâŠ?Sisaldab kĂ€skude komplekti peente snapshotide manipuleerimiseks ja kahe thin snapshot'i vahel tekkiva erinevuse sĂŒnkroonimiseks teise plokkseadmese, kasutades ddrescue ja blkdiscard.
Veel ĂŒks skript, mille paneme croni:
Natuke 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ĂŒnkroniseerida loetletud Ă”hukeste mahtude varukoopiaid. Skript jĂ€tab loetletud mahtude mitteaktiivsed snapshot'id, mis on vajalikud muudatuste jĂ€lgimiseks viimase sĂŒnkroniseerimise jĂ€rel.
Seda skripti tuleb kohandada, mÀÀrates loetelu Ă”hukestest mahtudest, mille jaoks on vajalik varukoopia tegemine. Antud nimed on esitatud nĂ€itena. Soovi korral vĂ”ib kirjutada skripti, mis sĂŒnkroniseerib 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 croni:
#/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 vĂ”tab aega, kuna Ă”hukesed mahud sĂŒnkroonitakse tĂ€ielikult kogu kasutatava ruumi kopeerimise teel. TĂ€nu LVM thin metaandmetele teame, milliseid blokke tegelikult kasutatakse, seega kopeeritakse ainult need Ă”hukeste mahude tĂ”eliselt kasutatavad plokid.
JÀrgmised kÀivitamised kopeerivad andmeid inkrementaalselt, jÀlgides muudatusi LVM thin metaandmete kaudu.
Vaatame, mis sai:
#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Àr 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
...
Ôhuke bassein <2,09t
Mis tÀhendavad matroƥkad?
TĂ”enĂ€oliselt seetĂ”ttu, et LVM LV loogilised mahud vĂ”ivad olla teiste VG fĂŒĂŒsilised mahud LVM PV. LVM vĂ”ib olla rekursiivne nagu matroĆĄkad. See annab LVM-le ĂŒlima paindlikkuse.
P.S.
JÀrgmisest artiklist proovime kasutada mitmeid sarnaseid mobiilseid tehishoidlaid/KVM-i geo-jaotatud storage/vm-klastri vÀljaarendamiseks, pakkudes varundust mitmel mandril koduste lauaarvutite, koduse interneti ja P2P-vÔrkude kaudu.
Allikas: habr.com
