Comment débloquer les serrures Postgres row possibles?
j'ai lancé une déclaration de mise à jour sur une grande table PostgreSQL à travers l'interface phpPgAdmin. Cette expiré comme il a duré trop longtemps.
je peux maintenant mettre à jour quelques lignes de cette table mais pas toutes. Essayer de mettre à jour quelques lignes va pendre.
les rangées sont-elles verrouillées? Comment puis-je permettre que ces lignes soient mises à jour?
4 réponses
quelle version de PostgreSQL utilisez-vous? Ce qui suit suppose 8.1.8 ou plus tard (il peut s'appliquer aux versions précédentes aussi, je ne sais pas).
je présume que vous voulez dire que phpPgAdmin a été chronométré -- le backend PostgreSQL prendra le temps qu'il faut pour compléter une requête/mise à jour. Dans ce cas, il est possible que la session originale soit toujours vivante et que la requête de mise à jour soit toujours en cours d'exécution. Je suggère d'exécuter la requête suivante (prise de chapitre 24 de l'PostgreSQL docs) sur la machine qui héberge le processus serveur PostgreSQL, pour voir si la session est toujours vivante:
ps auxwww|grep ^postgres
plusieurs lignes doivent apparaître: 1 pour le postmaster
processus maître, et 1 chacun pour les processus" writer"," stats buffer", et" stats collector". Les lignes restantes sont destinées aux processus de connexion DB. Ces lignes contiennent le nom d'utilisateur et le nom de base de données.
heureusement, à partir de là, vous pouvez voir si la session que vous avez effectuée l'original Mise à JOUR en question est toujours en suspens autour de. Bien qu'en théorie vous pourriez trouver des informations plus détaillées par SELECT
ing à partir de la vue système pg_stat_activity
, par défaut PostgreSQL N'est pas configuré pour remplir les champs les plus utiles (comme current_query
et query_start
). Voir le chapitre 24 pour savoir comment permettre cela à l'avenir.
si vous voyez que la session est toujours là, tuez-la. Vous devez être connecté en tant qu'utilisateur exécutant le processus (généralement postgres
) ou root pour le faire -- si vous n'utilisez pas le serveur vous-même, demande à ton DBA de faire ça pour toi.
encore une chose: pour mettre à jour des lignes dans une table, PostgreSQL évite d'utiliser des serrures. Au lieu de cela, il permet à chaque transaction écrite de créer une nouvelle "version" de la base de données, qui devient la "version courante" lorsque la transaction est engagée, à condition qu'elle n'entre pas en conflit avec les mises à jour effectuées entre-temps par d'autres transactions. Donc je soupçonne que la" pendaison " que vous voyez est causée par quelque chose d'autre -- quoique, je ne suis pas sûr. (Avez-vous vérifié l'évidence des choses, comme si la partition disque contenant la base de données est pleine?)
Il est possible de voir les verrous.
Voici une vue de la rendre un peu plus facile que d'utiliser pg_locks directement:
CREATE OR REPLACE VIEW public.active_locks AS
SELECT t.schemaname,
t.relname,
l.locktype,
l.page,
l.virtualtransaction,
l.pid,
l.mode,
l.granted
FROM pg_locks l
JOIN pg_stat_all_tables t ON l.relation = t.relid
WHERE t.schemaname <> 'pg_toast'::name AND t.schemaname <> 'pg_catalog'::name
ORDER BY t.schemaname, t.relname;
puis vous sélectionnez simplement dans la vue:
SELECT * FROM active_locks;
Et le tuer avec:
SELECT pg_cancel_backend('%pid%');
d'Autres solutions: http://wiki.postgresql.org/wiki/Lock_Monitoring
Simple:
Obtenir de l'actif serrures de pg_locks:
sélectionner T. relname, L. locktype, page, virtualtransaction,pid, mode, accordé de pg_locks l, pg_stat_all_tables T où L. relation=T. ordonnance de sursis par rapport asc;
copier le pid (ex: 14210) du résultat ci-dessus et le remplacer dans la commande ci-dessous.
sélectionnez pg_terminate_backend ('14210')
Je n'ai jamais travaillé avec Potresql mais si C'est similaire à d'autres je dirais que vous devez tuer la connexion/mettre fin à la transaction qui tient les serrures.