Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

Ke kopa ho arolelana le uena phihlelo ea ka ea pele e atlehileng ea ho tsosolosa polokelo ea polokelo ea Postgres hore e sebetse ka botlalo. Ke ile ka tloaelana le Postgres DBMS halofo ea selemo e fetileng; pele ho moo ke ne ke se na phihlelo ea tsamaiso ea database ho hang.

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

Ke sebetsa ke le moenjiniere oa li-semi-DevOps k'hamphaning e kholo ea IT. Khampani ea rona e hlahisa software bakeng sa lits'ebeletso tse ngata haholo, 'me ke ikarabella bakeng sa ts'ebetso, tlhokomelo le phepelo. Ke fuoe mosebetsi o tloaelehileng: ho nchafatsa kopo ho seva se le seng. Kopo e ngotsoe ka Django, nakong ea ho falla ha ntlafatso ho etsoa (liphetoho tsa sebopeho sa database), 'me pele ho ts'ebetso ena re nka sebaka se feletseng sa polokelo ea database ka lenaneo le tloaelehileng la pg_dump, haeba ho ka etsahala.

Phoso e neng e sa lebelloa e etsahetse nakong ea ho lahla (Postgres version 9.5):

pg_dump: Oumping the contents of table “ws_log_smevlog” failed: PQgetResult() failed.
pg_dump: Error message from server: ERROR: invalid page in block 4123007 of relatton base/16490/21396989
pg_dump: The command was: COPY public.ws_log_smevlog [...]
pg_dunp: [parallel archtver] a worker process dled unexpectedly

phosong "leqephe le fosahetseng bolokong" e bua ka mathata a boemo ba tsamaiso ea lifaele, e leng bobe haholo. Liforamong tse fapaneng ho ile ha khothaletsoa ho etsoa MOHLAKOLA PHETHA ka kgetho maqephe_a senyehileng_a_zero ho rarolla bothata bona. Joale, ha re lekeng...

Ho itokisetsa ho hlaphoheloa

HO NAHANA! Etsa bonnete ba hore u nka bekapo ea Postgres pele u leka ho khutlisa database ea hau. Haeba u na le mochini o sebetsang, emisa database 'me u nke senepe. Haeba ho sa khonehe ho nka snapshot, emisa polokelo ea polokelo 'me u kopise litaba tsa buka ea Postgres (ho kenyeletsoa le lifaele tsa wal) sebakeng se sireletsehileng. Ntho e ka sehloohong khoebong ea rona ha se ho mpefatsa lintho. Bala e.

Kaha database e ne e sebetsa molemong oa ka, ke ile ka ipehela sebaka sa ho lahla database, empa ke sa kenye tafole e nang le data e senyehileng (khetho -T, --exclude-tafole=TAEBELE ho pg_lahla).

Seva e ne e le 'mele, ho ne ho sa khonehe ho nka senepe. Backup e tlositsoe, ha re tsoeleng pele.

Hlahloba tsamaiso ea faele

Pele re leka ho tsosolosa database, re lokela ho etsa bonnete ba hore ntho e 'ngoe le e' ngoe e hlophisitsoe hantle le tsamaiso ea faele ka boeona. 'Me haeba ho na le liphoso, li lokise, hobane ho seng joalo u ka mpefatsa lintho.

Tabeng ea ka, sistimi ea faele e nang le database e ne e kentsoe "/ srv" mme mofuta o ne o le ext4.

Ho emisa database: systemctl setopong [imeile e sirelelitsoe] 'me u hlahlobe hore na sistimi ea faele ha e sebelisoe ke mang kapa mang mme e ka theoloa ho sebelisoa taelo lsof:
lsof +D /srv

Hape ke ile ka tlameha ho emisa database ea redis, kaha e ne e boetse e sebelisa "/ srv". Ka mor'a moo ke ile ka theoha / srv (ho phahamisa).

Sistimi ea faele e ile ea hlahlojoa ho sebelisoa lisebelisoa e-e ka switch -f (Qobella ho hlahloba le haeba sistimi ea faele e tšoailoe e hloekile):

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

E latelang, sebelisa lisebelisoa lahla2fs (sudo dumpe2fs /dev/mapper/gu2—sys-srv | grep e hlahlobiloe) o ka netefatsa hore cheke e hlile e entsoe:

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

e-e e re ha ho mathata a fumanoeng boemong ba tsamaiso ea faele ea ext4, ho bolelang hore u ka tsoela pele ho leka ho tsosolosa database, kapa ho e-na le hoo u khutlele ho vacuum e tletse (ehlile, o hloka ho khutlisa sistimi ea faele ebe o qala database).

Haeba u na le seva sa 'mele, etsa bonnete ba hore u sheba boemo ba li-disk (ka smartctl -a /dev/XXX) kapa molaoli oa RAID ho etsa bonnete ba hore bothata ha bo boemong ba hardware. Tabeng ea ka, RAID e ile ea fetoha "hardware", kahoo ke ile ka kōpa mookameli oa sebaka seo hore a hlahlobe boemo ba RAID (seva e ne e le lik'hilomithara tse makholo a 'maloa ho tloha ho' na). O ile a re ho ne ho se na liphoso, ho bolelang hore re ka qala ho tsosolosa.

Boiteko ba 1: zero_damaged_maqephe

Re hokela database ka psql ka akhaonto e nang le litokelo tsa superuser. Re hloka superuser, hobane ... kgetho maqephe_a senyehileng_a_zero ke yena feela ya ka fetohang. Tabeng ea ka ke postgres:

psql -h 127.0.0.1 -U postgres -s [database_name]

Khetho maqephe_a senyehileng_a_zero e hlokahalang bakeng sa ho hlokomoloha liphoso tsa ho bala (ho tsoa webosaeteng ea postgrespro):

Ha PostgreSQL e bona sehlooho sa leqephe se senyehileng, hangata e tlaleha phoso ebe e hlakola tšebetso ea hajoale. Haeba zero_damaged_pages e lumelletsoe, sistimi e fana ka temoso, e hlakola leqephe le senyehileng mohopolong, ebe e tsoela pele ho sebetsa. Boitšoaro bona bo senya data, e leng mela eohle e leqepheng le senyehileng.

Re nolofalletsa khetho mme re leka ho etsa vacuum e felletseng ea litafole:

VACUUM FULL VERBOSE

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)
Ka bomalimabe, bomalimabe.

Re fumane phoso e tšoanang:

INFO: vacuuming "“public.ws_log_smevlog”
WARNING: invalid page in block 4123007 of relation base/16400/21396989; zeroing out page
ERROR: unexpected chunk number 573 (expected 565) for toast value 21648541 in pg_toast_106070

pg_toast - mokhoa oa ho boloka "data e telele" ho Poetgres haeba e sa kene leqepheng le le leng (8kb ka kamehla).

Boiteko ba 2: reindex

Keletso ea pele e tsoang ho Google ha ea ka ea thusa. Ka mor'a metsotso e seng mekae ke batla, ke ile ka fumana keletso ea bobeli - ho etsa reindex tafole e senyehileng. Ke bone keletso ena libakeng tse ngata, empa ha ea ka ea etsa hore motho a itšepe. Ha re hlaloseng:

reindex table ws_log_smevlog

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

reindex phethoa ntle le mathata.

Leha ho le joalo, sena ha sea ka sa thusa, SEHLOKO LE PHETHA e thulane le phoso e tshoanang le yona. Kaha ke tloaetse ho hloleha, ke ile ka qala ho batla likeletso inthaneteng mme ka fumana tse ling tse khahlisang sengoloa.

Boiteko ba 3: KHETHA, MOLIMELI, PHETHA

Sengoloa se kaholimo se khothalelitse ho sheba lethathamo la tafole ka mola le ho tlosa data e nang le mathata. Pele ho tsohle, re lokela ho ela hloko likarolo tsohle:

for ((i=0; i<"Number_of_rows_in_nodes"; i++ )); do psql -U "Username" "Database Name" -c "SELECT * FROM nodes LIMIT 1 offset $i" >/dev/null || echo $i; done

Tabeng ea ka, tafole e ne e le teng 1 628 991 mela! Ho ne ho hlokahala ho hlokomeloa hantle karohano ya data, empa sena ke sehlooho sa puisano e arohaneng. E ne e le Moqebelo, ke ile ka matha taelo ena ka tmux eaba ke ea robala:

for ((i=0; i<1628991; i++ )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog LIMIT 1 offset $i" >/dev/null || echo $i; done

Hoseng ke ile ka etsa qeto ea ho hlahloba hore na lintho li tsamaea joang. Ke ile ka makala ha ke fumana hore ka mor'a lihora tse 20, ke 2% feela ea data e neng e hlahlojoa! Ke ne ke sa batle ho ema matsatsi a 50. Ho hloleha ho hong ho felletseng.

Empa ha kea ka ka tela. Ke ile ka ipotsa hore na ke hobane'ng ha scanning e nkile nako e telele hakana. Ho tsoa litokomaneng (hape ho postgrespro) ke fumane:

OFFSET e bolela ho tlola palo e boletsoeng ea mela pele e qala ho hlahisa mela.
Haeba ka bobeli OFFSET le LIMIT li hlalositsoe, sistimi e qala ka ho tlola mela ea OFFSET ebe e qala ho bala mela bakeng sa tšitiso ea LIMIT.

Ha o sebelisa LIMIT, ho bohlokoa hape ho sebelisa ORDER BY clause e le hore mela ea sephetho e khutlisetsoe ka tatellano e itseng. Ho seng joalo, likaroloana tse sa lebelloang tsa mela li tla khutlisoa.

Ho hlakile hore taelo e ka holimo e ne e fosahetse: pele, ho ne ho se na laela ka, phello e ka ba e fosahetseng. Taba ea bobeli, Postgres o ile a tlameha ho qala ho skena le ho tlola mela ea OFFSET, 'me ka ho eketseha OFFSET tlhahiso e ne e tla fokotseha le ho feta.

Boiteko ba 4: nka lahla ka mokhoa oa mongolo

Joale ho ile ha fihla mohopolo oa ka o bonahalang o le bohlale: nka lahla ka mokhoa oa mongolo 'me u hlahlobe mola o rekotiloeng oa ho qetela.

Empa pele, a re hlahlobeng sebōpeho sa tafole. ws_log_smevlog:

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

Tabeng ea rona re na le kholomo "Id", e neng e e-na le sekhetho se ikhethileng (counter) sa mola. Leano le ne le le tjena:

  1. Re qala ho lahla ka mokhoa oa mongolo (ka mokhoa oa litaelo tsa sql)
  2. Ka nako e itseng, ho lahla ho ne ho tla sitisoa ka lebaka la phoso, empa faele ea mongolo e ne e ntse e tla bolokoa ho disk.
  3. Re sheba qetellong ea faele ea mongolo, ka hona re fumana sekhetho (id) sa mohala oa ho qetela o tlositsoeng ka katleho.

Ke ile ka qala ho lahla ka mokhoa oa mongolo:

pg_dump -U my_user -d my_database -F p -t ws_log_smevlog -f ./my_dump.dump

Lahlela, joalo ka ha ho ne ho lebelletsoe, e ile ea sitisoa ke phoso e tšoanang:

pg_dump: Error message from server: ERROR: invalid page in block 4123007 of relatton base/16490/21396989

Ho feta moo mohatla Ke ile ka sheba pheletsong ea thotobolo (mohatla -5 ./my_dump.dump) o fumane hore thotobolo e ile ea sitisoa moleng o nang le id 186 525. "Kahoo bothata bo mocheng oa id 186 526, e robehile, 'me e hloka ho hlakoloa!" – ke ile ka nahana. Empa, ho etsa potso ho database:
«khetha * ho tloha ws_log_smevlog moo id=186529"Ho ile ha fumaneha hore ntho e 'ngoe le e' ngoe e ne e le hantle ka mohala ona ... Mela e nang le li-indices 186 - 530 e boetse e sebetsa ntle le mathata. “Khopolo e ’ngoe e bohlale” e ile ea hlōleha. Hamorao ke ile ka utloisisa hore na ke hobane'ng ha sena se etsahetse: ha o hlakola le ho fetola data tafoleng, ha e hlakoloe 'meleng, empa e tšoauoa e le "li-tuples tse shoeleng", ebe lia tla. autovacuum le ho tšoaea mela ena e le e hlakotsoeng le ho lumella mela ena hore e sebelisoe hape. Ho utloisisa, haeba data e tafoleng e fetoha 'me autovacuum e nolofalitsoe, joale ha e bolokehe ka tatellano.

Boiteko ba 5: KHETHA, HO TSOA, MANE id=

Ho hloleha ho re matlafatsa. Le ka mohla ha ua lokela ho tela, u lokela ho ea qetellong 'me u lumele ho uena le bokhoni ba hau. Kahoo ke ile ka etsa qeto ea ho leka khetho e 'ngoe: sheba feela lirekoto tsohle tse ka har'a database ka bonngoe. Ho tseba sebopeho sa tafole ea ka (bona ka holimo), re na le tšimo ea id e ikhethang (senotlolo sa mantlha). Re na le mela e 1 tafoleng le id li hantle, ho bolelang hore re ka li feta ka bonngoe:

for ((i=1; i<1628991; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

Haeba mang kapa mang a sa utloisise, taelo e sebetsa ka tsela e latelang: e hlahloba lethathamo la tafole ka mola 'me e romela stdout ho. / dev / null, empa haeba taelo ea SELECT e hlōleha, joale molaetsa oa phoso oa hatisoa (stderr o romelloa ho console) 'me mola o nang le phoso o hatisoa (ka lebaka la ||, ho bolelang hore mokhethoa o bile le mathata (khoutu ea ho khutlisa taelo). ha se 0)).

Ke bile lehlohonolo, ke bile le li-index tse entsoeng lebaleng id:

Phihlelo ea ka ea pele ea ho fumana database ea Postgres kamora ho hloleha (leqephe le sa sebetseng ho block 4123007 ea relatton base/16490)

Sena se bolela hore ho fumana mola o nang le id e lakatsehang ha hoa lokela ho nka nako e ngata. Ka khopolo e lokela ho sebetsa. Hantle, ha re ke re tsamaise taelo ka hare tmux mme a re yeng ho robala.

Hoseng ke fumane hore ho se ho shebiloe lipehelo tse ka bang 90, tse fetang 000%. Sephetho se setle ha se bapisoa le mokhoa o fetileng (5%)! Empa ke ne ke sa batle ho ema matsatsi a 2 ...

Boiteko ba 6: KHETHA, HO TSOA, MANE id >= le id

Moreki o ne a e-na le seva se setle se inehetseng ho database: dual-processor Intel Xeon E5-2697 v2, ho ne ho e-na le likhoele tse ka bang 48 sebakeng sa rōna! Mojaro o ka har'a seva e ne e le karolelano; re ne re ka khoasolla likhoele tse ka bang 20 ntle le mathata. Ho ne ho boetse ho na le RAM e lekaneng: hoo e ka bang 384 gigabytes!

Ka hona, taelo e ne e lokela ho bapisoa:

for ((i=1; i<1628991; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

Mona ho ne ho khoneha ho ngola mongolo o motle le o motle, empa ke ile ka khetha mokhoa o potlakileng oa ho bapisa: ka letsoho arola mefuta e fapaneng ea 0-1628991 ka linako tse ling tsa lirekoto tse 100 'me u tsamaise litaelo tse 000 tsa foromo ka thoko:

for ((i=N; i<M; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

Empa ha se eona feela. Ka khopolo, ho hokahanya le database le hona ho nka nako le lisebelisoa tsa tsamaiso. Ho hokahanya 1 ho ne ho se bohlale haholo, o tla lumela. Ka hona, ha re fumaneng mela e 628 sebakeng sa khokahano e le 'ngoe. Ka lebaka leo, sehlopha se fetohile:

for ((i=N; i<M; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done

Bula lifensetere tse 16 nakong ea tmux 'me u tsamaise litaelo:

1) for ((i=0; i<100000; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
2) for ((i=100000; i<200000; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
…
15) for ((i=1400000; i<1500000; i=$((i+1000)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
16) for ((i=1500000; i<1628991; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done

Letsatsi hamorao ke ile ka fumana liphetho tsa pele! E leng (litekanyetso XXX le ZZZ ha li sa bolokoa):

ERROR:  missing chunk number 0 for toast value 37837571 in pg_toast_106070
829000
ERROR:  missing chunk number 0 for toast value XXX in pg_toast_106070
829000
ERROR:  missing chunk number 0 for toast value ZZZ in pg_toast_106070
146000

Sena se bolela hore mela e meraro e na le phoso. Li-ID tsa litlaleho tsa bothata ba pele le ba bobeli li ne li le pakeng tsa 829 le 000, li-ID tsa boraro li ne li le pakeng tsa 830 le 000. Ka mor'a moo, re ne re tlameha feela ho fumana boleng ba id bo nepahetseng ba litlaleho tsa bothata. Ho etsa sena, re sheba lethathamong la rona ka lirekoto tse nang le mathata ka mohato oa 146 ebe re tseba id:

for ((i=829000; i<830000; i=$((i+1)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done
829417
ERROR:  unexpected chunk number 2 (expected 0) for toast value 37837843 in pg_toast_106070
829449
for ((i=146000; i<147000; i=$((i+1)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done
829417
ERROR:  unexpected chunk number ZZZ (expected 0) for toast value XXX in pg_toast_106070
146911

Qetellong e thabisang

Re fumane mela e nang le mathata. Re kena ka har'a database ka psql ebe re leka ho li hlakola:

my_database=# delete from ws_log_smevlog where id=829417;
DELETE 1
my_database=# delete from ws_log_smevlog where id=829449;
DELETE 1
my_database=# delete from ws_log_smevlog where id=146911;
DELETE 1

Ho makaleng ha ka, likeno li ile tsa hlakoloa ntle le mathata leha e le ntle le khetho maqephe_a senyehileng_a_zero.

Eaba ke hokela database, ke entse joalo SEHLOKO LE PHETHA (Ke nahana hore ho ne ho sa hlokahale ho etsa sena), mme qetellong ke ile ka tlosa bekapo ka katleho ke sebelisa pg_lahla. Thotobolo e nkiloe ntle le liphoso leha e le life! Bothata bo ile ba rarolloa ka tsela e hlokang kelello joalo. Thabo e ne e se na meeli, ka mor’a ho hlōleha ho hongata hakana re ile ra khona ho fumana tharollo!

Liteboho le Qetello

Ke kamoo phihlelo ea ka ea pele ea ho tsosolosa database ea sebele ea Postgres e ileng ea etsahala kateng. Ke tla hopola phihlelo ena ka nako e telele.

Qetellong, ke rata ho leboha PostgresPro bakeng sa ho fetolela litokomane ho Serussia le bakeng sa lithuto tsa mahala tsa inthanete ka ho felletseng, e ileng ea thusa haholo nakong ea tlhahlobo ea bothata.

Source: www.habr.com

Eketsa ka tlhaloso