web-dev-qa-db-fra.com

Puis-je annuler une transaction déjà engagée? (perte de données)

J'ai commis une déclaration incorrecte UPDATE et j'ai perdu des données.

Est-il possible de revenir en arrière maintenant, après que je me suis déjà engagé?

De l'aide?

ROLLBACK

dit NOTICE: there is no transaction in progress.

46
SSS

Non, vous ne pouvez pas annuler, annuler ou annuler un commit.

ARRÊTEZ LA BASE DE DONNÉES!

(Remarque: si vous avez supprimé le répertoire de données du système de fichiers, n’arrêtez PAS la base de données. Le conseil suivant s’applique à une validation accidentelle d’un DELETE ou similaire, et non d’un rm -rf /data/directory scénario).

Si ces données étaient importantes, ARRÊTEZ VOTRE BASE DE DONNÉES MAINTENANT et ne le redémarrez pas. Utilisation pg_ctl stop -m immediate afin qu'aucun point de contrôle ne soit exécuté à l'arrêt.

Vous ne pouvez pas annuler une transaction une fois qu'elle est validée. Vous devrez restaurer les données à partir de sauvegardes ou utiliser récupération à un moment précis , qui doit avoir été configuré avant l'accident s'est produit.

Si vous n'avez pas d'archivage PITR/WAL configuré et que vous n'avez pas de sauvegarde, vous avez de gros problèmes.

Atténuation urgente

Une fois que votre base de données est arrêtée, vous devez créer un niveau de système de fichiers de l’ensemble du répertoire de données - le dossier contenant base, pg_clog, etc. Copier le tout dans un nouvel emplacement. Ne faites rien pour copier dans le nouvel emplacement, c'est votre seul espoir de récupérer vos données si vous n'avez pas de sauvegardes. Faites une autre copie sur un stockage amovible si vous le pouvez, puis débranchez ce stockage de l'ordinateur. N'oubliez pas que vous avez besoin de absolument toutes les parties du répertoire de données, y compris pg_xlog etc. Aucune partie n'est sans importance.

La copie dépend du système d’exploitation que vous utilisez. Le répertoire de données dépend du système d'exploitation utilisé et de la manière dont vous avez installé PostgreSQL.

Comment certaines données auraient pu survivre

Si vous arrêtez votre base de données assez rapidement, vous pouvez espérer récupérer certaines données des tables. En effet, PostgreSQL utilise MVCC pour gérer les accès simultanés à son stockage. Parfois, il écrira nouvelles versions des lignes que vous mettez à jour dans la table, en laissant les anciennes en place, mais marquées comme "supprimées". Après un certain temps, autovaccum arrive et marque les lignes en tant qu'espace libre, afin qu'elles puissent être écrasées par un INSERT ou UPDATE ultérieur. Ainsi, les anciennes versions des lignes UPDATEd pourraient encore traîner, présentes mais inaccessibles.

De plus, Pg écrit en deux phases. Les premières données sont écrites dans le journal à écriture anticipée (WAL). Une fois que cela a été écrit dans le WAL et frappé sur le disque, il est ensuite copié dans le "tas" (les tables principales), écrasant éventuellement les anciennes données qui s'y trouvaient. Le contenu de WAL est copié dans le segment de mémoire principal par le bgwriter et par des points de contrôle périodiques. Par défaut, les points de contrôle ont lieu toutes les 5 minutes. Si vous parvenez à arrêter la base de données avant qu’un point de contrôle ne soit arrivé et si vous l’arrêtez en le tuant avec force, en débranchant la machine ou en utilisant pg_ctl en immediate vous avez peut-être capturé les données avant le point de contrôle, vos anciennes données ont donc plus de chances d'être encore dans le tas.

Maintenant que vous avez créé une copie complète du répertoire de données au niveau du système de fichiers, vous pouvez lancer la sauvegarde de votre base de données si vous en avez vraiment besoin. les données auront toujours disparu, mais vous avez fait tout votre possible pour vous donner un espoir de les récupérer. Étant donné le choix, je fermerais probablement la base de données pour des raisons de sécurité.

Récupération

Vous pouvez maintenant avoir besoin de engager un expert dans les entrailles de PostgreSQL pour vous aider dans une tentative de récupération de données. Soyez prêt à payer un professionnel pour leur temps, éventuellement un peu de temps.

J'ai posté à ce sujet sur la liste de diffusion Pg, et Виктор горов lié àle message de depesz sur pg_dirtyread , qui ressemble à ce que vous voulez, bien qu'il ne récupère pas TOASTed data est donc d'une utilité limitée. Essayez, si vous avez de la chance, cela pourrait marcher.

Voir: pg_dirtyread sur GitHub .

J'ai supprimé ce que j'avais écrit dans cette section, car il est obsolète par cet outil.

Voir aussi Principes de base du stockage de lignes PostgreSQL

La prévention

Voir mon entrée de blog prévention de la corruption de la base de données PostgreSQL .


Sur une note secondaire semi-liée, si vous utilisiez validation en deux phases vous pourriez ROLLBACK PREPARED pour une transaction préparée pour validation mais non totalement validée. C'est à peu près tout ce qui vous rapproche le plus de l'annulation d'une transaction déjà engagée et cela ne s'applique pas à votre situation.

89
Craig Ringer