Skip site navigation (1) Skip section navigation (2)

Re: Reponse lente de postgres

From: Guillaume Lelarge <guillaume(at)lelarge(dot)info>
To: Hajatiana RAHOLIARIJAONA <administrateur(at)saisie(dot)mg>
Cc: pgsql-fr-generale(at)postgresql(dot)org, Jean-Paul Argudo <jean-paul(at)argudo(dot)org>
Subject: Re: Reponse lente de postgres
Date: 2007-08-02 12:50:24
Message-ID: 46B1D310.4000204@lelarge.info (view raw or flat)
Thread:
Lists: pgsql-fr-generale
Hajatiana RAHOLIARIJAONA a écrit :
>    Begin transaction est suivi des insertions INSERT, c'est à ce moment
> que la table est verouillé et les autres instructions UPDATE sont mis en
> WAITING.
> 
>    Si l'insertion dure un peu plus, c'est là que la liste de waiting est
> longue et le serveur postgres est devenu lent.
> 

Ma session 1 s'appelle a le prompt pgfr_1, ma session 2 pgfr_2. Voici
mon test sur un 8.2.4 :

pgfr_1=# select pg_backend_pid();
 pg_backend_pid
----------------
          21993
(1 ligne)

pgfr_2=# select locktype, relation::regclass, transactionid,
pgfr_2=> transaction, pid, mode, granted from pg_locks;

   locktype    | relation | transactionid | transaction |  pid  |
mode       | granted
---------------+----------+---------------+-------------+-------+------------------+---------
 transactionid |          |        446965 |      446965 | 21996 |
ExclusiveLock    | t
 relation      | pg_locks |               |      446965 | 21996 |
AccessShareLock  | t
(2 lignes)

Donc pas de verrou pour ma session pgfr_1, pid 21993.

pgfr_1=# begin;
BEGIN

pgfr_2=# select locktype, relation::regclass, transactionid,
pgfr_2=> transaction, pid, mode, granted from pg_locks;

   locktype    | relation | transactionid | transaction |  pid  |
mode       | granted
---------------+----------+---------------+-------------+-------+------------------+---------
 transactionid |          |        446965 |      446965 | 21996 |
ExclusiveLock    | t
 transactionid |          |        446961 |      446961 | 21993 |
ExclusiveLock    | t
 relation      | pg_locks |               |      446965 | 21996 |
AccessShareLock  | t
(3 lignes)

J'ai un transactionid pour la transaction débutée par pgfr_1.

pgfr_1=# insert into a values (1);
INSERT 0 1

pgfr_2=# select locktype, relation::regclass, transactionid,
pgfr_2=> transaction, pid, mode, granted from pg_locks;

   locktype    | relation | transactionid | transaction |  pid  |
mode       | granted
---------------+----------+---------------+-------------+-------+------------------+---------
 transactionid |          |        446969 |      446969 | 21996 |
ExclusiveLock    | t
 relation      | a        |               |      446961 | 21993 |
RowExclusiveLock | t
 transactionid |          |        446967 |      446967 | 22014 |
ExclusiveLock    | t
 transactionid |          |        446961 |      446961 | 21993 |
ExclusiveLock    | t
 relation      | pg_locks |               |      446969 | 21996 |
AccessShareLock  | t
(5 lignes)

J'ai un verrou supplémentaire, sur la table a, mode RowExclusiveLock. En
gros, la session 1 a un accès exclusif à la ligne insérée.

pgfr_2=# insert into a values(2);
INSERT 0 1
pgfr_2=# select locktype, relation::regclass, transactionid,
transaction, pid, mode, granted from pg_locks;
   locktype    | relation | transactionid | transaction |  pid  |
mode       | granted
---------------+----------+---------------+-------------+-------+------------------+---------
 relation      | a        |               |      446961 | 21993 |
RowExclusiveLock | t
 transactionid |          |        446971 |      446971 | 21996 |
ExclusiveLock    | t
 transactionid |          |        446967 |      446967 | 22014 |
ExclusiveLock    | t
 transactionid |          |        446961 |      446961 | 21993 |
ExclusiveLock    | t
 relation      | pg_locks |               |      446971 | 21996 |
AccessShareLock  | t
(5 lignes)

Une autre insertion, de ma deuxième session, a bien eu lieu. Pas de
blocage. La table a n'est donc vraiment pas verrouillée, seule la ligne
insérée par la transaction non terminée est verrouillée.

pgfr_2=# update a set id=3 where id=2;
UPDATE 1

Je peux aussi mettre à jour les autres lignes.

pgfr_2=# update a set id=3 where id=1;
UPDATE 0

Même si je tente de mettre à jour la ligne insérée par la session 1, je
ne suis pas bloqué. En effet, mon deuxième processus n'a pas
connaissance de cette nouvelle ligne. Donc pas de blocage.

En fait, il ne peut y avoir blocage d'un processus que s'il essaie de
mettre à jour une ligne qui a été modifiée par un autre processus mais
que ce processus n'a pas encore envoyé un COMMIT. Dis autrement :

pgfr_1=# begin;
pgfr_1=# update a set id=2;
pgfr_2=# begin;
pgfr_2=# update a set id=3...;

--> blocage de pgfr_2 tant qu'il n'y a pas de commit sur pgfr_1.

Mon impression est donc que vos différents processus doivent tenter de
mettre à jour les mêmes lignes d'une table sans faire de commit. Cela
vous semble-t'il possible ?


-- 
Guillaume.
<!-- http://abs.traduc.org/
     http://lfs.traduc.org/
     http://docs.postgresqlfr.org/ -->

In response to

pgsql-fr-generale by date

Next:From: Alain LucariDate: 2007-08-02 19:49:19
Subject: Re: Reponse lente de postgres
Previous:From: Guillaume LelargeDate: 2007-08-02 12:24:04
Subject: Re: Reponse lente de postgres

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group