Pessoal,
Estou finalizando a implantação do PgBouncer 1.3 com PostgreSQL 8.2 e obtive excelentes resultados só pelo fato de colocar o Pool de Conexões na frente do “postmaster”.
Até aqui não temos nada de muito surpreendente a não ser pelo fato de que, segundo a documentação do próprio PgBouncer fala que podemos ter 100% de transparência com o PostgreSQL 8.3 pelo fato do comando ”DISCARD” estar presente apartir dessa release.
Como na versão que estamos utilizando, a 8.2, não existe essa implementação então o jeito foi implementar uma PL que “emule” o comportamento do ”DISCARD”.
Através da lista de discussão da Comunidade Brasileira de PostgreSQL (pgbr-geral), com a ajuda do colega Euler, implementei uma PL para suprir essa falta conforme segue:
server_reset_query = SELECT fc_discard_all()
Os únicos efeitos colaterais dessa solução são:
O modo do pool que estou utilizando é o “session” pois preciso da sessão do inicio ao fim com o mesmo estado.
Se alguém tiver alguma dica e/ou critica estou a disposição.
Cordialmente,
Fabrízio de Royes Mello
fabriziomello [at] gmail.com
Estou finalizando a implantação do PgBouncer 1.3 com PostgreSQL 8.2 e obtive excelentes resultados só pelo fato de colocar o Pool de Conexões na frente do “postmaster”.
Até aqui não temos nada de muito surpreendente a não ser pelo fato de que, segundo a documentação do próprio PgBouncer fala que podemos ter 100% de transparência com o PostgreSQL 8.3 pelo fato do comando ”DISCARD” estar presente apartir dessa release.
Como na versão que estamos utilizando, a 8.2, não existe essa implementação então o jeito foi implementar uma PL que “emule” o comportamento do ”DISCARD”.
Através da lista de discussão da Comunidade Brasileira de PostgreSQL (pgbr-geral), com a ajuda do colega Euler, implementei uma PL para suprir essa falta conforme segue:
No meu arquivo de configuração do pool (pgbouncer.ini) fiz o seguinte:
create or replace function fc_discard_all() returns void as
$$
declare
rComando record;
iVersao integer;
begin
select cast(setting as integer)
into iVersao
from pg_settings
where name ~ 'server_version_num';
if not found then
raise exception 'A versão do PostgreSQL deve ser >= 8.2';
end if;
if iVersao >= 80300 then
execute 'discard all';
return;
end if;
set session authorization default;
reset all;
for rComando in
select name
from pg_prepared_statements
loop
execute 'deallocate '||rComando.name;
end loop;
for rComando in
select name
from pg_cursors
where name not like '%unnamed%'
loop
execute 'close '||rComando.name;
end loop;
unlisten *;
perform pg_advisory_unlock_all();
for rComando in
select distinct
table_schema,
table_name
from information_schema.tables
where table_type = 'LOCAL TEMPORARY'
loop
execute 'drop table if exists '||quote_ident(rComando.table_schema)||'.'||quote_ident(rComando.table_name)||' cascade';
end loop;
return;
end;
$$
language plpgsql;
server_reset_query = SELECT fc_discard_all()
Os únicos efeitos colaterais dessa solução são:
- Se a base de dados que for acessada não tiver a PL acima criada vai gerar um log de erro, mas não impacta em problemas na conexão
- Não foi possível implementar uma emulação para o DISCARD PLANS pois, segundo o colega Euler, esse comando veio em conjunto com a funcionalidade de invalidação de planos em funções procedurais, logo não pode ser emulada em versões menores que 8.3
O modo do pool que estou utilizando é o “session” pois preciso da sessão do inicio ao fim com o mesmo estado.
Se alguém tiver alguma dica e/ou critica estou a disposição.
Cordialmente,
Fabrízio de Royes Mello
fabriziomello [at] gmail.com