Re: [pgbr-geral] Problema com ALTER TABLE depois de um SELECT
É 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
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
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 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
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