sql >> Database teknologi >  >> RDS >> PostgreSQL

Kan jeg fortryde en transaktion, jeg allerede har begået? (tab af data)

Nej, du kan ikke fortryde, rulle tilbage eller fortryde en commit.

STOP DATABASEN!

(Bemærk:Hvis du har slettet databiblioteket fra filsystemet, skal du IKKE stoppe databasen. Følgende råd gælder for en utilsigtet commit af en DELETE eller lignende, ikke en rm -rf /data/directory scenario).

Hvis disse data var vigtige, STOP DIN DATABASE NU og genstart den ikke. Brug pg_ctl stop -m immediate så der ikke køres et kontrolpunkt ved nedlukning.

Du kan ikke rulle en transaktion tilbage, når først den er forpligtet. Du bliver nødt til at gendanne dataene fra sikkerhedskopier eller bruge punkt-i-tidsgendannelse, som skal være konfigureret før ulykken skete.

Hvis du ikke har konfigureret nogen PITR/WAL-arkivering og ikke har sikkerhedskopier, er du i virkelige problemer.

Hastende afhjælpning

Når din database er stoppet, bør du lave en kopi på filsystemniveau af hele databiblioteket - mappen, der indeholder base , pg_clog osv. Kopier det hele til et nyt sted. Gør ikke noget ved kopien på den nye placering, det er dit eneste håb om at gendanne dine data, hvis du ikke har sikkerhedskopier. Lav en anden kopi på et flytbart lager, hvis du kan, og tag derefter det lager ud af computeren. Husk, du har brug for absolut alle dele af databiblioteket, inklusive pg_xlog osv. Ingen del er ligegyldig.

Præcis hvordan du laver kopien afhænger af hvilket operativsystem du kører. Hvor datadirigenten er, afhænger af hvilket OS du kører, og hvordan du installerede PostgreSQL.

Måder nogle data kunne have overlevet

Hvis du stopper din DB hurtigt nok, har du måske et håb om at gendanne nogle data fra tabellerne. Det er fordi PostgreSQL bruger multi-version concurrency control (MVCC) til at administrere samtidig adgang til dets lager. Nogle gange vil den skrive nye versioner af rækkerne opdaterer du til tabellen, og efterlader de gamle på plads, men markeret som "slettet". Efter et stykke tid kommer autovaccum og markerer rækkerne som ledig plads, så de kan overskrives af en senere INSERT eller UPDATE . Således er de gamle versioner af UPDATE d rækker kan stadig ligge, tilstede, men utilgængelige.

Derudover skriver Pg i to faser. De første data skrives til WAL-loggen (write-ahead). Først når det er blevet skrevet til WAL'en og ramt disken, bliver det derefter kopieret til "heapen" (hovedtabellerne), hvilket muligvis overskriver gamle data, der var der. WAL-indholdet kopieres til hovedbunken af ​​bgwriter og ved periodiske kontrolpunkter. Som standard sker kontrolpunkter hvert 5. minut. Hvis det lykkes dig at stoppe databasen, før et kontrolpunkt er sket, og stoppet det ved at slå den hårdt ihjel, trække stikket på maskinen eller bruge pg_ctl i immediate tilstand, du måske har fanget dataene fra før kontrolpunktet fandt sted, så dine gamle data er mere sandsynligt, at de stadig er i bunken.

Nu hvor du har lavet en komplet fil-system-niveau kopi af data dir kan du starte din database sikkerhedskopiere, hvis du virkelig har brug for det; dataene vil stadig være væk, men du har gjort hvad du kan for at give dig selv et håb om måske at gendanne dem. Givet valget ville jeg nok holde DB'en lukket for en sikkerheds skyld.

Gendannelse

Det kan være, at du nu skal hyre en ekspert i PostgreSQL's indre til at hjælpe dig med et forsøg på datagendannelse. Vær forberedt på at betale en professionel for deres tid, muligvis en hel del tid.

Jeg skrev om dette på Pg-mailinglisten, og Виктор Егоров linkede til depesz' indlæg på pg_dirtyread, som ligner lige det, du vil have, selvom det ikke genopretter TOAST ed data, så det er af begrænset nytte. Prøv det, hvis du er heldig, kan det virke.

Se:pg_dirtyread på GitHub.

Jeg har fjernet det, jeg havde skrevet i dette afsnit, da det er forældet af det værktøj.

Se også Grundlæggende oplysninger om PostgreSQL rækkelagring

Forebyggelse

Se mit blogindlæg Forhindrer PostgreSQL-databasekorruption.

På en semi-relateret sidebemærkning, hvis du brugte tofaset commit, kunne du ROLLBACK PREPARED for en transaktion, der var forberedt til commit, men ikke fuldt commiteret. Det er omtrent det tætteste, du kommer på at rulle en allerede forpligtet transaktion tilbage, og det gælder ikke for din situation.




  1. 2 måder at slette duplikerede rækker i Oracle

  2. Codeigniter-transaktioner

  3. Fejl ved oprettelse af unaccent-udvidelse på PostgreSQL

  4. SQL Vælg Distinct