Pages

quarta-feira, 15 de janeiro de 2014

Como deletar todas as tabelas de uma DB do MYSQL

Como deletar todas as tabelas de uma base mysql sem muito esforço, uma solução prática para esta tarefa.

Para concluir esta tarefa primeiro deixamos as tabelas sem relacionamento, ou seja eu posso excluir todo mundo que ninguem vai reclamar que está relacionada com a outra.

Este codigo retira todas as chaves estrangeiras (FK)


SET foreign_key_checks=off;
 

A outra questão é como fazer o drop certo ?

então o que fizemos foi concatenar a estrutura DROP TABLE com o nome das tabelas assim formando uma serie de registros

SELECT concat('DROP TABLE IF EXISTS ', TABLE_NAME, ';') FROM information_schema.TABLES


O resultado deste codigo vai ser todos os drops de todas as tabelas da db ai é só copiar o resultado e rodar que irá acontecer o esperado.

Copiando uma base MySQL de um servidor para outro. Clonar (duplicar) base de dados

Aqui vai uma dica das minhas horas “brincando” como sysadmin. Normalmente para gerar uma cópia do seu banco de dados mysql, você usa o mysqldump:

$ mysqldump -u usuario -p banco > copia_do_banco.sql

Para passar o arquivo copia_do_banco.sql para outro servidor basta usar sftp/ssh:

$ scp copia_do_banco.sql usuario@outro_server.com:/backup

Para subir:

$ mysql -u usuario -p banco < copia_do_banco.sql

Se você estiver no console do mysql pode optar por:

mysql> USE banco;
SOURCE copia_do_banco.sql


Creio que todo DBA ou Sysadmin sabe disso. Mas temos outros formas de se fazer isto, basta usarmos alguns recursos disponível no shell *nix.
Podemos executar estes mesmo comando em uma só linha, esta forma só deve ser usada em VPN ou redes seguras:

$ mysqldump -u usuario -p banco | mysql -h outro_server banco -u usuario -p

Se você não tem acesso remoto ao banco de dados, podemos usar o ssh:

$ mysqldump -u usuario -p banco | ssh usuario@outro_server.com mysql -u usuario -p banco

Você ainda pode copiar apenas uma tabela do banco para um servidor remoto:
$ mysqldump -u usuario -p banco tabela | ssh usuario@outro_server.com mysql -u usuario -p banco

Estes são alguns exemplos que dá pra fazer com o shell *nix. Prefiro o velho shell e indispensável à sistemas que prometem o mundo.




Imagine que vc possua dois servidores MySQL, sendo que um deles chamaremos de ORIGEM (onde estão os dados de origem) e o outro que chamaremos de DESTINO (onde os dados serão copiados).

Para clonar uma base de dados MySQL localizado num servidor de ORIGEM para um servidor DESTINO, basta digitar o comando no servidor de DESTINO:

mysqladmin create NOME_DO_BANCO_DESTINO -u USUARIO_DESTINO --password=SENHA_DESTINO && mysqldump -h SERVIDOR_ORIGEM -u USUARIO_ORIGEM --password=SENHA_ORIGEM NOME_DO_BANCO_ORIGEM --add-drop-table --add-locks --extended-insert --single-transaction --quick --lock-tables=false | mysql -u USUARIO_DESTINO --password=SENHA_DESTINO NOME_DO_BANCO_DESTINO

Obviamente, se houver necessidade de duplicar a base de dados num mesmo servidor MySQL, basta que o SERVIDOR_ORIGEM e SERVIDOR_DESTINO sejam omitidos, e que o nome do banco de dados DESTINO seja diferente do de ORIGEM. O primeiro trecho do código, onde inicia com mysqladmin e termina em && deverá ser eliminado se o servidor de DESTINO já contiver o banco a ser criado, caso contrário ocorrerá um erro e todo o script será interrompido.

Referência:

http://stackoverflow.com/questions/25794/mysql-copy-duplicate-database

domingo, 12 de janeiro de 2014

Trabalhando com processos de longa duração no PHP

Gostaria de apresentar dois exemplos reais que requerem processos PHP que rodem por longos períodos de tempo (ou até indefinidamente):
  1. Processamento de dados: Todas as noites o seu servidor precisa vasculhar milhões de dados para atualizar rankings, tabelas e estatísticas.
  2. Dados da API de Streaming do Twitter: Requer uma conexão constante com a API do Twitter para receber as mensagens conforme elas são postadas.

As ferramentas

Uma das melhores ferramentas que temos é o PHP CLI (Command Line Interface). Essa ferramenta permite que possamos rodar o PHP diretamente da linha de comando (mais conhecido como Terminal) sem possuir um tempo limite. Todas as dores com o set_time_limit() e as brigas com o php.ini vão embora!
Se você vai trabalhar com linha de comando, provavelmente você vai precisar saber um pouquinho de bash scripting. Deixo aqui uma dica: http://aurelio.net/shell/ - uma fonte ilimitada de conhecimento sobre shell/bash.
Outra coisa bacana é o cron (crontab / cron job)

SSH vs Cron Jobs

Você precisa saber rodar algo em uma sessão SSH é diferente do que configurar um cronjob pra fazer algo pra você. Uma sessão SSH pode ser um bom lugar para testar scripts e rodá-los uma vez apenas, enquanto um cronjob é a maneira correta de configurar um script que você deseja que rode regularmente.
Se eu escrever isso na minha sessão SSH
1
php meuScript.php
irei executar o meuScript.php. Contudo, meu terminal ficará bloqueado até que a execução seja encerrada.
Você pode passar por isso segurando Ctrl + Z (pausa a execução) e utilizando o comando bg (envia o processo para o background).
Para processos longos, pode ser bacana, mas se você perder a sessão SSH, a execução do script será encerrada.
Você pode driblar esse problema utilizando o nohup (no hangup – “não deixar cair”).
1
nohup php meuScript.php
O comando nohup permite que a execução continue mesmo que você perca a sessão. Isso quer dizer que se você utilizar esse comando, enviar o processo para o background e perder a conexão com o SSH, seu comando continuará rodando.
Mas ainda acho que a melhor maneira de executar um processo diretamente no background é utilizando um & (ampersand – “e comercial”). Você adiciona no final do comando e ele vai diretamente para o background, sem precisar de nenhum atalho.
1
nohup php meuScript.php &
É claro que tudo isso apenas importa se você estiver rodando comandos manualmente. Se você scripts com uma certa regularidade e usando os cronjobs, então você não precisa se preocupar com esses problemas. Uma vez que é o próprio servidor quem os executa, a sessão SSH não interessa pra nada.
Algumas vezes, você pode esquecer se rodar o processo utilizando o comando nohup e, mesmo assim, querer que ele continue rodando após a desconexão do SSH. Você pode tentar rodar scripts de madrugada, por achar que serão mais rápidos, e acabar descobrindo que eles demoram muito mais. Aqui fica uma pequena dica que vai te ajudar a rodar o script como daemon, assim não se encerrará ao término da sessão SSH.
  1. Ctrl + Z para pausar o programa e voltar ao shell
  2. bg para rodar no background
  3. disown -h [num-job], onde [num-job] é o número do job que está rodando (exemplo: %1 para o primeiro job rodando; você pode listar os jobs usando o comando jobs). Isso retirará sua propriedade do processo e ele não se encerrará após a saída do terminal.

Processando dados com PHP

Para quem roda scripts regularmente, é interessante criar um bash script para ser executado por um job agendado.
Exemplo de um bash script que, na verdade, roda um script PHP:
Example bash script which actually runs the PHP script:
1
2
#!/bin/sh
php /caminho/para/script.php
Exemplo de um cronjob:
1
0 23 * * * /bin/sh /caminho/para/bashScript.sh
Se você não sabe onde colocar o código acima, utilize o comando crontab -e para editar a sua tabela do cron e salvá-la. O 0 23 * * * indica que o script rodará aos 0 minutos, 23 horas de qualquer dia, em qualquer mês e em qualquer dia da semana (agradeço ao mbodock, que me alertou um detalhe que eu havia deixado passar aqui).
# *    *    *    *    *  comando
# ┬    ┬    ┬    ┬    ┬
# │    │    │    │    │
# │    │    │    │    │
# │    │    │    │    └───── dia da semana (0 - 6) (sunday - saturday)
# │    │    │    └────────── mês (1 - 12)
# │    │    └─────────────── dia do mês (1 - 31)
# │    └──────────────────── hora (0 - 23)
# └───────────────────────── minuto (0 - 59)
Exemplo extraído do artigo Cron da Wikipedia.
Vale também ressaltar que existem alguns nomes pré-definidos que você pode utilizar no lugar do horário de agendamento:
AbreviaçãoDescriçãoEquivalente a
@yearly (ou @annually)Uma vez por ano, à meia-noite de 1º de Janeiro0 0 1 1 *
@monthlyUma vez por mês, à meia-noite do primeiro dia do mês0 0 1 * *
@weeklyUma vez por semana, à meia-noite de domingo0 0 * * 0
@dailyUma vez por dia, à meia-noite0 0 * * *
@hourlyUma vez por hora, no começo da hora0 * * * *
@rebootQuando a máquina é inicializada@reboot
Bom, agora nós temos um script básico que rodará todas as noites às 11h. Não importa quanto tempo levará para executar, apenas irá começar às 23h e só encerrará quando terminar.

Twitter Streaming API

O segundo problema é mais interessante, porque o script PHP precisa estar rodando para coletar dados. Queremos que esteja rodando o tempo todo.
Para fazer o trabalho de capturar os dados da API do Twitter, podemos usar a excelente bibliotecaPhirehose (fica a dica).
A partir daí, teremos um script que manterá permanentemente uma conexão aberta com a API do Twitter, mas não podemos garantir que estará sempre rodando. O servidor pode reiniciar, podemos ter algum tipo de problema na execução ou erros de qualquer outra natureza.
Então uma solução que podemos lançar mão é: criar um bash script para ter certeza de que o processo está rodando. E se não estiver, que comece a rodá-lo.
1
2
3
4
5
6
7
#!/bin/sh
 
ps aux | grep '[m]euScript.php'
if [ $? -ne 0 ]
then
    php /caminho/para/meuScript.php
fi
Agora vamos dar uma olhada, linha por linha, o que faz esse script:
Line by line explanation:
1
#!/bin/sh
Inicia o script indicando qual é o path do shell.
1
ps aux | grep '[m]euScript.php'
O comando ps lista os processos. Depois há um pipe (|) que fará com que seja executado um comando sobre o resultado da saída. O comando grep irá procurar por ‘[m]euScript.php’. Usei a expressão regular [m] para que o comando não encontre a ele mesmo. O grep lançará um processo com meuScript.php no comando, então você sempre encontrará um resultado se não colocar alguma coisa nos brackets.
1
if [ $? -ne 0 ]
Verifica o retorno do último comando. Então se nada for retornado, significa que não existe nenhum resultado para [m]euScript na lista de processos.
1
2
3
then
    php /caminho/para/meuScript.php
fi
Essas linhas são executadas se o script php não for encontrado rodando. É esse comando que irá rodar nosso script php. Então a condicional é encerrada com fi.
Agora vamos criar um cron job para executar o script acima:
1
* * * * * /bin/sh rodarPraSempre.sh
Isso fará com que o sistema fique checando o tempo todo se o nosso script está rodando. Se não estiver, fará rodar.

Considerações finais

Dá pra perceber que o script de streaming do Twitter é uma versão mais avançada do processamento de dados. Ambas as versões de produção, possuem muito mais coisas, obviamente, mas vão além do objetivo proposto nesse artigo. Se você estiver interessado em estender esses scripts, é uma boa ideia ativar o sistema de logs, pois vai te ajudar a ter uma noção de como o seu sistema está se comportando.
Um abraço a todos e fiquem com Deus!