sql >> Base de Datos >  >> RDS >> Mysql

Función de copias de seguridad PDO MySQL

Ese script de copia de seguridad es ridículo y nadie debería hacer otra versión de él. He visto ese script antes, así como intentos similares, y tienen muchos problemas:

  • No delimita los nombres de las tablas en las comillas invertidas
  • No maneja valores NULL
  • No maneja conjuntos de caracteres
  • No maneja datos binarios
  • No realiza copias de seguridad de VIEW
  • No realiza copias de seguridad de DISPARADORES, PROCEDIMIENTOS ALMACENADOS, FUNCIONES ALMACENADAS o EVENTOS
  • Utiliza una extensión mysql obsoleta (pero esta es la razón por la que desea una versión PDO, ¿no es así?)
  • Utiliza las pestañas() en lugar de una función de escape de MySQL adecuada.
  • Agrega todos datos para todos tablas en una cadena realmente larga, antes de generar todo el contenido. Esto significa que debe poder almacenar toda su base de datos en una sola cadena, lo que seguramente superará su límite máximo de memoria de PHP.

Consulte también mi respuesta anterior sobre el desafortunado script de copia de seguridad de David Walsh:

Re tu comentario:

Lea los comentarios en la página a la que se vinculó. Mucha gente ha identificado problemas y algunos tienen soluciones o al menos sugerencias.

Creo que el hecho de que esta secuencia de comandos agregue todo en una cadena es un factor decisivo, pero no debería ser difícil cambiar la secuencia de comandos para abrir el archivo de salida primero , luego emita los datos de cada fila durante el ciclo, luego cierre el archivo después del ciclo. Eso es una especie de obviedad, no estoy seguro de por qué el guión no hace eso. Pero está bastante claro que el script no se probó muy bien.

Pero de todos modos, no intentaría reinventar esta rueda. Mysqldump o mydumper hacen bien este trabajo. FWIW, no tiene que ejecutar mysqldump en el mismo servidor donde reside la base de datos. Mysqldump admite una opción para --host por lo que puede ejecutar mysqldump en cualquier lugar para hacer una copia de seguridad de una base de datos remota, siempre que los firewalls no bloqueen la conexión de su cliente. Básicamente, si puede conectar una aplicación PHP a la base de datos desde algún host cliente, puede conectar mysqldump.

Si esa no es realmente una opción, entonces usaría la función de volcado de base de datos de phpmyadmin. Estos son maduros y bien probados y vuelcan todo correctamente. Aquí hay un artículo que describe cómo usar la función de volcado:

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

[Copiando mis comentarios de tu respuesta:]

Esto es entrar en la revisión del código, que no es el propósito de StackOverflow. Pero brevemente:

  • no hay soporte adecuado para NULL (los convierte a '');
  • no delimitar consistentemente los nombres de las tablas;
  • usar comillas dobles que no sean ANSI como delimitadores de cadena;
  • el uso de consultas almacenadas en búfer en tablas enormes romperá el límite máximo de memoria de PHP;
  • añadir todas las filas de una tabla enorme romperá el límite máximo de memoria de PHP;
  • utilizando addedlashes() en lugar de PDO::quote();
  • comprobación de errores de consulta solo al final de la función;
  • no verificar la creación fallida de archivos;
  • Es posible que la extensión gzip no esté cargada
  • Además, probablemente todavía no admita datos UTF8.

Sí, esto es mejor que el guión original de David Walsh. :-)

NULL no es lo mismo que '' en SQL (excepto en Oracle, pero no cumplen con el estándar SQL en este caso). Ver MySQL, mejor insertar NULL o vacío cadena?

Leí mal el código sobre el problema del límite de memoria. Está escribiendo la salida para cada fila, por lo que está bien (a menos que la fila contenga un blob de 1 GB o algo así).

Pero no debe generar una sola instrucción INSERT con un conjunto de filas separadas por comas. Incluso mysqldump --extended-insert genera una longitud finita de datos, luego inicia una nueva instrucción INSERT. El criterio es si la longitud de la instrucción INSERT se ajusta al argumento de opción para --net-buffer-length .

En ANSI SQL, las comillas simples '' se utilizan para delimitar literales de cadena o literales de fecha. Las comillas dobles "" se utilizan para delimitar identificadores como el nombre de la tabla o los nombres de las columnas. De forma predeterminada, MySQL los trata de la misma manera, pero esto no es estándar. Consulte ¿Las diferentes bases de datos usan comillas de nombres diferentes? . Si intenta importar sus datos de respaldo en un servidor MySQL donde tiene SET SQL_MODE=ANSI_QUOTES , la importación fallará.

Ejemplo:query('SELECT * FROM '.$table); y, de hecho, cada uno de los otros casos en los que usa $table en una consulta. Solo delimitó la tabla una vez, en la declaración INSERT que genera su secuencia de comandos.

MySQL siempre reconoce las comillas invertidas como delimitadores de identificadores y comillas simples para cadenas/fechas. Pero las comillas dobles cambian de significado según el SQL_MODE que mencioné. No puede asumir qué SQL_MODE está en efecto en la instancia de MySQL en la que restaura, por lo que es mejor si usa las marcas de retroceso para los identificadores y las comillas simples para las cadenas. La razón por la que los delimitaría al consultar su tabla es que podría tener nombres de tablas que son palabras reservadas de SQL o que contienen caracteres especiales, etc.

Puede insertar todos los tipos numéricos sin delimitadores. Solo las cadenas y las fechas necesitan delimitadores. Consulte dev.mysql.com/doc/refman/5.6/en/literals.html