Blocage détecté dans les fonctions PL/pgSQL
Je suis confronté à un problème de blocage à partir d'une de fonctions PL/pgSQL dans ma base de données PostgreSQL. S'il vous plaît trouver l'instruction SQL dans le bloc de code (juste un exemple):
BEGIN
UPDATE accounts SET balance = 0 WHERE acct_name like 'A%';
UPDATE accounts SET balance = balance + 100 WHERE acct_name like '%A';
EXCEPTION WHEN OTHERS THEN RAISE NOTICE SQLERRM;
END;
J'ai trouvé que le blocage s'est produit au cours de la présente déclaration a été en cours d'exécution. Mais je ne suis pas sûr qu'il y avait d'autres états essayer de mettre à jour ce tableau dans le même temps (parce que je n'ai pas trouvé dans mon système de journalisation).
Donc, est-il possible que le blocage s'est produit à l'intérieur de cette déclaration? Autant que je sache, si nous avons bloqué intégralité de la déclaration avec BEGIN
/END
. Il y aura la même transaction et ne doit pas être verrouillé par lui-même.
Par défaut, une transaction peut observer les changements engagés par d'autres transactions. Pour plus d'informations, voir l'Isolation de la Transaction de la documentation PostgreSQL.
Oui je l'ai, mais la déclaration que le déclencheur n'est pas liée à cette table. Pour l'explicite de verrouillage est également oui.
OriginalL'auteur Sathapanic Sriprom | 2012-04-09
Vous devez vous connecter pour publier un commentaire.
Il est certainement certains autres processus en compétition pour la même ressource. C'est la nature d'une impasse. Une fonction comme vous l'affichage ne peut jamais blocage lui-même. Voir commentaire par @kgrittn ci-dessous, qui est un expert sur la simultanéité dans PostgreSQL.
Votre version de PostgreSQL est manquant. Les versions modernes de soulever un message d'erreur détaillé. Les deux processus qui sont en concurrence pour les ressources sont énumérées en détail dans le standard des paramètres de journalisation. Vérifiez votre db journaux.
Le fait que vous attrapez l'erreur peut empêcher Postgres de vous donner le plus de détails. Supprimer la EXCEPTION bloc de votre fonction plpgsql, si vous n'obtenez pas les informations dans le journal de base de données et essayez à nouveau.
Pour soulager les blocages, vous pouvez faire un certain nombre de choses. Si tous vos clients d'accéder à des ressources dans un synchronisés, des blocages ne peut pas se produire. Le manuel fournit la stratégie de base pour résoudre la plupart des cas, dans le chapitre sur les blocages.
Comme pour version 8.3: envisager la mise à niveau vers une version plus récente. En particulier, cette amélioration dans la version 8.4 devrait être intéressant pour vous (citant les notes de version):
Aussi, la version 8.3 répondra à ses fin de vie en février 2013. Vous devriez commencer à envisager la mise à niveau.
Une situation de blocage impliquant
VACUUM
doit avoir été fixe dans 8.3.1.Normalement, le message d'erreur devrait vous donner les informations dont vous avez besoin. J'ai ajouté un peu de ma réponse.
Merci beaucoup pour vos conseils. Je continue à trouver ce que d'autres processus ont essayé de faire quelque chose avec ce tableau.
Une transaction ne sera jamais blocage avec lui-même, indépendamment de déclencheurs. La Version 8.3.6 ont été assez tôt dans la 8.3 cycle de vie que de quelques bugs avec les interactions entre les processus de premier plan et d'arrière-plan autovacuum des processus de blocage. Il pourrait aider à mettre à jour à 8.3.somethingrecent pour éliminer cette possibilité. De la planification à la mise à niveau vers une nouvelle version majeure avant 8.3 hits EOL en février serait aussi sage. postgresql.org/support/versioning
Peut-on re-produire le cas de cette impasse se produit pendant la mise à jour de la table en même temps avec autovacuum processus en cours d'exécution ? ou il n'arrive toujours mais parfois.
OriginalL'auteur Erwin Brandstetter
Vous n'obtiendrez pas de problème de blocage, si vous ajoutez commettre, à la libération des verrous exclusifs.
OriginalL'auteur jimmy chen
Dans PostgreSQL, commencer signifie que vous commencez lot de transaction.
Votre première mise à jour de verrouillage de lignes pour les comptes
WHERE acct_name like 'A%';
Ces lignes sont exclusivement verrouillé après la première mise à jour.
Deuxième mise à jour tente d'ouvrir exactement les mêmes lignes que la première mise à jour , mise à jour
l'échec, parce que la première mise à jour n'a PAS encore commis encore.
Donc deuxième mise à jour frapper impasse de restauration.
BEGIN
est que le début d'un bloc de code. Pas le même queBEGIN
/COMMIT
dans la plaine SQL.OriginalL'auteur jimmy chen