Zer dute komunean LVM eta Matryoshkak?

Egun on.
Komunitatearekin partekatu nahiko nuke nire esperientzia praktikoa KVMrako datuak biltegiratzeko sistema eraikitzeko md RAID + LVM erabiliz.

Programak honako hauek izango ditu:

  • Md RAID 1 eraikitzea NVMe SSD-tik.
  • SATA SSD eta unitate arruntetatik md RAID 6 muntatzea.
  • SSD RAID 1/6-n TRIM/DESBARTU eragiketaren ezaugarriak.
  • Md RAID 1/6 array abiagarri bat sortzea disko multzo komun batean.
  • Sistema NVMe RAID 1ean instalatzea BIOSan NVMe laguntzarik ez dagoenean.
  • LVM cachea eta LVM thin erabiliz.
  • BTRFS argazkiak erabiliz eta babeskopia egiteko bidali/jaso.
  • BTRFS estiloko babeskopietarako LVM thin snapshots eta thin_delta erabiliz.

Interesa baduzu, ikusi cat.

Statement

Egileak ez du bere gain hartzen artikulu honetako materialak/adibideak/kodeak/aholkuak/datuak erabiltzeak edo ez erabiltzeak dakartzan ondorioengatik. Material hau edozein modutan irakurriz edo erabiliz gero, ekintza horien ondorio guztien erantzukizuna hartzen duzu. Ondorio posibleak honako hauek dira:

  • Frijitutako NVMe SSDak.
  • Erabat erabilita grabatzeko baliabidea eta SSD unitateen hutsegitea.
  • Unitate guztietako datu guztiak galtzea, babeskopiak barne.
  • Ordenagailuaren hardware akastuna.
  • Denbora, nerbioak eta dirua galdu.
  • Goian zerrendatzen ez den beste edozein ondorio.

burdin

Hauek ziren eskuragarri:

2013 inguruko plaka nagusia Z87 chipsetarekin, Intel Core i7 / Haswell-ekin osatua.

  • Prozesadorea 4 nukleo, 8 hari
  • 32 GB DDR3 RAM
  • 1 x 16 edo 2 x 8 PCIe 3.0
  • 1 x 4 + 1 x 1 PCIe 2.0
  • 6 x 6 GBps SATA 3 konektoreak

SAS egokitzailea LSI SAS9211-8I IT / HBA modura piztu da. RAID gaitutako firmwarea nahita ordeztu da HBA firmwarearekin:

  1. Egokigailu hau edozein unetan bota dezakezu eta aurkitu duzun beste batekin ordezkatu.
  2. TRIM/Discard-ek normalean funtzionatu zuen diskoetan, zeren... RAID firmwarean komando hauek ez dira batere onartzen, eta HBAk, oro har, ez du axola zer komandoak transmititzen diren autobusean.

Disko gogorrak - HGST Travelstar 8K7-ren 1000 pieza 1 TB-ko edukiera dutenak 2.5 forma-faktorean, ordenagailu eramangarrietan bezala. Unitate hauek RAID 6 array batean zeuden aurretik. Sistema berrian ere erabilera izango dute. Tokiko babeskopiak gordetzeko.

Gainera, gehitu:

6 pieza SATA SSD modelo Samsung 860 QVO 2TB. SSD hauek bolumen handia behar zuten, SLC cache baten presentzia, fidagarritasuna eta prezio baxua nahi ziren. Baztertu/zerorako laguntza behar zen, dmesg-en lerroak egiaztatzen duena:

kernel: ata1.00: Enabling discard_zeroes_data

NVMe SSD ereduko 2 pieza Samsung SSD 970 EVO 500GB.

SSD hauetarako, ausazko irakurketa/idazketa abiadura eta zure beharretarako baliabideen gaitasuna garrantzitsuak dira. Erradiadorea haientzat. Derrigorrez. Erabat. Bestela, frijitu kurruskariak izan arte lehen RAID sinkronizazioan.

StarTech PEX8M2E2 2 x NVMe SSDrako egokitzailea PCIe 3.0 8x zirrikituan instalatuta. Hau, berriro ere, HBA bat besterik ez da, baina NVMerentzat. Egokigailu merkeetatik desberdina da, ez duelako PCIe bifurkazio euskarria behar plakatik PCIe etengailu integratua dagoelako. PCIe-rekin sistema zaharrenean ere funtzionatuko du, x1 PCIe 1.0 zirrikitua bada ere. Noski, dagokion abiaduran. Bertan ez dago RAIDrik. Ez dago BIOS integraturik taula gainean. Beraz, zure sistemak ez du magikoki ikasiko NVMe-rekin abiarazten, are gutxiago NVMe RAID-a gailu honi esker.

Osagai hau sisteman doako 8x PCIe 3.0 bakarra egoteagatik izan zen eta, doako 2 zirrikitu badaude, erraz ordezkatu daiteke bi zentimo PEX4M2E1 edo analogoekin, edonon eros daitezkeenak 600 prezioan. errubloak.

Hardware mota guztiak edo integratutako chipset/BIOS RAIDak nahita egin ziren, sistema osoa guztiz ordezkatu ahal izateko, SSD/HDD beraiek izan ezik, datu guztiak gordez. Egokiena, instalatutako sistema eragilea ere gorde dezakezu hardware guztiz berri/desberdin batera mugitzean. Gauza nagusia SATA eta PCIe portuak daudela da. Zuzeneko CD edo abiarazteko flash drive bat bezalakoa da, oso azkarra eta apur bat handia.

UmoreaBestela, badakizu zer gertatzen den; batzuetan presaz eraman behar duzu array osoa eraman ahal izateko. Baina ez dut daturik galdu nahi. Horretarako, aipatutako euskarri guztiak kaxa estandarraren 5.25 baoetan dauden diapositibetan kokatuta daude.

Beno, eta, noski, Linux-en SSD katxeatzeko metodo desberdinak esperimentatzeko.

Hardware erasoak aspergarriak dira. Piztu. Edo funtzionatzen du edo ez. Eta mdadm-ekin beti daude aukerak.

Soft

Aurretik, Debian 8 Jessie instalatu zen hardwarean, hau da, EOLtik gertu dagoena. RAID 6 LVMrekin parekatuta aipatutako HDDetatik muntatu zen. Kvm/libvirt-en makina birtualak exekutatzen zituen.

Zeren Egileak esperientzia egokia du SATA/NVMe disko eramangarriak abiarazteko diskoak sortzen eta, gainera, ohiko txantiloi egokia ez apurtzeko, Ubuntu 18.04 aukeratu zen helburu-sistema gisa, dagoeneko nahiko egonkortuta dagoena, baina oraindik 3 urte dituena. laguntza etorkizunean.

Aipatutako sistemak kutxatik kanpo behar ditugun hardware kontrolatzaile guztiak ditu. Ez dugu hirugarrenen softwarerik edo kontrolatzailerik behar.

Instalatzeko prestatzen

Sistema instalatzeko Ubuntu Mahaigaineko Irudia behar dugu. Zerbitzari-sistemak nolabaiteko instalatzaile indartsua du, eta horrek UEFI sistemaren partizioa diskoetako batean sartuz desgaitu ezin den gehiegizko independentzia erakusten du, edertasun guztia hondatuz. Horren arabera, UEFI moduan bakarrik instalatzen da. Ez du aukerarik eskaintzen.

Ez gaude honekin pozik.

Zergatik?Zoritxarrez, UEFI abiarazte oso gaizki bateragarria da abioko software RAIDarekin, zeren... Inork ez digu UEFI ESP partizioaren erreserbarik eskaintzen. Sarean daude ESP partizioa USB ataka batean flash drive batean jartzea proposatzen duten errezetak, baina hau hutsegite puntu bat da. Badira 1 metadatuen bertsioa duen mdadm RAID 0.9 softwarea erabiltzen duten errezetak UEFI BIOSak partizio hau ikustea eragozten ez dutenak, baina hau bizi da BIOSak edo beste hardware sistema batek ESP-ra zerbait idazten duen eta beste batzuekin sinkronizatzea ahazten duen momentu zoriontsua arte. ispiluak.

Horrez gain, UEFI abiarazte NVRAM-en araberakoa da, ez baita diskoekin batera mugituko sistema berrira, izan ere. plakaren parte da.

Beraz, ez dugu gurpil berri bat berrasmatuko. Dagoeneko prest daukagu, denboran probatutako aitonaren bizikleta, orain Legacy/BIOS boot izenekoa, UEFIrekin bateragarriak diren sistemetan CSM izen harroa duena. Apalategitik kendu, koipeztatu, pneumatikoak ponpatu eta zapi heze batekin garbituko ditugu.

Ubunturen mahaigaineko bertsioa ere ezin da behar bezala instalatu Legacy bootloader-arekin, baina hemen, esaten den bezala, aukerak badaude behintzat.

Eta, beraz, hardwarea bildu eta sistema Ubuntu Live abiarazte-unitatetik kargatzen dugu. Paketeak deskargatu beharko ditugu, beraz, zuretzat lan egiten duen sarea konfiguratuko dugu. Ez badu funtzionatzen, beharrezkoak diren paketeak aldez aurretik karga ditzakezu flash drive batean.

Mahaigaineko ingurunera sartuko gara, terminal-emuladorea abiarazi eta abiatzen gara:

#sudo bash

Nola…?Goiko lerroa sudoari buruzko holiwars-en abiarazle kanonikoa da. C bΠΎaukera handiagoak datoz etaΠΎerantzukizun handiagoa. Kontua da ea zure gain hartu dezakezun. Jende askok uste du sudoa horrela erabiltzea ez dela kontuz, behintzat. Hala ere:

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

Zergatik ez ZFS...?Gure ordenagailuan softwarea instalatzen dugunean, funtsean, gure hardwarea ematen diegu software honen garatzaileei gidatzeko.
Software honi gure datuen segurtasuna fidatzen dugunean, datu horiek berreskuratzearen kostuaren adinako mailegu bat egiten dugu, noizbait ordaindu beharko duguna.

Ikuspegi honetatik, ZFS Ferrari bat da, eta mdadm+lvm bizikleta baten antzekoa da.

Subjektiboki, egileak nahiago du bizikleta bat kreditu bat maileguan utzi ezezagunei Ferrari bati beharrean. Bertan, gaiaren prezioa ez da altua. Ez dago eskubiderik behar. Trafiko arauak baino sinpleagoa. Aparkalekua doakoa da. Cross-country gaitasuna hobea da. Bizikleta bati hankak lotu ditzakezu beti, eta zure eskuekin konpon dezakezu bizikleta.

Zergatik orduan BTRFS...?Sistema eragilea abiarazteko, Legacy/BIOS GRUB-en onartzen den fitxategi-sistema bat behar dugu, eta, aldi berean, zuzeneko argazkiak onartzen dituena. /boot partiziorako erabiliko dugu. Horrez gain, egileak nahiago du FS hau / (root) erabili, beste edozein softwaretarako LVM-n partizio bereiziak sor ditzakezula eta beharrezko direktorioetan muntatu ditzakezula kontuan izan gabe.

Ez dugu makina birtualen edo datu-baseen irudirik gordeko FS honetan.
FS hau itzali gabe sistemaren argazkiak sortzeko soilik erabiliko da eta, ondoren, argazki horiek kopia-disko batera transferitzeko bidali/jasotzen erabiliz.

Horrez gain, egileak orokorrean nahiago du software gutxieneko hardwarean zuzenean gorde eta beste software guztia makina birtualetan exekutatu, GPUak eta PCI-USB Host kontrolagailuak KVM-ra IOMMU bidez birbidaltzea bezalako gauzak erabiliz.

Hardwarean geratzen diren gauza bakarrak datuak biltegiratzea, birtualizazioa eta babeskopia dira.

ZFS gehiago fidatzen bazara, orduan, printzipioz, zehaztutako aplikaziorako trukagarriak dira.

Hala ere, egileak nahita alde batera uzten ditu ZFS, BRTFS eta LVM-k dituzten ispilu/RAID eta erredundantzia-funtzioak.

Argumentu gehigarri gisa, BTRFS-k ausazko idazketak sekuentzialetan bihurtzeko gaitasuna du, eta horrek oso eragin positiboa du HDDko argazki/backups sinkronizatzeko abiaduran.

Berriro eskaneatu ditzagun gailu guztiak:

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

Ikus dezagun ingurura:

#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

Diskoaren diseinua

NVMe SSD

Baina ez ditugu inola ere markatuko. Dena den, gure BIOS-ak ez ditu unitate hauek ikusten. Beraz, RAID softwarera joango dira erabat. Bertan ez ditugu atalak ere sortuko. "Canon" edo "nagusiki" jarraitu nahi baduzu, sortu partizio handi bat, HDD bat bezala.

SATA HDD

Hemen ez dago ezer berezirik asmatu beharrik. Denetarako atal bat sortuko dugu. Partizio bat sortuko dugu, BIOSak disko hauek ikusten dituelako eta haietatik abiarazten saia daitekeelako. Geroago ere instalatuko dugu GRUB disko hauetan, sistemak bat-batean hori egin dezan.

#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

Hemen gauzak interesgarriak egiten zaizkigu.

Lehenik eta behin, gure diskoek 2 TB-ko tamaina dute. Hau MBRrako tarte onargarriaren barruan dago, hau da, erabiliko duguna. Beharrezkoa izanez gero, GPT-rekin ordezka daiteke. GPT diskoek bateragarritasun-geruza bat dute, MBR-rekin bateragarriak diren sistemei lehen 4 partizioak ikusteko aukera ematen diena, lehenengo 2 terabyteetan kokatzen badira. Garrantzitsua da disko hauetako abio-partizioa eta bios_grub partizioa hasieran egon behar dutela. Horrek GPT Legacy/BIOS unitateetatik abiarazteko aukera ematen du.

Baina hau ez da gure kasua.

Hemen bi atal sortuko ditugu. Lehenengoak 1 GB-ko tamaina izango du eta RAID 1 /boot-erako erabiliko da.

Bigarrena RAID 6rako erabiliko da eta geratzen den espazio libre guztia hartuko du diskoaren amaieran esleitu gabeko eremu txiki bat izan ezik.

Zein da markarik gabeko eremu hori?Sareko iturrien arabera, gure SATA SSDek 6 eta 78 gigabyte arteko tamainako SLC cache dinamikoki hedagarria dute. 6 gigabyte lortzen ditugu "doan" unitatearen datu-orrian "gigabyte" eta "gibibyte" arteko ezberdintasuna dela eta. Gainerako 72 gigabyte erabili gabeko espaziotik esleitzen dira.

Hemen kontuan izan behar da SLC cache bat dugula, eta espazioa 4 biteko MLC moduan okupatuta dagoela. Horrek esan nahi du guretzat 4 gigabyte libreko espazio bakoitzeko gigabyte 1 SLC cache baino ez dugula lortuko.

Biderkatu 72 gigabyte 4z eta lortu 288 gigabyte. Hau da markatuko ez dugun espazio librea, unitateek SLC cachea guztiz erabiltzeko aukera izan dezaten.

Horrela, 312 gigabyte SLC cache lortuko ditugu guztira sei unitateetatik. Unitate guztietatik, 2 RAIDen erabiliko dira erredundantziarako.

Cache-kopuru honek bizitza errealean oso gutxitan topatzea ahalbidetuko digu idazketa bat cachera joaten ez den egoera batekin. Horrek oso ondo konpentsatzen du QLC memoriaren eragozpen tristeena - idazketa-abiadura oso baxua datuak cachea saihestuz idazten direnean. Zure kargak honekin bat ez badatoz, gomendatzen dizut zure SSD-ak zenbat denbora iraungo duen horrelako kargapean pentsatzea, datu-orriko TBW kontuan hartuta.

#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

Array sortzea

Lehenik eta behin, makinari izena aldatu behar diogu. Hau beharrezkoa da ostalariaren izena mdadm barruan dagoen array izenaren parte delako eta zerbaiti eragiten diolako nonbait. Noski, matrizeak geroago izena alda daiteke, baina hau alferrikako urratsa da.

#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

Zergatik -asumitu-garbitu...?Arrayak hasieratzea ekiditeko. RAID 1 eta 6 mailetarako balio du. Dena hasieratu gabe funtziona dezake matrize berria bada. Gainera, SSD matrizea sortzean hasieratzea TBW baliabidea xahutzea da. Ahal den neurrian, TRIM/DISCARD erabiltzen dugu muntatutako SSD matrizeetan horiek "hasiarazteko".

SSD matrizeetarako, RAID 1 DISCARD kutxatik kanpo onartzen da.

SSD RAID 6 DISCARD arrayetarako, nukleoaren moduluaren parametroetan gaitu behar duzu.

Hau egin beharko litzateke sistema honetako 4/5/6 mailan erabiltzen diren SSD guztiek discard_zeroes_data-rako euskarria badute. Batzuetan, kernelari funtzio hori onartzen dela esaten dioten unitate arraroekin topo egiten duzu, baina egia esan ez dago hor, edo funtzioak ez du beti funtzionatzen. Momentuz, laguntza ia edonon dago eskuragarri, hala ere, akatsak dituzten disko eta firmware zaharrak daude. Hori dela eta, DISCARD laguntza desgaituta dago lehenespenez RAID 6rako.

Kontuz, hurrengo komandoak NVMe unitateetako datu guztiak suntsitu egingo ditu array-a "zeroekin" hasieratuz.

#blkdiscard /dev/md0

Zerbait gaizki ateratzen bada, saiatu urrats bat zehazten.

#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

Zergatik hain handia...?Zati-tamaina handitzeak eragin positiboa du ausazko irakurketaren abiaduran blokeetan zati-tamaina barne. Hau gertatzen da tamaina egokia edo txikiagoa den eragiketa bat gailu bakarrean erabat burutu daitekeelako. Hori dela eta, gailu guztietako IOPSak laburbiltzen dira. Estatistiken arabera, IOaren% 99ak ez du 512K gainditzen.

RAID 6 IOPS idazketa bakoitzeko beti unitate baten IOPS baino txikiagoa edo berdina. Noiz, ausazko irakurketa gisa, IOPS disko batena baino hainbat aldiz handiagoa izan daiteke, eta hemen blokearen tamaina funtsezkoa da.
Egileak ez du zentzurik ikusten RAID 6 diseinuaren arabera txarra den parametro bat optimizatzen saiatzeari eta, horren ordez, RAID 6rako ona den optimizatzen du.
RAID 6ren ausazko idazketa eskasa konpentsatuko dugu NVMe cache batekin eta hornikuntza meheko trikimailuekin.

Oraindik ez dugu DISCARD gaituta RAID 6rako. Beraz, oraingoz ez dugu array hau "hasiaraziko". Hau geroago egingo dugu, OS instalatu ondoren.

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-en

Abiadurarako, erro fitxategi-sistema jarri nahi dugu NVMe RAID 1-en, hau da, /dev/md0.
Hala ere, array azkar hau beste behar batzuetarako beharko dugu oraindik, hala nola trukatzeko, metadatuak eta LVM-cache eta LVM-thin metadatuak, beraz, LVM VG bat sortuko dugu matrize honetan.

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

Sortu dezagun partizio bat erro fitxategi sistemarako.

#lvcreate -L 128G --name root root

Sor dezagun partizio bat trukatzeko RAMaren tamainaren arabera.

#lvcreate -L 32G --name swap root

OS instalazioa

Guztira, sistema instalatzeko beharrezko guztia daukagu.

Abiarazi sistemaren instalazioaren morroia Ubuntu Live ingurunetik. Instalazio arrunta. Instalatzeko diskoak hautatzeko fasean bakarrik, honako hau zehaztu behar duzu:

  • /dev/md1, - muntatze-puntua /boot, FS - BTRFS
  • /dev/root/root (aka /dev/mapper/root-root), - muntatze-puntua / (root), FS - BTRFS
  • /dev/root/swap (aka /dev/mapper/root-swap), - erabili trukatzeko partizio gisa
  • Instalatu abio-kargatzailea /dev/sda-n

Erroko fitxategi-sistema gisa BTRFS hautatzen duzunean, instalatzaileak automatikoki sortuko ditu "@" / (erroa) eta "@home" / home izeneko bi BTRFS bolumen.

Hasi gaitezen instalazioa...

Instalazioa abio-kargatzailea instalatzean errore bat adieraziko duen elkarrizketa-koadro modal batekin amaituko da. Zoritxarrez, ezin izango duzu elkarrizketa-koadro honetatik irten bitarteko estandarrak erabiliz eta instalazioarekin jarraitu. Sistematik irten eta berriro saioa hasten dugu, Ubuntu Live mahaigain garbi batean amaituz. Ireki terminala eta berriro:

#sudo bash

Sortu chroot ingurune bat instalazioarekin jarraitzeko:

#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

Konfigura ditzagun sarea eta ostalari izena chroot-en:

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

Goazen chroot ingurunera:

#chroot /mnt/chroot

Lehenik eta behin, paketeak entregatuko ditugu:

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

Egiazta ditzagun eta konpon ditzagun sistemaren instalazio osatu gabe zegoelako gaizki instalatuta zeuden pakete guztiak:

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

Zerbait konpontzen ez bada, baliteke lehenik /etc/apt/sources.list editatu behar izatea

Doitu ditzagun RAID 6 moduluaren parametroak MOZTU/EZERTATU gaitzeko:

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

Doitu ditzagun gure arrayak pixka bat:

#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

Zer zen..?Honako hau egingo duen udev arau multzo bat sortu dugu:

  • Ezarri RAID 2020rako blokeen cachearen tamaina 6rako egokia izan dadin. Balio lehenetsia, dirudienez, ez da aldatu Linux sortu zenetik, eta ez da egokia izan denbora luzez.
  • Erreserbatu IO gutxieneko array egiaztapenak/sinkronizazioek irauten duten bitartean. Hau zure matrizeak kargapean betiko sinkronizazio egoeran trabatu ez daitezen da.
  • Mugatu gehienezko IO-a matrizeen egiaztapen/sinkronizazioan. Hau beharrezkoa da SSD RAID-ak sinkronizatzeak/egiaztatzeak zure diskoak birrindu ez ditzan. Hau bereziki egia da NVMe-rentzat. (Gogoratzen al zara erradiadoreaz? Ez nintzen txantxetan ari.)
  • Debekatu diskoei ardatzaren biraketa (HDD) geldiaraztea APM bidez eta ezarri disko-kontrolagailuen lo-denbora 7 ordutan. APM guztiz desgai dezakezu zure diskoek egin dezaketen baldin badago (-B 255). Balio lehenetsiarekin, unitateak bost segundoren buruan geldituko dira. Ondoren, sistema eragileak disko-cachea berrezarri nahi du, diskoak berriro piztuko dira eta dena berriro hasiko da. Diskoek ardatzaren biraketa kopuru mugatua dute. Horrelako ziklo lehenetsi sinple batek zure diskoak erraz hil ditzake urte pare batean. Disko guztiek ez dute hori jasaten, baina gureak β€œordenagailu eramangarriak” dira, lehenetsitako ezarpen egokiekin, RAID-a mini-MAID baten itxura ematen dutenak.
  • Instalatu readhead diskoetan (biratzen) 1 megabyte - bi bloke/zati jarraian RAID 6
  • Desgaitu readhead arrayetan bertan.

Editatu dezagun /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

Zergatik da hori..?/boot partizioa UUID bidez bilatuko dugu. Array izenak teorikoki alda daitezke.

Gainerako atalak LVM izenen arabera bilatuko ditugu /dev/mapper/vg-lv idazkeran, zeren eta partizioak nahiko modu berezian identifikatzen dituzte.

Ez dugu UUID erabiltzen LVMrako LVM bolumenen UUID eta haien argazkiak berdinak izan daitezke.Muntatu /dev/mapper/root-root.. bi aldiz?Bai. Zehazki. BTRFS-ren ezaugarria. Fitxategi-sistema hau hainbat aldiz munta daiteke subbols ezberdinekin.

Ezaugarri hori bera dela eta, BTRFS bolumen aktiboen LVM argazkirik ez sortzea gomendatzen dut. Baliteke sorpresa bat jasotzea berrabiarazten duzunean.

Birsor dezagun mdadm konfigurazioa:

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

Doitu ditzagun LVM ezarpenak:

#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

Zer zen..?LVM igerileku meheen hedapen automatikoa gaitu dugu okupatutako espazioaren % 90era bolumenaren % 5era iristean.

LVM cacherako cache blokeen gehienezko kopurua handitu dugu.

LVM-k LVM bolumenak (PV) bilatzea eragotzi dugu:

  • LVM cachea (cdata) duten gailuak
  • LVM cachea erabiliz gordetako gailuak, cachea saihestuz ( _korig). Kasu honetan, cachean gordetako gailua bera cachetik eskaneatu egingo da (besterik gabe ).
  • LVM cache metadatuak (cmeta) dituzten gailuak
  • VGko gailu guztiak izen-irudiekin. Hemen makina birtualen disko-irudiak izango ditugu, eta ez dugu nahi ostalariaren LVM-k OS gonbidatuari dagozkion bolumenak aktibatzea.
  • VGko gailu guztiak babeskopia izenarekin. Hemen makina birtualen irudien babeskopiak izango ditugu.
  • izena "gpv"-rekin amaitzen duten gailu guztiak (gonbidapenaren bolumen fisikoa)

DISCARD euskarria gaitu dugu LVM VG-n doako espazioa askatzean. Kontuz ibili. Honek SSDko LVak ezabatzeak denbora asko hartuko du. Hau bereziki SSD RAID 6-ri dagokio. Hala ere, planaren arabera, hornikuntza mehea erabiliko dugu, beraz, honek ez gaitu batere oztoporik izango.

Eguneratu dezagun initramfs irudia:

#update-initramfs -u -k all

Instalatu eta konfiguratu grub:

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

Zein disko aukeratu behar dituzu?sd* diren guztiak. Sistemak funtzionatzen duen edozein SATA unitatetik edo SSDtik abiarazteko gai izan behar du.

Zergatik gehitu dute os-prober..?Gehiegizko independentziarako eta esku jostalariengatik.

Ez du behar bezala funtzionatzen RAIDetako bat egoera degradatuan badago. Hardware honetan exekutatzen diren makina birtualetan erabiltzen diren partizioetan OS bilatzen saiatzen da.

Behar izanez gero, utzi dezakezu, baina kontuan izan aurreko guztia. Sarean esku bihurriak kentzeko errezetak bilatzea gomendatzen dut.

Honekin hasierako instalazioa amaitu dugu. Instalatutako sistema eragile berrian berrabiarazteko garaia da. Ez ahaztu abiarazteko Live CD/USB kentzea.

#exit
#reboot

Hautatu SATA SSDren bat abiarazteko gailu gisa.

LVM SATA SSD-n

Une honetan, dagoeneko sistema eragile berrian abiarazi dugu, sarea konfiguratu dugu, egokitu dugu, terminal emuladorea ireki eta exekutatu dugu:

#sudo bash

Jarrai dezagun.

"Hasi" matrizea SATA SSDtik:

#blkdiscard /dev/md2

Ez badu funtzionatzen, saiatu:

#blkdiscard --step 65536 /dev/md2
Sortu LVM VG SATA SSD-n:

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

Zergatik beste VG..?Izan ere, dagoeneko badugu root izeneko VG bat. Zergatik ez gehitu dena VG batean?

VG batean hainbat PV badaude, orduan VG behar bezala aktibatzeko, PV guztiak egon behar dira (online). Salbuespena LVM RAID da, nahita erabiltzen ez duguna.

Benetan nahi dugu RAID 6 arrayren batean hutsegite bat gertatzen bada (irakurtzeko datu-galera), sistema eragilea normal abiaraziko duela eta arazoa konpontzeko aukera emango digu.

Horretarako, abstrakzio lehen mailan β€œeuskarri” fisiko mota bakoitza VG bereizi batean isolatuko dugu.

Zientifikoki hitz eginez, RAID array desberdinak "fidagarritasun-domeinu" desberdinetakoak dira. Ez zenuke haientzako hutsegite puntu komun gehigarririk sortu behar VG batean sartuz.

LVM "hardware" mailan egoteak RAID array ezberdinetako piezak modu arbitrarioan moztu ahal izango ditugu, modu ezberdinetan konbinatuz. Adibidez - korrika aldi berean, bcache + LVM thin, bcache + BTRFS, LVM cache + LVM thin, ZFS konfigurazio konplexua cacheekin, edo dena konparatzen saiatzeko beste edozein nahasketa infernukoa.

"Hardware" mailan, ez dugu LVM bolumen zahar "lodi" onak ez diren beste ezer erabiliko. Arau honen salbuespena babeskopia-partizioa izan daiteke.

Uste dut momentu honetan irakurle asko hasi zirela habia-panpinari buruzko zerbait susmatzen.

LVM SATA HDD-n

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

VG berria berriro..?Benetan nahi dugu datuen babeskopia egiteko erabiliko dugun disko-matrizeak huts egiten badu, gure sistema eragileak normaltasunez funtzionatzen jarraituko duela, babeskopia ez diren datuetarako sarbidea ohi bezala mantenduz. Horregatik, VG aktibatzeko arazoak ekiditeko, VG bereizi bat sortzen dugu.

LVM cachea konfiguratzen

Sortu dezagun LV bat NVMe RAID 1-en cache gailu gisa erabiltzeko.

#lvcreate -L 70871154688B --name cache root

Zergatik dago hain gutxi...?Kontua da gure NVMe SSDek SLC cache bat ere badutela. 4 gigabyte "libre" eta 18 gigabyte dinamikoa, 3 biteko MLCan okupatutako espazio libreagatik. Cache hau agortuta dagoenean, NVMe SSDak ez dira gure SATA SSDak cachearekin baino askoz azkarragoak izango. Egia esan, horregatik, ez du zentzurik guretzat LVM cache partizioa NVMe diskoaren SLC cachearen tamainaren bikoitza baino askoz handiagoa izatea. Erabilitako NVMe unitateetarako, egileak arrazoizkotzat jotzen du 32-64 gigabyte cache egitea.

Emandako partizioaren tamaina behar da 64 gigabyte cache, cache metadatuak eta metadatuen babeskopia antolatzeko.

Gainera, ohartzen naiz sistema zikin bat itzali ondoren, LVM-k cache osoa zikin gisa markatuko duela eta berriro sinkronizatuko dela. Gainera, gailu honetan lvchange erabiltzen den bakoitzean errepikatuko da sistema berriro berrabiarazi arte. Horregatik, cachea berehala birsortzea gomendatzen dut script egokia erabiliz.

Sortu dezagun LV bat SATA RAID 6-n, cacheko gailu gisa erabiltzeko.

#lvcreate -L 3298543271936B --name cache data

Zergatik hiru terabyte bakarrik..?Beraz, beharrezkoa izanez gero, SATA SSD RAID 6 erabil dezakezu beste behar batzuetarako. Cacheko espazioaren tamaina dinamikoki handitu daiteke, hegalean, sistema gelditu gabe. Horretarako, cachea aldi baterako gelditu eta berriro gaitu behar duzu, baina LVM-cache-ren abantaila bereizgarria, adibidez, bcache-ren aldean, hau hegan egin daitekeela da.

Sortu dezagun VG berri bat cachean gordetzeko.

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

Sortu dezagun LV bat cacheko gailuan.

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

Hemen berehala hartu genuen /dev/data/cache-ko espazio libre guztia, beharrezkoak diren beste partizio guztiak berehala sortu ziren /dev/root/cache-n. Leku okerrean zerbait sortu baduzu, mugitu dezakezu pvmove erabiliz.

Sortu eta gaitu dezagun cachea:

#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

Zergatik halako tamaina ..?Esperimentu praktikoen bidez, egileak emaitzarik onena lortzen dela jakin ahal izan zuen LVM cache blokearen tamaina LVM bloke mehearen tamainarekin bat badator. Gainera, zenbat eta tamaina txikiagoa izan, orduan eta hobeto funtzionatzen du konfigurazioak ausazko grabazio batean.

64k LVM meherako onartzen den bloke-tamaina minimoa da.

Kontuz idazten..!Bai. Cache mota honek idazketa-sinkronizazioa atzeratzen du cacheko gailuarekin. Horrek esan nahi du cachea galtzen bada, cacheko gailuko datuak gal ditzakezula. Geroago, egileak esango dizu zein neurri har daitezkeen, NVMe RAID 1az gain, arrisku hori konpentsatzeko.

Cache mota hau nahita aukeratu zen RAID 6-ren ausazko idazketa-errendimendu eskasa konpentsatzeko.

Ikus dezagun zer lortu dugun:

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

[cachedata_corig] bakarrik egon behar da /dev/data/cache-n. Zerbait gaizki badago, erabili pvmove.

Behar izanez gero, cachea desgai dezakezu komando batekin:

#lvconvert -y --uncache cache/cachedata

Hau on-line egiten da. LVM-k cachea diskoarekin sinkronizatuko du, kendu eta cachedata_corig izena aldatuko du berriro cachedatara.

LVM thin konfiguratzea

Dezagun gutxi gorabehera zenbat espazio behar dugun LVM metadatu meheetarako:

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

Biribildu gehienez 4 gigabyte: 4294967296B

Biderkatu bi eta gehitu 4194304B LVM PV metadatuetarako: 8594128896B
Sortu dezagun partizio bereizi bat NVMe RAID 1-en LVM metadatu meheak eta haien babeskopia bertan jartzeko:

#lvcreate -L 8594128896B --name images root

Zertarako..?Hemen galdera sor daiteke: zergatik jarri LVM metadatuak bereizita NVMe-n cachean gordeko badira eta azkar funtzionatuko badute.

Hemen abiadura garrantzitsua den arren, arrazoi nagusitik urrun dago. Gauza da cachea porrot puntu bat dela. Zerbait gerta liteke, eta LVM metadatuak cachean gordetzen badira, dena erabat galduko da. Metadatu osorik gabe, ia ezinezkoa izango da bolumen meheak muntatzea.

Metadatuak cachean gorde gabeko baina azkar bolumen batera eramanez, metadatuen segurtasuna bermatzen dugu cachea galtzen edo hondatzen bada. Kasu honetan, cache-galerak eragindako kalte guztiak bolumen meheen barruan kokatuko dira, eta horrek berreskurapen-prozedura sinplifikatu egingo du magnitude ordenatan. Probabilitate handiarekin, kalte hauek FS erregistroak erabiliz berreskuratuko dira.

Gainera, aldez aurretik bolumen mehe baten argazkia hartu bazen, eta ondoren cachea guztiz sinkronizatu bazen gutxienez behin, orduan, LVM thin-en barne-diseinua dela eta, argazkiaren osotasuna bermatuko da cachea galtzen bada. .

Sortu dezagun hornikuntza meheaz arduratuko den VG berri bat:

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

Sortu dezagun igerilekua:

#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T images/thin-pool
Zergatik -Z yModu hau benetan pentsatuta dagoenaz gain - espazioa birbanatzean makina birtual bateko datuak beste makina birtual batera isurtzea saihesteko - zeroa ere erabiltzen da 64k baino txikiagoak diren blokeetan ausazko idazketaren abiadura handitzeko. Bolumen mehearen aldez aurretik esleitu gabeko eremu batean 64k baino gutxiagoko idazkera 64K ertz lerrokatuko da cachean. Horri esker, eragiketa erabat egingo da cachearen bidez, cacheko gailua saihestuz.

Muga ditzagun LVak dagozkien PVetara:

#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

Egiaztatu dezagun:

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

Sor dezagun probak egiteko bolumen mehe bat:

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

Probak eta jarraipena egiteko paketeak instalatuko ditugu:

#apt-get install sysstat fio

Honela gure biltegiratze-konfigurazioaren portaera ikus dezakezu denbora errealean:

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

Honela gure konfigurazioa probatu dezakegu:

#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

Kontuz! Baliabidea!Kode honek 36 proba ezberdin egingo ditu, bakoitza 4 segundoz. Proben erdiak grabatzeko dira. NVMe-n asko graba dezakezu 4 segundotan. Gehienez 3 gigabyte segundoko. Beraz, idazketa proba bakoitzak 216 gigabyte SSD baliabide jan ditzake.

Irakurketa eta idazketa nahastuta?Bai. Zentzuzkoa da irakurtzeko eta idazteko probak bereizita egitea. Gainera, zentzuzkoa da cache guztiak sinkronizatuta daudela ziurtatzea, aldez aurretik egindako idazketa batek irakurketari eraginik ez diezaion.

Emaitzak asko aldatuko dira lehen abiaraztean eta ondorengoetan, cachea eta bolumen mehea betetzen diren heinean, eta sistemak azken abiaraztean betetako cacheak sinkronizatzea lortu duenaren arabera.

Besteak beste, argazkia atera berri den bolumen mehe batean abiadura neurtzea gomendatzen dut. Egileak aukera izan zuen ausazko idazketak nola azkar azkartzen diren ikusteko lehen argazkia sortu eta berehala, batez ere cachea oraindik guztiz beteta ez dagoenean. Hau copy-on-write idazketa-semantikaren, cachearen eta bolumen-bloke meheen lerrokatzearen ondorioz gertatzen da eta RAID 6-n ausazko idazketa bat RAID 6-tik ausazko irakurketa bilakatzen dela eta ondoren cachean idazteko. Gure konfigurazioan, RAID 6-tik ausazko irakurketa 6 aldiz (matrizeko SATA SSD kopurua) idazten baino azkarragoa da. Zeren CoW-rako blokeak multzo mehe batetik sekuentzialki esleitzen dira, gero grabazioa, gehienetan, sekuentzial bihurtzen da.

Bi ezaugarri hauek zure onurarako erabil daitezke.

Cachean argazki "koherenteak".

Cachearen kalteak/galerak gertatuz gero datuak galtzeko arriskua murrizteko, egileak proposatzen du argazkien biraketa praktika sartzea kasu honetan haien osotasuna bermatzeko.

Lehenik eta behin, bolumen meheko metadatuak cache gabeko gailu batean daudenez, metadatuak koherenteak izango dira eta balizko galerak datu-blokeetan isolatu egingo dira.

Hurrengo argazkien biraketa-zikloak argazkien barneko datuen osotasuna bermatzen du cachea galtzen bada:

  1. <izena> izena duen bolumen mehe bakoitzeko, sortu argazki bat <izena>.cached izenarekin
  2. Ezar dezagun migrazio-atalasa arrazoizko balio altu batean: #lvchange --quiet --cachesettings "migration_threshold=16384" cache/cachedata
  3. Begiztan cachean dauden bloke zikinen kopurua egiaztatzen dugu: #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' zero lortu arte. Zero luzeegia falta bada, cachea idazteko modura aldi baterako aldatuz sor daiteke. Hala ere, gure SATA eta NVMe SSD matrizeen abiadura ezaugarriak kontuan hartuta, baita haien TBW baliabidea ere, momentua azkar harrapatzeko gai izango zara cache modua aldatu gabe, edo zure hardwareak baliabide osoa guztiz jango du. egun batzuk. Baliabideen mugak direla eta, sistemak, printzipioz, ezin du % 100eko idazketa-kargaren azpitik egon denbora guztian. Gure NVMe SSDek %100eko idazketa-kargaren azpian baliabidea guztiz agortuko dute 3 4-egun. SATA SSDek bi aldiz gehiago iraungo dute. Hori dela eta, karga gehiena irakurtzera doala suposatuko dugu, eta epe laburrean nahiko jarduera oso handiko eztandak ditugu, batez beste, idazteko karga baxuarekin konbinatuta.
  4. Zero bat harrapatu (edo egin) bezain laster, <izena>.cached izena aldatuko dugu <izena>.committed. <name>.committed zaharra ezabatu da.
  5. Aukeran, cachea %100 beteta badago, script baten bidez birsortu daiteke, horrela garbitu. Cache erdi hutsarekin, sistemak askoz azkarrago funtzionatzen du idaztean.
  6. Ezarri migrazioaren atalasea zeroan: #lvchange --quiet --cachesettings "migration_threshold=0" cache/cachedata Horrek aldi baterako saihestuko du cachea euskarri nagusiarekin sinkronizatzea.
  7. Cachean aldaketa asko pilatu arte itxarongo dugu #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' edo tenporizadorea itzali egingo da.
  8. Berriro errepikatzen dugu.

Zergatik zailtasunak migrazio atalasearekin...?Gauza da praktika errealean, "ausazko" grabaketa bat ez dela guztiz ausazkoa. 4 kilobyte-ko tamainako sektore bati zerbait idazten badiogu, probabilitate handia dago hurrengo bi minutuetan erregistro bat egiteko sektore berean edo ondoko (+- 32K) sektore batean.

Migrazio atalasea zeroan ezarriz gero, idazketa sinkronizazioa atzeratzen dugu SATA SSDean eta hainbat aldaketa batzen ditugu cacheko 64K bloke batean. Horrek nabarmen aurrezten du SATA SSDaren baliabidea.

Non dago kodea..?Zoritxarrez, egileak bash scripten garapenean gaitasun nahikorik ez duelako uste du, % 100 autodidakta delako eta "google"-ek bultzatutako garapena praktikatzen duelako, horregatik bere eskuetatik ateratzen den kode ikaragarria inork ez duela erabili behar uste du. bestela.

Uste dut arlo honetako profesionalek modu independentean irudikatzeko gai izango direla goian deskribatutako logika guztia, behar izanez gero, eta, agian, ederki diseinatzeko sistemaren zerbitzu gisa ere, egileak egiten saiatu zen bezala.

Snapshot-en biraketa-eskema sinple batek SATA SSD-n argazki bat etengabe sinkronizatuta edukitzeaz gain, thin_delta utilitatea erabiliz, sortu ondoren zein bloke aldatu diren jakiteko aukera emango digu, eta horrela kalteak lokalizatu ahal izango ditugu. bolumen nagusiak, berreskurapena asko erraztuz .

MOZTU/BATERTU libvirt/KVM-n

Zeren datuen biltegiratzea libvirt exekutatzen ari den KVM-rako erabiliko da, orduan ideia ona litzateke gure VM-ei espazio librea hartzen ez ezik, beharrezkoa ez dena askatzen ere irakastea.

Hau disko birtualetan TRIM/DISCARD euskarria emulatuz egiten da. Horretarako, kontrolagailu mota virtio-scsi-ra aldatu eta xml-a editatu behar duzu.

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

LVM-k behar bezala prozesatzen ditu OS gonbidatuetatik BESTATEAK, eta blokeak behar bezala askatzen dira bai cachean eta baita igerileku mehean ere. Gure kasuan, hau, batez ere, modu atzeratuan gertatzen da, hurrengo argazkia ezabatzean.

BTRFS babeskopia

Erabili prest egindako script-ekin muturrekoa kontuz eta norberaren ardurapean. Egileak berak idatzi zuen kode hau eta beretzat soilik. Ziur nago esperientziadun Linux erabiltzaile askok antzeko tresnak dituztela, eta ez dago beste norbaitena kopiatu beharrik.

Sortu dezagun bolumen bat babeskopia gailuan:

#lvcreate -L 256G --name backup backup

Formateatu dezagun BTRFS-n:

#mkfs.btrfs /dev/backup/backup

Sor ditzagun muntaketa-puntuak eta munta ditzagun fitxategi-sistemaren erro azpiatalak:

#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

Sor ditzagun babeskopiak egiteko direktorioak:

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

Sortu dezagun direktorio bat babeskopien scriptetarako:

#mkdir /root/btrfs-backup

Kopiatu dezagun gidoia:

Bash kode beldurgarri asko. Erabili zure ardurapean. Ez idatzi haserrezko gutunik egileari...#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

Zer egiten du..?BTRFS argazkiak sortzeko eta beste FS batera kopiatzeko komando soil bat dauka, BTRFS bidali/jasotuz.

Lehen abiarazte nahiko luzea izan daiteke, zeren... Hasieran, datu guztiak kopiatuko dira. Aurkezpen gehiago oso azkarrak izango dira, izan ere... Aldaketak soilik kopiatuko dira.

Cron-en jarriko dugun beste script bat:

Bash kode gehiago#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

Zer egiten du..?Zerrendatutako BTRFS bolumenen argazki gehigarriak sortzen eta sinkronizatzen ditu babeskopia FSn. Horren ondoren, duela 60 egun sortutako argazki guztiak ezabatzen ditu. Abiarazi ondoren, zerrendatutako bolumenen argazki datatuak agertuko dira /backup/btrfs/back/remote/ azpidirektorioetan.

Eman diezaiogun kodea exekutatzeko eskubideak:

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

Egiaztatu eta jarri cron-en:

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

Sortu dezagun igerileku mehe bat babeskopia gailuan:

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

Instala dezagun ddrescue, zeren... scriptek tresna hau erabiliko dute:

#apt-get install gddrescue

Sortu dezagun scriptetarako direktorio bat:

#mkdir /root/lvm-thin-backup

Kopiatu ditzagun gidoiak:

Barruan kolpe asko...#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

Zer egiten du...?Argazki meheak manipulatzeko eta thin_delta bidez jasotako bi argazki meheren arteko aldea ddrescue eta blkdiscard erabiliz beste bloke-gailu batekin sinkronizatzeko komando multzo bat dauka.

Cron-en jarriko dugun beste script bat:

Pixka bat gehiago#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

Zer egiten du...?Aurreko script-a erabiltzen du zerrendatutako bolumen meheen babeskopiak sortzeko eta sinkronizatzeko. Scriptak zerrendatutako bolumenen argazki inaktiboak utziko ditu, azken sinkronizaziotik izandako aldaketen jarraipena egiteko beharrezkoak direnak.

Script hau editatu behar da, segurtasun kopiak egin behar diren bolumen meheen zerrenda zehaztuz. Emandako izenak helburu ilustratiboetarako dira soilik. Nahi baduzu, bolumen guztiak sinkronizatuko dituen script bat idatz dezakezu.

Eman ditzagun eskubideak:

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

Egiaztatu eta jarri cron-en:

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

Lehenengo jaurtiketa luzea izango da, izan ere... bolumen meheak guztiz sinkronizatuko dira erabilitako espazio guztia kopiatuz. LVM metadatu meheei esker, badakigu zeintzuk diren benetan erabiltzen diren blokeak, beraz, benetan erabiltzen diren bolumen-bloke meheak bakarrik kopiatuko dira.

Ondorengo exekuzioek datuak pixkanaka kopiatuko dituzte LVM metadatu meheen bidez aldaketen jarraipenari esker.

Ikus dezagun zer gertatu den:

#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

Zer zerikusi du honek habia-panpinekin?

Seguruenik, LVM LV bolumen logikoak beste VG batzuetarako LVM PV bolumen fisikoak izan daitezkeela kontuan hartuta. LVM errekurtsiboa izan daiteke, habia-panpinak bezala. Horrek muturreko malgutasuna ematen dio LVMri.

PS

Hurrengo artikuluan, antzeko biltegiratze sistema/KVM antzeko batzuk erabiltzen saiatuko gara hainbat kontinenteetan erredundantzia duen biltegiratze geobanatua/vm kluster bat sortzeko oinarri gisa etxeko mahaigainak, etxeko Interneta eta P2P sareak erabiliz.

Iturria: www.habr.com

Gehitu iruzkin berria