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.