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.
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
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):
Deinde utens utilitate dumpe2fs (sudo dumpe2fs /dev/mapper/gu2—sys-srv | grep sedatus) cognoscere potes quod perscriptio facta est:
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
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
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
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
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
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:
In casu nostro columnam habemus 'D'quod unicum identificatorium ordinis continebat. Consilium hoc erat simile;
- Incipimus accipere TUBER in textu formam (in forma sql mandata)
- In quodam puncto temporis, TUBER ob errorem interpellaretur, sed fasciculus textus in orbe adhuc salvus esset.
- 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:
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
Source: www.habr.com