sql >> Database >  >> RDS >> PostgreSQL

Kan ik een transactie terugdraaien die ik al heb gepleegd? (data verlies)

Nee, je kunt een commit niet ongedaan maken, terugdraaien of terugdraaien.

STOP DE DATABASE!

(Opmerking:als je de datadirectory van het bestandssysteem hebt verwijderd, stop de database dan NIET. Het volgende advies is van toepassing op een onbedoelde commit van een DELETE of iets dergelijks, geen rm -rf /data/directory scenario).

Als deze gegevens belangrijk waren, STOP NU UW DATABASE en start het niet opnieuw op. Gebruik pg_ctl stop -m immediate zodat er geen checkpoint wordt uitgevoerd bij afsluiten.

U kunt een transactie niet terugdraaien nadat deze is vastgelegd. U moet de gegevens van back-ups herstellen of point-in-time recovery gebruiken, dat vóór moet zijn ingesteld het ongeval is gebeurd.

Als je geen PITR / WAL-archivering had ingesteld en geen back-ups hebt, heb je echt problemen.

Dringende beperking

Zodra uw database is gestopt, moet u een kopie op bestandssysteemniveau maken van de hele gegevensmap - de map die base bevat , pg_clog , enz. Kopieer alles naar een nieuwe locatie. Doe niets aan de kopie op de nieuwe locatie, het is uw enige hoop om uw gegevens te herstellen als u geen back-ups hebt. Maak indien mogelijk nog een kopie op een verwisselbare opslag en koppel die opslag vervolgens los van de computer. Onthoud dat je absoluut elk onderdeel nodig hebt van de gegevensmap, inclusief pg_xlog etc. Geen enkel onderdeel is onbelangrijk.

Hoe u de kopie precies maakt, hangt af van het besturingssysteem dat u gebruikt. Waar de gegevensmap zich bevindt, hangt af van het besturingssysteem dat u gebruikt en hoe u PostgreSQL hebt geïnstalleerd.

Manieren waarop sommige gegevens het hadden kunnen overleven

Als je je DB snel genoeg stopt, heb je misschien de hoop om wat gegevens uit de tabellen te herstellen. Dat komt omdat PostgreSQL multi-version concurrency control (MVCC) gebruikt om gelijktijdige toegang tot zijn opslag te beheren. Soms schrijft het nieuwe versies van de rijen die u bijwerkt naar de tabel, waarbij u de oude op hun plaats laat maar gemarkeerd als "verwijderd". Na een tijdje komt autovacuüm langs en markeert de rijen als vrije ruimte, zodat ze kunnen worden overschreven door een latere INSERT of UPDATE . Dus de oude versies van de UPDATE d rijen kunnen nog steeds rondslingeren, aanwezig maar ontoegankelijk.

Daarnaast schrijft Pg in twee fasen. De eerste gegevens worden naar het write-ahead log (WAL) geschreven. Pas als het eenmaal naar de WAL en de hitdisk is geschreven, wordt het gekopieerd naar de "heap" (de hoofdtabellen), waarbij mogelijk oude gegevens worden overschreven die daar waren. De WAL-inhoud wordt naar de hoofdheap gekopieerd door de bgwriter en door periodieke controleposten. Standaard vinden controlepunten elke 5 minuten plaats. Als het je lukt om de database te stoppen voordat er een checkpoint heeft plaatsgevonden en deze stopt door hem hard te doden, de stekker uit de machine te trekken of pg_ctl te gebruiken in immediate modus hebt u mogelijk de gegevens vastgelegd van voordat het controlepunt plaatsvond, dus de kans is groter dat uw oude gegevens nog in de hoop zijn.

Nu u een volledige kopie op bestandssysteemniveau van de gegevensmap hebt gemaakt, kunt u een back-up van uw database starten als dat echt nodig is; de gegevens zijn nog steeds verdwenen, maar je hebt gedaan wat je kon om jezelf enige hoop te geven om het misschien te herstellen. Als ik de keuze had, zou ik de database waarschijnlijk voor de zekerheid afgesloten houden.

Herstel

Mogelijk moet u nu een expert in de ingewanden van PostgreSQL inhuren om u te helpen bij een poging tot gegevensherstel. Wees bereid om een ​​professional te betalen voor hun tijd, mogelijk behoorlijk wat tijd.

Ik heb hierover gepost op de Pg-mailinglijst en Виктор Егоров linkte naar het bericht van depesz op pg_dirtyread, wat precies lijkt op wat je wilt, hoewel het TOAST niet herstelt ed data, dus het is van beperkt nut. Probeer het eens, als je geluk hebt, werkt het misschien.

Zie:pg_dirtyread op GitHub.

Ik heb verwijderd wat ik in deze sectie had geschreven omdat het door die tool verouderd is.

Zie ook de basisprincipes van PostgreSQL-rijopslag

Preventie

Zie mijn blogartikel PostgreSQL-databasecorruptie voorkomen.

Een semi-gerelateerde kanttekening, als je twee-fasen commit zou gebruiken, zou je ROLLBACK PREPARED voor een transactie die is voorbereid voor commit maar niet volledig is vastgelegd. Dat komt ongeveer het dichtst in de buurt bij het terugdraaien van een reeds vastgelegde transactie, en is niet van toepassing op uw situatie.




  1. NAMEN INSTELLEN utf8 in MySQL?

  2. Autonome transactie in PostgreSQL 9.1

  3. Percona XtraDB Cluster installeren op CentOS 7

  4. Hoe de functie POSITION() werkt in MySQL