Azok a pillanatok amikor az emberi hülyeség extra adag szorgalommal párosul.
Na ez is egy ilyen volt..
A történet ott kezdődik, hogy a /app_fs filerendszer elérhetetlenné vált a rendszeren, és valaki meg (hogy hogy nem) szerette volna viszont látni. Az ember ilyenkor megnézi az alap dolgokat (nincs e overmount, elérhető e a VG egyáltalán, mountolva van e az FS), majd konstatálja, hogy valami tényleg nem kerek:
Őő... Jaj... Na szóval.. Van az FS, ami épp closed-ban van (ez meg is magyarázza hova tűnt a filerendszer :)), ami épp a hdisk7en terül el, ami meg kopp hiányzik az lsvg szerint.. AIX mit tud minderről?server1:root:[/] # mount |grep -c /app_fs 0 server1:root:[/] # lsvg -l appvg |grep applv applv jfs2 320 320 1 closed/syncd /app_fs server1:root:[/] # lslv -l applv applv:/app_fs PV COPIES IN BAND DISTRIBUTION hdisk7 320:000:000 27% 000:089:089:089:053 server1:root:[/] # lsvg -p appvg appvg: PV_NAME PV STATE TOTAL PPs FREE PPs FREE DISTRIBUTION hdisk2 active 319 0 00..00..00..00..00 hdisk3 active 1599 0 00..00..00..00..00 hdisk4 active 799 0 00..00..00..00..00 hdisk5 active 959 0 00..00..00..00..00 hdisk6 active 319 32 00..00..00..00..32 hdisk7 missing 447 127 90..00..00..00..37
Él és virul, minden szép, akkor meg mi a fene? Olvassunk már rá a VGDA-ra...server1:root:[/] # lsdev -Cc disk hdisk0 Available Virtual SCSI Disk Drive hdisk1 Available Virtual SCSI Disk Drive hdisk2 Available Virtual SCSI Disk Drive hdisk3 Available Virtual SCSI Disk Drive hdisk4 Available Virtual SCSI Disk Drive hdisk5 Available Virtual SCSI Disk Drive hdisk6 Available Virtual SCSI Disk Drive hdisk7 Available Virtual SCSI Disk Drive server1:root:[/] # lspv |grep appvg hdisk5 00c3b9f4e1709f60 appvg active hdisk2 00c5effd70395ab2 appvg active hdisk3 00c5effd7c2e18d2 appvg active hdisk4 00c3b9f4aeed3ccd appvg active hdisk7 00c3b9f4b2a59c9b appvg active hdisk6 00c3b9f47a309de6 appvg active
őőő.. What?? Na szóval.. van egy PV, elérhető, elvileg része a VG-nek, gyakorlatilag meg nem (más a vg_id)... Kis gondolkodás hogy is lehet ez, majd szembejött a megvilágosodás hangos kürt szóval: Ezt a PV-t valaki más is használatba vette!server1:root:[/] # for i in $(lsvg -p appvg |awk '/hdisk/{print $1}');do echo "$i \c";readvgda /dev/$i|grep vg_id;done hdisk2 vg_id: 00c5effd00004c000000010da807da15 hdisk3 vg_id: 00c5effd00004c000000010da807da15 hdisk4 vg_id: 00c5effd00004c000000010da807da15 hdisk5 vg_id: 00c5effd00004c000000010da807da15 hdisk6 vg_id: 00c5effd00004c000000010da807da15 hdisk7 vg_id: 00c5effd00004c0000000110796187ae
Tekintve, hogy Virtual diszk, így spuri a VIO-hoz, majd gyors lekérdezések után elő is jött a bűnös probléma:
És valóban.. És akkor mit csinál a másik gépen a PV?padmin:vios:[/home/padmin] $ lsmap -all |grep -p hdisk108 VTD server2_hdisk4 Status Available LUN 0x8700000000000000 Backing device hdisk108 Physloc U7311.D20.0637FDC-P1-C02-T1-W5005076801302EA8-L19000000000000 VTD server1_hdisk7 Status Available LUN 0x8400000000000000 Backing device hdisk108 Physloc U7311.D20.0637FDC-P1-C02-T1-W5005076801302EA8-L19000000000000
Na most alapjáraton ilyenkor jut eszembe tanult kollégám szava járása miszerint: "Some people just need a hug... around their neck... with a rope."server2:root:[/] # lspv hdisk0 00c3b9f42b11232e rootvg active hdisk1 00c3b9f4724a36f5 rootvg active hdisk2 00c5effd70926735 dbvg active hdisk3 00c3b9f418b7da43 dbvg active hdisk4 00c3b9f4b2a59c9b dbvg active hdisk5 00c3b9f47715582b dbvg active
Egy óriási mázlink volt csak.. Ez:
Tehát.. Ott a másik szerver, valaki idióta kiassignolta ugyan azt a LUN-t neki, majd berakta egy másik VG-be, ami felül is vágta a VGDA-t, de mákunkra nem használja ezen felül semmire, így a PV-n lévő adat a VGDA-t leszámítva sértetlen.server2:root:[/] # lspv -l hdisk4 server2:root:[/] #
# Azt azért jegyezzük meg, hogy valaminek az ilyen nagyságrendű elcseszése is igen nagy erőfeszítésbe telik, ugyan is mind a VIO szerver, mind az AIX közli, hogy "Ez mintha már használatban lenne, úgy hogy ha biztos vagy a dolgodban, akkor a -force-ot add még meg a parancshoz" ergo 2x is szorgalmas hülyének kell lennie valakinek, hogy ezt összehozza..
Na jó.. akkor a kérdés már csak az, hogy hogy is varázsoljuk vissza a PV-t a helyére..
A hivatalos megoldás kb annyi, hogy "Reméljük van backupod az FS-ről, mert az FS-t/LV-t törölni kell, kiszedni a PV-t mind a 2 VG-ből (a 2. szerveren menni fog, az eredetin csak félig), szedd le a VIO-ról a LUN zónázást, majd aztán extendvg-vel rakd vissza a PV-t az eredeti VG-be, hozd létre a filerendszert, aztán backupból töltsd vissza az adatokat".
Na ez pont az amit nem akarunk :) (Meg ez a blog bejegyzés se született volna akkor meg).. A mi célunk, hogy az adatokat élve visszaszerezzük. A hogyan már jobb kérdés. Ami tiszta az az, hogy az új VG-ben nem maradhat a PV, úgy hogy onnan szedjük ki, aztán meg a VIO-ról szedjük le a LUN allokációt, hogy csak a source szerveren legyen a PV elérhető.
A következő "elméleti" lépés pedig az lenne, hogy rakjuk vissza a VGDA-t az érintett PV alá..
Ennek kivitelezése némi kis elméleti háttérismeretet igényel:
- AIX alatt minden VG felépítése azonos (az elmélet legalább is, a kivitelezésben vannak némi eltérések)
- Minden VG-ben lévő PV tartalmazza a VGDA-t (A PV elején), amely leírja, hogy a VG alatt pontosan milyen PVID-jű diszkek találhatók, azokon belül melyik PV-n milyen LV-k (és milyen kiosztásban) helyezkednek el, van e LV tükrözés (mirroring), és hasonló úri huncutságok.
- Ergo a dolog szépsége, hogy mindenki tud többé kevésbé mindenkiről mindent, 1-2 dolgot leszámítva, és csak 1-2 alapvető dolog különbözik
# Megjegyzem azért, hogy van a VGDA-ban 1-2 olyan adat is, ami meglehetősen szemétnek minősül és PV-nként eltérhet, de azokkal most nem fogok foglalkozni
Na szóval a feladat a következő: Fogjunk a VG-ből egy egészséges diszket, pakoljuk át a VGDA-ját a hibás PV-re, írjuk át azt ami PV specifikus, aztán imádkozzunk, hogy minden menni fog
!!! Had ne mondjam, hogy ez a módszer véletlenül és semmilyen körülmény között sem támogatott hivatalosan, így ha valakinek van IBM-es szerződése az inkább nyisson PMR-t ha tényleg fontos adatról van szó!!!
Akkor kezdjük az első lépést.. VGDA átmásolás.. Hogy ezt meg tudjuk csinálni 1x is tudnunk kell a VGDA méretét, ez viszont VG típusonként más, úgy hogy tudni kell a VG típusát is :) Ehhez kell egy VG-n belüli PV, amin még minden rendben van, legyen ez mondjuk a hdisk2 (mert csak, amúgy bármelyik másik jó lenne)
server1:root:[/] # readvgda /dev/hdisk2 |grep type ..... readvgda_type: smallvg vgtype: 0
# Némi kis segítség a VGDA méretének megállapításában:
# Small VG: 17x 128K
# Big VG: 71x 128K
# Scalable: 548x 128K
Jó.. Most hogy tudjuk mi és merre csináljunk egy backupot a jelenlegi VGDA-ról (igen, amit előzőleg nulláztunk, de akkor is legyen lehetőség visszaállítani ami volt), aztán vágjuk is felül :)
A következő egyedi azonosító a PV ID-ja lenne (nem összekeverendő a PVID-val), ami megmondja, hogy az adott diszk hányadik is a VG-n belül. Ehhez első körben meg kell keresni, hogy az adott adat hol is tárolódik (VG-nként máshol, de mindig az LVM leíró környékén). Én általában az első 1000 szektorcsoportot keresem végig:server1:root:[/] # dd if=/dev/hdisk7 of=/tmp/hdisk7.smallvg.vgda.save bs=128K count=17 17+0 records in 17+0 records out server1:root:[/] # dd if=/dev/hdisk2 of=/dev/hdisk7 bs=128K count=17 17+0 records in 17+0 records out
Szupi.. Tehát 0E00 körül keződidik az LVM leíró része.server1:root:[/] # lquerypv -h /dev/hdisk2 0 1000 |grep LVM 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....|
Na most ebből lehet nem sok derül ki annak aki nem tudja mit keressen, de ha összenézzük ugyan ezt a többi diszk VGDA-jával, akkor remélhetőleg már könyebben rájön mindenki hol is van a kutya elásva:Akkor most nézzük meg mi van azon a környéken: server1:root:[/] # lquerypv -h /dev/hdisk2 e00 40 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....| 00000E10 A807DA15 00001074 00000832 00000088 |.......t...2....| 00000E20 000008C2 013FFEFF 00000100 00010019 |.....?..........| 00000E30 00000008 00000080 000008BA 001E0000 |................|
Ha megfigyelitek, akkor az VGDA leírók ezen része szinte teljesen egyezik, kivétel a 0x0E2D címen lévő érték, ami szépen növekszik 1től 5ig.. Na most ha még emlékeztek a post elejére, akkor 6 PV volt hivatalosan ebben a VG-ben:server1:root:[/] # for i in $(lsvg -p appvg |grep -v hdisk7 |awk '/hdisk/{print $1}');do echo $i;lquerypv -h /dev/$i e00 40;done hdisk2 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....| 00000E10 A807DA15 00001074 00000832 00000088 |.......t...2....| 00000E20 000008C2 013FFEFF 00000100 00010019 |.....?..........| <= '0001' a 0x0E2C címnél 00000E30 00000008 00000080 000008BA 001E0000 |................| hdisk3 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....| 00000E10 A807DA15 00001074 00000832 00000088 |.......t...2....| 00000E20 000008C2 063FFEFF 00000100 00020019 |.....?..........| <= '0002' a 0x0E2C címnél 00000E30 00000008 00000080 000008BA 001E0000 |................| hdisk4 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....| 00000E10 A807DA15 00001074 00000832 00000088 |.......t...2....| 00000E20 000008C2 031FFEFF 00000100 00030019 |................| <= '0003' a 0x0E2C címnél 00000E30 00000008 00000080 000008BA 001E0000 |................| hdisk5 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....| 00000E10 A807DA15 00001074 00000832 00000088 |.......t...2....| 00000E20 000008C2 03BFFEFF 00000100 00040019 |................| <= '0004' a 0x0E2C címnél 00000E30 00000008 00000080 000008BA 001E0000 |................| hdisk6 00000E00 5F4C564D 00C5EFFD 00004C00 0000010D |_LVM......L.....| 00000E10 A807DA15 00001074 00000832 00000088 |.......t...2....| 00000E20 000008C2 013FFEFF 00000100 00050019 |.....?..........| <= '0005' a 0x0E2C címnél 00000E30 00000008 00000080 000008BA 001E0000 |................|
Tehát, a PV ID (!=PVID) a hiányzó diszkünknél a 6os lesz, amit vissza is kéne írni a megfelelő pontra.. dd-vel ez megoldható, de ahhoz decimálisan tudnunk kell a pontos poziciót:server1:root:[/] # readvgda /dev/hdisk2 |grep pv_id |cat -n 1 pv_id: 00c5effd7c2e18d2 2 pv_id: 00c5effd70395ab2 3 pv_id: 00c3b9f4aeed3ccd 4 pv_id: 00c3b9f4e1709f60 5 pv_id: 00c3b9f47a309de6 6 pv_id: 00c3b9f4b2a59c9b
3629.. Jó. Akkor írjuk is be a helyére a megfelelő értéket:server1:root:[/] # echo "ibase=16; E2D" |bc 3629
Ez után jön akkor a tényleges PVID. Ha még emlékeztek, akkor erre anno mutattam is egy módszert, amit ismét elő is szedek, és visszaírom az eredetileg a PV-n lévő PVID-t:server1:root:[/] # echo "\06" | dd of=/dev/hdisk7 bs=1 count=1 seek=3629 1+0 records in 1+0 records out
A script maga:
A futtatás módja:server1:root:[/] # cat /tmp/chpvid.sh #!/usr/bin/ksh pvid=$1 disk=$2 set -A a `echo $pvid|\ awk ' { for (f=1; f <= length($0); f=f+2) { print "ibase=16\nobase=8\n"toupper(substr($0,f,2)) } }'|\ bc 2>/dev/null` /usr/bin/echo "\0"${a[0]}"\0"${a[1]}"\0"${a[2]}"\0"${a[3]}"\0"\ ${a[4]}"\0"${a[5]}"\0"${a[6]}"\0"${a[7]}"\0\0\0\0\0\0\0\0\c"|\ dd bs=1 seek=128 of=/dev/$disk
Visszaellenőrzés:server1:root:[/] # sh /tmp/chpvid.sh 00c3b9f4b2a59c9b hdisk7 16+0 records in 16+0 records out
VGDA ellenőrzés:server1:root:[/] # od -A n -j 128 -N 8 -x /dev/hdisk7 00c3 b9f4 b2a5 9c9b
Még mielött tényleg bármit is csinálnánk nézzük meg, hogy minden tényleg úgy van ahogy volt:server1:root:[/] # for i in $(lsvg -p appvg |awk '/hdisk/{print $1}');do echo "$i \c";readvgda /dev/$i|grep vg_id;done hdisk2 vg_id: 00c5effd00004c000000010da807da15 hdisk3 vg_id: 00c5effd00004c000000010da807da15 hdisk4 vg_id: 00c5effd00004c000000010da807da15 hdisk5 vg_id: 00c5effd00004c000000010da807da15 hdisk6 vg_id: 00c5effd00004c000000010da807da15 hdisk7 vg_id: 00c5effd00004c000000010da807da15
Aztán térdre imára, és varyon-oljuk vissza a VG-t:server1:root:[/] # lsvg -p appvg appvg: PV_NAME PV STATE TOTAL PPs FREE PPs FREE DISTRIBUTION hdisk2 active 319 0 00..00..00..00..00 hdisk3 active 1599 0 00..00..00..00..00 hdisk4 active 799 0 00..00..00..00..00 hdisk5 active 959 0 00..00..00..00..00 hdisk6 active 319 32 00..00..00..00..32 hdisk7 missing 447 127 90..00..00..00..37
server1:root:[/] # varyonvg appvg server1:root:[/] # lsvg -p appvg appvg: PV_NAME PV STATE TOTAL PPs FREE PPs FREE DISTRIBUTION hdisk2 active 319 0 00..00..00..00..00 hdisk3 active 1599 0 00..00..00..00..00 hdisk4 active 799 0 00..00..00..00..00 hdisk5 active 959 0 00..00..00..00..00 hdisk6 active 319 32 00..00..00..00..32 hdisk7 active 447 127 90..00..00..00..37
Hoppá... alakul a molekula :) Nézzük mi van szeretett filerendszerünkel:
Na jó.. ez várható volt.. Adjuk meg amit kér:server1:root:[/] # mount /app_fs Replaying log for /dev/applv. mount: /dev/applv on /app_fs_rest: Unformatted or incompatible media The superblock on /dev/applv is dirty. Run a full fsck to fix.
Aztán próbáljuk meg újra:server1:root:[/] # fsck /dev/applv The current volume is: /dev/applv Primary superblock is valid. *** Phase 1 - Initial inode scan *** Phase 2 - Process remaining directories *** Phase 3 - Process remaining files *** Phase 4 - Check and repair inode allocation map *** Phase 5 - Check and repair block allocation map File system is clean. Superblock is marked dirty; FIX? y All observed inconsistencies have been repaired.
Profit :))server1:root:[/] # mount /app_fs server1:root:[/] #