Script para fazer Backup de bases do MySQL facilmente

Bom, neste meu segundo post vou mostrar um sistema fácil para fazer um backup sem complicação de bancos do MySQL. Esse sistema foi testado em uma plataforma Linux, com servidor Apache 2.2, PHP4 e 5, e MySQL 4. A lógica do sistema é conectar no banco, pegar as informações da tabela e posteriormente pegar os dados que serão inseridos, gerando o create table e os inserts todos pelo php.

Aí você me pergunta: qual a finalidade de ter um script pra backup, se 90% das contas de provedores de hospedagem tem opção para backup? Uma simples explicação: com esse script nós podemos receber o backup por email (coisa que muitos serviços não fazem), colocar em uma crontab(para aqueles que tem acesso ao console da máquina), e/ou manter armazenado no servidor, bastando apenas remover a função de envio de e-mail.

Sobre a crontab eu não vou falar muito porque pode ser tópico no próximo post. Apenas uma explicação básica: o Crontab funciona de forma semelhante ao “agendador de tarefas” do Windows.

No linux temos uma vantagem com o crontab. Além de termos um arquivo GLOBAL, ele também pode funcionar por usuário, ou seja, cada um pode ter a sua agenda de scripts.
Normalmente, quando o servidor é seu, costuma-se configurar todos os serviços no Crontab do “root”, logo, para acessá-lo, você precisa estar conectado como root no servidor.
O Crontab é uma “carta na manga”, que pode lhe ajudar em muitos casos e atrapalhar em outros, portanto não abuse colocando tudo lá, não “encha” o crontab, e faça um script chamar outros, se possível.

  • Segue o código abaixo:

<?php // Aqui colocamos uma classe pra lidar com SQL
class ConexaoMysql
{
var $servidor = "localhost";
var $usuario = "usuario_do_banco";
var $senha = "senha_do_usuario";
var $banco = "nome_do_banco";
var $link = "";
var $query = "";

// Metodo Construtor
function ConexaoMysql()
{
$this->ConectaBase();
}

// Conexao com banco
function ConectaBase()
{
$this->link = @mysql_connect( $this->servidor, $this->usuario, $this->senha);
if (!$this->link) {
die(”Error na conexao: “.mysql_error().” - “.mysql_errno());
} elseif (!mysql_select_db($this->banco, $this->link)) {
die(”Error na conexao: “.mysql_error().” - “.mysql_errno());
// mysql_errno(): numero do erro
//mysql_error(): descrição do erro
}
}

// Execução da query
function sql($query)
{
$this->query = $query;
if ($result = mysql_query($this->query,$this->link)) {
return $result;
} else {
return 0;
}
}
// dados da tabela
function tabelas()
{
if ($result = mysql_list_tables($this->banco)) {
return $result;
} else {
return 0;
}
}
// função de mandar email
function Sendmail($arquivo, $para, $assunto)
{

$body = “”;
$attach_name = “”;

if ($arquivo != “”) {

$file = fopen($arquivo, “r”);
$contents = fread($file, (1024*1024));
$encoded_attach = chunk_split(base64_encode($contents));
fclose($file);
$attach_name = $arquivo;

$anexo .= “\n\n–Message-Boundary\n”;
$anexo .= “Content-type: $attach_type; name=\”$attach_name\”\n”;
$anexo .= “Content-Transfer-Encoding: BASE64\n”;
$anexo .= “Content-disposition: attachment; filename=\”$attach_name\”\n\n”;
$anexo .= “$encoded_attach\n”;
$anexo .= “–Message-Boundary–\n”;

}

$cabecalho = “From: Nome <meu@email.com> \r\n”;
$cabecalho .= “Content-Type: text/html;”;
$cabecalho .= “MIME-version: 1.0\n”;
$cabecalho .= “Content-type: multipart/html; “;
$cabecalho .= “boundary=\”Message-Boundary\”\n”;
$cabecalho .= “Content-transfer-encoding: 7BIT\n”;
$cabecalho .= “X-attachments: $attach_name”;

$mensagem = “–Message-Boundary\n”;
$mensagem .= “Content-type: text/html; charset=US-ASCII\n”;
$mensagem .= “Content-transfer-encoding: 7BIT\n”;
$mensagem .= “Content-description: Mail message body\n\n”;

$mensagem .= $body . $anexo;

mail($para, $assunto, $mensagem, $cabecalho);
}
}

// pasta temporaria pra geração do gzip
$path = “backup”;
// nome do banco
$dbname = “nome_do_banco”;
// nome do arquivo sql
$nome_arquivo_sql = $path.”_”.$nome_arquivo.”.sql”;
// nome do arquivo sql compactado
$nome_arquivo_gz = $dbname.”_”.date(”d-m-Y”).”.sql.gz”;

// cria e abre o arquivo como leitura
$back = fopen($nome_arquivo_sql,”w”);

// recebe os dados da tabela com o camando da classe mysql_list_tables()
$res = $objConexao->tabelas();

// aqui cria um cabeçalho para o arquivo sql
// como exemplo nome, criado em, autor, dados do banco vc pode escrever aqui
fwrite($back,”#\n# Arquivo de Geração de Backup\n”);
fwrite($back,”# Autor: Seu Nome - email opcional \n”);
fwrite($back,”# Banco: MySql\n#\n\n\n”);

// aqui começamos a lógica
// enquanto receber valor do $res ele faz a rotina
while ($row = mysql_fetch_row($res)) {
// listamos todas as tabelas
// e pegamos sempre o [0] q sempre vem o nome da tabela
$table = $row[0];
// aqui pega os dados da criação tabela q vem do item acima, sempre na ordem
$res2 = mysql_query(”SHOW CREATE TABLE $table”);
// entao aqui entramos na proxima rotina,
// onde pegamos os valores da tabela e montamos os inserts
while ( $lin = mysql_fetch_row($res2)){

// aqui escrevemos um cabeçalho pra cada tabela
// identificando a tabela e separando os inserts
fwrite($back,”\n#\n# Criação da Tabela : $table\n#\n\n”);
fwrite($back,”$lin[1] ;\n\n#\n# Dados a serem incluídos na tabela\n#\n\n”);

// então pegamos os dados da tabela pra monta os insert’s
$res3 = $objConexao->sql(”SELECT * FROM $table”);
while($r = mysql_fetch_row($res3)){
// colocamos o prefixo que insere os valores na tabela
$sql=”INSERT INTO $table VALUES (”;

//cada linha de registro separamos com os vamores com aspas simples ” e virgula ,
for($j=0; $j<mysql_num_fields($res3);$j++)
{
if(!isset($r[$j]))
$sql .= “” ,”;
elseif($r[$j] != “”)
//essa função addlashes faz escapar as aspas simples (ex.: d’agua = d\’agua)
$sql .= ” ‘”.addslashes($r[$j]).”‘,”;
else
$sql .= “” ,”;
}
// usamos aqui a ereg_replace() pra remover uma falha q fica no final “,$”
$sql = ereg_replace(”,$”, “”, $sql);
// então usamos o pulo de linha para ficar certinho o arquivio
$sql .= “);\n”;

// depois de montado a linha de insert, escreveremos no arquivo
// isso é feito pra cada linha de registro;
fwrite($back,$sql);
}
}
}

// fechamos a escrita e salvamos o aquivo
fclose($back);

// agora a compactação do arquivo
// abrimos em modo leitura com ponteiro no inicio (r) forçando com modo binario (b)
$fp = fopen($nome_arquivo_sql, “rb”);
// aqui lemos o arquivo e grava o conteudo em na variavel $data
$data = fread($fp, filesize($nome_arquivo_sql));
// fechamos o arquivo
fclose($fp);

//abrimos o arquivo em compactação wb9 q é a padrao para saber mais www.php.net/gzopen
$zp = gzopen($nome_arquivo_gz, “wb9″);
// escrevemos o conteudo no arquivo de compactação
gzwrite($zp, $data);
// fechamos o arquivo compactado
gzclose($zp);

// aqui vai a parte de envio por email o arquivo de backup
// monta o assunto
$assunto = “[Labcis] - Backup: (”.date(”d/m/Y @ H:i”).”)”;
$email_destino = “seu@email
“;

// chama a função de mandar o email
$objConexao->Sendmail($nome_arquivo_gz, $email_destino, $assunto);

// apaga os arquivos temporarios do servidor
unlink(”$nome_arquivo_gz”);
unlink(”$nome_arquivo_sql”);

?>