terça-feira, 18 de janeiro de 2011

Oracle - ORA-00210 - Perda de controlfile no OracleXE 10g

Como solucionar:

SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup nomount pfile="/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/config/scripts/initXETemp.ora";
ORACLE instance started.
Total System Global Area  146800640 bytes
Fixed Size                  1257668 bytes
Variable Size              58724156 bytes
Database Buffers           83886080 bytes
Redo Buffers                2932736 bytes
SQL> Create controlfile reuse set database "XE"
  2  MAXINSTANCES 8
  3  MAXLOGHISTORY 1
  4  MAXLOGFILES 16
  5  MAXLOGMEMBERS 3
  6  MAXDATAFILES 100
  7  Datafile
  8  '/usr/lib/oracle/xe/oradata/XE/system.dbf',
  9  '/usr/lib/oracle/xe/oradata/XE/undo.dbf',
 10  '/usr/lib/oracle/xe/oradata/XE/sysaux.dbf',
 11  '/usr/lib/oracle/xe/oradata/XE/users.dbf'
 12  LOGFILE
 13  GROUP 1 SIZE 51200K,
 14  GROUP 2 SIZE 51200K,
 15  RESETLOGS;
Control file created.
SQL> alter system enable restricted session;
System altered.
SQL> alter database "XE" open resetlogs;
Database altered.
SQL> alter database rename global_name to "XE";
Database altered.
SQL> alter system switch logfile;
System altered.
SQL> alter system checkpoint;
System altered.
SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/usr/lib/oracle/xe/oradata/XE/temp.dbf' SIZE 20480K REUSE AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED;
Tablespace altered.
SQL> select tablespace_name from dba_tablespaces where tablespace_name='USERS';
no rows selected
SQL> alter system disable restricted session;
System altered.

   Deste modo salvei a database. Agora como o banco está utilizando um PFILE e não SPFILE, para abrir a database 'XE' utilize:

$ sqlplus sys as sysdba
SQL> startup open pfile="/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/config/scripts/initXETemp.ora";

PostgreSQL - PGAgent - Jobs no PostgreSQL

O PGAgent é uma aplicação que possibilita a execução agendada de tarefas no banco de dados PostgreSQL, uma vez que este agendamento não é nativo como no Oracle. Então vamos deixar de "blablabla" e mão na massa:

Este post utilizará como base o PostgreSQL 8.4 e o PGAgent 3.0.

Então como no pica-pau, e lá vamos nós...

Considerando que seu banco já está ativo, configurado para ouvir na porta 5432 e você usa RedHat like, baixe o PGAgent:

# cd /opt/resources
# wget http://wwwmaster.postgresql.org/download/mirrors-ftp/pgadmin3/release/pgagent/pgAgent-3.0.0-Linux.tar.gz

Descompacte e acesse o diretório share da pasta que acabou de extrair:

# tar xvfz pgAgent-3.0.0-Linux.tar.gz
# cd pgAgent-3.0.0-Linux/share

Se seu banco ainda não tem a linguagem 'plpgsql', crie com o seguinte comando:

# createlang plpgsql

Agora importe o arquivo 'pgagent.sql' e 'pgagent_upgrade.sql' para a database 'postgres':

# psql -U postgres postgres < pgagent.sql ; psql -U postgres postgres < pgagent_upgrade.sql

Não esqueça de que para o PgAgent funcionar corretamente no pg_hba.conf as conexões locais devem ser configuradas para 'trust', pois sua senha da role 'postgres' na string de conexão não seria legal.

Bom, agora vamos ao daemon, vamos criar um "service" para o pgagent, que será iniciado depois do banco por razões claras.

Segue fonte do "service":


#!/bin/sh
#
# pgagent:      Agent Jobs to PostgreSQL.
#
# chkconfig:    2345 96 89
# description:  PGAgent is a daemon to scheduler jobs in PostgreSQL.
#

# Source function library.
. /etc/rc.d/init.d/functions

# --- CONFIG --- #

# Log mode - 0 = error 1 = warning 2 = debug
LOG=1

# Log destination
STDERR="/var/log/pgagent.log"

# Connection string
CONN="hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres"

# --- #

start()
{
        echo -n $"Starting PGAgent: OK"
        /opt/resources/bin/pgagent -f -l $LOG -s $STDERR $CONN >> $STDERR 2>&1 &

        echo
}

stop()
{
        echo -n $"Shutting down PGAgent: "
        /usr/bin/killall -9 pgagent

        echo
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        stop
        start
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|reload}"
        exit 1
esac

exit 0


Adicione o "service" com o seguinte comando:

# cd /etc/init.d ; chmod +x pgagent ; chkconfig --add pgagent

Pronto, agora é só iniciar ele(service pgagent start) e criar seus jobs.

Para criar jobs é muito fácil pelo PgAdmin, segue a documentação de como fazer:

http://www.pgadmin.org/docs/1.4/pgagent.html

quarta-feira, 5 de janeiro de 2011

JBoss - 5.1 AS Org e como corrigir o bug do VFS

Sintoma: Após algum tempo o diretório 'tmp' da instância ativa começa a ficar absurdamente grande, algo acima dos 20Gb em pouco tempo.

Problema: O problema que isso ocasiona é simples, falta de espaço em disco, logo a instância do JBoss parará de funcionar. Isso é causado por uma falha do VFS nativo do JBoss AS Org 5.1, que a cada sessão aberta pelo usuário ele duplica os arquivos de sessão.

Solução: Atualizar o VFS com a versão corrigida, para isso basta parar a instância do JBoss e atualizar o arquivo 'jboss-vfs.jar' localizado na pasta lib da raiz do JBoss. Atualizar é somente substituir, mas lembre-se de fazer um backup, o arquivo está disponível no link abaixo:

https://issues.jboss.org/secure/attachment/12332395/jboss-vfs.jar

terça-feira, 4 de janeiro de 2011

PostgreSQL - Configurando um 'Warm-standby'

   Primeiramente precisamos entender o que é e como funciona uma solução do PostgreSQL em 'Warm-standby'. Este tipo de configuração consiste em ter duas instâncias, uma master em archive mode e outra em slave importando os archives gerados pelo master. Importante, a instância slave não aceita conexões, está em standby e só é ativada quando um arquivo definido pelo DBA existe.

   Então sem mais papo, vamos ao cenário:


Sistema Operacional: CentOS 5.5 x86
Banco de dados: PostgreSQL 8.4

Pacotes RPM instalados:

postgresql84-test-8.4.5-1.el5_5.1
postgresql84-8.4.5-1.el5_5.1
postgresql84-docs-8.4.5-1.el5_5.1
postgresql84-libs-8.4.5-1.el5_5.1
postgresql84-devel-8.4.5-1.el5_5.1
postgresql84-contrib-8.4.5-1.el5_5.1
postgresql-libs-8.1.18-2.el5_4.1
postgresql84-server-8.4.5-1.el5_5.1

Ambiente: A ideia é configurar duas instâncias no mesmo servidor, sendo que a master responde na porta TCP 5432(padrão PostgreSQL) e a slave na porta TCP 5433.


Ajuste dos services do /etc/init.d, acesse este diretório e execute os comandos abaixo para configurar duas instâncias:

# cp postgresql postgresql-5432
# cp postgresql postgresql-5433

Vamos ativar os serviços no boot do Linux e também desativar o serviço padrão do PostgreSQL:

# chkconfig --del postgresql
# chkconfig --add postgresql-5432
# chkconfig --level 345 postgresql-5432 on
# chkconfig --add postgresql-5433
# chkconfig --level 345 postgresql-5433 on

Agora precisamos ajustar os parâmetros de inicialização do serviço para que os parâmetros de uma instância não conflite com a outra, para isso ajuste cada arquivo ficando assim:

/etc/init.d/postgresql-5432:

PGPORT=5432
PGDATA=/var/lib/pgsql/data1
PGLOG=/var/lib/pgsql/pgstartup1.log

/etc/init.d/postgresql-5433:
PGPORT=5433
PGDATA=/var/lib/pgsql/data2
PGLOG=/var/lib/pgsql/pgstartup2.log

Agora crie a cluster database do Master com o seguinte comando:

# service postgresql-5432 initdb

Feito isto precisamos ajustar os seguintes parâmetros no postgresql.conf do Master:

archive_mode = on                                                                      
archive_command = 'rsync -a %p /data1/archive_log/%f'
archive_timeout = 60

Salve e crie o diretório /data1/archive_log onde o usuário 'postgres' deve ser o dono.

Pode iniciar o banco com o comando: # service postgresql-5432 start

Se tudo deu certo o PostgreSQL está respondendo na porta padrão 5432 onde você pode conectar se ajustou o pg_hba.

Agora vamos ao slave.

Precisamos colocar o banco master para backup e depois fazer uma cópia física que será repassada para o slave. Seguem comandos para executar quando logado no banco master:

postgres=# SELECT pg_start_backup('test1');
postgres=# \q


Agora faça a cópia para o data2, pode ser feito via rsync, aqui vou usar o copy mesmo:

# cp -rfp /var/lib/pgsql/data1 /var/lib/pgsql/data2
# rm -rf /var/lib/pgsql/data2/pg_xlog/*

Vamos parar o processo de backup do master:

postgres=# SELECT pg_stop_backup();
postgres=# \q


Ajuste o arquivo '/var/lib/pgsql/data2/postgresql.conf' e deixe da seguinte forma:

archive_mode = on                                                                    
archive_command = 'rsync -a %p /data2/archive_log/%f'  

Crie o diretório /data2/archive_log onde o usuário 'postgres' deve ser o dono.

Crie a arquivo '/var/lib/pgsql/data2/recovery.conf' com o seguinte conteudo:                  

restore_command = 'pg_standby -d -s 1 -t /tmp/pgsql.trigger.5432 /data2/archive_log %f %p %r 2>> /var/lib/pgsql/data2/pg_standby.log'
recovery_end_command = 'rm -f /tmp/pgsql.trigger.5432'

Agora precisamos criar o cara que irá criar a trigger caso o master pare de funcionar, então vamos criar o '/root/slave.pl' com o seguinte conteúdo:

#!/usr/bin/perl

($opt_port, $opt_timeout) = @ARGV;

if(!$opt_port or !$opt_timeout){

        print "Missing arguments\n";
        exit(2);

}

my $path="/var/log";
my @cmd=();
my $flag=0;
my $counter=0;

for(;$counter<=$opt_timeout;$counter++){

        @cmd=`/bin/netstat -anp | /bin/grep .s.PGSQL.$opt_port`;

        unless($cmd[0]){$flag++; print "$cmd[0]\n";}

        sleep(01);

}

# Date log
my $date=`/bin/date`;
chomp($date);

# --- Thresholds to slave trigger --- #
if($flag>=$opt_timeout){

        print "ERROR - $date - Master is down - starting slave\n";
        @cmd=`su - postgres -c 'touch /tmp/pgsql.trigger.5432'`;
        exit(0);

}

if($flag<$opt_timeout){

        print "OK - $date - Master up\n";
        exit(0);

}


# EOF


Este arquivo deve ser executável e vamos colocar ele na Cron do root da seguinte forma:

*/2 * * * * /root/slave.pl 5432 15 >> /var/log/slave.log 2>&1

Agora precisamos ainda migrar os archives do master para o diretório do slave, isso é feito com o seguinte comando no Crontab do root:

*/2 * * * * rsync -avzo --remove-sent-files /data1/archive_log/ /data2/archive_log/ >> /dev/null 2>&1


Pronto, pode subir o slave 'service postgresql-5433' e acompanhar os logs de importação através do pg_standby.log no diretório 'data2'. Para testar basta parar o master com um 'service postgresql-5432 stop' e aguarde até o slave ser acionado.

Nesta configuração foi utilizado o 'smart-failover' que é o mais adequado para garantir a recuperação dos dados.

Importante, para um ambiente de produção pode utilizar um LVS monitorando a porta 5432, pois assim você terá um IP de serviço para suas aplicações.