Serie PostgreSQL Contribs: adminpack

No momento que escrevo estas linhas a versão atual do Postgres é a 9.2 e ao todo são 41 módulos no contrib, então vou iniciar uma série onde vou apresentar o funcionamento da maioria deles e farei isto seguindo a ordem alfabética dos módulos.

Vamos iniciar pelo adminpack que é uma extensão que contém algumas funções que permitem a manipulação remota de determinados arquivos por um super-usuário (como o postgres por exemplo) ou ferramentas administrativas. É possível, através destas funções, renomear um arquivo, ler seu conteúdo ou até mesmo escrever no arquivo.

Mas vamos deixar de conversa e vamos ao que interessa: mão-na-massa.

Para utilizar uma contrib você precisa criar a extensão, e para que isto ocorra com sucesso você precisa ter ela instalada no cluster. Seguindo a documentação do Postgres você percebe que a instalação do módulo depende de como o Postgres foi instalado.

No meu caso o Postgres foi instalado através do código-fonte compilado, então o que eu preciso fazer é acessar o diretório da instalação e procurar a contrib e instalá-la:

$ cd $HOME/programas/PostgreSQL/postgres/contrib/adminpack
$ make install
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -fpic -I../../src/interfaces/libpq -I. -I. -I../../src/include -D_GNU_SOURCE   -c -o adminpack.o adminpack.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -fpic -shared -o adminpack.so adminpack.o -L../../src/port -Wl,--as-needed -Wl,-rpath,'/home/guedes/.local/postgres/lib',--enable-new-dtags
/bin/mkdir -p '/home/guedes/.local/postgres/lib'
/bin/mkdir -p '/home/guedes/.local/postgres/share/extension'
/bin/mkdir -p '/home/guedes/.local/postgres/share/extension'
/bin/sh ../../config/install-sh -c -m 755  adminpack.so '/home/guedes/.local/postgres/lib/adminpack.so'
/bin/sh ../../config/install-sh -c -m 644 ./adminpack.control '/home/guedes/.local/postgres/share/extension/'
/bin/sh ../../config/install-sh -c -m 644 ./adminpack--1.0.sql  '/home/guedes/.local/postgres/share/extension/'

Uma vez que a contrib esteja instalada, seja via pacote ou via compilação, acesse o banco onde você deseja utilizá-la e “carregue-a” através do comando:

testdb=# CREATE EXTENSION adminpack;
testdb# \dx+ adminpack
     Objects in extension "adminpack"
            Object Description
-------------------------------------------
 function pg_file_length(text)
 function pg_file_read(text,bigint,bigint)
 function pg_file_rename(text,text)
 function pg_file_rename(text,text,text)
 function pg_file_unlink(text)
 function pg_file_write(text,text,boolean)
 function pg_logdir_ls()
 function pg_logfile_rotate()

E agora vamos testá-la, vamos começar criando um arquivo:

testdb=# select pg_file_write('teste.txt', 'Ola Mundo', false);
 pg_file_write
---------------
             9
(1 row)

Se tentarmos criar o arquivo novamente não vamos conseguir, e por isso temos que passar true no último parâmetro.

testdb=# select pg_file_write('teste.txt', 'Ola Mundo', false);
ERROR:  file "teste.txt" exists

testdb=# select pg_file_write('teste.txt', 'Ola Mundo', true);
 pg_file_write
---------------
             9
(1 row)

Só é possivel manipular arquivos dentro do $PGDATA do cluster, por questões de segurança. Sendo assim, é esperado que o arquivo esteja lá:

~$ ls -la $HOME/.local/postgres/data/teste.txt
-rw------- 1 guedes guedes 18 Fev 14 23:15 /home/guedes/.local/postgres/data/teste.txt
~$ cat $HOME/.local/postgres/data/teste.txt
Ola MundoOla Mundo
~$

Ele concatenou sem quebrar linha, como o esperado já que não passamos caracteres de controle de quebra de linha, e agora, para teste, vamos renomear o arquivo (via Postgres, claro):

testdb=# select pg_file_rename('teste.txt', 'ola_mundo');
 pg_file_rename
----------------
 t
(1 row)

Como foi obtido sucesso, a função retorna true, entretanto, se tentarmos sobrescrever um arquivo, mesmo sendo super-usuários, não vamos conseguir:

testdb=# select pg_file_rename('ola_mundo', 'postgresql.conf');
ERROR:  cannot rename to target file "postgresql.conf"
testdb=# select pg_file_rename('ola_mundo', 'postmaster.opts');
ERROR:  cannot rename to target file "postmaster.opts"

Podemos ser ousados e tentar algo como:

testdb=# select pg_file_write('postgresql.conf','logging_collector = true', true);
 pg_file_write
---------------
            24
(1 row)

… reiniciar o cluster:

~$ pg_ctl -D $HOME/.local/postgres/data restart

… e dar uma olhadinha nos logs:

testdb=# select t.* from pg_logdir_ls() t(data_hora timestamp, logfile text);
      data_hora      |                 logfile
---------------------+-----------------------------------------
 2013-02-27 23:34:59 | pg_log/postgresql-2013-02-27_233459.log

Hum, tá, nem tão ousados assim porque precisamos ter acesso ao S.O. e em muitas situações você não tem este acesso.

AVISO: Cuidado ao escrever em arquivos como postmaster.opts ou postgresql.conf você pode acabar gerando um problema caso o banco precise ser re-iniciado e você tenha concatenado algo errado neles.

Bom por hoje é isto e até a próxima contrib!

Um abraço!

comments powered by Disqus