LVM û Matryoshka çi hevpar in?

Wê demê rojane.
Ez dixwazim ezmûna xwe ya pratîkî ya avakirina pergalek hilanîna daneyê ji bo KVM bi karanîna md RAID + LVM bi civakê re parve bikim.

Bername dê di nav de:

  • Avakirina md RAID 1 ji NVMe SSD.
  • Md RAID 6 ji SATA SSD û ajokarên birêkûpêk berhev dikin.
  • Taybetmendiyên operasyona TRIM / DISCARD li ser SSD RAID 1/6.
  • Li ser komek dîskên hevpar a array md RAID 1/6 a bootable çêbikin.
  • Sazkirina pergalê li ser NVMe RAID 1 dema ku di BIOS-ê de piştgiriya NVMe tune.
  • Bikaranîna cache LVM û LVM zirav.
  • Wêneyên BTRFS bikar bînin û ji bo hilanînê bişînin / bistînin.
  • Ji bo paşvekêşana şêwaza BTRFS wêneyên hûrgelên LVM û thin_delta bikar tînin.

Heke hûn eleqedar in, ji kerema xwe pisîkê bibînin.

Forma serîlêdanê

Nivîskar ti berpirsiyariyek ji encamên karanîna an ne karanîna materyalên / nimûne / kod / şîret / daneyên vê gotarê nagire. Bi xwendina an karanîna vê materyalê bi her awayî, hûn berpirsiyariya hemî encamên van çalakiyan digirin ser xwe. Encamên gengaz ev in:

  • SSD-yên NVMe-pijdandî.
  • Bi tevahî çavkaniya tomarkirinê û têkçûna ajokarên SSD bikar anîn.
  • Bi tevahî windabûna hemî daneyan li ser hemî ajokeran, tevî kopiyên hilanînê.
  • Hêza komputerê ya xelet.
  • Wext, nerv û pereyên winda kirin.
  • Encamên din ên ku li jor nehatine navnîş kirin.

Iron

Berdest bûn:

Motherboard ji dora 2013-an bi chipset Z87, bi Intel Core i7 / Haswell tije ye.

  • Pêvajoya 4 core, 8 têlan
  • 32 GB DDR3 RAM
  • 1 x 16 an 2 x 8 PCIe 3.0
  • 1 x 4 + 1 x 1 PCIe 2.0
  • 6 x 6 GBps SATA 3 connectors

Adaptera SAS LSI SAS9211-8Ez di moda IT / HBA de şewq da. Firmware-ya çalakkirî ya RAID-ê bi qestî bi firmwareya HBA-yê hate guheztin ku:

  1. Hûn dikarin di her kêliyê de vê adapterê bavêjin û wê bi ya din a ku hûn pê re rû bi rû bihêlin biguhezînin.
  2. TRIM/Destavêtin bi asayî li ser dîskê dixebitî, ji ber ku... di firmware RAID de ev ferman bi tevahî nayên piştgirî kirin, û HBA, bi gelemperî, ferq nake ka çi ferman li ser otobusê têne şandin.

Dîskên hişk - 8 perçeyên HGST Travelstar 7K1000 bi kapasîteya 1 TB di faktorek forma 2.5 de, wekî ji bo laptopan. Van ajokeran berê di nav rêzek RAID 6 de bûn. Ew ê di pergala nû de jî bikar bînin. Ji bo hilanîna paşnavên herêmî.

Zêdetir lê zêde kirin:

6 perçe SATA SSD model Samsung 860 QVO 2TB. Van SSD-yan hêjmarek mezin hewce dikir, hebûna cache SLC, pêbawerî û bihayek kêm dihat xwestin. Piştgiriya avêtin / sifir hewce bû, ku ji hêla rêza dmesg ve tê kontrol kirin:

kernel: ata1.00: Enabling discard_zeroes_data

2 perçe NVMe SSD modela Samsung SSD 970 EVO 500GB.

Ji bo van SSD-an, leza xwendinê/nivîsandinê ya rasthatî û kapasîteya çavkaniyê ji bo hewcedariyên we girîng in. Radyator ji bo wan. Pêdivî ye. Bêsînor. Wekî din, di dema hevdemkirina RAID-ê ya yekem de wan bipijiqînin.

Adaptera StarTech PEX8M2E2 ji bo 2 x NVMe SSD-ya ku di hêlîna PCIe 3.0 8x de hatî saz kirin. Ev, dîsa, tenê HBA ye, lê ji bo NVMe. Ew ji adaptorên erzan cûda dibe ku ji ber hebûna veguhezek PCIe-ya çêkirî hewcedariya wê bi piştgiriya bifurckirina PCIe ji dayikê nake. Ew ê di pergala herî kevnar a bi PCIe re jî bixebite, hetta ew hêlînek x1 PCIe 1.0 be. Bi xwezayî, bi leza guncan. Li wir RAID tune. Li ser balafirê BIOS-a çêkirî tune. Ji ber vê yekê, pergala we dê bi efsûnî fêr nebe ku bi NVMe re boot bike, pir kêmtir bi saya vê cîhazê NVMe RAID bike.

Ev pêkhate tenê ji ber hebûna tenê yek 8x PCIe 3.0 belaş di pergalê de bû, û ger 2 hêlînên belaş hebin, ew dikare bi hêsanî bi du quruş PEX4M2E1 an analogan ve were guheztin, ku dikare li her deverê bi bihayê 600 were kirîn. rûbil.

Nepejirandina her cûre hardware an chipset-a çêkirî / BIOS RAID-ê bi zanebûn hate çêkirin, ji bo ku bikaribe bi tevahî pergalê, ji bilî SSD/HDD-ê bixwe, di heman demê de ku hemî daneyan bigire. Bi îdeal, da ku hûn gava ku hûn berbi hardware bi tevahî nû/cuda ve diçin, hûn dikarin pergala xebitandina sazkirî jî hilînin. Ya sereke ev e ku portên SATA û PCIe hene. Ew mîna CD-yek zindî an ajokerek flash bootable, tenê pir bilez û piçûkek mezin e.

HumorWekî din, hûn dizanin ka çi diqewime - carinan hûn hewce ne ku bi lezgînî tevahiya rêzê bi xwe re bigirin da ku jê bistînin. Lê ez naxwazim daneyan winda bikim. Ji bo kirina vê yekê, hemî medyayên navborî bi hêsanî li ser slaytên di 5.25 bayiyên doza standard de cih digirin.

Welê, û, bê guman, ji bo ceribandina rêbazên cûda yên cachkirina SSD-ê li Linux-ê.

Serdegirtinên hardware bêzar in. Vê vekin. Ew an dixebite an na. Û bi mdadm re her dem vebijark hene.

Soft

Berê, Debian 8 Jessie li ser hardware, ku nêzî EOL-ê ye, hate saz kirin. RAID 6 ji HDD-yên ku li jor hatine destnîşan kirin bi LVM-ê re hatine berhev kirin. Ew makîneyên virtual di kvm/libvirt de xebitî.

Bo Nivîskar xwedan ezmûnek maqûl e ku di afirandina ajokarên flash SATA/NVMe-ya bootable portable de, û her weha, ji bo ku şablona asayî ya asayî neyê şikandin, Ubuntu 18.04 wekî pergala armancê hate hilbijartin, ku jixwe têra xwe stabîl bûye, lê hîn jî 3 sal heye. piştgirî di pêşerojê de.

Pergala navborî hemî ajokarên hardware yên ku em ji qutiyê hewce ne vedihewîne. Em ne hewceyê nermalava sêyemîn an ajokeran in.

Amade kirin ku saz bikin

Ji bo sazkirina pergalê ji me re Wêneya Sermaseya Ubuntu hewce ye. Pergala serverê xwedan cûreyek sazkerek zexm e, ku serxwebûna zêde nîşan dide ku bi xistina dabeşa pergala UEFI li ser yek ji dîskê nayê asteng kirin, û hemî bedewiyê xera dike. Li gorî vê yekê, ew tenê di moda UEFI de tê saz kirin. Ti vebijarkan nade.

Em ji vê ne kêfxweş in.

ÇimaMixabin, boota UEFI bi nermalava boot RAID-ê re zehf qels e, ji ber ku ... Kes ji bo dabeşkirina UEFI ESP rezervan pêşkêşî me nake. Li ser Înternetê reçete hene ku pêşniyar dikin ku dabeşkirina ESP-ê li ser ajokerek di portek USB-yê de bicîh bikin, lê ev xalek têkçûn e. Reçeteyên ku nermalava mdadm RAID 1 bi guhertoya metadata 0.9 re bikar tînin hene ku nahêlin UEFI BIOS vê dabeşkirinê bibîne, lê ev heya wê kêliya dilşad dimîne ku BIOS an OS-ya hardware ya din tiştek ji ESP re dinivîse û ji bîr dike ku wê bi yên din re hevdeng bike. mirrors.

Wekî din, boota UEFI bi NVRAM-ê ve girêdayî ye, ku ew ê bi dîskên pergala nû re tevnegere, ji ber ku beşek ji motherboard e.

Ji ber vê yekê, em ê tekerek nû ji nû ve neafirînin. Me berê duçerxeyek bapîrê amadekirî, ceribandin-dem-ceribandinî heye, ku naha jê re Legacy/BIOS boot tê gotin, ku navê serbilind CSM li ser pergalên lihevhatî UEFI hildigire. Em ê tenê wê ji refê derxînin, rûn bikin, tirênan pomp bikin û bi qumaşê şil paqij bikin.

Guhertoya sermaseyê ya Ubuntu jî bi bootloader Legacy re bi rêkûpêk nayê saz kirin, lê li vir, wekî ku ew dibêjin, bi kêmanî vebijark hene.

Bi vî rengî, em hardware berhev dikin û pergalê ji ajokera flash bootable Ubuntu Live bar dikin. Em ê hewce ne ku pakêtan dakêşin, ji ber vê yekê em ê tora ku ji we re dixebite saz bikin. Ger ew nexebite, hûn dikarin berê pakêtên pêwîst li ser ajokerek flashê bar bikin.

Em diçin hawîrdora Sermaseyê, emûlatora termînalê dest pê dikin, û em diçin:

#sudo bash

Çawa…?Rêza li jor ji bo holiwarên di derbarê sudo de teşeya kanonîkî ye. C bоderfetên mezintir tên ûоberpirsiyariya mezintir. Pirs ev e ku hûn dikarin wê li ser xwe bigirin. Pir kes difikirin ku karanîna sudo bi vî rengî bi kêmanî ne baldar e. Lebê:

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

Çima ne ZFS...?Dema ku em nermalavê li ser komputera xwe saz dikin, em di bingeh de nermalava xwe deyn didin pêşdebirên vê nermalavê da ku ajotin.
Gava ku em bi ewlehiya daneyên xwe ji vê nermalavê bawer dikin, em deynek bi qasî lêçûna vegerandina van daneyan digirin, ku em ê rojekê neçar bikin ku bidin.

Ji vî alî ve, ZFS Ferrari ye, û mdadm + lvm bêtir mîna bisîkletek e.

Subjektîf, nivîskar tercîh dike ku li şûna Ferrari bike bi deyn bide kesên nenas. Li wir bihayê meseleyê ne zêde ye. Ne hewceyî mafan e. Ji qaîdeyên trafîkê sadetir. Parkkirin belaş e. Kapasîteya cross-welat çêtir e. Hûn dikarin her gav lingan bi bîsîkletekê ve girêbidin, û hûn dikarin bi destên xwe bîsîkletek tamîr bikin.

Wê demê çima BTRFS ...?Ji bo ku em pergala xebitandinê boot bikin, pêdivî ye ku em pergalek pelê ya ku di Legacy/BIOS GRUB-ê de ji qutiyê ve hatî piştgirî kirin, û di heman demê de wêneyên zindî piştgirî bike. Em ê wê ji bo dabeşkirina /boot bikar bînin. Wekî din, nivîskar tercîh dike ku vê FS-ê ji bo / (root) bikar bîne, ji bîr neke ku ji bo nermalava din hûn dikarin li ser LVM dabeşên cihê biafirînin û wan di pelrêçên pêwîst de bixin.

Em ê ti wêneyên makîneyên virtual an databasan li ser vê FS-ê hilînin.
Dê ev FS tenê ji bo afirandina dîmenên pergalê bêyî ku jê were girtin were bikar anîn û dûv re van wêneyan bi karanîna şandin / wergirtinê veguhezîne dîskek paşvekêşanê.

Wekî din, nivîskar bi gelemperî tercîh dike ku hindiktirîn nermalava rasterast li ser hardware bigire û hemî nermalava din di makîneyên virtual de bi karanîna tiştên wekî şandina GPU û kontrolkerên Mêvandar PCI-USB ji KVM-ê re bi navgîniya IOMMU ve bimeşîne.

Tiştên ku li ser hardware mane tenê hilanîna daneyê, virtualkirin û hilanînê ne.

Heke hûn bêtir ji ZFS-ê bawer dikin, wê hingê, di prensîbê de, ji bo serîlêdana diyarkirî ew têne guheztin.

Lêbelê, nivîskar bi qestî taybetmendiyên neynikê / RAID û zêdebûnê yên ku ZFS, BRTFS û LVM hene paşguh dike.

Wekî argumanek pêvek, BTRFS xwedan şiyana nivîsandina rasthatî li yên rêzdar e, ku bandorek zehf erênî li leza hevdengkirina wêneyan / paşvekêşana li ser HDD-ê dike.

Ka em hemî cîhazan ji nû ve bişopînin:

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

Ka em li dora xwe binêrin:

#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

Plansaziya dîskê

NVMe SSD

Lê em ê bi tu awayî wan nîşan nekin. Di heman demê de, BIOS-a me van ajokaran nabîne. Ji ber vê yekê, ew ê bi tevahî biçin RAID-a nermalavê. Em ê li wir jî beşan çênekin. Heke hûn dixwazin "canon" an "serekî" bişopînin, dabeşek mezin, mîna HDD, biafirînin.

SATA HDD

Li vir ne hewce ye ku meriv tiştek taybetî îcad bike. Em ê ji bo her tiştî yek beş ava bikin. Em ê dabeşek çêbikin ji ber ku BIOS van dîskan dibîne û dibe ku hewil bide ku ji wan dest pê bike. Em ê paşê GRUB-ê li ser van dîskan saz bikin da ku pergal ji nişka ve vê yekê bike.

#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

Li vir tişt ji bo me balkêş dibin.

Ya yekem, ajokarên me bi mezinahiya 2 TB ne. Ev ji bo MBR di nav rêza pejirandî de ye, ya ku em ê bikar bînin. Ger hewce be, dikare bi GPT ve were guheztin. Dîskên GPT xwedan qatek lihevhatinê ye ku dihêle pergalên lihevhatî yên MBR-ê 4 dabeşên pêşîn bibînin heke ew di nav 2 terabytên pêşîn de cih bigirin. Ya sereke ev e ku divê dabeşkirina boot û bios_grub li ser van dîskan di destpêkê de be. Ev tewra dihêle hûn ji ajokarên GPT Legacy/BIOS-ê boot bikin.

Lê ev ne rewşa me ye.

Li vir em ê du beşan çêbikin. Yekem dê mezinahiya 1 GB be û ji bo RAID 1 /boot tê bikar anîn.

Ya duyemîn dê ji bo RAID 6-ê were bikar anîn û dê hemî cîhê belaş yê mayî bigire ji bilî deverek piçûk a ne veqetandî li dawiya ajotinê.

Ev qada nenas çi ye?Li gorî çavkaniyên li ser torê, SATA SSD-yên me li ser kaşê SLC-ya dînamîkî ya berfirehkirî heye ku bi mezinahiya ji 6 heta 78 gîgabaytê ye. Ji ber cudahiya di navbera "gigabytes" û "gibibytes" de di pelgeya daneya ajokerê de em 6 gîgabaytan "belaş" digirin. 72 gîgabaytên mayî ji cîhê ku nayê bikar anîn têne veqetandin.

Li vir divê were zanîn ku me cacheyek SLC heye, û cîh di moda MLC ya 4 bit de tê dagir kirin. Ya ku ji bo me bi bandor tê vê wateyê ku ji bo her 4 gigabayt cîhê belaş em ê tenê 1 gigabyte cache SLC bistînin.

72 gîgabaytan li 4 zêde bikin û 288 gîgabaytan bistînin. Ev cîhê belaş e ku em ê destnîşan nekin da ku rê bidin ajokaran ku bi tevahî cache SLC bikar bînin.

Bi vî rengî, em ê bi tevahî ji şeş ajokaran heya 312 gigabayt cache SLC bistînin. Ji hemî ajokaran, 2 dê di RAID-ê de ji bo zêdebûnê werin bikar anîn.

Ev mîqdara cache dê bihêle ku em di jiyana rast de pir kêm bi rewşek ku nivîsek naçe cache-ê re rûbirû bibin. Ev pir baş kêmasiya herî xemgîn a bîranîna QLC-ê telafî dike - leza nivîsandinê ya pir kêm dema ku dane ji hêla cache ve têne nivîsandin. Ger barkirinên we bi vê yekê re naguncin, wê hingê ez pêşniyar dikim ku hûn bi giranî bifikirin ka SSD-ya we dê kengî di bin barek wusa de bimîne, TBW-ya ji pelê daneyê hesab bike.

#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

Çêkirina Arrays

Pêşîn, em hewce ne ku navê makîneyê biguherînin. Ev pêdivî ye ji ber ku navê mêvandar beşek ji navê array e ku li cîhek di hundurê mdadm de ye û li cîhek tiştek bandor dike. Bê guman, array dikarin paşê binav bikin, lê ev gavek nepêwist e.

#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

Çima -bihesibînin-paqij...?Ji bo pêşîgirtina rêzikên destpêkê. Ji bo her du astên RAID 1 û 6 ev derbasdar e. Her tişt dikare bêyî destpêkkirinê bixebite heke ew rêzek nû be. Digel vê yekê, destpêkirina rêza SSD-ê piştî afirandinê windakirina çavkaniya TBW ye. Em TRIM/DISCARD-ê li cîhê ku gengaz be li ser rêzikên SSD-ya berhevkirî bikar tînin da ku wan "destpêkirin" bikin.

Ji bo rêzikên SSD, RAID 1 DISCARD li derveyî qutiyê piştgirî tê kirin.

Ji bo rêzikên SSD RAID 6 DISCARD, divê hûn wê di pîvanên modula kernel de çalak bikin.

Pêdivî ye ku ev tenê were kirin ger hemî SSD-yên ku di rêzikên asta 4/5/6 de di vê pergalê de têne bikar anîn ji bo discard_zeroes_data piştgirîya xebatê hebe. Carinan hûn rastî ajokarên xerîb têne ku ji kernelê re dibêjin ku ev fonksiyon piştgirî ye, lê bi rastî ew ne li wir e, an fonksiyon her gav naxebite. Heya nuha, piştgirî hema hema li her derê heye, lêbelê, ajokarên kevn û firmware bi xeletî hene. Ji ber vê yekê, piştgiriya DISCARD ji bo RAID 6-ê ji hêla xwerû ve neçalak e.

Hişyarî, fermana jêrîn dê hemî daneyên li ser ajokarên NVMe bi "destpêkirina" rêzika bi "sifir" hilweşîne.

#blkdiscard /dev/md0

Ger tiştek xelet derkeve, hewl bidin ku gavekê diyar bikin.

#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

Çima ewqas mezin...?Zêdekirina mezinahiya perçeyê bandorek erênî li ser leza xwendina rasthatî ya di blokan de heya bi mezinahiya perçeyê tevde dike. Ev diqewime ji ber ku yek operasyonek bi pîvana guncan an piçûktir dikare bi tevahî li ser amûrek yekane were qedandin. Ji ber vê yekê, IOPS ji hemî cîhazan tête kurt kirin. Li gorî statîstîkan, 99% IO ji 512K derbas nabe.

RAID 6 IOPS per nivîsandinê her tim kêmtir an wekhev ji IOPS ya yek ajokerê. Gava ku, wekî xwendinek rasthatî, IOPS dikare çend caran ji ya yek ajokerê mezintir be, û li vir mezinahiya blokê girîngiyek bingehîn e.
Nivîskar di hewildana xweşbînkirina parametreyek ku di RAID 6-ê de ji hêla sêwiranê ve xirab e xalê nabîne û li şûna wê tiştê ku RAID 6 jê re baş e xweşbîn dike.
Em ê nivîsandina belengaz a rasthatî ya RAID 6-ê bi cache NVMe û hîleyên tezmînatê telafî bikin.

Me hîna ji bo RAID 6-ê DISCARD çalak nekiriye. Ji ber vê yekê em ê ji bo nuha "destpêkê" nekin. Em ê vê paşê, piştî sazkirina OS-ê bikin.

SATA HDD

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

LVM li ser NVMe RAID

Ji bo lezê, em dixwazin pergala pelê root-ê li ser NVMe RAID 1-ê ku /dev/md0 e bi cîh bikin.
Lêbelê, em ê hîna jî ji bo hewcedariyên din hewceyê vê berhevoka bilez bin, wek guheztin, metadata û LVM-cache û metadata LVM-tenik, ji ber vê yekê em ê LVM VG-yek li ser vê rêzê biafirînin.

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

Ka em ji bo pergala pelê root dabeşek çêbikin.

#lvcreate -L 128G --name root root

Werin em ji bo guheztina li gorî mezinahiya RAM-ê parçeyek çêbikin.

#lvcreate -L 32G --name swap root

sazkirina OS

Bi tevahî, ji bo sazkirina pergalê her tiştê me heye.

Ji hawîrdora Ubuntu Live sêrbazê sazkirina pergalê dest pê bikin. Sazkirina normal. Tenê di qonaxa hilbijartina dîskên ji bo sazkirinê de, hûn hewce ne ku jêrîn diyar bikin:

  • /dev/md1, - xala mount /boot, FS - BTRFS
  • /dev/root/root (aka /dev/mapper/root-root), - xala çiyê / (root), FS - BTRFS
  • /dev/root/swap (aka /dev/mapper/root-swap), - wekî dabeşkirina guheztinê bikar bînin
  • Bootloader li ser / dev/sda saz bikin

Dema ku hûn BTRFS wekî pergala pelê root hilbijêrin, sazker dê bixweber du cildên BTRFS bi navê "@" ji bo / (root), û "@home" ji bo /home biafirîne.

Ka em dest bi sazkirinê bikin...

Sazkirin dê bi qutiyek diyalogê ya modal bi dawî bibe ku di sazkirina bootloader de xeletiyek nîşan dide. Mixabin, hûn ê nikaribin bi karanîna rêgezên standard ji vê diyalogê derkevin û sazkirinê bidomînin. Em ji pergalê derdikevin û dîsa têkevinê, di dawiya sermaseyek paqij a Ubuntu Live de diqede. Termînalê vekin, û dîsa:

#sudo bash

Jîngehek chroot biafirînin ku sazkirinê bidomînin:

#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

Ka em torê û navê mêvandarê di chroot de mîheng bikin:

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

Ka em biçin hawîrdora chroot:

#chroot /mnt/chroot

Berî her tiştî, em ê pakêtan radest bikin:

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

Ka em hemî pakêtên ku ji ber netemamî sazkirina pergalê bi xeletî hatine saz kirin kontrol bikin û rast bikin:

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

Ger tiştek nexebite, dibe ku hûn hewce ne ku pêşî /etc/apt/sources.list biguherînin

Ka em parametreyên ji bo modula RAID 6 rast bikin da ku TRIM/DISCARD çalak bike:

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

Werin em rêzikên xwe hinekî biguhezînin:

#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

Ew çi bû..?Me komek rêzikên udev çêkiriye ku dê jêrîn bikin:

  • Mezinahiya cache ya blokê ya ji bo RAID 2020-ê ji bo 6-an guncan destnîşan bikin. Wusa dixuye ku nirxa xwerû, ji damezrandina Linux-ê ve nehatiye guhertin, û ji bo demek dirêj ve têr nebûye.
  • Ji bo dirêjahiya kontrolên array / hevdemkirinê kêmtirîn IO rezerv bikin. Ev e ku pêşî li rêzikên we bigire ku di bin barkirinê de di rewşek hevdemkirina bêdawî de asê bimînin.
  • Di dema kontrolkirin/senkronîzekirina rêzan de IO-ya herî zêde bisînor bikin. Ev pêdivî ye da ku hevdengkirin/kontrolkirina SSD RAID-ên ajokarên we bi rengek hişk nekeve. Ev bi taybetî ji bo NVMe rast e. (Li ser radyatorê tê bîra min? Min henek nekir.)
  • Dêsikên ku zivirandina spindle (HDD) bi riya APM rawestînin qedexe bikin û dema xewê ji bo kontrolkerên dîskê 7 demjimêran destnîşan bikin. Heke ajokarên we dikarin wiya bikin (-B 255) hûn dikarin APM bi tevahî neçalak bikin. Bi nirxa xwerû, ajoker dê piştî pênc saniyan rawestin. Dûv re OS-ê dixwaze cache-a dîskê ji nû ve saz bike, dê dîsk dîsa bizivire, û her tişt dê ji nû ve dest pê bike. Dîskên xwedan hejmarek herî zêde ya zivirînên spindle hene. Çêlekek xwerû ya wusa hêsan dikare di nav çend salan de bi hêsanî dîskên we bikuje. Ne hemî dîskên ji vê yekê diêşin, lê yên me yên "laptop" in, bi mîhengên xwerû yên guncav, ku RAID-ê wekî mini-MAID-ê xuya dike.
  • Pêşiya xwendinê li ser dîskan saz bikin (zivirandin) 1 megabyte - du blokên li pey hev / parçe RAID 6
  • Pêşiya xwendinê li ser rêzan bixwe neçalak bikin.

Ka em biguherînin /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

Çima wisa ye..?Em ê ji hêla UUID ve li dabeşa /boot bigerin. Navê array dikare bi teorîkî biguhere.

Em ê li beşên mayî bi navên LVM-ê di nîşana /dev/mapper/vg-lv de bigerin, ji ber ku ew dabeşan bi rengek bêhempa nas dikin.

Em ji bo LVM UUID bikar naynin ji ber ku UUID ya cildên LVM û dîmenên wan dikarin yek bin.Çiyayê /dev/mapper/root-root.. du caran?Erê. Tam. Taybetmendiya BTRFS. Ev pergala pelan dikare çend caran bi binevokên cûda ve were saz kirin.

Ji ber vê heman taybetmendiyê, ez pêşniyar dikim ku tu carî wêneyên LVM yên cildên BTRFS yên çalak neafirînin. Gava ku hûn ji nû ve saz bikin dibe ku hûn surprîzek bibin.

Ka em konfigurasyona mdadm ji nû ve nûve bikin:

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

Ka em mîhengên LVM-ê rast bikin:

#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

Ew çi bû..?Me berfirehkirina otomatîkî ya hewzên nazik ên LVM çalak kiriye ku bigihîje% 90 ji cîhê dagirkirî ji sedî 5 ê qebareyê.

Me ji bo cache LVM hejmara herî zêde blokên cache zêde kiriye.

Me rê neda ku LVM li cildên LVM (PV) bigere li ser:

  • cîhazên ku cache LVM (cdata) hene
  • cîhazên ku bi karanîna cache LVM-ê veşartibûn, cache-ê derbas dikin ( _corig). Di vê rewşê de, cîhaza cache bixwe dê hîn jî di nav cache-ê de were şopandin (tenê ).
  • cîhazên ku metadata cache ya LVM (cmeta) hene
  • hemî cîhazên di VG de bi navên wêneyan. Li vir em ê wêneyên dîskê yên makîneyên virtual hebin, û em naxwazin LVM li ser mêvandar cildên ku girêdayî OS-ya mêvan in çalak bike.
  • hemû cîhazên li VG bi navê hilanînê. Li vir em ê kopiyên paşîn ên wêneyên makîneya virtual hebin.
  • hemî cîhazên ku navê wan bi "gpv" (hejmara fîzîkî ya mêvan) bi dawî dibe

Dema ku cîhê belaş li ser LVM VG azad dike, me piştgiriya DISCARD çalak kiriye. Baldar be. Ev ê jêbirina LV-yên li ser SSD-ê pir dem dixwe. Ev bi taybetî ji bo SSD RAID 6 derbas dibe. Lêbelê, li gorî planê, em ê dabînkirina tenik bikar bînin, ji ber vê yekê ew ê qet me asteng neke.

Ka em wêneya initramfs nûve bikin:

#update-initramfs -u -k all

Grub saz bikin û mîheng bikin:

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

Divê hûn kîjan dîskê hilbijêrin?Hemû yên ku sd* in. Pêdivî ye ku pergal bikaribe ji her ajokerek SATA an SSD-ya xebitandinê boot bike.

Çima os-prober lê zêde kirin..?Ji bo serxwebûna zêde û destên lîstikvan.

Ger yek ji RAID-ê di rewşek xirab de be ew rast naxebite. Ew hewl dide ku li OS-ê li ser dabeşên ku di makîneyên virtual yên ku li ser vê hardware dixebitin de têne bikar anîn bigere.

Ger hewceyê we be, hûn dikarin wê bihêlin, lê hemî tiştên jorîn ji bîr mekin. Ez pêşniyar dikim ku ji bo ku hûn ji destên nebaş xilas bibin serhêl li reçeteyan bigerin.

Bi vê yekê me sazkirina destpêkê temam kir. Wext e ku hûn di OS-ya ku nû hatî saz kirin de ji nû ve bidin destpêkirin. Ji bîr nekin ku CD/USB-ya Zindî ya bootable rakin.

#exit
#reboot

Yek ji SATA SSD-ên wekî cîhaza bootê hilbijêrin.

LVM li ser SATA SSD

Di vê nuqteyê de, me berê xwe da OS-ya nû, torê mîheng kir, apt, emulatora termînalê vekir û dest pê kir:

#sudo bash

Em berdewam bikin.

Rêzeya ji SATA SSD "destpêk bikin":

#blkdiscard /dev/md2

Ger ew nexebite, wê hingê biceribîne:

#blkdiscard --step 65536 /dev/md2
Li ser SATA SSD LVM VG biafirînin:

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

Çima VG din ..?Bi rastî, me berê VG-ya bi navê root heye. Çima her tiştî li yek VG zêde nakin?

Ger di VG de çend PV hebin, hingê ji bo ku VG rast were çalak kirin, divê hemî PV (serhêl) hebin. Ji îstîsna LVM RAID e, ku em bi qestî bikar naynin.

Em bi rastî dixwazin ku heke têkçûnek (wendabûna daneyê bixwîne) li ser yek ji rêzikên RAID 6-ê hebe, pergala xebitandinê dê bi normalî boot bike û fersendê bide me ku em pirsgirêkê çareser bikin.

Ji bo vê yekê, di asta yekem a abstraksiyonê de, em ê her celeb "medya" laşî di VG-yek cihêreng de veqetînin.

Ji hêla zanistî ve, rêzikên RAID-ê yên cihêreng ji "domên pêbaweriyê" yên cihê ne. Pêdivî ye ku hûn ji wan re xalek têkçûnek hevpar a din ava nekin û wan li yek VG-ê bixin.

Hebûna LVM-ê di asta "hardware" de dê bihêle ku em bi kêfî perçeyên rêzikên RAID-ê yên cihêreng bi hev re bi awayên cihêreng qut bikin. Ji bo nimûne - birevin di heman demê de bcache + LVM zirav, bcache + BTRFS, cache LVM + LVM zirav, veavakirinek ZFS ya tevlihev a bi kaş, an tevliheviyek din a dojehê ku hûn hemî biceribînin û bidin ber hev.

Di asta "hardware" de, em ê ji bilî cildên LVM-ê yên kevn ên baş ên "qûr" tiştek din bikar neynin. Ji îstîsna vê qaîdeyê dibe ku dabeşkirina hilanînê be.

Ez difikirim ku di vê gavê de, gelek xwendevanan jixwe dest pê kiribû ku di derheqê kulika hêlînê de tiştek guman bikin.

LVM li ser SATA HDD

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

Dîsa VG-ya nû..?Em bi rastî dixwazin ku ger rêzika dîskê ya ku em ê ji bo paşvekişandina daneyê bikar bînin têk biçe, pergala xebitandina me dê bi asayî xebata xwe bidomîne, di heman demê de ku gihandina daneyên ne-vekêşanê wekî berê biparêze. Ji ber vê yekê, ji bo ku ji pirsgirêkên aktîvkirina VG dûr nekevin, em VG-yek cihêreng diafirînin.

Sazkirina cache LVM

Ka em li ser NVMe RAID 1 LV biafirînin da ku wê wekî amûrek caching bikar bînin.

#lvcreate -L 70871154688B --name cache root

Çima kêm e...?Rastî ev e ku NVMe SSD-yên me di heman demê de cache SLC jî hene. 4 gigabayt "belaş" û 18 gîgabayt dînamîk ji ber cîhê belaş ku di MLC-ya 3-bit dagirtî ye. Gava ku ev cache qediya, NVMe SSD dê ji SATA SSD-ya me ya bi cache-ê pir zûtir nebin. Bi rastî, ji ber vê yekê, ji me re bê wate ye ku em dabeşkirina cache ya LVM-ê ji du caran ji mezinahiya cache SLC ya ajokera NVMe mezintir bikin. Ji bo ajokarên NVMe yên ku têne bikar anîn, nivîskar maqûl dibîne ku 32-64 gigabayt cache çêbike.

Mezinahiya dabeşkirina diyarkirî ji bo organîzekirina 64 gigabayt cache, metadata cache, û paşvekişandina metadata hewce ye.

Wekî din, ez not dikim ku piştî girtina pergala qirêj, LVM dê hemî cache wekî qirêj nîşan bide û dê dîsa hevdeng bike. Wekî din, ev ê her carê ku lvchange li ser vê cîhazê were bikar anîn heya ku pergal ji nû ve were nûve kirin dê dubare bibe. Ji ber vê yekê, ez pêşniyar dikim ku tavilê cache-ê bi karanîna skrîpta guncan ji nû ve biafirînin.

Ka em li ser SATA RAID 6 LV biafirînin da ku wê wekî amûrek cache bikar bînin.

#lvcreate -L 3298543271936B --name cache data

Çima tenê sê terabytes..?Ji ber vê yekê, heke hewce be, hûn dikarin SATA SSD RAID 6 ji bo hin hewcedariyên din bikar bînin. Mezinahiya cîhê cached dikare bi dînamîk, li ser firînê, bêyî sekinandina pergalê were zêdekirin. Ji bo kirina vê yekê, hûn hewce ne ku bi demkî cache-ê rawestînin û ji nû ve çalak bikin, lê avantaja ciyawaz a LVM-cache li ser, mînakî, bcache ev e ku ev dikare di firînê de were kirin.

Ka em ji bo cachkirinê VG-yek nû biafirînin.

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

Werin em li ser cîhaza cached LV biafirînin.

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

Li vir me tavilê cîhê belaş li ser /dev/data/cache girt da ku hemî dabeşên din ên pêwîst tavilê li ser /dev/root/cache-ê hatin afirandin. Ger we tiştek li cîhek xelet afirandiye, hûn dikarin wê bi karanîna pvmove veguherînin.

Ka em cache biafirînin û çalak bikin:

#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

Çima wisa çeqilmast..?Bi ceribandinên pratîkî, nivîskar karîbû fêr bibe ku heke mezinahiya bloka cache ya LVM bi mezinahiya bloka zirav a LVM re hevaheng be, encamek çêtirîn tê bidestxistin. Digel vê yekê, her ku mezinahî piçûktir be, veavakirin di tomarek bêserûber de çêtir çêdibe.

64k mezinahiya blokê ya herî hindik e ku ji bo LVM zirav destûr tê dayîn.

Hişyar bin binivîsin..!Erê. Ev celeb cache hevdengkirina nivîsandinê li ser cîhaza cache paşde dixe. Ev tê vê wateyê ku heke cache winda bibe, dibe ku hûn daneyên li ser cîhaza cache winda bikin. Dûv re, nivîskar dê ji we re vebêje ku ji bilî NVMe RAID 1, çi tedbîr dikare were girtin da ku vê xetereyê telafî bike.

Ev celeb cache bi mebest hate hilbijartin da ku berdêla performansa nivîsandina rasthatî ya xirab a RAID 6 bide.

Ka em kontrol bikin ka me çi girt:

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

Tenê [cachedata_corig] divê li ser /dev/data/cache-ê were cîh kirin. Ger tiştek xelet e, wê hingê pvmove bikar bînin.

Ger hewce be bi yek fermanê hûn dikarin cache-ê neçalak bikin:

#lvconvert -y --uncache cache/cachedata

Ev li ser înternetê tê kirin. LVM dê tenê cache-ê bi dîskê re hevdeng bike, jê rake, û navê cachedata_corig vegerîne cachedata.

Sazkirina LVM tenik

Ka em bi texmînî texmîn bikin ka ji metadata hûrgelê ya LVM re çiqas cîh hewce ye:

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

Bi qasî 4 gigabaytan dor bikin: 4294967296B

Bi duyan zêde bikin û ji bo metadata LVM PV 4194304B lê zêde bikin: 8594128896B
Werin em li ser NVMe RAID 1 dabeşek cihêreng biafirînin da ku metadata tenik a LVM û kopiyek paşde ya wan li ser bi cîh bikin:

#lvcreate -L 8594128896B --name images root

Bo çi..?Li vir dibe ku pirs derkeve: gelo çima metadata LVM-ya zirav ji hev cuda bi cîh bikin ger ew ê hîn jî li ser NVMe were vegirtin û dê zû bixebite.

Her çend bilez li vir girîng e, ew ji sedema sereke dûr e. Tişt ev e ku cache xala têkçûnê ye. Tiştek dikare biqewime, û heke metadata nazik ya LVM-ê were vegirtin, ew ê bibe sedem ku her tişt bi tevahî winda bibe. Bêyî metadata bêkêmasî, berhevkirina cildên zirav dê hema ne gengaz be.

Bi veguheztina metadaneyê berbi cildek veqetandî ya ne-cached, lê bilez, em ewlehiya metadata di bûyera windabûna cache-ê de an jî xirabûnê de garantî dikin. Di vê rewşê de, hemî zirarên ku ji ber windabûna cache-ê têne çêkirin dê di hundurê cildên zirav de bêne cih kirin, ku dê prosedûra başbûnê bi fermanên mezinahiyê hêsan bike. Bi îhtîmalek mezin, dê van ziraran bi karanîna têketinên FS-ê werin sererast kirin.

Digel vê yekê, heke berê wêneyek cildek zirav hatibe kişandin, û piştî wê jî cache bi kêmî ve carekê bi tevahî were hevdem kirin, wê hingê, ji ber sêwirana hundurîn a LVM-ya zirav, di bûyera windabûna cache de dê yekitiya wêneyê were garantî kirin. .

Werin em VG-ya nû biafirînin ku dê berpirsiyariya dabînkirina zirav be:

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

Ka em hewzek çêbikin:

#lvcreate -L 274877906944B --poolmetadataspare y --poolmetadatasize 4294967296B --chunksize 64k -Z y -T images/thin-pool
Çima -Z yDigel vê yekê ku ev mod bi rastî ji bo çi tê armanc kirin - ji bo ku nehêle daneyên ji makîneyek virtual di dema ji nû ve dabeşkirina cîhê de ji makîneyek virtual din dernekeve - zerokirin jî ji bo zêdekirina leza nivîsandina bêserûber di blokên ji 64k piçûktir de tê bikar anîn. Her nivîsandina ku ji 64k kêmtir li deverek hêjî ya zirav ya berê nehatibû veqetandin dê di cache-ê de bibe 64K li kêleka hev. Ev ê bihêle ku operasyon bi tevahî bi navgîniya cache-ê ve were kirin, cîhaza keşkirî derbas bike.

Ka em LV-yan biguhezînin PV-yên têkildar:

#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

Ka em kontrol bikin:

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

Ka em ji bo ceribandinan cildek zirav biafirînin:

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

Em ê ji bo ceribandin û çavdêriyê pakêtan saz bikin:

#apt-get install sysstat fio

Bi vî rengî hûn dikarin tevgerê veavakirina hilanîna me di demek rast de bişopînin:

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

Bi vî rengî em dikarin veavakirina xwe biceribînin:

#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

Bi baldarî! Kanî!Ev kod dê 36 ceribandinên cûda bimeşîne, her yek ji bo 4 çirkeyan dixebite. Nîvê testan ji bo tomarkirinê ne. Hûn dikarin di 4 çirkeyan de li ser NVMe gelek tomar bikin. Heya 3 gigabayt di çirkeyê de. Ji ber vê yekê, her ceribandinek ceribandinên nivîsandinê dikare heya 216 gigabayt çavkaniya SSD ji we bixwe.

Xwendin û nivîsandin tevlihev?Erê. Aqil e ku meriv ceribandinên xwendin û nivîsandinê ji hev cuda bimeşîne. Digel vê yekê, maqûl e ku meriv pê ewle bibe ku hemî kaş têne hevdem kirin da ku nivîsek berê hatî çêkirin bandorê li xwendinê neke.

Encam dê di dema destpêkirina yekem û ya paşîn de pir cûda bibin ji ber ku cache û volga zirav tijî dibe, û her weha li gorî wê yekê jî girêdayî ye ka pergalê kariye kaşên ku di dema destpêkirina paşîn de dagirtî hevdeng bike.

Di nav tiştên din de, ez pêşniyar dikim ku leza li ser hêjmarek jixwe tije zirav a ku ji nû ve wêneyek jê hatî kişandin were pîvandin. Nivîskar fersendê dît ku çawa nivîsên bêserûber tavilê piştî çêkirina wêneya yekem bi lez û bez bilezîne, nemaze dema ku cache hîn bi tevahî tije nebûye. Ev diqewime ji ber semantîka nivîsandina kopî-li-nivîsandinê, lihevhatina cache û blokên hûrgelê yên zirav, û rastiya ku nivîsandinek birêkûpêk ji RAID 6 re vediguhere xwendinek bêserûber ji RAID 6 û dûv re jî nivîsandinek li cache. Di veavakirina me de, xwendina rasthatî ji RAID 6 heya 6 carî (hejmara SATA SSD-yên di rêzê de) ji nivîsandinê zûtir e. Bo blokên ji bo CoW bi rêz ji hewzek zirav têne veqetandin, wê hingê tomarkirin, bi piranî, di heman demê de vediguhere rêzikan.

Van her du taybetmendiyan dikarin ji bo berjewendiya we werin bikar anîn.

Wêneyên "hevgirêdan" cache bikin

Ji bo kêmkirina xetera windabûna daneyê di bûyera zirar / windabûna cache de, nivîskar pêşniyar dike ku pratîka zivirandina wêneyan destnîşan bike da ku di vê rewşê de yekbûna wan garantî bike.

Pêşîn, ji ber ku metadaneyên qebareya zirav li ser amûrek neçaxkirî dimîne, metadata dê domdar be û windahiyên gengaz dê di nav blokên daneyê de werin veqetandin.

Di çerxa zivirandina wêneya jêrîn de di bûyera windabûna cache de yekitiya daneya di hundurê wêneyan de garantî dike:

  1. Ji bo her cildeke tenik bi navê <nav>, wêneyek bi navê <name> biafirîne.cached
  2. Werin em sînorê koçberiyê li ser nirxek bilind a maqûl destnîşan bikin: #lvchange --quiet --cachesettings "migration_threshold=16384" cache/cachedata
  3. Di pêlê de em hejmara blokên qirêj ên di cache de kontrol dikin: #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' heta ku em sifir bibin. Ger zero ji bo demek dirêj winda bibe, ew dikare bi guheztina cache ya demkî li moda nivîsandinê were afirandin. Lêbelê, bi girtina taybetmendiyên bilez ên arrayên me yên SATA û NVMe SSD, û her weha çavkaniya wan a TBW, hûn ê yan zû karibin bêyî ku moda cache-ê biguhezînin demek zû bigirin, an jî hardware we dê bi tevahî çavkaniya xwe bixwin. çend rojan. Ji ber tixûbên çavkaniyê, pergal, di prensîbê de, nikare her dem di binê 100% barkirina nivîsandinê de be. SSD-yên me yên NVMe di binê barkirina nivîsandinê de ji% 100 dê çavkaniyê bi tevahî biqewirînin 3-4 ya rojê. SATA SSD dê tenê du caran dirêj bimînin. Ji ber vê yekê, em ê texmîn bikin ku piraniya bargiraniyê ber bi xwendinê ve diçe, û di navgîniyê de ji bo nivîsandinê pêlên kêm-kurt ên çalakiya pir zêde bi hev re hene.
  4. Hema ku me sifirek girt (an jî çêkir), em navê <name> .cached kirin <name>.committed. <name>.committed kevin tê jêbirin.
  5. Vebijarkî, heke cache 100% tije be, ew dikare ji hêla skrîptekê ve were çêkirin, bi vî rengî wê paqij bike. Bi cacheyek nîv-vala, pergal dema nivîsandinê pir zûtir dixebite.
  6. Rêjeya koçberiyê li ser sifirê saz bike: #lvchange --quiet --cachesettings "migration_threshold=0" cache/cachedata Ev dê bi demkî rê li ber hevdengkirina cache bi medyaya sereke bigire.
  7. Em li bendê ne heya ku gelek guhertin di cache de kom bibin #lvs --rows --reportformat basic --quiet -ocache_dirty_blocks cache/cachedata | awk '{print $2}' an jî demjimêr dê biçe.
  8. Em dîsa dubare dikin.

Çima zehmetiyên sînorê koçberiyê...?Tişt ev e ku di pratîka rastîn de, tomarek "random" bi rastî bi tevahî ne tesadufî ye. Ger me ji sektorek mezinahiya 4 kilobyte re tiştek binivîsanda, îhtimalek mezin heye ku di çend hûrdeman de tomarek li heman an yek ji sektorên cîran (+- 32K) were çêkirin.

Bi danîna sînorê koçberiyê li ser sifir, em hevdemkirina nivîsandinê li ser SATA SSD paşde dixin û çend guhertinan li yek blokek 64K di cache de berhev dikin. Ev bi girîngî çavkaniya SATA SSD-ê xilas dike.

Kod li ku ye..?Mixabin, nivîskar xwe di pêşvebirina nivîsarên bash de têra xwe ne jêhatî dihesibîne ji ber ku ew 100% xwe hînkirî ye û pêşkeftina "google"-rêveber dike, ji ber vê yekê ew di wê baweriyê de ye ku koda tirsnak a ku ji destên wî derdikeve divê ji hêla kesek ve neyê bikar anîn. wekîdi.

Ez difikirim ku pisporên di vî warî de dê karibin serbixwe hemî mantiqa ku li jor hatî destnîşan kirin, heke hewce bike, nîşan bidin, û, belkî, wê jî bi xweşikî wekî karûbarek pergalî sêwirînin, wekî ku nivîskar hewl da ku bike.

Pîlana zivirandina wêneya wusa hêsan dê ne tenê bihêle ku em ne tenê bi berdewamî yek wêneyek bi tevahî li ser SATA SSD-yê hevdem bikin, lê di heman demê de dê rê bide me, ku bi karanîna kargêriya thin_delta-yê bikar bînin, em fêr bibin ka kîjan blokan piştî afirandina wê hatine guhertin, û bi vî rengî zirarê li ser herêmî bikin. cildên sereke, başbûnek pir hêsan dike.

Di libvirt/KVM de TRIM/DÎŞANDIN

Bo hilanîna daneyê dê ji bo KVM-ya libvirt-ê dimeşîne were bikar anîn, wê hingê dê fikrek baş be ku em VM-yên xwe hîn bikin ku ne tenê cîhê belaş bigirin, lê di heman demê de tiştê ku êdî hewce nake jî azad bikin.

Ev bi emilandina piştgiriya TRIM/DISCARD li ser dîskên virtual pêk tê. Ji bo vê yekê, hûn hewce ne ku celebê kontrolkerê biguherînin virtio-scsi û xml biguherînin.

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

Bûyerên weha ji OS-yên mêvanan ji hêla LVM-ê ve rast têne hilberandin, û blokan hem di cache û hem jî di hewza zirav de rast têne berdan. Di rewşa me de, ev bi piranî bi rengek dereng diqewime, dema ku wêneya paşîn jêbirin.

BTRFS Backup

Skrîptên amade bi kar bînin bêfêhm zêde hişyarî û li ser rîska xwe. Nivîskar ev kod bi xwe û tenê ji bo xwe nivîsandiye. Ez pê bawer im ku gelek bikarhênerên Linux-ê yên xwedî ezmûn xwedan amûrên wekhev in, û ne hewce ye ku yên kesek din kopî bikin.

Ka em li ser cîhaza hilanînê dengek biafirînin:

#lvcreate -L 256G --name backup backup

Ka em wê di BTRFS de format bikin:

#mkfs.btrfs /dev/backup/backup

Ka em xalên mountê biafirînin û binbeşên root ên pergala pelan bixin:

#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

Ka em pelrêçan ji bo hilanînê biafirînin:

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

Ka em pelrêçek ji bo skrîptên hilanînê biafirînin:

#mkdir /root/btrfs-backup

Ka em skrîptê kopî bikin:

Gelek koda bash ya tirsnak. Li ser rîska xwe bikar bînin. Ji nivîskar re nameyên hêrs nenivîsin...#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

Ew jî çi dike..?Ji bo afirandina wêneyên BTRFS-ê û kopîkirina wan li FS-ya din bi karanîna şandina / wergirtina BTRFS-ê komek fermanên hêsan vedihewîne.

Destpêka yekem dikare bi rengek dirêj dirêj be, ji ber ku ... Di destpêkê de, hemî dane dê bêne kopî kirin. Destpêkên din dê pir bilez bin, ji ber ku ... Tenê guhertin dê bêne kopî kirin.

Nivîsarek din a ku em ê têxin nav cron:

Hin bêtir koda bash#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

Çi dike..?Li ser FS-ya paşvekêşanê dîmenên zêdebûyî yên cildên BTRFS yên navnîşkirî diafirîne û hevdeng dike. Piştî vê yekê, ew hemî wêneyên ku 60 roj berê hatine afirandin jêbirin. Piştî destpêkirinê, dîmenên tarîxî yên cildên navnîşkirî dê di bin pelrêça /backup/btrfs/paş/dûr/ de xuya bibin.

Ka em mafên pêkanîna kodê bidin:

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

Ka em wê kontrol bikin û têxin nav kronê:

#/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 hilanînê tenik

Ka em li ser cîhaza hilanînê hewzek tenik biafirînin:

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

Ka em ddrescue saz bikin, ji ber ku ... Skrîpta dê vê amûrê bikar bînin:

#apt-get install gddrescue

Ka em pelrêçekek ji bo skrîptan çêbikin:

#mkdir /root/lvm-thin-backup

Werin em skrîptan kopî bikin:

Di hundurê de gelek şor ...#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

Çi dike...?Komek fermanan ji bo manîpulekirina dîmenên nazik û hevdengkirina cûdahiya di navbera du dîmenên zirav ên ku ji hêla thin_delta ve hatine wergirtin ji amûrek bloka din re bi karanîna ddrescue û blkdiscard vedihewîne.

Skrîpteke din a ku em ê têxin kronê:

A piçek bêtir 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

Çi dike...?Skrîpta berê bikar tîne da ku paşpirtikên cildên zirav ên navnîşkirî biafirîne û hevdeng bike. Skrîpt dê dîmenên neçalak ên cildên navnîşkirî bihêle, yên ku ji bo şopandina guhertinan ji hevdemkirina paşîn ve hewce ne.

Pêdivî ye ku ev skrîpt were sererast kirin, navnîşa cildên zirav ên ku ji bo wan kopiyên paşvekêşanê bêne çêkirin diyar bike. Navên hatine dayîn tenê ji bo armancên ronîkirinê ne. Ger hûn bixwazin, hûn dikarin skrîptek ku dê hemî cildan hevdeng bike binivîsin.

Ka em mafan bidin:

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

Ka em wê kontrol bikin û têxin nav kronê:

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

Destpêka yekem dê dirêj be, ji ber ku ... cildên zirav dê bi kopîkirina hemî cîhê hatî bikar anîn bi tevahî hevdeng bibin. Bi saya metadata nazik ya LVM, em dizanin ka kîjan blokên bi rastî têne bikar anîn, ji ber vê yekê tenê blokên volgayên zirav ên bi rastî têne bikar anîn dê werin kopî kirin.

Rêvekirinên paşîn dê bi saya şopandina biguheztina bi navgîniya metadata zirav ya LVM-ê daneyan bi rengek zêde kopî bikin.

Ka em bibînin ka çi bûye:

#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

Çi eleqeya vê bi kuçikên hêlînê re heye?

Bi îhtîmalek mezin, ji ber ku cildên mentiqî yên LVM LV dikarin ji bo VG-yên din cildên laşî yên LVM PV bin. LVM dikare vegerî be, mîna kuçikên hêlînê. Ev ji LVM re nermbûnek zehf dide.

PS

Di gotara paşîn de, em ê hewl bidin ku gelek pergalên hilanîna mobîl / KVM-ya wekhev bikar bînin wekî bingehek ji bo afirandina depoyek jeo-belavkirî / vm-ê bi zêdebûnê li gelek parzemînan bi karanîna sermaseyên malê, Internetnterneta malê û torên P2P-ê bikar bînin.

Source: www.habr.com

Add a comment