On Thu, Feb 6, 2014 at 12:33 PM, <[email protected]> wrote:

> Olá,
>
> estamos investigando o comportamento de uma aplicação que começou a
> apresentar erros após a migração do banco da versão 8.4 para a versão 9.2
>
>
Quais erros são apresentados? Deixe-me adivinhar, algo do tipo:

    ERROR:  40001: could not serialize access due to read/write
dependencies among transactions

Você está usando transações em nível SERIALIZABLE, correto?

Estou assumindo isso nas respostas que seguem (e não acho que faria sentido
se não fosse o caso, então...).


Montamos a query abaixo (cruzamento de dados entre a pg_stat_activity e a
> pg_locks) e gostaríamos de ajuda para interpretar o resultado da mesma
>
> select a.pid, a.waiting, a.state, a.query, l.mode, count(*)
> from pg_stat_activity a, pg_locks l
> where a.pid =l.pid
> group by a.pid, a.waiting, a.state, a.query, l.mode
> order by 6 desc, a.pid;
>
>  a.pid, a.waiting, a.state, a.query, l.mode, count(*)
> 43299;f;"idle";"COMMIT";"SIReadLock";37971
> 43327;f;"idle";"COMMIT";"SIReadLock";5055
> 43306;f;"idle";"COMMIT";"SIReadLock";730
> 43323;f;"idle";"COMMIT";"SIReadLock";191
> 43304;f;"idle";"COMMIT";"SIReadLock";24
>
>
Bem como suspeitava, os locks do tipo SIRead são os utilizados para
Serializable Snapshot Isolation (SSI), que foi um novo nível de isolamento
que surgiu na versão 9.1 do PostgreSQL. Em [1] tem exemplos e detalhes
sobre o mesmo. Resumindo o que tem lá (bem por cima), basicamente uma
transação SERIALIZABLE irá abortar caso outra transação (que tenha
finalizado) "poderia" ter lido um dado sendo tratado pela mesma.

Quanto à como trabalhar com esse nível, tínhamos que antes da 9.1 o nível
REPEATABLE READ não era usado, e se alguém iniciasse nesse nível (presente
por compatibilidades com o padrão) o PostgreSQL iria passar a usar
SERIALIZABLE. Na 9.1 em diante isso mudou, o que antes era SERIALIZABLE
passou a ser REPEATABLE READ e esse novo nível (SSI) passou a ser o
SERIALIZABLE.

Resumindo, primeiro entenda melhor o que esse novo nível faz [1]. Se você
não precisa deste nível, passe a utilizar o REPEATABLE READ, que terás o
mesmo comportamento que tinha na versão 8.4. E mesmo que tenha ainda que
usar a 8.4, nela tanto REPEATABLE READ quanto o SERIALIZABLE têm o mesmo
efeito, logo sua aplicação continua funcionando em ambas.



> Algumas sessões/processos estão com um número muito grande locks do tipo
> SIReadLock mesmo estando com o status=idle e tendo executado um COMMIT. A
> explicação para este comportamento seria o que está escrito no trecho
> abaixo do manual?
>
> There are two ways to acquire an advisory lock in PostgreSQL: at session
> level or at transaction level. Once acquired at session level, an advisory
> lock is held until explicitly released or the session ends. Unlike standard
> lock requests, session-level advisory lock requests do not honor
> transaction semantics: a lock acquired during a transaction that is later
> rolled back will still be held following the rollback, and likewise an
> unlock is effective even if the calling transaction fails later. A lock can
> be acquired multiple times by its owning process; for each completed lock
> request there must be a corresponding unlock request before the lock is
> actually released.
>
>
> http://www.postgresql.org/docs/9.2/static/explicit-locking.html#LOCKING-TABLES
>
>
Não, isso não tem nada a ver com "advisory locks", mas com o SSI e
"predicate locks". A parte que explica o porquê desses locks ainda estarem
ativos depois do COMMIT é o seguinte parágrafo em [2] (cortei as partes
menos relevantes):

" Predicate locks in PostgreSQL, like in most other database systems, are
based on data actually accessed by a transaction. These will show up in the
pg_locks system view with a mode of SIReadLock. [...] A READ ONLY
transaction may be able to release its SIRead locks before completion, if
it detects that no conflicts can still occur which could lead to a
serialization anomaly. [...] SIRead locks often need to be kept past
transaction commit, until overlapping read write transactions complete. "

Ou seja, esses locks ficarão aí até que outras transações sendo executadas
concomitantemente e com possibilidade de conflito terminem.




> Grato,
>
> Equipe DBA IBGE
>
>

Legal ver uma equipe toda na lista, ainda mais de uma organização como
IBGE... :)


Continuem participando...

[1] http://wiki.postgresql.org/wiki/SSI
[2] http://www.postgresql.org/docs/9.2/static/transaction-iso.html

Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a