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
Views: Raw Message | Whole Thread | Download mbox | Resend email
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

Browse pgsql-fr-generale by date

  From Date Subject
Next Message Alain Lucari 2007-08-02 19:49:19 Re: Reponse lente de postgres
Previous Message Guillaume Lelarge 2007-08-02 12:24:04 Re: Reponse lente de postgres