Finalizar todas as sessões ativas de um banco PostgreSQL

Para fazer um DROP DATABASE é necessário “matar” as conexões ativas, existe várias maneiras de fazer isso, porém a mais simples é você usar a a função pg_terminate_backend(int).

Você pode obter todas as seções ativas, rodando pg_stat_activity.

A forma mais simples de matar todas as sessões é executando essa query (claro que você não pode estar conectado na mesma base de dados).

select pg_terminate_backend(procpid)
from pg_stat_activity
where datname = ‘nome_do_database’

Fonte: http://stackoverflow.com/

Resolvendo o problema Too many connections do MySQL

O MySQL por default vem configurado para aceitar 100 conexões simultâneas e isso é mais que suficiente para a grande maioria das situações. Porém é comum receber periodicamente o erro “Too many connections”.

Uma solução paliativa é aumentar o número de conexões do MySQL, dessa forma:

Fara MySQL 3.x:
# vi /etc/my.cnf
set-variable = max_connections = 250

Para MySQL 4.x and 5.x:
# vi /etc/my.cnf
max_connections = 250

Reiniciar o MySQL. É possível checar o número de conexões configuradas dessa forma:

echo “show variables like ‘max_connections’;” | mysql

Agora, este problema normalmente ocorre porque o PHP esta persistindo as conexões, ou seja, cada vez que chama-se uma página com conexão com o banco, é adicionado mais um pool de conexão. Para resolver de vez, não é necessário aumentar o número de conexões do MySQL, conforme mostrado acima, pois o problema esta na configuração do PHP, tem que desativar a persistência das conexões, editando o arquivo php.ini, e colocando o allow_persistent em OFF.

[MySQL]
; Allow or prevent persistent links.
mysql.allow_persistent = Off

E é tudo, reinicie o Apache com /etc/init.d/httpd restart.

MySQL ORDER BY RAND() – Qual a melhor forma de fazer?

Essa é uma dúvida que volta e meia aparece nos fóruns, como obter linhas aleatórias em uma query. Normalmente o que vemos é algo assim:

SELECT * FROM tabela ORDER BY rand();

Contudo, o que muitos não sabem é que uma query dessa forma causa um grande impacto na performance do SGBD.

A maneira correta para ordenar os resultados por um número aleatório é:

SELECT *, RAND() as rand FROM tabela ORDER BY rand;

Por quê? Bem, a resposta é realmente muito simples, ORDER BY RAND () faz com que a ordem seja recalculada a cada vez que é buscado uma nova linha pois cada linha RAND () retorna um valor diferente.

Quando usado na seleção o valor é calculado apenas uma vez por linha e os resultados só são ordenados.

Inspiração:
http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/

Alterando o encoding de um banco Postgresql

Bem, essa dica não serve para converter um banco já existente de UTF-8 para LATIN1, para isso existem outras técnicas. A idéia apresentada aqui é para quando você tem um Dump LATIN1 e precisa restaurar em um novo servidor com o mesmo encoding, mas  o Locale de seu Sistema Operacional não permite que você crie um banco LATIN1.

O erro de Locale aparece quando você executa:

# CREATE DATABASE xpto ENCODING ‘latin1’ TEMPLATE template0;
ERROR: encoding “LATIN1” does not match locale “pt_BR.UTF-8”
DETAIL: The chosen LC_CTYPE setting requires encoding “UTF8”.

Ocorre devido ao Locale estar configurado para UTF-8, você pode corrigir o locale, mas também pode simplesmente criar o banco em UTF-8 e depois alterar para LATIN1

# CREATE DATABASE xpto TEMPLATE template0;

Assim você acabou de criar o banco xpto com encoding UTF-8, para conferir basta dar um \l no PSQL.

Agora para alterar para LATIN1 basta executar:
# update pg_database set encoding = pg_char_to_encoding(‘LATIN1’) where datname = ‘xpto’;

Pronto, confira novamente com \l que o encoding já esta alterado.

Agora é só restaurar seu dump.

Habilitando acesso remoto ao servidor Mysql

Howto: Habilitando acesso remoto ao servidor Mysql

Dica velha que de vez em quando é necessário relembrar, por isso vou deixar registrado aqui para não ter que ficar procurando no google sempre que precisar.

Executar todos os passos abaixo como root:

1 – Edite o arquivo:
/etc/mysql/my.cnf

2 – Altere a seguinte linha:
bind-address = 127.0.0.1
Deixando assim:
bind-address = 0.0.0.0

3 – Reinicie o Mysql
# /etc/init.d/mysql restart

4 – Vamos agora dar GRANT no usuário root, logue no mysql:
# mysql -u root -p

5 – Após se logar, digite o seguinte comando:
GRANT ALL ON *.* TO root@’%’ IDENTIFIED BY ‘sua_senha’;

Dessa forma você libera o acesso ao seu servidor Mysql vindo de qualquer máquina externa, caso queira liberar somente o acesso da sua máquina, é só verificar qual é seu IP e entrar com o comando:

GRANT ALL ON *.* TO root@’192.168.0.2′ IDENTIFIED BY ‘sua_senha‘;

6. Após isso, basta dar uma reiniciada novamente no Mysql e realiazar a conexão remota.
# /etc/init.d/mysql restart

====================================================

Caso você queira desfazer o acesso remoto é bem simples também.

1 – Altere a seguinte linha:
bind-address = 0.0.0.0
Deixando assim:
bind-address = 127.0.0.1

2. Logue no Mysql:
# mysql -u root -p

3. Delete todos os privilégios remotos:
DELETE FROM mysql.user WHERE User = ‘root’ AND Host = ‘%’;
FLUSH PRIVILEGES;

4. Reinicie o Mysql e pronto, não estará mais acessível remotamente.

 
Fontes:
http://darkstrikerd.wordpress.com/
http://www.cyberciti.biz/
http://ptankov.wordpress.com/

Script de Backup (dump) Postgresql – Com bancos a escolher

Depois que publiquei o artigo Script de Backup (dump) Postgresql – Múltiplos bancos em arquivos separados, onde por meio de um script shell, é gerados dumps de todos os bancos existentes no servidor, cada banco um arquivo separado e compactado, me perguntaram se era possível, com a mesma idéia fazer um script que ao invés de realizar o dump de todas as bases, fosse possível definir quais bancos seriam backupiados.

Pois bem, é bem simples de fazer isso, vejamos:

[shell]
#!/bin/bash
#
# Um simples script de backup
# Autor: Jonas Ferreira

# db_array – lista dos bancos que se deseja fazer o dump
db_array=”banco1 banco2 banco3 banco4″

# logfile – arquivo que grava o log de cada execucao do script
logfile=”/tmp/pgsql-backup.log”

#Diretorio de destino do arquivos
DIR=/tmp/backup

for db in $db_array
do
/usr/bin/pg_dump $db > “$DIR/$db.sql” 1>> $logfile 2>> $logfile
tar zcvf “$DIR/$db.tgz” “$DIR/$db.sql”
rm -rf “$DIR/$db.sql”
done
[/shell]

Simples assim!

Script de Backup (dump) Mysql – Múltiplos bancos em arquivos separados

Com certeza você já deve conhecer diversas maneiras de realizar backup de sua base Mysql. Mas o objetivo deste howto é apenas uma variação de um script clássico de backup.

Vamos ao problema:

A maioria das pessoas utilizam este comando para backup:

mysqldump -u root -pPASSWORD –all-databases | gzip > /mnt/database`data ‘ %m-%d-%Y’`.sql.gz

Isso vai gerar um backup de todos os bancos de dados de seu SGBD e compactar com o nome de data 03/22/2012.sql.gz. O problema esta ai, pois ele irá gerar todas as querys em um único arquivo, ou seja, se você quiser restaurar um único banco de dados, terá que procurar o trecho no dump que corresponde ao banco desejado.

A solução apresentada abaixo é uma alternativa, onde a partir de um laço, lê todos os elementos do SGBD, e gera um dump já compactado de cada banco, separadamente.

[shell]
#!/bin/bash
# backup mysql com –all-databases, mas separados cada banco em um único arquivo

DIR=”/var/arquivos_backup/mysql”
USER=”root”
PASSWORD=”senha”
OUTPUTDIR=”/var/lib/databases”
MYSQLDUMP=”/usr/bin/mysqldump”
MYSQL=”/usr/bin/mysql”

# elimando arquivos de backup antigos
rm -rf $DIR/*

# lendo a lista de banco de dados
databases=`$MYSQL –user=$USER –password=$PASSWORD \
-e “SHOW DATABASES;” | tr -d “| ” | grep -Ev ‘(Database|information_schema)’`

# realizando o dump e compactando cada arquivo gerado
for db in $databases; do
echo $db
$MYSQLDUMP –force –opt –user=$USER –password=$PASSWORD \
–databases $db | gzip > “$OUTPUTDIR/$db.gz”
done
[/shell]

Com essa idéia, pode-se editar um pouco mais este script, como por exemplo compactar a pasta com todos os arquivos gerados, e já transferir para seu storage com Active Directory, por exemplo.

Aqui disponibilizo para download um script exatamente com essa idéia em prática.

Script de Backup – Mysql – Com depósito no Storage – AD

Depois é só colocar no CronTab.

Referência: snowfrog.net

Remover árvore de diretórios em uma compactação TAR

Se você trabalha com servidores Linux, provavelmente trabalha com processos de backups personalizados para todos os seus dados importantes. Sem dúvida as cópias de segurança acabam sendo armazenadas na forma de um arquivo.tar. Tudo funciona muito bem, as cópias são feitas, comprimidas e enviadas para um storage externo. Há apenas uma questão, sempre que você abrir um desses backups, ele irá incluir toda a árvore de diretórios acima da pasta onde os arquivos foram gerados.

Esse “problema” sempre me deixou chateado quando da criação de dumps de banco de dados. Por exemplo,vamos considerar que meu script de backup gere os arquivos de dumps e salve no diretório: /var/lib/mysql/meu_banco. Eu gostaria de fazer um backup TAR do diretório meu_banco, e chama-lo de meu_banco.tar.gz.

Acontece que quando vou descompactar o arquivo meu_banco.tar.gz, eu vou ter um monte de subpastas inúteis, eu vou ter que fazer drill-down, através da raíz onde eu descompactar, até /var/lib/mysql/meu_banco. Tudo que eu realmente quero é o diretório meu_banco, os demais (/var/lib/mysql) não me interessa.

Veja como é simples se livras desses diretórios. Antes de executar o comando TAR, primeiro você deve usar o comando CD para se mover até o diretório pai que contém o diretório que você deseja, não dentro da pasta que você irá compactar, no exemplo acima, você deve estar dentro de /var/lib/mysql e não dentro de /var/lib/mysql/meu_banco.

Eis a seqüência de comando para exemplo anterior:

[shell]cd /var/lib/mysql
tar -czf /pasta/onde/voce/ira/armazenar/meu_banco.tar.gz meu_banco[/shell]

Com isso, ao descompactar o meu_banco.tar.gz terá apenas um único subdiretório, chamado meu_banco.

Agora, provavelmente você vai executar esses comandos em um script maior de backup, neste caso o comando CD direto não irá funcionar, ainda mais se o script estiver no /etc/init.d/script_bkp.

Felizmente, há uma solução fácil: você pode acrescentar vários comandos shell em conjunto, utilizando && . Com && , cada comando será executado e concluído antes do próximo começar, simulando a digitação de comandos em uma linha.

[shell]cd /var/lib/mysql && tar -czf /pasta/onde/voce/ira/armazenar/meu_banco.tar.gz meu_banco[/shell]

Pronto. 🙂

Adicionando um novo usuário no MySQL

Sei que este é um assunto muito simples, ainda mais se você já tiver o PhpMyAdmin instalado, mas como nem sempre podemos instalar essa ferramenta, o legal é lembrar como adicionar os usuários direto no terminal. Na verdade sempre preciso disso e nunca lembro a sintaxe.

Este procedimento funciona com MySQL 4.x e 5.x

1. Considerando que você já tenha o Mysql instalado e rodando 100%.

[php]mysql –user=root mysql[/php]

Se sua conta root solicitar senha, você pode acrescentar o parâmetro -p ou –password

[php]
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 81
Server version: 5.1.61 Source distribution

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql>
[/php]

2. Criando usuário com acesso full
Depois de conectar, é só executar os comandos para criar o usuário e senha, bem como a definição de privilégios.

[php]
mysql> CREATE USER ‘bkpiador’@’localhost’ IDENTIFIED BY ‘a3$b2#c1!’;
mysql> GRANT ALL PRIVILEGES ON *.* TO ‘bkpiador’@’localhost’ WITH GRANT OPTION;
[/php]

Vejamos o que estamos fazendo:

Na linha 1 é criado o usuário (com acesso permitido somente de localhost) e a senha de acesso.
Na linha 2 define-se as políticas de acesso do usuário, nesse exemplo, o usuário tem permissão para acessar tudo e somente apartir de localhost.

[php]
mysql> CREATE USER ‘bkpiador’@’%’ IDENTIFIED BY ‘a3$b2#c1!’;
mysql> GRANT ALL PRIVILEGES ON *.* TO ‘bkpiador’@’%’ WITH GRANT OPTION;
[/php]

Novamente, na linha 1 é criado o usuário, (agora para acesso de qualquer host) e a senha.
E na linha 2 o usuário tem permissão para acessar tudo apartir de qualquer host.