sql >> Databasteknik >  >> RDS >> PostgreSQL

Kan jag återställa en transaktion som jag redan har genomfört? (dataförlust)

Nej, du kan inte ångra, återställa eller ångra en commit.

STOPPA DATABASEN!

(Obs:om du raderade datakatalogen från filsystemet, stoppa INTE databasen. Följande råd gäller för en oavsiktlig commit av en DELETE eller liknande, inte en rm -rf /data/directory scenario).

Om denna information var viktig STOPPA DIN DATABAS NU och starta inte om den. Använd pg_ctl stop -m immediate så att ingen kontrollpunkt körs vid avstängning.

Du kan inte återställa en transaktion när den väl har genomförts. Du måste återställa data från säkerhetskopior eller använda punkt-i-tid återställning, som måste ha ställts in före olyckan inträffade.

Om du inte har konfigurerat någon PITR/WAL-arkivering och inte har säkerhetskopior, har du stora problem.

Brådskande begränsning

När din databas har stoppats bör du göra en kopia på filsystemnivå av hela datakatalogen - mappen som innehåller base , pg_clog , etc. Kopiera allt till en ny plats. Gör inget med kopian på den nya platsen, det är ditt enda hopp att återställa dina data om du inte har säkerhetskopior. Gör en kopia till på någon flyttbar lagringsenhet om du kan, och koppla sedan bort lagringen från datorn. Kom ihåg att du behöver absolut varje del i datakatalogen, inklusive pg_xlog etc. Ingen del är oviktig.

Exakt hur man gör kopian beror på vilket operativsystem du kör. Var datakatalogen finns beror på vilket operativsystem du kör och hur du installerade PostgreSQL.

Sätt som vissa data kunde ha överlevt

Om du stoppar din DB tillräckligt snabbt kan du ha ett hopp om att återställa vissa data från tabellerna. Det beror på att PostgreSQL använder multi-version concurrency control (MVCC) för att hantera samtidig åtkomst till dess lagring. Ibland skriver den nya versioner av raderna uppdaterar du till tabellen, och lämnar de gamla på plats men markerade som "raderade". Efter ett tag kommer autovaccum och markerar raderna som ledigt utrymme, så att de kan skrivas över av en senare INSERT eller UPDATE . Således, de gamla versionerna av UPDATE d rader kan fortfarande ligga kvar, närvarande men otillgängliga.

Dessutom skriver Pg i två faser. Första data skrivs till förskrivningsloggen (WAL). Först när den har skrivits till WAL och träffdisken, kopieras den sedan till "högen" (huvudtabellerna), vilket eventuellt skriver över gammal data som fanns där. WAL-innehållet kopieras till huvudhögen av bgwriter och genom periodiska kontrollpunkter. Som standard sker kontrollpunkter var 5:e minut. Om du lyckas stoppa databasen innan en kontrollpunkt har hänt och stoppat den genom att hårt döda den, dra ur kontakten på maskinen eller använda pg_ctl i immediate läge som du kanske har fångat in data från innan kontrollpunkten inträffade, så det är mer sannolikt att din gamla data fortfarande finns i högen.

Nu när du har gjort en fullständig kopia av datafilen på filsystemnivå kan du starta säkerhetskopieringen av din databas om du verkligen behöver; data kommer fortfarande att vara borta, men du har gjort vad du kan för att ge dig själv lite hopp om att kanske återställa den. Med tanke på valet skulle jag förmodligen hålla DB nedstängd bara för säkerhets skull.

Återställning

Du kan nu behöva anlita en expert på PostgreSQL:s inre för att hjälpa dig i ett försök att återställa data. Var beredd att betala en professionell för sin tid, möjligen ganska mycket tid.

Jag skrev om detta på Pg-postlistan, och Виктор Егоров länkade till depeszs inlägg på pg_dirtyread, som ser ut precis som du vill, även om det inte återställer TOAST ed data så det är av begränsad användbarhet. Ge det ett försök, om du har tur kanske det fungerar.

Se:pg_dirtyread på GitHub.

Jag har tagit bort det jag skrivit i det här avsnittet eftersom det är föråldrat av det verktyget.

Se även PostgreSQL-radlagringsgrunderna

Förebyggande

Se mitt blogginlägg Förhindra korruption av PostgreSQL-databas.

På en semi-relaterad sidonotering, om du använde tvåfasig commit kan du ROLLBACK PREPARED för en transaktion som var förberedd för commit men inte helt commit. Det är ungefär det närmaste du kommer att återställa en redan genomförd transaktion, och det gäller inte din situation.




  1. Kontrollera Constraint i SQL

  2. SQL Filtrera kriterier i joinkriterier eller where-sats som är mer effektivt

  3. Duplicera, kopiera eller säkerhetskopiera tabeller i MySQL, MariaDB, Oracle, PostgreSQL, DB2 och SQLite med Skapa tabell som SQL

  4. Microsoft Access Table Tips – Tricks och riktlinjer del III