Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

Emi yoo fẹ lati pin pẹlu rẹ iriri aṣeyọri akọkọ mi ti mimu-pada sipo data Postgres si iṣẹ ṣiṣe ni kikun. Mo ti mọ pẹlu Postgres DBMS ni idaji ọdun sẹyin ṣaaju pe Emi ko ni iriri ninu iṣakoso data rara.

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

Mo ṣiṣẹ bi ẹlẹrọ ologbele-DevOps ni ile-iṣẹ IT nla kan. Ile-iṣẹ wa n ṣe agbekalẹ sọfitiwia fun awọn iṣẹ fifuye giga, ati pe Mo ni iduro fun iṣẹ ṣiṣe, itọju ati imuṣiṣẹ. A fun mi ni iṣẹ-ṣiṣe boṣewa: lati ṣe imudojuiwọn ohun elo kan lori olupin kan. Ohun elo naa ti kọ ni Django, lakoko awọn iṣipopada imudojuiwọn ni a ṣe (awọn iyipada ninu ipilẹ data), ati ṣaaju ilana yii a mu idalẹnu data ni kikun nipasẹ eto pg_dump boṣewa, o kan ni ọran.

Aṣiṣe airotẹlẹ waye lakoko mimu idalẹnu kan (Ẹya Postgres 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

Error "oju-iwe ti ko tọ ni idina" sọrọ ti awọn iṣoro ni ipele eto faili, eyiti o buru pupọ. Lori awọn apejọ oriṣiriṣi o ti daba lati ṣe Igbale FULL pẹlu aṣayan odo_bajẹ oju ewe lati yanju isoro yi. O dara, jẹ ki a gbiyanju...

Ngbaradi fun imularada

IWO! Rii daju pe o gba afẹyinti Postgres ṣaaju igbiyanju eyikeyi lati mu pada data rẹ pada. Ti o ba ni ẹrọ foju kan, da data data duro ki o ya aworan kan. Ti ko ba ṣee ṣe lati ya aworan kan, da data data duro ki o daakọ awọn akoonu ti itọsọna Postgres (pẹlu awọn faili wal) si aaye ailewu. Ohun akọkọ ninu iṣowo wa kii ṣe lati jẹ ki awọn nkan buru si. Ka eyi ni.

Niwọn bi data data ṣe n ṣiṣẹ fun mi ni gbogbogbo, Mo fi opin si ara mi si idalẹnu data deede, ṣugbọn yọkuro tabili pẹlu data ti o bajẹ (aṣayan -T, --exclude-table=TABLE ninu pg_dump).

Olupin naa jẹ ti ara, ko ṣee ṣe lati ya aworan kan. A ti yọ afẹyinti kuro, jẹ ki a tẹsiwaju.

Ṣayẹwo eto faili

Ṣaaju igbiyanju lati mu pada database, a nilo lati rii daju pe ohun gbogbo wa ni ibere pẹlu eto faili funrararẹ. Ati ninu ọran ti awọn aṣiṣe, ṣe atunṣe wọn, nitori bibẹẹkọ o le jẹ ki awọn nkan buru si.

Ninu ọran mi, eto faili pẹlu data data ti gbe sinu "/srv" ati iru wà ext4.

Duro data data: systemctl da postgresql@9.5-main.service ati ṣayẹwo pe eto faili ko si ni lilo nipasẹ ẹnikẹni ati pe o le yọ kuro nipa lilo aṣẹ naa tun:
lsof +D/srv

Mo tun ni lati da redis database duro, niwon o tun nlo "/srv". Next Mo unmounted /srv (oke).

Eto faili ti ṣayẹwo ni lilo ohun elo naa e2fsck pẹlu yipada -f (Fi agbara mu ṣiṣe ayẹwo paapaa ti eto faili ba jẹ ami mimọ):

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

Nigbamii ti, lilo ohun elo dumpe2fs (sudo dumpe2fs /dev/mapper/gu2-sys-srv | grep ẹnikeji) o le rii daju pe ayẹwo naa ti ṣe ni otitọ:

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

e2fsck sọ pe ko si awọn iṣoro ti a rii ni ipele eto faili ext4, eyiti o tumọ si pe o le tẹsiwaju igbiyanju lati mu data data pada, tabi dipo pada si igbale kun (dajudaju, o nilo lati gbe eto faili pada ki o bẹrẹ data data).

Ti o ba ni olupin ti ara, rii daju lati ṣayẹwo ipo awọn disiki naa (nipasẹ smartctl -a /dev/XXX) tabi oluṣakoso RAID lati rii daju pe iṣoro naa ko si ni ipele ohun elo. Ninu ọran mi, RAID ti jade lati jẹ “hardware”, nitorinaa Mo beere lọwọ alabojuto agbegbe lati ṣayẹwo ipo ti RAID (olupin naa wa ni ọpọlọpọ awọn ibuso kilomita si mi). O sọ pe ko si awọn aṣiṣe, eyiti o tumọ si pe dajudaju a le bẹrẹ imupadabọ.

Igbiyanju 1: zero_damaged_pages

A sopọ si ibi ipamọ data nipasẹ psql pẹlu akọọlẹ kan ti o ni awọn ẹtọ superuser. A nilo superuser, nitori... aṣayan odo_bajẹ oju ewe on nikan lo le yipada. Ninu ọran mi o jẹ postgres:

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

Aṣayan odo_bajẹ oju ewe nilo lati foju kọ awọn aṣiṣe kika (lati oju opo wẹẹbu postgrespro):

Nigbati PostgreSQL ṣe awari akọsori oju-iwe ti o bajẹ, o maa n jabo aṣiṣe kan ati ki o fawọ idunadura lọwọlọwọ. Ti awọn oju-iwe zero_damaged_ṣiṣẹ ba ṣiṣẹ, eto dipo ikilọ kan, yọkuro oju-iwe ti o bajẹ ni iranti, ati tẹsiwaju sisẹ. Iwa yii npa data run, eyun gbogbo awọn ori ila ni oju-iwe ti o bajẹ.

A mu aṣayan ṣiṣẹ ati gbiyanju lati ṣe igbale kikun ti awọn tabili:

VACUUM FULL VERBOSE

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)
Laanu, buburu orire.

A ṣe alabapade iru aṣiṣe kan:

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_tositi - ẹrọ kan fun titoju “data gigun” ni Poetgres ti ko ba wo oju-iwe kan (8kb nipasẹ aiyipada).

Igbiyanju 2: atunṣe

Imọran akọkọ lati ọdọ Google ko ṣe iranlọwọ. Lẹhin iṣẹju diẹ ti wiwa, Mo rii imọran keji - lati ṣe atunkọ ti bajẹ tabili. Mo ti rii imọran yii ni ọpọlọpọ awọn aaye, ṣugbọn ko fun ni igboya. Jẹ ki a tun atọkasi:

reindex table ws_log_smevlog

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

atunkọ pari lai isoro.

Sibẹsibẹ, eyi ko ṣe iranlọwọ, VACUM FULL kọlu pẹlu iru aṣiṣe. Niwọn igba ti Mo ti lo si awọn ikuna, Mo bẹrẹ lati wa siwaju fun imọran lori Intanẹẹti ati pe o nifẹ si pupọ nkan.

Igbiyanju 3: Yan, LIMIT, OFFSET

Nkan ti o wa loke daba wiwo tabili laini laini ati yiyọ data iṣoro kuro. Ni akọkọ a nilo lati wo gbogbo awọn ila:

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

Ninu ọran mi, tabili ti o wa ninu 1 628 991 awọn ila! O jẹ dandan lati ṣe abojuto daradara data ipin, ṣugbọn eyi jẹ koko-ọrọ fun ijiroro lọtọ. O jẹ Satidee, Mo ran aṣẹ yii ni tmux mo si lọ si ibusun:

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

Ni owurọ Mo pinnu lati ṣayẹwo bi awọn nkan ṣe nlọ. Si iyalenu mi, Mo ṣe awari pe lẹhin awọn wakati 20, nikan 2% ti data ti ṣayẹwo! Emi ko fẹ lati duro 50 ọjọ. Ikuna pipe miiran.

Sugbon Emi ko fun. Mo ṣe iyalẹnu idi ti wíwo naa ṣe pẹ to. Lati iwe (lẹẹkansi lori postgrespro) Mo rii pe:

OFFSET ni pato lati foju nọmba awọn ori ila ti a sọ tẹlẹ ṣaaju ki o to bẹrẹ si awọn ori ila jade.
Ti mejeeji OFFSET ati LIMIT jẹ pato, eto naa kọkọ fo awọn ori ila OFFSET ati lẹhinna bẹrẹ kika awọn ori ila fun ihamọ LIMIT.

Nigbati o ba nlo LIMIT, o ṣe pataki lati tun lo BERE NIPA gbolohun ọrọ ki awọn ila abajade yoo pada ni aṣẹ kan pato. Bibẹẹkọ, awọn ipin ti a ko sọtẹlẹ ti awọn ori ila yoo pada.

O han ni, aṣẹ ti o wa loke ko tọ: ni akọkọ, ko si paṣẹ nipasẹ, abajade le jẹ aṣiṣe. Ni ẹẹkeji, Postgres akọkọ ni lati ṣe ọlọjẹ ati fo awọn ori ila OFFSET, ati pẹlu jijẹ TITẸ iṣelọpọ yoo kọ paapaa siwaju sii.

Igbiyanju 4: gbe silẹ ni fọọmu ọrọ

Lẹhinna imọran ti o dabi ẹnipe o wuyi wa si ọkan mi: gbe silẹ ni fọọmu ọrọ ki o ṣe itupalẹ laini ti o gbasilẹ kẹhin.

Ṣugbọn akọkọ, jẹ ki a wo ọna ti tabili naa. w_log_smevlog:

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

Ninu ọran wa a ni ọwọn "Id", eyiti o ni idamo ara oto (counter) ti kana. Ètò náà rí báyìí:

  1. A bẹrẹ lati mu idalẹnu ni fọọmu ọrọ (ni irisi awọn aṣẹ sql)
  2. Ni aaye kan ni akoko, idalenu naa yoo ni idilọwọ nitori aṣiṣe kan, ṣugbọn faili ọrọ yoo tun wa ni fipamọ sori disiki.
  3. A wo ipari faili ọrọ naa, nitorinaa a rii idanimọ (id) ti laini ikẹhin ti o yọkuro ni aṣeyọri

Mo bẹrẹ si mu idalẹnu kan ni fọọmu ọrọ:

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

Idasonu naa, bi o ti ṣe yẹ, ni idilọwọ pẹlu aṣiṣe kanna:

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

Siwaju sii nipasẹ iru Mo wo opin idalẹnu naa (ìrù -5 ./my_dump.dump) ṣe awari pe idalẹnu naa ni idilọwọ lori laini pẹlu id 186 525. "Nitorina iṣoro naa wa ni laini pẹlu id 186 526, o ti bajẹ, o nilo lati paarẹ!" – Mo ro. Ṣugbọn, ṣiṣe ibeere kan si aaye data:
«yan * lati ws_log_smevlog nibiti id=186529"O wa ni pe ohun gbogbo dara pẹlu laini yii ... Awọn ori ila pẹlu awọn atọka 186 - 530 tun ṣiṣẹ laisi awọn iṣoro. “Ero didan” miiran kuna. Nigbamii Mo loye idi ti eyi fi ṣẹlẹ: nigbati piparẹ ati yiyipada data lati tabili kan, wọn ko paarẹ ti ara, ṣugbọn ti samisi bi “awọn tuple ti o ku”, lẹhinna wa. autovacuum o si samisi awọn ila wọnyi bi paarẹ ati gba awọn ila wọnyi laaye lati tun lo. Lati loye, ti data ti o wa ninu tabili ba yipada ati pe a ti mu adaṣe ṣiṣẹ, lẹhinna ko tọju ni lẹsẹsẹ.

Igbiyanju 5: Yan, LATI, NIBI id=

Awọn ikuna mu wa lagbara. O ko gbọdọ fi silẹ, o nilo lati lọ si opin ati gbagbọ ninu ara rẹ ati awọn agbara rẹ. Nitorinaa Mo pinnu lati gbiyanju aṣayan miiran: kan wo nipasẹ gbogbo awọn igbasilẹ ti o wa ninu database ni ọkọọkan. Mọ ilana ti tabili mi (wo loke), a ni aaye id eyiti o jẹ alailẹgbẹ (bọtini akọkọ). A ni 1 awọn ori ila ninu tabili ati id wa ni ibere, eyi ti o tumọ si pe a le lọ nipasẹ wọn ni ọkọọkan:

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

Ti ẹnikẹni ko ba loye, aṣẹ naa n ṣiṣẹ bi atẹle: o ṣe ayẹwo laini tabili ni ila ati firanṣẹ stdout si / dev / null, ṣugbọn ti o ba ti yan pipaṣẹ kuna, lẹhinna ọrọ aṣiṣe ti wa ni titẹ (stderr ti firanṣẹ si console) ati laini ti o ni aṣiṣe naa ti tẹ (ọpẹ si ||, eyiti o tumọ si pe yan ni awọn iṣoro (koodu ipadabọ ti aṣẹ naa) kii ṣe 0)).

Mo ni orire, Mo ni awọn atọka ti a ṣẹda lori aaye naa id:

Iriri akọkọ mi n gba data data Postgres pada lẹhin ikuna kan (oju-iwe ti ko tọ ni bulọki 4123007 ti ipilẹ relatton/16490)

Eyi tumọ si wiwa laini pẹlu id ti o fẹ ko yẹ ki o gba akoko pupọ. Ni imọran o yẹ ki o ṣiṣẹ. O dara, jẹ ki a ṣiṣẹ aṣẹ naa sinu tmux kí a sì sùn.

Ni owurọ Mo rii pe awọn titẹ sii 90 ti wo, eyiti o kọja 000%. Abajade ti o tayọ nigbati a bawe pẹlu ọna iṣaaju (5%)! Ṣugbọn Emi ko fẹ lati duro 2 ọjọ ...

Igbiyanju 6: Yan, LATI, NIBI id>= ati id

Onibara ni olupin ti o tayọ ti a ṣe igbẹhin si ibi ipamọ data: meji-isise Intel Xeon E5-2697 v2, ọpọlọpọ bi awọn okun 48 wa ni ipo wa! Awọn fifuye lori olupin je apapọ; Ramu tun wa: bi 20 gigabytes!

Nitorinaa, aṣẹ naa nilo lati wa ni afiwe:

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

Nibi o ṣee ṣe lati kọ iwe afọwọkọ ẹlẹwa ati didara, ṣugbọn Mo yan ọna isọdọkan yiyara: pẹlu ọwọ pin sakani 0-1628991 si awọn aaye arin ti awọn igbasilẹ 100 ati ṣiṣe lọtọ awọn aṣẹ 000 ti fọọmu naa:

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

Sugbon ti o ni ko gbogbo. Ni imọran, sisopọ si ibi ipamọ data tun gba akoko diẹ ati awọn orisun eto. Sisopọ 1 kii ṣe ọlọgbọn pupọ, iwọ yoo gba. Nitorinaa, jẹ ki a gba awọn ori ila 628 pada dipo ọkan lori asopọ kan. Bi abajade, ẹgbẹ naa yipada si eyi:

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

Ṣii awọn window 16 ni igba tmux ati ṣiṣe awọn aṣẹ:

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

Ni ọjọ kan Mo gba awọn abajade akọkọ! Eyun (awọn iye XXX ati ZZZ ko ni ipamọ mọ):

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

Eyi tumọ si pe awọn ila mẹta ni aṣiṣe ninu. Awọn ids ti awọn igbasilẹ iṣoro akọkọ ati keji wa laarin 829 ati 000, awọn ids kẹta wa laarin 830 ati 000 ni atẹle, a ni lati wa iye id gangan ti awọn igbasilẹ iṣoro naa. Lati ṣe eyi, a wo nipasẹ iwọn wa pẹlu awọn igbasilẹ iṣoro pẹlu igbesẹ ti 146 ati ṣe idanimọ 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

Ipari alayo

A ri awọn ila iṣoro. A lọ sinu aaye data nipasẹ psql ati gbiyanju lati pa wọn rẹ:

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

Si iyalenu mi, awọn titẹ sii ti paarẹ laisi awọn iṣoro eyikeyi paapaa laisi aṣayan odo_bajẹ oju ewe.

Nigbana ni mo ti sopọ si awọn database, ṣe VACUM FULL (Mo ro pe ko ṣe pataki lati ṣe eyi), ati nikẹhin Mo yọ afẹyinti kuro ni lilo pg_idasonu. A mu idalẹnu naa laisi awọn aṣiṣe eyikeyi! A yanjú ìṣòro náà lọ́nà òmùgọ̀ bẹ́ẹ̀. Ayọ naa ko mọ awọn opin, lẹhin ọpọlọpọ awọn ikuna a ṣakoso lati wa ojutu kan!

Awọn iyin ati Ipari

Eyi ni bii iriri akọkọ mi ti mimu-pada sipo data Postgres gidi kan tan. Emi yoo ranti iriri yii fun igba pipẹ.

Ati nikẹhin, Emi yoo fẹ lati sọ o ṣeun si PostgresPro fun titumọ iwe naa si Russian ati fun patapata free online courses, eyiti o ṣe iranlọwọ pupọ lakoko itupalẹ iṣoro naa.

orisun: www.habr.com

Ra alejo gbigba igbẹkẹle fun awọn aaye pẹlu aabo DDoS, awọn olupin VPS VDS 🔥 Ra gbigbalejo oju opo wẹẹbu ti o gbẹkẹle pẹlu aabo DDoS, awọn olupin VPS VDS | ProHoster