La vue pg_locks fournit un accès aux informations concernant les verrous détenus par les transactions ouvertes sur le serveur de bases de données. Voir le Chapitre 13, Contrôle d'accès simultané pour une discussion plus importante sur les verrous.
pg_locks contient une ligne par objet verrouillable actif, type de verrou demandé et transaction associée. Un même objet verrouillable peut apparaître plusieurs fois si plusieurs transactions ont posé ou attendent des verrous sur celui-ci. Toutefois, un objet qui n'est pas actuellement verrouillé n'apparaît pas.
Il existe plusieurs types distincts d'objets verrouillables : les relations complètes (tables, par exemple), les pages individuelles de relations, des tuples individuels de relations, les identifiants de transaction (virtuels et permanents) et les objets généraux de la base de données (identifiés par l'OID de la classe et l'OID de l'objet, de la même façon que dans pg_description ou pg_depend). De plus, le droit d'étendre une relation est représenté comme un objet verrouillable distinct. Et enfin, les verrous informatifs peuvent être pris sur les numéros qui ont la signification définie par l'utilisateur.
Tableau 45.57. Colonnes pg_locks
Nom | Type | Références | Description |
---|---|---|---|
locktype | text | Type de l'objet verrouillable : relation, extend, page, tuple, transactionid, virtualxid, object, userlock ou advisory | |
database | oid | pg_database.oid | L'OID de la base de données dans laquelle existe l'objet, 0 si l'objet est partagé ou NULL si l'objet est un identifiant de transaction |
relation | oid | pg_class.oid | L'OID de la relation ou NULL si l'objet n'est pas une relation ni une partie de relation |
page | integer | Le numéro de page à l'intérieur de cette relation ou NULL si l'objet n'est pas un tuple ou une page de relation | |
tuple | smallint | Le numéro du tuple dans la page ou NULL si l'objet n'est pas un tuple | |
virtualxid | text | L'identifiant virtuel d'une transaction, ou NULL si l'objet n'est pas un identifiant virtuel de transaction | |
transactionid | xid | L'identifiant d'une transaction ou NULL si l'objet n'est pas un identifiant de transaction | |
classid | oid | pg_class.oid | L'OID du catalogue système contenant l'objet ou NULL si l'objet n'est pas un objet général de la base de données |
objid | oid | n'importe quelle colonne OID | L'OID de l'objet dans son catalogue système ou NULL si l'objet n'est pas un objet général de la base de données. |
objsubid | smallint | Numéro de la colonne ciblée par le verrou (classid et objid font référence à la table elle-même), ou 0 si la cible est un autre objet de la base de données, ou NULL si l'objet n'est pas un objet de la base de données. | |
virtualtransaction | text | L'identifiant virtuel de la transaction qui détient ou attend le verrou. | |
pid | integer | L'identifiant du processus serveur qui détient ou attend le verrou. NULL si le verrou est possédé par une transaction préparée. | |
mode | text | Nom du type de verrou détenu ou attendu par ce processus (voir la Section 13.3.1, « Verrous de niveau table » et Section 13.2.3, « Niveau d'Isolation Serializable ») | |
granted | boolean | True si le verrou est détenu, false s'il est attendu |
granted est true sur une ligne représentant un verrou tenu par la transaction indiquée. Une valeur false indique que cette transaction attend l'acquisition du verrou, ce qui implique qu'une autre transaction a choisi un mode de verrouillage conflictuel sur le même objet verrouillable. La transaction en attente dort jusqu'au relâchement du verrou (ou jusqu'à ce qu'une situation de blocage soit détectée). Une transaction unique peut attendre l'acquisition d'au plus un verrou à la fois.
Chaque transaction détient un verrou exclusif sur son identifiant virtuel de transaction pour toute sa durée. Si un identifiant permanent est affecté à la transaction (ce qui arrive habituellement si la transaction change l'état de la base de données), il détient aussi un verrou exclusif sur son identifiant de transaction permanent jusqu'à sa fin. Quand une transaction trouve nécessaire d'attendre spécifiquement une autre transaction, elle le fait en essayant d'acquérir un verrou partagé sur l'identifiant de l'autre transaction (identifiant virtuel ou permanent selon la situation). Ceci n'est couronné de succès que lorsque l'autre transaction termine et relâche son verrou.
Bien que les lignes constituent un type d'objet verrouillable, les informations sur les verrous de niveau ligne sont stockées sur disque, et non en mémoire. Ainsi, les verrous de niveau ligne n'apparaissent normalement pas dans cette vue. Si une transaction attend un verrou de niveau ligne, elle apparaît sur la vue comme en attente de l'identifiant permanent de la transaction actuellement détentrice de ce verrou de niveau ligne.
Les verrous consultatifs peuvent être acquis par des clés constituées soit d'une seule valeur bigint, soit de deux valeurs integer. Une clé bigint est affichée avec sa moitié haute dans la colonne classid, sa partie basse dans la colonne objid et objsubid à 1. Les clés integer sont affichées avec la première clé dans la colonne classid, la deuxième clé dans la colonne objid et objsubid à 2. La signification réelle des clés est laissée à l'utilisateur. Les verrous consultatifs sont locaux à chaque base, la colonne database a donc un sens dans ce cas.
pg_locks fournit une vue globale de tous les verrous du cluster, pas seulement de ceux de la base en cours d'utilisation. Bien que la colonne relation puisse être jointe avec pg_class.oid pour identifier les relations verrouillées, ceci ne fonctionne correctement qu'avec les relations de la base accédée (celles pour lesquelles la colonne database est l'OID de la base actuelle ou 0).
La vue pg_locks affiche des données provenant du gestionnaire de verrous standards et du gestionnaire de verrous de prédicats, qui sont des systèmes autrement séparés. Quand un utilisateur accède à cette vue, les structures de données internes de chaque gestionnaire de verrous sont temporairement verrouillées, et des copies sont faites que la vue va afficher. Chaque gestionnaire de verrous produira du coup un ensemble cohérent de résultats mais, comme nous ne verrouillons pas les deux gestionnaires simultanément, il est possible que des verrous soient donnés ou relachés après avoir interrogé le gestionnaire de verrous standard et avant avoir interrogé le gestionnaire de verrous de prédicat. Chaque gestionnaire est verrouillé le moins de temps possible pour réduire l'impact sur les performances mais un impact sur les performances du serveur peut néanmoins être observé si la vue est utilisée fréquemment.
La colonne pid peut être jointe à la colonne procpid de la vue pg_stat_activity pour obtenir plus d'informations sur la session qui détient ou attend un verrou. De plus, si des transactions préparées sont utilisées, la colonne transaction peut être jointe à la colonne transaction de la vue pg_prepared_xacts pour obtenir plus d'informations sur les transactions préparées qui détiennent des verrous. (Une transaction préparée ne peut jamais être en attente d'un verrou mais elle continue à détenir les verrous qu'elle a acquis pendant son exécution.)