Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Função de backups PDO MySQL


Esse script de backup é ridículo e ninguém deveria fazer outra versão dele. Eu já vi esse script antes, bem como tentativas semelhantes, e eles têm muitos problemas:
  • Não delimita nomes de tabelas em back-ticks
  • Não lida com NULLs
  • Não lida com conjuntos de caracteres
  • Não processa dados binários
  • Não faz backup de VIEWs
  • Não faz backup de GATILHOS ou PROCEDIMENTOS ARMAZENADOS ou FUNÇÕES ARMAZENADAS ou EVENTOS
  • Usa extensão mysql obsoleta (mas é por isso que você quer uma versão PDO, não é?)
  • Usa addlashes() em vez de uma função de escape adequada do MySQL.
  • Anexa todos dados para todos tabelas em uma string muito longa, antes de produzir todo o conteúdo. Isso significa que você deve ser capaz de armazenar todo o seu banco de dados em uma string, o que quase certamente ultrapassará seu limite máximo de memória do PHP.

Veja também minha resposta anterior sobre o infeliz script de backup de David Walsh:

Re seu comentário:

Leia os comentários na página que você vinculou. Muitas pessoas identificaram problemas e algumas têm correções ou pelo menos sugestões.

O fato de esse script anexar tudo em uma string é um fator decisivo, eu acho, mas não deve ser difícil alterar o script para abrir o arquivo de saída primeiro , em seguida, produza os dados de cada linha durante o loop e feche o arquivo após o loop. Isso é meio óbvio, não sei por que o script não faz isso. Mas está bem claro que o script não foi testado muito bem.

Mas de qualquer forma, eu não tentaria reinventar essa roda. Mysqldump ou mydumper fazem esse trabalho bem. FWIW, você não precisa executar o mysqldump no mesmo servidor em que o banco de dados reside. Mysqldump suporta uma opção para --host então você pode executar o mysqldump em qualquer lugar para fazer backup de um banco de dados remoto, desde que os firewalls não impeçam a conexão do seu cliente. Basicamente, se você puder conectar um aplicativo PHP ao banco de dados de algum host cliente, poderá conectar o mysqldump.

Se isso não for realmente uma opção, então eu usaria o recurso de despejo de banco de dados do phpmyadmin. Estes são maduros e bem testados e despejam tudo corretamente. Aqui está um artigo que descreve como usar o recurso de despejo:

http://www.techrepublic. com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/

[Copiando meus comentários da sua resposta:]

Isso está entrando na revisão de código, que não é o objetivo do StackOverflow. Mas brevemente:
  • sem suporte adequado para NULL (você os converte para '');
  • não delimitando consistentemente os nomes das tabelas;
  • usando aspas duplas não ANSI como delimitadores de string;
  • usar consultas em buffer em tabelas enormes quebrará o limite máximo de memória do PHP;
  • Anexar todas as linhas para uma tabela enorme quebrará o limite máximo de memória do PHP;
  • usando addlashes() em vez de PDO::quote();
  • verificação de erros de consulta apenas no final da função;
  • não verificando falha na criação do arquivo;
  • A extensão gzip pode não ser carregada
  • Além disso, provavelmente ainda não é compatível com dados UTF8.

Sim, isso é melhor do que o roteiro original de David Walsh. :-)

NULL não é o mesmo que '' no SQL (exceto no Oracle, mas eles não estão de acordo com o padrão SQL neste caso). Veja MySQL, é melhor inserir NULL ou vazio seqüência?

Eu li errado o código sobre o problema do limite de memória. Você está escrevendo a saída para cada linha, então tudo bem (a menos que a linha contenha um blob de 1 GB ou algo assim).

Mas você não deve apenas gerar uma única instrução INSERT com um conjunto de linhas separadas por vírgula. Mesmo mysqldump --extended-insert emite um comprimento finito de dados e, em seguida, inicia uma nova instrução INSERT. O critério é se o comprimento da instrução INSERT se encaixa no argumento de opção para --net-buffer-length .

Em ANSI SQL, aspas simples '' são usadas para delimitar literais de string ou literais de data. Aspas duplas "" são usadas para delimitar identificadores como nome de tabela ou nomes de coluna. Por padrão, o MySQL os trata da mesma forma, mas isso não é padrão. Consulte Bancos de dados diferentes usam citação de nome diferente? . Se você tentar importar seus dados de backup em um servidor MySQL onde você tenha SET SQL_MODE=ANSI_QUOTES , a importação falhará.

Exemplo:query('SELECT * FROM '.$table); e, de fato, cada um dos outros casos em que você usa $table em uma consulta. Você só delimitou a tabela uma vez, na instrução INSERT que seu script gera.

O MySQL sempre reconhece back-ticks como delimitadores de identificadores e aspas simples para strings/datas. Mas aspas duplas mudam de significado dependendo do SQL_MODE que mencionei. Você não pode presumir qual SQL_MODE está em vigor na instância do MySQL em que você restaura, portanto, é melhor usar os acentos graves para identificadores e aspas simples para strings. A razão pela qual você os delimita ao consultar sua tabela é que você pode ter nomes de tabela que são palavras reservadas SQL ou que contêm caracteres especiais, etc.

Você pode inserir todos os tipos numéricos sem delimitadores. Apenas strings e datas precisam de delimitadores. Consulte dev.mysql.com/doc/refman/5.6/en/literals.html