PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 09/08/2017 16:47:36

lemjid
Membre

maintenance_postgresql face aux locks

Bonjour à toutes et à tous,

J'ai une version pg 8.4 sur linux redhat 4.1
PostgreSQL 8.4.4 on x86_64-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42), 64-bit
jusqu'à là rien n'est très grave. Mon problème c'est que la tâche de maintenance (vacuum full/reindex...) automatisées pas crontab restent bloquées sur une table. Le blocage est logique car la table en question attend un verrou exclusif.
Voici le résultat après une tentative de reindex : (la table en question 'acls')
procpid |   usename    |       age       |           relname           |        mode         | granted
---------+--------------+-----------------+-----------------------------+---------------------+---------
   31964 | pmbd01update | 00:00:06.977733 | hierarchy_primarytype_idx     | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | hierarchy_parentid_name_idx | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | acls                                      | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | common                               | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | locks_pk                               | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | dc_contributors                     | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | dublincore                             | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | locks                                    | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | proxies                                 | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | proxies_targetid_idx              | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | proxies_versionableid_idx      | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | proxies_pk                            | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | common_pk                          | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | dublincore_pk                       | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | hierarchy                              | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | acls_id_idx                           | AccessShareLock     | f
   31964 | pmbd01update | 00:00:06.977733 | dc_contributors_id_idx          | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | hierarchy_pk                        | AccessShareLock     | t
   31964 | pmbd01update | 00:00:06.977733 | hierarchy_parentid_idx          | AccessShareLock     | t
   32150 | postgres     | 00:00:08.007351 | acls                                           | ShareLock           | t
   32150 | postgres     | 00:00:08.007351 | acls_id_idx                                 | AccessExclusiveLock | f
=============
Ce qui me pose problème c'est que à chaque fois que je lance un 'vacuum full' ou 'reindex' sur la table ou l'index de 'acls', des verrous sortent partout comme dans l'exemple ou plus (ça peut rester bloqué une éternité) alors qu'avant le tout est en sommeil aucune connexion, aucune requête en cours.
================
Voici la définition de la table:
   Column   |          Type          | Modifiers | Storage  | Description
------------+------------------------+-----------+----------+-------------
id         | character varying(36)  | not null  | extended |
pos        | integer                |           | plain    |
name       | character varying(250) |           | extended |
grant      | boolean                |           | plain    |
permission | character varying(250) |           | extended |
user       | character varying(250) |           | extended |
group      | character varying(250) |           | extended |
Indexes:
    "acls_id_idx" btree (id), tablespace "tbs_pmbd01_index"
    Foreign-key constraints:
    "acls_id_hierarchy_fk" FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE
Triggers:
    nx_trig_acls_modified AFTER INSERT OR DELETE OR UPDATE ON acls FOR EACH ROW EXECUTE PROCEDURE nx_log_acls_modified()
Has OIDs: no
Tablespace: "tbs_pmbd01_data"
========================
J'ai tenté un disable trigger puis reindex ==> NOK.
j'ai tenté aussi de faire create index concurrently, le problème qu'avec la version 8.4 on ne peut pas faire un "drop index concurrently"!!!
...
Tout simplement je ne trouve pas quel est le meilleur chemin à prendre pour résoudre ce problème.
Quelqu'un pourra m'aiguiller SVP, par avance merci.

Hors ligne

#2 10/08/2017 10:22:32

rjuju
Administrateur

Re : maintenance_postgresql face aux locks

lemjid a écrit :

Bonjour à toutes et à tous,

J'ai une version pg 8.4 sur linux redhat 4.1
PostgreSQL 8.4.4 on x86_64-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42), 64-bit
jusqu'à là rien n'est très grave.

Heu, une version de PostgreSQL qui date de 7 ans et un OS qui date de 12 ans ? Si, c'est plutôt grave.

Mon problème c'est que la tâche de maintenance (vacuum full/reindex...) automatisées pas crontab restent bloquées sur une table. Le blocage est logique car la table en question attend un verrou exclusif.
[...]
J'ai tenté un disable trigger puis reindex ==> NOK.
j'ai tenté aussi de faire create index concurrently, le problème qu'avec la version 8.4 on ne peut pas faire un "drop index concurrently"!!!
...
Tout simplement je ne trouve pas quel est le meilleur chemin à prendre pour résoudre ce problème.
Quelqu'un pourra m'aiguiller SVP, par avance merci.

Je vous conseillerais de commencer par mettre à jour avec la dernière versions mineure de la 8.4 (8.4.22, soit 18 versions de retard, soit environ 4 ans et demi...).

Hors ligne

#3 10/08/2017 10:33:14

lemjid
Membre

Re : maintenance_postgresql face aux locks

Bonjour "rjuju"

Merci pour ta réactivité. Je comprend tout à fait ta réponse (je m'ai attend). Tu comprends bien qu'il y a des solution du long, moyen et court terme. Mon souhait et de trouver un issue à ce problème tout en travaillant pour convaincre ceux qui ont habilité de prendre la décision pour la migration. Tu sais aussi mieux que moi que dans certaines structures c'est fastidieux pour bouger déjà une ligne de code qui est là depuis un certain temps... Bref c'est un autre sujet.

As tu STP (au une autre personne), une idée pour ce cas.

Par avance merci.

Hors ligne

#4 10/08/2017 11:23:00

rjuju
Administrateur

Re : maintenance_postgresql face aux locks

Je ne parle pas de migration mais d'appliquer les mise à jour de sécurité et correctifs de bug.  Une simple mise à jour mineure de PostgreSQL n'implique que quelques secondes d'interruption de service.



Pour le reste, pour quelle raison faire un VACUUM FULL (très mauvaise idée en version 8.4) ou REINDEX ?  Avez-vous mesuré une fragmentation qui augmente toujours, que l'autovacuum ou des tâches de maintenances régulières et moins aggressives ne permet pas de corriger ?

Hors ligne

#5 10/08/2017 12:34:36

lemjid
Membre

Re : maintenance_postgresql face aux locks

A vrai dire c'est une routine, mais justifié car il y a un bloat sur quelques tables 'actives'. Pas de mesure dans le sens comparatif avec les vacuum/analyze simple. En revanche je ne me souviens pas avoir vu les inconvénients du "vacuum full' sur la version 8.4 et j'aimerai bien avoir un lien ou un titre ou autre...etc

On peut abandonner l'idée du vacuum full mais à un moment donnée il faut peut être faire un reindex un moment ou un autre.

Le problème c'est impossible de prendre le verrou sur cette maudite table il est toujours en attente d'acquisition (granted=f). Aucun moyen de forcer le 'pg_try_advisory_lock' ou 'begin; lock table.....;' et impossible de voir le verrous est détenu par qui????? et c'est le centre de mon problème.

Hors ligne

#6 10/08/2017 17:03:59

rjuju
Administrateur

Re : maintenance_postgresql face aux locks

Pour VACUUM FULL en version 8.4 et moins, vous pouvez lire https://wiki.postgresql.org/wiki/VACUUM_FULL.

Pour le reste, impossible de vous aider sans beaucoup plus d'information.  Vous devriez au minimum regarder quelle est la requête bloquante dans pg_stat_activity, par exemple https://wiki.postgresql.org/wiki/Lock_Monitoring

Hors ligne

#7 10/08/2017 17:24:00

lemjid
Membre

Re : maintenance_postgresql face aux locks

Merci encore "rjuju".

Le problème c'est que dans les locks il n'y a rien, mais ma requête reste en attente en attente de verrou.
Ce qui est plus étonnant, j'ai redémarré la base et j'ai coupé toutes les connexions, les connexions (applicatives) aussi. Je lance un reindex sur cette table, elle se met à attendre un verrou même le process dans "/proc/xxxxx/status  il est en waiting.
Voilà ce qui pose problème. S'il y a un UPDATE ou une tâche qui verrouille la table, ça sera compréhensible mais là rien  (Voir la capture de dessus).

Une question: Est ce que la dépendance d'une table peut jouer? Le fait d'avoir un trigger dessus qui appelle cette fonction...?
CREATE OR REPLACE FUNCTION public.nx_log_acls_modified()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
-- Trigger to log change in the acls table
DECLARE
  doc_id varchar(36);
BEGIN
  IF (TG_OP = 'DELETE') THEN
    doc_id := OLD.id;
  ELSE
    doc_id := NEW.id;
  END IF;
  INSERT INTO hierarchy_modified_acl VALUES(doc_id, 'f');
  RETURN NEW;
END $function$
Par avance merci!

Hors ligne

#8 10/08/2017 17:45:24

rjuju
Administrateur

Re : maintenance_postgresql face aux locks

Et bien la capture du dessus montre justement le problème

   31964 | pmbd01update | 00:00:06.977733 | acls_id_idx                           | AccessShareLock     | f
[...]
   32150 | postgres     | 00:00:08.007351 | acls_id_idx                                 | AccessExclusiveLock | f

Le reindex (processus 32150) est en bloqué par le processus 31964.  La requête fournie dans mon message précédent vous donnera plus d'information sur la requête associée au processus 31964.

Hors ligne

#9 11/08/2017 10:42:13

lemjid
Membre

Re : maintenance_postgresql face aux locks

D'accord,

Mais la colonne "age" c'est la '32150' qui est plus ancienne (00:00:08.007351 contre 00:00:06.977733)?!
Dans le doute j'ai refait la manip et voilà le résultat:

pmbd01=# SELECT
procpid, usename,
(now() - query_start) as age,
c.relname,
l.mode,
l.granted from
pg_stat_activity a
left outer join pg_locks l
on (a.procpid = l.pid)
left outer join pg_class c
on (l.relation = c.oid)
where
c.relname !~ '^pg_'
order by
pid;
procpid | usename  |       age       | relname |        mode         | granted
---------+----------+-----------------+---------+---------------------+---------
   27613 | postgres | 00:01:40.860525 | acls    | AccessExclusiveLock | f
(1 row)

Hors ligne

#10 11/08/2017 10:55:37

rjuju
Administrateur

Re : maintenance_postgresql face aux locks

C'est peut-être du à une transaction préparée.

Hors ligne

#11 11/08/2017 11:33:24

lemjid
Membre

Re : maintenance_postgresql face aux locks

Bonjour,

En effet il y en a deux:
select transaction, prepared, database  from pg_prepared_xacts ;
transaction   |           prepared                           | database
---------------+-------------------------------          +----------
    55790841 | 2017-06-14 08:35:37.905075+02 | xyz01
    55790842 | 2017-06-14 08:38:04.791443+02 | xyz01
(2 rows)
=====
Désolé mais la transaction préparé elle prend un verrou?!
Comment faire si oui ?

Hors ligne

#12 11/08/2017 12:02:12

rjuju
Administrateur

Re : maintenance_postgresql face aux locks

La transaction préparée possède des verrous en fonction des requêtes exécutées dans cette transaction...

Il faut soit valider soit annuler la transaction préparée qui bloque (si le problème vient bien de là), avec COMMIT PREPARED ou ROLLBACK PREPARED (https://docs.postgresql.fr/8.4/sql-commit-prepared.html par exemple).

Hors ligne

#13 11/08/2017 14:44:59

lemjid
Membre

Re : maintenance_postgresql face aux locks

C'était ça le vrai problème. Après un rollback de la transaction préparé ça à marché.

Merci beaucoup Julien pour ton aide.

Bon week-end

Hors ligne

Pied de page des forums