PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Puis-je annuler une transaction que j'ai déjà validée ? (perte de données)

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. Les conseils suivants s'appliquent à une validation accidentelle d'un DELETE ou similaire, pas 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. Utilisez 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 a été validée. Vous devrez restaurer les données à partir de sauvegardes ou utiliser la récupération ponctuelle, qui doit avoir été configurée avant l'accident s'est produit.

Si vous n'avez pas configuré d'archivage PITR / WAL et que vous n'avez pas de sauvegardes, vous êtes vraiment dans le pétrin.

Atténuation urgente

Une fois votre base de données arrêtée, vous devez faire une copie au niveau du système de fichiers de l'ensemble du répertoire de données - le dossier qui contient base , pg_clog , etc. Copiez tout cela vers un nouvel emplacement. Ne faites rien sur la copie 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 d'absolument chaque pièce du répertoire de données, y compris pg_xlog etc. Aucune partie n'est sans importance.

La façon exacte de faire la copie dépend du système d'exploitation que vous utilisez. L'emplacement du répertoire de données dépend du système d'exploitation que vous utilisez 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 le contrôle de concurrence multi-version (MVCC) pour gérer l'accès simultané à son stockage. Parfois, il écrira de nouvelles versions des lignes que vous mettez à jour dans le tableau, en laissant les anciennes en place mais marquées comme "supprimées". Au bout d'un moment, l'autovaccum arrive et marque les lignes comme espace libre, afin qu'elles puissent être écrasées par un INSERT ultérieur ou UPDATE . Ainsi, les anciennes versions de la UPDATE d lignes peuvent encore traîner, présentes mais inaccessibles.

De plus, Pg écrit en deux phases. Les premières données sont écrites dans le journal d'écriture anticipée (WAL). Ce n'est qu'une fois qu'il a été écrit dans le WAL et sur le disque qu'il est ensuite copié dans le "tas" (les tables principales), en écrasant éventuellement les anciennes données qui s'y trouvaient. Le contenu WAL est copié dans le tas principal par le bgwriter et par des points de contrôle périodiques. Par défaut, les points de contrôle se produisent toutes les 5 minutes. Si vous parvenez à arrêter la base de données avant qu'un point de contrôle ne se soit produit et que vous l'arrêtiez en la tuant brutalement, en débranchant la machine ou en utilisant pg_ctl en immediate mode, vous avez peut-être capturé les données avant que le point de contrôle ne se produise, de sorte que vos anciennes données sont plus susceptibles d'être encore dans le tas.

Maintenant que vous avez fait une copie complète du répertoire de données au niveau du système de fichiers, vous pouvez démarrer la sauvegarde de votre base de données si vous en avez vraiment besoin ; les données auront toujours disparu, mais vous avez fait ce que vous pouviez pour vous donner un peu d'espoir de les récupérer peut-être. Si j'avais le choix, je garderais probablement la base de données fermée juste pour être sûr.

Récupération

Vous devrez peut-être maintenant embaucher un expert des entrailles de PostgreSQL pour vous aider dans une tentative de récupération de données. Soyez prêt à payer un professionnel pour son temps, peut-être un peu de temps.

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

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 Fondamentaux du stockage de lignes PostgreSQL

Prévention

Voir mon entrée de blog Empêcher la corruption de la base de données PostgreSQL.

D'un autre côté, si vous utilisiez un commit en deux phases, vous pouviez ROLLBACK PREPARED pour une transaction qui a été préparée pour la validation mais pas entièrement validée. C'est à peu près ce qui se rapproche le plus de l'annulation d'une transaction déjà validée et ne s'applique pas à votre situation.