Re: [pgbr-geral] Problema com ALTER TABLE depois de um SELECT

2009-12-19 Por tôpico Clayton Graf
É estranho mas o AccessShareLock ocorre mesmo quando o primeiro comando após
a conexão é um SELECT e este select não tem a cláusula FOR SHARE.

Estou conectando via jdbc e parece que é algo no driver. Revisei tudo e não
consegui achar o problema. O driver é o último que tem disponível
(postgresql-8.4-701.jdbc4.jar)

Segue o trecho que reproduz o problema:

Class.forName(jdbc).newInstance();
Connection connection = DriverManager.getConnection(url, login, password);
connection.setCatalog(database);
connection.setAutoCommit(false);
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery(select * from controle);
while (rs.next()) {
System.out.println(rs.getString(1));
}
rs.close();
st.close();

Clayton

2009/12/18 Euler Taveira de Oliveira eu...@timbira.com

 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




-- 
Clayton Graf
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Problema com ALTER TABLE depois de um SELECT

2009-12-19 Por tôpico Euler Taveira de Oliveira
Clayton Graf escreveu:
 É estranho mas o AccessShareLock ocorre mesmo quando o primeiro comando
 após a conexão é um SELECT e este select não tem a cláusula FOR SHARE.
 
Todo SELECT adiquire AccessShareLock; SELECT ... FOR UPDATE adquire
AccessRowShareLock.

 Estou conectando via jdbc e parece que é algo no driver. Revisei tudo e
 não consegui achar o problema. O driver é o último que tem disponível
 (postgresql-8.4-701.jdbc4.jar)
 
Não. Você que *não* está terminando as transações adequadamente. No seu
exemplo, você terá:

BEGIN;
SELECT * FROM controle;

Faltou o COMMIT ali. Caso você tenha um pool de conexões, esta transação
ficará em aberto e, consequentemente, você terá problemas com transações que
querem obter um AccessExclusiveLock.


-- 
  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


Re: [pgbr-geral] Problema com ALTER TABLE depois de um SELECT

2009-12-19 Por tôpico Clayton Graf
Euler, acho que entendi a questão...

Na verdade nós não estávamos fazendo uma unidade lógica quando temos somente
selects, ou seja,
ao invés de fazer:

BEGIN;
SELECT * FROM tabela1;
SELECT * FROM tabelan;
COMMIT;

estávamos simplesmente fazendo

SELECT * FROM tabela1;
SELECT * FROM tabelan

Pensava que a unidade lógica iniciava no primeiro UPDATE ou DELETE. No
MS-SQLSERVER é assim e não me ative a este detalhe.

Muito oObrigado,

Clayton



2009/12/19 Euler Taveira de Oliveira eu...@timbira.com

 Clayton Graf escreveu:
  É estranho mas o AccessShareLock ocorre mesmo quando o primeiro comando
  após a conexão é um SELECT e este select não tem a cláusula FOR SHARE.
 
 Todo SELECT adiquire AccessShareLock; SELECT ... FOR UPDATE adquire
 AccessRowShareLock.

  Estou conectando via jdbc e parece que é algo no driver. Revisei tudo e
  não consegui achar o problema. O driver é o último que tem disponível
  (postgresql-8.4-701.jdbc4.jar)
 
 Não. Você que *não* está terminando as transações adequadamente. No seu
 exemplo, você terá:

 BEGIN;
 SELECT * FROM controle;

 Faltou o COMMIT ali. Caso você tenha um pool de conexões, esta transação
 ficará em aberto e, consequentemente, você terá problemas com transações
 que
 querem obter um AccessExclusiveLock.


 --
   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




-- 
Clayton Graf
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Problema com ALTER TABLE depois de um SELECT

2009-12-18 Por tôpico Osvaldo Kussama
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?


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

Osvaldo

[1] http://www.postgresql.org/docs/current/interactive/sql-select.html
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] Problema com ALTER TABLE depois de um SELECT

2009-12-18 Por tôpico Euler Taveira de Oliveira
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