Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

Te vellem communicare primam meam felicitatem experientiam restituendi Postgres datorum ad plenam functionem. Cognovi cum Postgres DBMS dimidium annum ante, ante me nullam expertus essem in administratione datorum omnino.

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

Laboro ut semi-DevOps architectus in magna IT comitatu. Societas nostra programmata pro maximis oneris officiis enucleat, et ego responsalis effectus, sustentationis et instruere. Vexillum negotium datum est: ad applicationem in uno servo update. Applicatio in Django scripta est, dum migrationes renovationis fiunt (mutationes in structuram datorum), et antequam hoc processum plenam datorum TUBER per vexillum pg_dump programmatis accipimus, in casu.

Error inopinatus occurrit accipiens TUBER (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

Error "Nulla pagina in obstructionum" loquitur de quaestionibus in ordine tabellae systematis, quod est pessimum. In variis foris facere suggesserant Plenus VACUUM per optionem zero_damaged_pages solvere hanc quaestionem. Bene, experiri...

Praeparans ad recuperationem

ВНИМАНИЕ! Vide ut tergum recipias Postgres antequam aliquem conatum database tui restituendi. Si machinam virtualem habes, siste datorum et schoham accipe. Si snapshot non potest accipere, siste datorum et effingo contenta directorii Postgres (inclusa fasciculis muralibus) ad locum tutum. Summa in negotio nostro non est peiora facere. Legere quod.

Cum datorum plerumque pro me laboravi, me ad TUBER datorum regularium circumscripsi, sed mensam cum notitia laesa exclusivi (optionem -T, --exclude-table=TABLE in pg_dump).

Servus corporis erat, fieri potuit ut snapshot. Tergum remotum est, proficiscamur.

File systema reprehendo

Priusquam ad datorum rationem redintegrare conaris, efficere debemus ut omnia ordine disposita sint cum ipsa tabella systema. Et si erratis, corrige, quia aliter non potes facere deterius.

In casu meo, tabella systematis datorum inclusum est "/srv" et genus ext4.

Restitit database: systemctl stop [Inscriptio protected] et vide quod ratio tabellae a quovis usui non sit, et possit incedere utendo imperio lsof *:
lsof +D /srv

Mihi quoque datorum redis sistendum erat, quia etiam usus erat "/srv". Proximum inequitare / srv (umount).

Tabella ratio de utilitate sedatus est e2fsck cum switch -f (Vis reprehendo etsi filesystem notatum est mundum):

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

Deinde utens utilitate dumpe2fs (sudo dumpe2fs /dev/mapper/gu2—sys-srv | grep sedatus) cognoscere potes quod perscriptio facta est:

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

e2fsck dicit nullas difficultates inventas esse ad gradum systematis fasciculi ext4, quod significat te pergere conari restituere database vel potius redire ad vacuum plenum (sane, lima ratio retro conscendere debes et datorum committitur).

Si corporalis server, cave statum orbis reprimendam (via smartctl -a /dev/XXX) vel INCURSIO moderatoris efficere ut problema non sit in hardware massa. In causa mea, INCURSIO evasit "hardware", ergo rogavi loci admin ut statum RAID reprimeret (servitor complures centum chiliometrorum a me abesset). Negavit errores fuisse, qui per certam restitutionem inchoare possimus.

Temptare I: zero_damaged_pages

Coniungimus ad psql datorum per rationem quae iura superuser habet. Superusorem opus est, quia... optio zero_damaged_pages tantum mutare potest. In mea causa est postgres;

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

optionem zero_damaged_pages opus est ut errores legeres ignorare (ex postgrespro website);

Cum PostgreSQL paginam corruptam detegit, typice errorem tradit et transactionem hodiernam abortivum facit. Si nulla_damaged_pages datur, ratio potius admonet, zephyris paginam laesam in memoria trahit et processus pergit. Ista mores data destruit, nimirum omnes ordines in pagina laesa.

Optionem dabimus et conantur facere plenum vacuum tabularum;

VACUUM FULL VERBOSE

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)
Infeliciter, Sorte.

Similem errorem offendit nos:

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 - Mechanismus in reponenda "longa notitia" apud Poetgres si non convenit in una pagina (8kb per defaltam).

Conatus II: reindex

Primum consilium a Google non adiuvat. Paucis minutis inquisitione, alterum extremum inveni - facere reindex laedi mensa. Hoc consilium multis in locis vidi, sed ea res parum fidebat. Let's index:

reindex table ws_log_smevlog

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

reindex sine quaestionibus perficitur.

Sed hoc non profuit; VACUUM FULL simili errore ingruat. Cum ego in defectibus soleo, consilium in Interreti quaerere longius coepi et plus interesting occurrit articulus.

Conatus III, SELECT, FINIS, INCREMENTUM

Articulus supra suggessit ordinem mensae inspicere per ordinem et notitias difficultates tollendas. Primum ad omnes lineas spectare oportuit;

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

In casu meo, mensa continebat 1 628 991 lineae! Necesse est ut bene cura notitia partitionibussed hic locus est separatim disputationis. Sabbatum erat, cucurri hoc mandatum in tmux, et ivi cubitum;

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

Mane decrevi quomodo res sequatur. Ut miretur, deprehendi post XX horas, tantum 20% notitiarum lustratam! L dies expectare nolui. Alterum defectum completum.

Sed non cedere. Mirabar cur tam diu intuens. Ex documentis (iterum in postgrespro) inveni e:

INCREMENTULUM cificat certum numerum ordinum omittere antequam incipias ad output ordines.
Si uterque INCREMENTUM et TERMINUS specificantur, systema primum ordines INDULGENTIA vagatur et deinde ordines computat propter limitem coactionis.

Cum FINIS utens, interest etiam ordinem clausulam uti, ut eventus ordinis certo ordine reddantur. Alioquin vagus ordines copia reddetur.

Patet hoc praeceptum deceptus ordinemquod evenit erronee. Secundo, Postgres primum debuit lustrare et omittere ordines, et cum augere INCREMENTUM productio etiam ulterius declinaret.

Temptare IV: accipies TUBER in text forma

Tunc mihi in mentem venit idea speciosa splendida: accipe dump in forma textu et ultimam notatam lineam resolvere.

Sed primum inspice structuram tabulae. ws_log_smevlog:

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

In casu nostro columnam habemus 'D'quod unicum identificatorium ordinis continebat. Consilium hoc erat simile;

  1. Incipimus accipere TUBER in textu formam (in forma sql mandata)
  2. In quodam puncto temporis, TUBER ob errorem interpellaretur, sed fasciculus textus in orbe adhuc salvus esset.
  3. Finem fasciculi textus spectamus, inde invenimus identifier (id) lineae ultimae quae feliciter sublata est.

Coepi accipiens TUBER in text forma:

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

Effundite, ut expectatur, eodem errore interpolatus est;

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

Praeterea per cauda Vidi in fine TUBER (cauda -5 ./my_dump.dump) TUBER intermissum in linea cum id 186 525. "Quaestio igitur est in linea cum id 186 526, fractum est et deletum est"! - Cogitavi. Sed interrogationem datorum datorum:
«eligere * ex ws_log_smevlog ubi id = 186529"Contigit omnia denique cum hoc versu ... Ordines cum indicibus 186 - 530 etiam sine problematibus elaborasse. Alia "idea praeclara" defecit. Postea intellexi cur hoc factum sit: cum notitia ex tabula delendo et mutando non corpore deleta sunt, sed ut "tuples mortua" signata sunt, tunc venit. autovacuum et notat has lineas quasi deletas et has lineas reddi permittit. Ad intellegendum, si notitiae in tabula mutationibus et autovacuum datur, tunc non continue reponitur.

Conatus V: SELECT, unde, WHERE id =

Defectus fortiores nos faciunt. Numquam desistas, ad finem ire debes et in te tuisque facultatibus credere. Itaque aliam optionem probandam decrevi: modo per omnia monumenta in datorum singillatim inspicias. Mensae meae structuram cognoscentes (vide supra), campum id habemus quod unicum est (clavis primaria). Habemus 1 ordines in mensa et id sunt in ordine, quod per eas singillatim percurrere possumus;

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

Si quis non intellegit, mandatum hoc modo facit: per ordinem mensam lustrat et per ordinem mittit / Dev / nullsed si mandatum SELECTA deficit, error textus impressus est (stderr mittitur ad consolandum) et linea continens errorem impressum est (gratias ago ||, quod significat selectos habuisse problemata (reditus codici praecepti. non 0)).

Fortunatus eram, indices habebam in agro creatos id:

Prima mea experientia recuperandae datorum Postgres post defectum (inrita pagina in scandalum 4123007 de relatton basi / 16490)

Id est invenire lineam desideratam non multum temporis. In theoria laboret. Age, mandatum curramus tmux et eamus ad lectum.

Mane exploratum inveni circa 90 viscus esse, quod plus quam 000% est. O praeclarum exitum cum methodo praecedenti (5%) comparatum! Sed XX dies expectare nolui.

Conatus VI, SELECT, unde, ubi id> = et id

Emptorem optimum servo deditum datorum: dual-processus Intel Xeon E5-2697 v2quot 48 stamina in loco nostro erant! Onus in calculonis mediocris erat, nos circiter 20 stamina sine ullis problematibus detrahere potuimus. Etiam satis RAM: quantum 384 Gigabytes!

Oportet ergo quod praecepti sit parallelismum;

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

Hic scribere pulchre et eleganter potuit scribere, sed quam celerrime methodum parallelizationis elegi: manually latitudinem 0-1628991 in intervalla 100 monumentorum scindere et separatim 000 praecepta formae discurrere;

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

Sed id nulla enim. In theoria, connectio datorum, etiam tempus ac facultates systematas accipit. Connectens 1 non valde sapis, tu consenties. Itaque 628 ordines pro uno in unum nexum repetamus. Quam ob rem quadrigis in hunc modum mutatus est;

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

16 Aperi fenestras in tmux sessione et currunt mandata;

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

Post dies primos eventus accepi! Nempe (valores XXX et ZZZ non amplius conservantur);

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

Hoc significat errorem tres lineas continere. Primae et secundae quaestionis ides erant inter 829 et 000, tertiae ides erant inter 830 et 000. Deinde simpliciter necessarium erat invenire valorem quaestionis in commentariis. Ad hoc perspicimus per ambitum nostrum cum monumentis problematicis gressum 146 ac pervidere 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

felix finis

Difficilis lineas invenimus. In via datorum psql imus et eas delere conamur:

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

Ut mirum, introitus sine ullis quaestionibus etiam sine optione deletae sunt zero_damaged_pages.

Tunc connexa database fecit VACUUM FULL (Hoc facere non necessarium puto), et tandem feliciter utens tergum amovi pg_dump. Sublatus est TUBER sine ullis erroribus! Quaestio tam stolide solvitur. Gaudium nullum modum cognovi, postquam tot delictis solutionem potuimus invenire!

Agnitiones et Conclusio

Hoc est quomodo prima experientia mea restituendi realem datorum Postgres evasit. Huius experientiae diu recordabor.

Denique gratias ago tibi dicere PostgresPro in translatione documentorum in Russian et for omnino liberum onlinequi multum adiuvit in analysi problematum.

Source: www.habr.com

Add a comment