Osvaldo Kussama escreveu:
> 2009/12/18 Clayton Graf <clay...@intelidata.inf.br>:
>> Pessoal, estou tendo um problema e gostaria de saber como vocês fazem para
>> contornar a situação.
>> Quando faço um SELECT o pgsql gera um lock na tabela (AccessShareLock). Se
>> logo após faço um ALTER TABLE na mesma tabela este comando não é executado
>> devido ao LOCK gerado pelo SELECT.
>> Na prática isto significa que somente posso alterar a estrutura do banco
>> quando não tiver nenhum usuário conectado, o que dificulta as coisas.
>> É assim mesmo? Como vocês fazem? Tem como não gerar o lock "AccessShareLock"
>> após o select?
> 
Não. Você certamente está deixando transações abertas antes de executar o
ALTER TABLE. Veja:

sessão A:

euler=# begin;
BEGIN
euler=# select * from aa;
 a | b
---+---
(0 rows)

sessão B:

euler=# begin;
BEGIN
euler=# alter table aa add column c integer; -- não retorna até conseguir lock
LOG:  process 4920 still waiting for AccessExclusiveLock on relation 73841 of
database 16384 after 1000.230 ms

sessão C:

euler=# select relation,relation::regclass,pid,mode,granted from pg_locks;
 relation | relation |  pid  |        mode         | granted
----------+----------+-------+---------------------+---------
    73841 | aa       |  4920 | AccessExclusiveLock | f
          |          |  4920 | ExclusiveLock       | t
    10969 | pg_locks | 15405 | AccessShareLock     | t
    73841 | aa       | 15319 | AccessShareLock     | t
          |          | 15319 | ExclusiveLock       | t
          |          | 15405 | ExclusiveLock       | t
(6 rows)

Veja que a primeira linha mostra que há um travamento que não foi adquirido
ainda (granted = 'f'). Logo abaixo descobrimos o processo 15319 com travamento
adiquirido que está bloqueando a transação que contém o ALTER TABLE.

sessão A:

euler=# rollback; -- depois desse comando o ALTER TABLE é executado
ROLLBACK

sessão B:

LOG:  process 4920 acquired AccessExclusiveLock on relation 73841 of database
16384 after 253610.896 ms
ALTER TABLE
euler=#

> Certamente você não está executando um SELECT simples mas sim um
> SELECT com a cláusula FOR SHARE [1].
> 
Não necessariamente.

Vale ressaltar que _somente_ o AccessExclusiveLock conflita com o
AccessShareLock [1].


[1] http://www.postgresql.org/docs/8.4/static/explicit-locking.html


-- 
  Euler Taveira de Oliveira
  http://www.timbira.com/
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a