Wat het LVM en Matryoshka in gemeen?

Goeie dag.
Ek wil graag my praktiese ervaring van die bou van 'n databergingstelsel vir KVM met md RAID + LVM met die gemeenskap deel.

Die program sal:

  • Bou md RAID 1 vanaf NVMe SSD.
  • Samestelling van md RAID 6 vanaf SATA SSD en gewone aandrywers.
  • Kenmerke van TRIM/DISCARD-werking op SSD RAID 1/6.
  • Skep 'n selflaaibare md RAID 1/6-skikking op 'n algemene stel skywe.
  • Installeer die stelsel op NVMe RAID 1 in die afwesigheid van NVMe-ondersteuning in die BIOS.
  • Gebruik LVM-kas en LVM dun.
  • Gebruik BTRFS-kiekies en stuur/ontvang vir rugsteun.
  • Gebruik LVM dun foto's en thin_delta vir BTRFS styl rugsteun.

As jy belangstel, sien kat.

Verklaring

Die skrywer dra geen verantwoordelikheid vir die gevolge van die gebruik of nie gebruik van materiaal/voorbeelde/kode/wenke/data uit hierdie artikel nie. Deur hierdie materiaal op enige manier te lees of te gebruik, aanvaar jy verantwoordelikheid vir alle gevolge van hierdie aksies. Moontlike gevolge sluit in:

  • Brosgebraaide NVMe SSD's.
  • Volledig verbruikte skryfhulpbron en mislukking van SSD-aandrywers.
  • Volledige verlies van alle data op alle dryf, insluitend rugsteunkopieë.
  • Foutiewe rekenaar hardeware.
  • Vermorste tyd, senuwees en geld.
  • Enige ander gevolge wat nie hierbo gelys is nie.

yster

Beskikbaar was:

Moederbord van ongeveer 2013 met Z87-skyfiestel, kompleet met Intel Core i7 / Haswell.

  • Verwerker 4 kerne, 8 drade
  • 32 GB DDR3 RAM
  • 1 x 16 of 2 x 8 PCIe 3.0
  • 1 x 4 + 1 x 1 PCIe 2.0
  • 6 x 6 GBps SATA 3-verbindings

SAS-adapter LSI SAS9211-8I het na IT / HBA-modus geflits. RAID-geaktiveerde firmware is doelbewus vervang met HBA-firmware om:

  1. Jy kan hierdie adapter enige tyd uitgooi en dit vervang met enige ander een wat jy teëgekom het.
  2. TRIM/Gooi gewerk het normaalweg op skywe, want... in RAID-firmware word hierdie opdragte glad nie ondersteun nie, en die HBA gee in die algemeen nie om watter opdragte oor die bus oorgedra word nie.

Hardeskywe - 8 stukke HGST Travelstar 7K1000 met 'n kapasiteit van 1 TB in 'n 2.5-vormfaktor, soos vir skootrekenaars. Hierdie aandrywers was voorheen in 'n RAID 6-skikking. Hulle sal ook 'n gebruik in die nuwe stelsel hê. Om plaaslike rugsteun te stoor.

Bykomend bygevoeg:

6 stukke SATA SSD-model Samsung 860 QVO 2TB. Hierdie SSD's het 'n groot volume benodig, die teenwoordigheid van 'n SLC-kas, betroubaarheid en 'n lae prys was verlang. Ondersteuning vir weggooi/nul was nodig, wat deur die reël in dmesg nagegaan word:

kernel: ata1.00: Enabling discard_zeroes_data

2 stukke NVMe SSD-model Samsung SSD 970 EVO 500GB.

Vir hierdie SSD's is ewekansige lees-/skryfspoed en hulpbronkapasiteit vir jou behoeftes belangrik. Radiator vir hulle. Nodig. Absoluut. Anders, braai hulle tot bros tydens die eerste RAID-sinchronisasie.

StarTech PEX8M2E2-adapter vir 2 x NVMe SSD geïnstalleer in PCIe 3.0 8x-gleuf. Dit is weer net 'n HBA, maar vir NVMe. Dit verskil van goedkoop adapters deurdat dit nie PCIe-vertakkingsondersteuning vanaf die moederbord benodig nie as gevolg van die teenwoordigheid van 'n ingeboude PCIe-skakelaar. Dit sal selfs in die oudste stelsel met PCIe werk, selfs al is dit 'n x1 PCIe 1.0-gleuf. Natuurlik teen die gepaste spoed. Daar is geen RAID's daar nie. Daar is geen ingeboude BIOS aan boord nie. So, jou stelsel sal nie magies leer om met NVMe te begin nie, nog minder doen NVMe RAID danksy hierdie toestel.

Hierdie komponent was uitsluitlik te danke aan die teenwoordigheid van slegs een gratis 8x PCIe 3.0 in die stelsel, en as daar 2 gratis gleuwe is, kan dit maklik vervang word met twee pennie PEX4M2E1 of analoë, wat op enige plek teen 'n prys van 600 gekoop kan word roebels.

Die verwerping van alle soorte hardeware of ingeboude skyfiestel / BIOS RAID's is bewustelik gemaak om die hele stelsel heeltemal te kan vervang, met die uitsondering van die SSD / HDD self, met die behoud van alle data. Ideaal gesproke kan jy selfs die geïnstalleerde bedryfstelsel stoor wanneer jy na 'n heeltemal nuwe / ander hardeware beweeg. Die belangrikste ding is dat daar SATA- en PCIe-poorte is. Dit is soos 'n lewendige CD of 'n selflaaibare flash drive, net baie vinnig en 'n bietjie lywig.

HumorAndersins weet jy wat gebeur - soms moet jy dringend die hele reeks saamneem om weg te neem. Maar ek wil nie data verloor nie. Om dit te doen, is al die genoemde media gerieflik geleë op die skyfies in die 5.25 baaie van die standaardkas.

Wel, en natuurlik om te eksperimenteer met verskillende metodes van SSD-kas in Linux.

Hardeware klopjagte is vervelig. Skakel dit aan. Dit werk of dit werk nie. En met mdadm is daar altyd opsies.

sagte

Voorheen is Debian 8 Jessie op die hardeware geïnstalleer, wat naby EOL is. RAID 6 is saamgestel vanaf die bogenoemde HDD's wat met LVM gepaard is. Dit het virtuele masjiene in kvm/libvirt uitgevoer.

Omdat Die skrywer het gepaste ondervinding in die skep van draagbare selflaaibare SATA/NVMe-flitsaandrywers, en ook, om nie die gewone gepaste sjabloon te breek nie, is Ubuntu 18.04 gekies as die teikenstelsel, wat reeds genoegsaam gestabiliseer is, maar nog steeds 3 jaar van ondersteun in die toekoms.

Die genoemde stelsel bevat al die hardeware drywers wat ons uit die boks benodig. Ons het geen derdeparty sagteware of drywers nodig nie.

Voorbereiding vir installering

Om die stelsel te installeer, benodig ons Ubuntu Desktop Image. Die bedienerstelsel het 'n soort kragtige installeerder, wat buitensporige onafhanklikheid toon wat nie gedeaktiveer kan word deur die UEFI-stelselpartisie op een van die skywe te druk nie, wat al die skoonheid bederf. Gevolglik word dit slegs in UEFI-modus geïnstalleer. Bied geen opsies nie.

Ons is nie gelukkig hiermee nie.

Hoekom?Ongelukkig is UEFI-selflaai uiters swak versoenbaar met opstartsagteware RAID, want ... Niemand bied ons besprekings vir die UEFI ESP-partisie nie. Daar is resepte aanlyn wat voorstel dat die ESP-partisie op 'n flash drive in 'n USB-poort geplaas word, maar dit is 'n punt van mislukking. Daar is resepte wat sagteware mdadm RAID 1 met metadata weergawe 0.9 gebruik wat nie verhoed dat die UEFI BIOS hierdie partisie sien nie, maar dit leef tot die gelukkige oomblik wanneer die BIOS of 'n ander hardeware-bedryfstelsel iets na die ESP skryf en vergeet om dit met ander te sinchroniseer spieëls.

Boonop hang UEFI-selflaai af van NVRAM, wat nie saam met die skywe na die nuwe stelsel sal beweeg nie, want is deel van die moederbord.

So, ons sal nie 'n nuwe wiel herontdek nie. Ons het reeds 'n klaargemaakte, beproefde oupa-fiets, wat nou Legacy/BIOS-stewel genoem word, wat die trotse naam van CSM op UEFI-versoenbare stelsels dra. Ons haal dit net van die rak af, smeer dit, pomp die bande op en vee dit met 'n klam lap af.

Die lessenaarweergawe van Ubuntu kan ook nie behoorlik met die Legacy selflaaiprogram geïnstalleer word nie, maar hier is, soos hulle sê, ten minste opsies.

En so, ons versamel die hardeware en laai die stelsel vanaf die Ubuntu Live selflaaibare flash drive. Ons sal pakkette moet aflaai, so ons sal die netwerk opstel wat vir jou werk. As dit nie werk nie, kan jy vooraf die nodige pakkette op 'n flash drive laai.

Ons gaan na die lessenaaromgewing, begin die terminale emulator, en ons gaan:

#sudo bash

Hoe…?Die lyn hierbo is die kanonieke sneller vir holiwars oor sudo. C bоmeer geleenthede kom en bоgroter verantwoordelikheid. Die vraag is of jy dit self kan aanvat. Baie mense dink dat die gebruik van sudo op hierdie manier ten minste nie versigtig is nie. Maar:

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

Hoekom nie ZFS nie...?Wanneer ons sagteware op ons rekenaar installeer, leen ons in wese ons hardeware aan die ontwikkelaars van daardie sagteware.
Wanneer ons hierdie sagteware met die veiligheid van ons data vertrou, neem ons 'n lening aan gelykstaande aan die koste om hierdie data te herstel, wat ons eendag sal moet afbetaal.

Vanuit hierdie oogpunt is ZFS 'n Ferrari, en mdadm+lvm is meer soos 'n fiets.

Subjektief verkies die skrywer om 'n fiets op krediet aan onbekende individue te leen in plaas van 'n Ferrari. Daar is die prys van die uitgawe nie hoog nie. Geen behoefte aan regte nie. Eenvoudiger as verkeersreëls. Parkering is gratis. Landloop vermoë is beter. Jy kan altyd bene aan 'n fiets vasmaak, en jy kan 'n fiets met jou eie hande herstel.

Hoekom dan BTRFS...?Om die bedryfstelsel te begin, benodig ons 'n lêerstelsel wat in Legacy/BIOS GRUB uit die boks ondersteun word, en terselfdertyd lewendige foto's ondersteun. Ons sal dit gebruik vir die /boot partisie. Daarbenewens verkies die skrywer om hierdie FS vir / (wortel) te gebruik, en moenie vergeet om daarop te let dat jy vir enige ander sagteware aparte partisies op LVM kan skep en dit in die nodige gidse kan monteer nie.

Ons sal nie beelde van virtuele masjiene of databasisse op hierdie FS stoor nie.
Hierdie FS sal slegs gebruik word om kiekies van die stelsel te skep sonder om dit af te skakel en dan hierdie kiekies na 'n rugsteunskyf oor te dra deur stuur/ontvang.

Daarbenewens verkies die skrywer oor die algemeen om 'n minimum sagteware direk op die hardeware te hou en al die ander sagteware in virtuele masjiene te laat loop deur dinge soos om GPU's en PCI-USB-gasheerbeheerders na KVM aan te stuur via IOMMU.

Die enigste dinge wat op die hardeware oorbly, is databerging, virtualisering en rugsteun.

As jy ZFS meer vertrou, dan is hulle in beginsel uitruilbaar vir die gespesifiseerde toepassing.

Die skrywer ignoreer egter doelbewus die ingeboude spieël-/RAID- en oortolligheidskenmerke wat in ZFS, BRTFS en LVM gevind word.

As 'n bykomende argument het BTRFS die vermoë om ewekansige skryfwerk in opeenvolgende skryfwerk te verander, wat 'n baie positiewe uitwerking het op die spoed van sinchronisasie van foto's / rugsteun op die HDD.

Kom ons skandeer alle toestelle weer:

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

Kom ons kyk rond:

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

Partisionering van "skywe"

NVMe SSD's

Maar ons sal hulle op geen manier merk nie. Ons BIOS sien egter nie hierdie aandrywers nie. Dus, hulle sal heeltemal na sagteware RAID gaan. Ons sal nie eers afdelings daar skep nie. As jy die "kanon" of "hoofsaaklik" wil volg, skep een groot partisie, soos 'n HDD.

SATA HDD

Hier is niks besonders om uit te vind nie. Ons sal een afdeling vir alles skep. Ons sal 'n partisie skep omdat die BIOS hierdie skywe sien en selfs kan probeer om van hulle af te begin. Ons sal selfs GRUB later op hierdie dryf installeer sodat die stelsel dit skielik het.

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

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

SATA SSD

Dit is waar dinge vir ons interessant raak.

Eerstens is ons aandrywers 2 TB groot. Dit is binne die aanvaarbare omvang vir MBR, wat is wat ons sal gebruik. Indien nodig, kan vervang word met GPT. GPT-skywe het 'n versoenbaarheidslaag wat MBR-versoenbare stelsels toelaat om die eerste 4 partisies te sien as hulle binne die eerste 2 teragrepe geleë is. Die belangrikste ding is dat die opstartpartisie en bios_grub-partisie op hierdie skywe aan die begin moet wees. Dit laat jou selfs toe om vanaf GPT Legacy/BIOS-aandrywers te begin.

Maar dit is nie ons geval nie.

Hier sal ons twee afdelings skep. Die eerste een sal 1 GB groot wees en gebruik word vir RAID 1 /boot.

Die tweede een sal vir RAID 6 gebruik word en sal al die oorblywende vrye spasie opneem, behalwe vir 'n klein ontoegekende area aan die einde van die stasie.

Wat is hierdie ongemerkte area?Volgens bronne op die netwerk het ons SATA SSD's 'n dinamies uitbreidbare SLC-kas aan boord wat in grootte wissel van 6 tot 78 gigagrepe. Ons kry 6 gigagrepe "gratis" as gevolg van die verskil tussen "gigagrepe" en "gibigrepe" in die datablad van die aandrywer. Die oorblywende 72 gigagrepe word uit ongebruikte spasie toegeken.

Hier moet kennis geneem word dat ons 'n SLC-kas het, en die spasie word in 4-bis MLC-modus beset. Wat vir ons effektief beteken dat ons vir elke 4 gigagrepe vrye spasie net 1 gigagreep SLC-kas sal kry.

Vermenigvuldig 72 gigagrepe met 4 en kry 288 gigagrepe. Dit is die vrye spasie wat ons nie sal uitmerk nie om die aandrywers toe te laat om die SLC-kas ten volle te gebruik.

Ons sal dus effektief tot 312 gigagrepe se SLC-kas kry vanaf 'n totaal van ses dryf. Van al die aandrywers sal 2 in RAID vir oortolligheid gebruik word.

Hierdie hoeveelheid kas sal ons in staat stel om uiters selde in die werklike lewe 'n situasie teëkom waar 'n skrywe nie na die kas gaan nie. Dit vergoed uiters goed vir die hartseerste nadeel van QLC-geheue - die uiters lae skryfspoed wanneer data geskryf word deur die kas te omseil. As jou vragte nie hiermee ooreenstem nie, beveel ek aan dat jy mooi dink oor hoe lank jou SSD onder so 'n las sal hou, met inagneming van die TBW van die datablad.

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

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

Skep skikkings

Eerstens moet ons die masjien hernoem. Dit is nodig omdat die gasheernaam deel is van die skikkingsnaam iewers binne mdadm en iets iewers beïnvloed. Natuurlik kan skikkings later hernoem word, maar dit is 'n onnodige stap.

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

NVMe SSD's

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

Hoekom -aanvaar-skoon...?Om nie skikkings te inisialiseer nie. Vir beide RAID-vlakke 1 en 6 is dit aanvaarbaar. Alles kan werk sonder inisialisering as dit 'n nuwe skikking is. Boonop is die inisiasie van 'n SSD-skikking by skepping 'n vermorsing van die TBW-hulpbron. Ons gebruik TRIM/DISCARD waar moontlik op saamgestelde SSD-skikkings om hulle te "initialiseer".

Vir SSD-skikkings word RAID 1 DISCARD uit die boks ondersteun.

Vir SSD RAID 6 DISCARD skikkings, moet jy dit aktiveer in die kern module parameters.

Dit moet slegs gedoen word as alle SSD's wat in vlak 4/5/6 skikkings in hierdie stelsel gebruik word, werkende ondersteuning vir discard_zeroes_data het. Soms kom jy vreemde aandrywers teë wat vir die kern sê dat hierdie funksie ondersteun word, maar in werklikheid is dit nie daar nie, of die funksie werk nie altyd nie. Op die oomblik is ondersteuning byna oral beskikbaar, maar daar is ou aandrywers en firmware met foute. Om hierdie rede is DISCARD-ondersteuning by verstek gedeaktiveer vir RAID 6.

Let op, die volgende opdrag sal alle data op NVMe-aandrywers vernietig deur die skikking met "nulle" te "initialiseer".

#blkdiscard /dev/md0

As iets verkeerd geloop het, probeer dan om die stap te spesifiseer.

#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

Hoekom so groot...?'n Toename in stukgrootte het 'n positiewe uitwerking op die spoed van ewekansige lees in blokke tot en met stukgrootte ingesluit. Dit is omdat een bewerking van die toepaslike grootte of minder geheel en al op 'n enkele toestel uitgevoer kan word. Daarom word IOPS van alle toestelle opgesom. Volgens statistieke oorskry 99% van IO nie 512K nie.

RAID 6 IOPS per skryf altyd minder as of gelyk aan die IOPS van een aandrywer. Wanneer, as 'n ewekansige lees, IOPS 'n paar keer groter kan wees as dié van een aandrywer, en hier is die blokgrootte van sleutelbelang.
Die skrywer sien nie die sin daarin om 'n parameter te probeer optimaliseer wat sleg is in RAID 6-deurontwerp nie en in plaas daarvan te optimaliseer waarmee RAID 6 goed is.
Ons sal vergoed vir die swak ewekansige skryf van RAID 6 met 'n NVMe-kas en dun-voorsiening-truuks.

Ons het nog nie DISCARD vir RAID 6 geaktiveer nie. Ons sal dus nog nie hierdie skikking “initialiseer” nie. Ons sal dit later doen, nadat ons die bedryfstelsel geïnstalleer het.

SATA HDD

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

LVM op NVMe RAID

Vir spoed wil ons die wortellêerstelsel op NVMe RAID 1 plaas wat /dev/md0 is.
Ons sal egter steeds hierdie vinnige skikking benodig vir ander behoeftes, soos ruil, LVM-kas metadata en kas, en LVM-dun metadata, so ons sal 'n LVM VG op hierdie skikking skep.

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

Kom ons skep 'n partisie vir die wortellêerstelsel.

#lvcreate -L 128G --name root root

Kom ons skep 'n partisie om te ruil volgens die grootte van die RAM.

#lvcreate -L 32G --name swap root

OS installasie

In totaal het ons alles wat nodig is om die stelsel te installeer.

Begin die stelselinstallasie-assistent vanaf die Ubuntu Live-omgewing. Normale installasie. Slegs in die stadium van die keuse van skywe vir installasie, moet u die volgende spesifiseer:

  • /dev/md1, - monteerpunt /boot, FS - BTRFS
  • /dev/root/root (a.k.a /dev/mapper/root-root), - bergpunt / (root), FS - BTRFS
  • /dev/root/swap (a.k.a /dev/mapper/root-swap), - gebruik as ruilpartisie
  • Installeer die selflaaiprogram op /dev/sda

Wanneer jy BTRFS as die wortellêerstelsel kies, sal die installeerder outomaties twee BTRFS-volumes met die naam "@" vir / (root), en "@home" vir /home skep.

Kom ons begin die installasie...

Die installasie sal eindig met 'n modale dialoogkassie wat 'n fout met die installering van die selflaaiprogram rapporteer. Ongelukkig sal jy nie hierdie dialoog met gewone maniere kan verlaat en met die installasie voortgaan nie. Ons meld uit van die stelsel en meld weer aan, om by 'n skoon Ubuntu Live-lessenaar te kom. Maak 'n terminaal oop en weer:

#sudo bash

Skep 'n chroot-omgewing om voort te gaan met die installasie:

#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

Kom ons stel die netwerk en gasheernaam in chroot op:

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

Kom ons gaan na die chroot-omgewing:

#chroot /mnt/chroot

Eerstens sal ons die pakkette aflewer:

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

Kom ons kyk en herstel alle pakkette wat skeef geïnstalleer is as gevolg van onvolledige stelselinstallasie:

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

As iets nie uitwerk nie, moet jy dalk eers /etc/apt/sources.list wysig

Kom ons pas die parameters vir die RAID 6-module aan om TRIM/DISCARD te aktiveer:

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

Kom ons pas ons skikkings 'n bietjie aan:

#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

Wat was dit..?Ons het 'n stel udev-reëls geskep wat die volgende sal doen:

  • Stel die blokkasgrootte vir RAID 2020 om voldoende te wees vir 6. Die verstekwaarde, blyk dit, het nie verander sedert die skepping van Linux nie, en was vir 'n lang tyd nie voldoende nie.
  • Bespreek 'n minimum van IO vir die duur van skikkingskontroles/sinchronisasies. Dit is om te verhoed dat jou skikkings in 'n toestand van ewige sinchronisasie onder las vassit.
  • Beperk die maksimum IO tydens kontrole/sinchronisasie van skikkings. Dit is nodig sodat die sinchronisering/nagaan van SSD RAID's nie jou dryf tot 'n skerp braai nie. Dit geld veral vir NVMe. (Onthou jy van die verkoeler? Ek het nie 'n grap gemaak nie.)
  • Verbied skywe om spilrotasie (HDD) via APM te stop en stel die slaaptydverloop vir skyfbeheerders op 7 uur. Jy kan APM heeltemal deaktiveer as jou dryf dit kan doen (-B 255). Met die verstekwaarde sal die aandrywers na vyf sekondes stop. Dan wil die OS die skyfkas terugstel, die skywe sal weer draai, en alles sal weer van voor af begin. Skyfies het 'n beperkte maksimum aantal spilrotasies. So 'n eenvoudige versteksiklus kan u skywe maklik binne 'n paar jaar doodmaak. Nie alle skywe ly hieraan nie, maar ons s'n is "skootrekenaars", met die toepaslike verstekinstellings, wat die RAID soos 'n mini-MAID laat lyk.
  • Installeer readahead op skywe (roterende) 1 megagreep - twee opeenvolgende blokke/chunk RAID 6
  • Deaktiveer leesvooruit op die skikkings self.

Kom ons wysig /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

Hoekom is dit..?Ons sal soek vir die /boot-afdeling deur UUID. skikkingsbenoeming kan teoreties verander.

Ons sal soek vir die oorblywende afdelings deur LVM name in /dev/mapper/vg-lv notasie, want hulle identifiseer partisies uniek.

Ons gebruik nie UUID vir LVM nie, want Die UUID van LVM-volumes en hul foto's kan dieselfde wees.Monteer /dev/mapper/root-root.. twee keer?Ja. Presies. Kenmerk van BTRFS. Hierdie lêerstelsel kan verskeie kere met verskillende subvols gemonteer word.

As gevolg van dieselfde kenmerk, beveel ek aan dat u nooit LVM-kiekies van aktiewe BTRFS-volumes skep nie. Jy kan dalk 'n verrassing kry wanneer jy herlaai.

Kom ons herskep die mdadm-konfigurasie:

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

Kom ons pas die LVM-instellings aan:

#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

Wat was dit..?Ons het outomatiese uitbreiding van LVM dun poele geaktiveer wanneer 90% van die besette spasie met 5% van die volume bereik is.

Ons het die maksimum aantal kasblokke vir LVM-kas verhoog.

Ons het LVM verhinder om na LVM-volumes (PV) te soek op:

  • toestelle wat LVM-kas (cdata) bevat
  • toestelle wat gekas is met LVM-kas wat die kas omseil (_corig). In hierdie geval sal die kastoestel self steeds deur die kas geskandeer word (net ).
  • toestelle wat LVM-kas-metadata bevat (cmeta)
  • alle toestelle in VG met die naam beelde. Hier sal ons skyfbeelde van virtuele masjiene hê, en ons wil nie hê dat LVM op die gasheer volumes aktiveer wat aan die gas-bedryfstelsel behoort nie.
  • alle toestelle in VG met die naam rugsteun. Hier sal ons rugsteunkopieë van virtuele masjienbeelde hê.
  • alle toestelle wie se naam eindig met "gpv" (gas fisiese volume)

Ons het DISCARD-ondersteuning geaktiveer wanneer spasie op LVM VG vrygestel word. Wees versigtig. Dit sal die verwydering van LV op SSD lank genoeg maak. Dit is veral waar vir SSD RAID 6. Volgens die plan sal ons egter dun voorsiening gebruik, so dit sal ons glad nie pla nie.

Kom ons werk die initramfs-beeld op:

#update-initramfs -u -k all

Installeer en konfigureer grub:

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

Watter skywe moet u kies?Al wat sd* is. Die stelsel moet vanaf enige werkende SATA-skyf of SSD kan selflaai.

Hoekom het hulle os-prober bygevoeg..?Vir oormatige onafhanklikheid en speelse hande.

Dit werk nie korrek as een van die RAID's in 'n gedegradeerde toestand is nie. Dit probeer om die bedryfstelsel te soek op partisies wat gebruik word in virtuele masjiene wat op hierdie hardeware werk.

As jy dit nodig het, kan jy dit los, maar hou al die bogenoemde in gedagte. Ek beveel aan om aanlyn resepte te soek om van stoute hande ontslae te raak.

Hiermee het ons die aanvanklike installasie voltooi. Dit is tyd om te herlaai na die nuut geïnstalleerde bedryfstelsel. Moenie vergeet om die selflaaibare Live CD/USB te verwyder nie.

#exit
#reboot

Kies enige van die SATA SSD's as die selflaaitoestel.

LVM op SATA SSD

Op hierdie stadium het ons reeds in die nuwe bedryfstelsel begin, die netwerk gekonfigureer, apt, die terminale emulator oopgemaak en van stapel gestuur:

#sudo bash

Kom ons gaan aan.

"Initialiseer" 'n reeks SATA SSD:

#blkdiscard /dev/md2

As dit nie werk nie, dan probeer ons:

#blkdiscard --step 65536 /dev/md2
Skep LVM VG op SATA SSD:

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

Hoekom nog 'n VG..?Trouens, ons het reeds 'n VG genaamd root. Hoekom nie alles by een VG voeg nie?

As daar verskeie PV's in 'n VG is, moet alle PV's teenwoordig wees (aanlyn) om die VG korrek te aktiveer. Die uitsondering is LVM RAID, wat ons doelbewus nie gebruik nie.

Ons wil regtig hê dat as daar 'n mislukking (lees dataverlies) op enige van die RAID 6-skikkings is, die bedryfstelsel normaal sal begin en ons die geleentheid gee om die probleem op te los.

Om dit te doen, sal ons op die eerste vlak van abstraksie elke tipe fisiese "media" in 'n aparte VG isoleer.

Wetenskaplik gesproke behoort verskillende RAID-skikkings aan verskillende "betroubaarheidsdomeine". Jy moet nie 'n bykomende algemene punt van mislukking vir hulle skep deur hulle in een VG te prop nie.

Die teenwoordigheid van LVM op die “hardeware”-vlak sal ons in staat stel om stukke van verskillende RAID-skikkings arbitrêr te sny deur hulle op verskillende maniere te kombineer. Byvoorbeeld - hardloop gelyktydig bcache + LVM dun, bcache + BTRFS, LVM-kas + LVM dun, 'n komplekse ZFS-konfigurasie met caches, of enige ander helse mengsel om dit alles te probeer vergelyk.

Op die "hardeware"-vlak sal ons niks anders as goeie ou "dik" LVM-volumes gebruik nie. Die uitsondering op hierdie reël kan die rugsteunpartisie wees.

Ek dink teen hierdie tyd het baie lesers al iets oor die matrjosjka begin vermoed.

LVM op SATA HDD

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

Weer nuwe VG..?Ons wil regtig hê dat as die skyfskikking wat ons vir data-rugsteun sal gebruik, misluk, ons bedryfstelsel sal voortgaan om normaal te werk, terwyl toegang tot nie-rugsteundata soos gewoonlik behou word. Daarom, om VG-aktiveringsprobleme te vermy, skep ons 'n aparte VG.

Stel LVM-kas op

Kom ons skep 'n LV op NVMe RAID 1 om dit as 'n kastoestel te gebruik.

#lvcreate -L 70871154688B --name cache root

Hoekom is daar so min...?Die feit is dat ons NVMe SSD's ook 'n SLC-kas het. 4 gigagrepe "gratis" en 18 gigagrepe dinamiese as gevolg van die vrye spasie wat in die 3-bis MLC beset word. Sodra hierdie kas uitgeput is, sal NVMe SSD's nie veel vinniger wees as ons SATA SSD met kas nie. Om hierdie rede maak dit eintlik geen sin vir ons om die LVM-kaspartisie veel groter as twee keer die grootte van die SLC-kas van die NVMe-stasie te maak nie. Vir die NVMe-aandrywers wat gebruik word, ag die skrywer dit redelik om 32-64 gigagrepe kas te maak.

Die gegewe partisiegrootte word benodig om 64 gigagrepe se kas, kas-metadata en metadata-rugsteun te organiseer.

Daarbenewens neem ek kennis dat LVM na 'n vuil stelsel-afsluiting die hele kas as vuil sal merk en weer sal sinchroniseer. Boonop sal dit elke keer herhaal word wanneer lvchange op hierdie toestel gebruik word totdat die stelsel weer herlaai word. Daarom beveel ek aan dat u die kas onmiddellik herskep met die toepaslike skrif.

Kom ons skep 'n LV op SATA RAID 6 om dit as 'n kastoestel te gebruik.

#lvcreate -L 3298543271936B --name cache data

Hoekom net drie teragrepe..?Sodat jy, indien nodig, SATA SSD RAID 6 vir ander behoeftes kan gebruik. Die grootte van die kasruimte kan dinamies vergroot word, op die vlug, sonder om die stelsel te stop. Om dit te doen, moet jy die kas tydelik stop en heraktiveer, maar die kenmerkende voordeel van LVM-kas bo byvoorbeeld bcache is dat dit dadelik gedoen kan word.

Kom ons skep 'n nuwe VG vir cache.

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

Kom ons skep 'n LV op die kas toestel.

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

Hier het ons dadelik al die vrye spasie op /dev/data/cache opgeneem sodat alle ander nodige partisies onmiddellik op /dev/root/cache geskep is. As jy iets op die verkeerde plek geskep het, kan jy dit skuif met pvmove.

Kom ons skep en aktiveer die kas:

#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

Hoekom sulke brokkies..?Deur praktiese eksperimente het die skrywer daarin geslaag om uit te vind dat die beste resultaat behaal word as die grootte van die LVM-kasblok dieselfde is as die grootte van die LVM dun blok. Terselfdertyd, hoe kleiner die grootte, hoe beter vertoon die konfigurasie homself op 'n ewekansige rekord.

64k is die minimum blokgrootte wat toegelaat word vir LVM dun.

Wees versigtig terugskryf..!Ja. Hierdie tipe kas stel skryfsinchronisasie na die kastoestel uit. Dit beteken dat as die kas verlore gaan, jy data op die kastoestel kan verloor. Later sal die skrywer jou vertel watter maatreëls, benewens NVMe RAID 1, getref kan word om vir hierdie risiko te vergoed.

Hierdie tipe kas is doelbewus gekies om te vergoed vir die swak werkverrigting van RAID 6 op ewekansige skryfwerk.

Kom ons kyk wat ons gekry het:

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

Slegs [cachedata_corig] moet op /dev/data/cache geleë wees. As iets verkeerd is, gebruik dan pvmove.

Jy kan die kas deaktiveer indien nodig met een opdrag:

#lvconvert -y --uncache cache/cachedata

Dit word aanlyn gedoen. LVM sinkroniseer eenvoudig die kas na skyf, vee dit uit en hernoem cachedata_corig terug na kasdata.

Die opstel van LVM dun

Kom ons skat rofweg hoeveel spasie ons benodig vir LVM dun metadata:

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

Rond af na 4 gigagrepe: 4294967296B

Vermenigvuldig met twee en voeg 4194304B by vir LVM PV-metadata: 8594128896B
Kom ons skep 'n aparte partisie op NVMe RAID 1 om LVM dun metadata en die rugsteun daarvan daarop te plaas:

#lvcreate -L 8594128896B --name images root

Vir wat..?Hier kan die vraag ontstaan: hoekom LVM dun metadata apart plaas as dit steeds op NVMe gekas sal word en vinnig sal werk.

Alhoewel spoed hier belangrik is, is dit ver van die hoofrede af. Die ding is dat die kas 'n punt van mislukking is. Iets kan daarmee gebeur, en as die LVM-dun metadata in die kas gestoor is, sal dit veroorsaak dat alles heeltemal verlore gaan. Sonder volledige metadata sal dit byna onmoontlik wees om dun volumes saam te stel.

Deur die metadata na 'n aparte, nie-gekas, maar vinnige volume te skuif, waarborg ons die veiligheid van die metadata ingeval die kas verlore raak of beskadig word. In hierdie geval sal alle skade wat veroorsaak word deur kasverlies binne dun volumes gelokaliseer word, wat die herstelprosedure met ordes van grootte sal vereenvoudig. Met 'n hoë waarskynlikheid, sal hierdie skade verhaalbaar wees met behulp van FS logs.

Verder, as 'n momentopname van 'n dun volume voorheen geneem is, en daarna is die kas ten minste een keer volledig gesinchroniseer, dan, as gevolg van die interne ontwerp van LVM thin, sal die integriteit van die momentopname gewaarborg word in die geval van kasverlies .

Kom ons skep 'n nuwe VG wat verantwoordelik sal wees vir dun-voorsiening:

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

Kom ons skep 'n swembad:

#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T images/thin-pool
Hoekom -Z yBenewens waarvoor hierdie modus eintlik bedoel is - om te verhoed dat data van een virtuele masjien na 'n ander virtuele masjien lek wanneer spasie herverdeel word - word nulstelling ook gebruik om die spoed van ewekansige skryfwerk in blokke kleiner as 64k te verhoog. Enige skryf van minder as 64k na 'n voorheen nie-toegekende area van die dun volume sal 64K randbelyn word in die kas. Dit sal toelaat dat die operasie geheel en al deur die kas uitgevoer word, en die kastoestel omseil.

Kom ons skuif die LV'e na die ooreenstemmende PV's:

#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

Kom ons kyk:

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

Kom ons skep 'n dun volume vir toetse:

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

Ons sal pakkette installeer vir toetse en monitering:

#apt-get install sysstat fio

Dit is hoe u die gedrag van ons bergingkonfigurasie intyds kan waarneem:

#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)'

Dit is hoe ons ons konfigurasie kan toets:

#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

Versigtig! Hulpbron!Hierdie kode sal 36 verskillende toetse laat loop, elkeen vir 4 sekondes. Die helfte van die skryftoetse. Jy kan baie in 4 sekondes op NVMe opneem. Tot 3 gigagrepe per sekonde. Dus, elke reeks skryftoetse kan tot 216 gigagrepe se SSD-hulpbron van jou af eet.

Lees en skryf gemeng?Ja. Dit maak sin om die lees- en skryftoetse afsonderlik uit te voer. Boonop is dit sinvol om te verseker dat alle kasgeheue gesinchroniseer word sodat 'n voorheen gemaak skryf nie die lees beïnvloed nie.

Die resultate sal baie verskil tydens die eerste bekendstelling en daaropvolgendes soos die kas en dun volume vol raak, en ook afhangende van of die stelsel daarin geslaag het om die kas wat tydens die laaste bekendstelling gevul is, te sinchroniseer.

Ek beveel onder andere aan om die spoed te meet op 'n reeds vol dun volume waaruit 'n momentopname pas geneem is. Die skrywer het die geleentheid gehad om waar te neem hoe ewekansige skryfstukke onmiddellik na die skep van die eerste momentopname skerp versnel, veral wanneer die kas nog nie heeltemal vol is nie. Dit gebeur as gevolg van kopieer-op-skryf skryf semantiek, belyning van kas en dun volume blokke, en die feit dat 'n ewekansige skryf na RAID 6 verander in 'n ewekansige lees vanaf RAID 6 gevolg deur 'n skryf na die kas. In ons konfigurasie is ewekansige lees van RAID 6 tot 6 keer (die aantal SATA SSD's in die skikking) vinniger as om te skryf. Omdat blokke vir CoW word opeenvolgend vanaf 'n dun poel toegewys, dan verander die opname, vir die grootste deel, ook in opeenvolgend.

Beide hierdie kenmerke kan met voordeel gebruik word.

Kas "koherente" kiekies

Om die risiko van dataverlies in geval van kasskade/verlies te verminder, stel die skrywer voor om die praktyk van roterende foto's in te voer om hul integriteit in hierdie geval te waarborg.

Eerstens, omdat dun volume metadata op 'n ongekas toestel woon, sal die metadata konsekwent wees en moontlike verliese sal binne datablokke geïsoleer word.

Die volgende kiekie-rotasiesiklus waarborg die integriteit van die data binne-in die kiekies in geval van kasverlies:

  1. Vir elke dun volume met die naam , skep 'n momentopname met die naam .cached
  2. Kom ons stel die migrasiedrempel op 'n redelike hoë waarde: #lvchange --quiet --cachesettings "migration_threshold=16384" cache/cachedata
  3. In die lus kyk ons ​​na die aantal vuil blokke in die kas: #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' totdat ons nul kry. As die nul te lank ontbreek, kan dit geskep word deur die kas tydelik na deurskryfmodus oor te skakel. Met inagneming van die spoedeienskappe van ons SATA- en NVMe SSD-skikkings, sowel as hul TBW-hulpbron, sal jy óf vinnig die oomblik kan vang sonder om die kasmodus te verander, óf jou hardeware sal sy hele hulpbron heeltemal opvreet in n paar dae. As gevolg van hulpbronbeperkings is die stelsel in beginsel nie in staat om heeltyd onder 100% skryflading te wees nie. Ons NVMe SSD's onder 100% skryflading sal die hulpbron heeltemal uitput 3-4 dae. SATA SSD's sal net twee keer so lank hou. Daarom sal ons aanvaar dat die meeste van die las na lees gaan, en ons het relatief korttermyn sarsies van uiters hoë aktiwiteit gekombineer met 'n lae las gemiddeld vir skryf.
  4. Sodra ons 'n nul gevang (of gemaak het), hernoem ons .cached na .committed. Die ou .committed is uitgevee.
  5. Opsioneel, as die kas 100% vol is, kan dit deur 'n skrip herskep word en dit dus skoon maak. Met 'n halfleë kas werk die stelsel baie vinniger wanneer jy skryf.
  6. Stel die migrasiedrempel na nul: #lvchange --quiet --cachesettings "migration_threshold=0" cache/cachedata Dit sal tydelik verhoed dat die kas met die hoofmedia sinchroniseer.
  7. Wag vir genoeg veranderinge om in die kas te versamel #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' of die timer sal afgaan.
  8. Ons herhaal weer.

Hoekom probleme met migrasie drempel ...?Die ding is dat in die werklike praktyk 'n "lukraak" opname eintlik nie heeltemal lukraak is nie. As ons iets geskryf het aan 'n sektor van 4 kilogrepe groot, is daar 'n groot waarskynlikheid dat in die volgende paar minute 'n rekord gemaak sal word na dieselfde of een van die naburige (+- 32K) sektore.

Deur die migrasiedrempel op nul te stel, stel ons skryfsinchronisasie op die SATA SSD uit en versamel verskeie veranderinge in een 64K-blok in die kas. Dit bespaar die hulpbron van SATA SSD aansienlik.

Waar is die kode..?Ongelukkig beskou die skrywer homself as onvoldoende bekwaam in die ontwikkeling van bash scripts, want hy is 100% selfonderrig en beoefen "google"-gedrewe ontwikkeling, daarom glo hy dat die verskriklike kode wat uit sy hande kom beter is om dit nie te wees nie. deur enigiemand anders gebruik word.

Ek dink dat professionele persone in hierdie veld in staat sal wees om al die logika wat hierbo beskryf word, onafhanklik uit te beeld, indien nodig, en miskien selfs pragtig te ontwerp as 'n stelseldiens, soos die skrywer probeer doen het.

So 'n eenvoudige momentopname-rotasieskema sal ons nie net toelaat om voortdurend een momentopname ten volle op die SATA SSD te laat sinchroniseer nie, maar sal ons ook in staat stel om, met behulp van die thin_delta-nutsding, uit te vind watter blokke na die skepping daarvan verander is, en sodoende skade te lokaliseer op die hoofvolumes, wat herstel aansienlik vereenvoudig.

TRIM/VERWEER in libvirt/KVM

Omdat die databerging sal gebruik word vir KVM wat libvirt laat loop, dan sal dit 'n goeie idee wees om ons VM's nie net te leer om vrye spasie op te neem nie, maar ook om dit wat nie meer nodig is nie, vry te maak.

Dit word gedoen deur TRIM/DISCARD-ondersteuning op virtuele skywe na te boots. Om dit te doen, moet jy die beheerdertipe verander na virtio-scsi en die xml wysig.

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

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

Sulke DISCARDs van gas OS's word korrek deur LVM verwerk, en blokke word korrek vrygestel in beide die kas en in die dun poel. In ons geval gebeur dit hoofsaaklik op 'n vertraagde manier wanneer die volgende foto uitvee.

BTRFS-rugsteun

Gebruik klaargemaakte skrifte met uiterste versigtigheid en op eie risiko. Die skrywer het hierdie kode self en uitsluitlik vir homself geskryf. Ek is seker dat baie ervare Linux-gebruikers soortgelyke gereedskap het, en dit is nie nodig om iemand anders s'n te kopieer nie.

Kom ons skep 'n volume op die rugsteuntoestel:

#lvcreate -L 256G --name backup backup

Kom ons formateer dit in BTRFS:

#mkfs.btrfs /dev/backup/backup

Kom ons skep bergpunte en monteer die wortelonderafdelings van die lêerstelsel:

#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

Skep gidse vir rugsteun:

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

Kom ons skep 'n gids vir rugsteunskrifte:

#mkdir /root/btrfs-backup

Kom ons kopieer die skrif:

Baie eng bash-kode. Gebruik op eie risiko. Moenie kwaai briewe aan die skrywer skryf nie...#cat >/root/btrfs-backup/btrfs-backup.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

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

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

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

function wait_lock()
{
flock 98
}

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

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

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

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

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

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

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

}

(
COMMAND="$1"
shift

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

EOF

Wat doen dit selfs..?Bevat 'n stel eenvoudige opdragte om BTRFS-kiekies te skep en dit na 'n ander FS te kopieer met behulp van BTRFS-stuur/ontvang.

Die eerste bekendstelling kan relatief lank wees, want... Aan die begin sal alle data gekopieer word. Verdere bekendstellings sal baie vinnig wees, want... Slegs veranderinge sal gekopieer word.

Nog 'n skrif wat ons in cron sal plaas:

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

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

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

Wat doen dit..?Skep en sinchroniseer inkrementele foto's van die gelyste BTRFS-volumes op die rugsteun-FS. Hierna vee dit alle prente uit wat 60 dae gelede geskep is. Na bekendstelling sal gedateerde foto's van die gelyste volumes in die /backup/btrfs/back/remote/ subgidse verskyn.

Kom ons gee die kode uitvoering regte:

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

Kom ons kyk na dit en plaas dit in die cron:

#/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

Rugsteun LVM dun

Kom ons skep 'n dun poel op die rugsteuntoestel:

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

Kom ons installeer ddrescue, want... skrifte sal hierdie hulpmiddel gebruik:

#apt-get install gddrescue

Kom ons skep 'n gids vir skrifte:

#mkdir /root/lvm-thin-backup

Kom ons kopieer die skrifte:

Baie bash binne...#cat >/root/lvm-thin-backup/lvm-thin-backup.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

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

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

export LVM_SUPPRESS_FD_WARNINGS=1

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

function wait_lock()
{
flock 98
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

dmsetup message $DIFF_POOL_PATH_TPOOL 0 release_metadata_snap

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

}

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

activate_volume $SYNC_VG $SYNC_PEND

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

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

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

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

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

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

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

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

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

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

echo Syncronizing "$SOURCE_BASE_LV_PATH" to "$TARGET_BASE_LV_PATH"

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

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

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

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

}

(
COMMAND="$1"
shift

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

EOF

Wat doen dit...?Bevat 'n stel opdragte om dun foto's te manipuleer en die verskil tussen twee dun foto's wat via thin_delta ontvang is, te sinchroniseer na 'n ander bloktoestel deur ddrescue en blkdiscard te gebruik.

Nog 'n skrif wat ons in cron sal plaas:

'n Bietjie meer bash#cat >/root/lvm-thin-backup/cron-daily.sh << EOF
#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

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

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

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

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

EOF

Wat doen dit...?Gebruik die vorige skrif om rugsteune van die gelyste dun volumes te skep en te sinchroniseer. Die skrip sal onaktiewe foto's van die gelyste volumes laat, wat nodig is om veranderinge sedert die laaste sinchronisasie op te spoor.

Hierdie skrif moet geredigeer word, wat die lys dun volumes spesifiseer waarvoor rugsteunkopieë gemaak moet word. Die name gegee is slegs vir illustrasie doeleindes. As jy wil, kan jy 'n skrif skryf wat alle volumes sal sinchroniseer.

Kom ons gee die regte:

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

Kom ons kyk na dit en plaas dit in die cron:

#/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

Die eerste bekendstelling sal lank wees, want... dun volumes sal ten volle gesinchroniseer word deur alle gebruikte spasie te kopieer. Danksy LVM dun metadata weet ons watter blokke werklik in gebruik is, dus sal slegs werklik gebruikte dun volume blokke gekopieer word.

Daaropvolgende lopies sal die data inkrementeel kopieer danksy veranderingsnasporing via LVM dun metadata.

Kom ons kyk wat gebeur het:

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

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

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

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

Wat het dit met nesende poppe te doen?

Heel waarskynlik, gegewe dat LVM LV logiese volumes LVM PV fisiese volumes vir ander VG's kan wees. LVM kan rekursief wees, soos nesende poppe. Dit gee LVM uiterste buigsaamheid.

PS

In die volgende artikel sal ons probeer om verskeie soortgelyke mobiele bergingstelsels/KVM te gebruik as die basis vir die skep van 'n geo-verspreide berging/vm-groepering met oortolligheid op verskeie kontinente deur tuisrekenaars, die tuisinternet en P2P-netwerke te gebruik.

Bron: will.com

Voeg 'n opmerking