2009-12-04

Cron para Backup y Optimizacion de tablas con PHP + Zend Framework

Hace mucho no escribía un post, y quiero volver a retomar el habito con este pequeño scripts realizado con Zend Framework para optimizar todas las tablas de una base de datos mysql y además generar un dump por cada tabla, los resultados los vamos a comprimir para que no ocupe espacio innecesario.

Mantener un backup de nuestras tablas es mas que recomendable, uno nunca sabe cuando lo va a necesitar, sobre todo porque es muy fácil implementar un sistema automatico para generar backups como vamos a ver a continuacion.

En este post aunque es corto quiero demostrar que es posible realizar lo siguientes puntos:

1- Correr php desde la consola de linux
2- Correr Zend Framework desde la consola ( si es posible! ) y usar componentes de Zend Framework sin la necesidad de usar MVC, Zend_Application.
3- Realizar backups diarios de sus base de datos.

1- Correr php desde la consola de linux.

Esto espero que no sea una ciencia para ninguno, realmente es muy fácil. Creamos un scripts antes de los tags php ?> agregamos #!ruta_de_php en mi caso seria #!/usr/bin/php con esta linea le decimos a quien llamar para ejecutar el código que viene a continuación.
Un ejemplo simple seria el siguiente.

  1. #!/usr/bin/php
  2. < ? php
  3. echo "Estoy imprimiendo directamente en la consola";
  4. ? >

Guardamos el archivo como test.php, y le damos permisos de ejecución con el comando

$ chmod a+x test.php

Ahora lo ejecutamos

$ ./test.php

El resultado es el siguiente

2- Correr Zend Framework desde la consola ( si es posible! ).

Zend Framework mas allá de un montón de herramientas que nos brinda y formas de trabajo. Así como Zend_Application, Estructura de directorios organizadas, MVC, etc tambien nos permite usar sus componentes individualmente.
Si nosotros quisieramos usar Zend_Db, y todos los beneficios que este trae, solo necesitamos una configuracion mínima y listo. Podemos usar Zend_Db sin usar MVC o Zend_Application y mantener nuestra estructura de directorios.

En este caso voy a usar Zend_Db para conectarme a una base y conseguir un listado de tablas.

El código es el siguiente.

  1. #!/usr/bin/php
  2. < ? php
  3. set_include_path( implode( PATH_SEPARATOR, array(
  4. realpath( ‘library’ ),
  5. )));
  6. require_once( "library/Zend/Db.php" );
  7. /** Conectamos a la base de datos con ZF */
  8. $db = Zend_Db::factory( ‘Pdo_Mysql’,
  9. ‘adapterNamespace’ => Zend_Db_Adapter,
  10. ‘dbname’ => ‘mysql’,
  11. ‘host’ => ‘localhost’,
  12. ‘username’ => ‘test’,
  13. ‘password’ => ‘qwerty’
  14. )
  15. );
  16. $db->getConnection();
  17. $rowset = $db->fetchAll( "SHOW TABLES" );
  18. print_r( serialize( $rowset ));
  19. ? >

Para el ejemplo yo use Pdo_Mysql pero puden usar el adapter que quieran. Yo serialize el array $rowset para que sea mas claro en la imagen que se ve a continuacion que muestra todas las tablas que tiene la base de datos mysql.

3- Incentivar a realizar backups diarios de sus base de datos.

Es muy comun que una tabla se rompa o alguien cometa algun error y se pierdan datos o dañe una tabla o toda una base. Hay mil factores que pueden hacer que necesitemos un backup reciente de nuestra base. Si creamos un dump entero de nuestra base cuando queramos recuperar una tabla se nos va a complicar un poco realizar esta tarea sin tener que abrir un archivo que vaya a saber cuando miles de mega ocupe. Por eso es conveniente hacer backup de las tablas individualmente, asi en el caso que tengamos problemas con una sola tabla recuperar esa tabla se hace una tarea facil .

Hacer un script que genere este backup diariamente no es complicado, creamos el scripts, y configuramos el cron para que se ejecute a la hora que tengamos la menor cantidad de visitas.

Este script esta en PHP, en realidad la manera mas optima seria hacerlo en shell scripting pero tambien queria demostrar los 2 puntos anteriores.

Mi script es muy sencillo y es facil de entender. Primero trae todas las tablas de la base que estamos usando. Ejecutamos un optimize para cada tabla, inmediatamente generamos un backup de esa tabla en una carpeta temporal, cuando terminamos de hacer estas acciones con todas las tablas comprimimos la carpeta y borramos la carpeta orginal, para que no ocupe espacio.

Para ejecutar los comandos de linux use noFollow y no me preocupe mucho en validarlo, cada uno puede buscar la forma de optimizar el codigo.

El script cuenta con dos archvios. Un application.ini donde guardo toda la info de la base de datos

config/application.ini
[db]
adapter = Pdo_Mysql
params.adapterNamespace = Zend_Db_Adapter
params.host = localhost
params.username = test
params.password = “qwerty
params.dbname = mibase
params.port = 3306
params.options.autoQuoteIdentifiers = 0

Y el script completo

  1. #!/usr/bin/php
  2. < ? php
  3. set_include_path( implode( PATH_SEPARATOR, array(
  4. realpath( ‘library’ ),
  5. )));
  6. require_once( "library/Zend/Config/Ini.php" );
  7. require_once( "library/Zend/Db.php" );
  8. /** Conectamos a la base de datos con ZF */
  9. $applicationConfig = new Zend_Config_Ini( ‘config/application.ini’ );
  10. $db = Zend_Db::factory(
  11. $applicationConfig->db
  12. );
  13. $db->getConnection();
  14. $rootPath = "/home/backup/db/";
  15. $destination = $rootPath . date("Y.m.d") ;
  16. mkdir ( $destination );
  17. $config = $db->getConfig();
  18. $rowset = $db->fetchAll( "SHOW TABLES" );
  19. foreach ( $rowset as $row ){
  20. /** Optimizamos la tabla */
  21. $query = "OPTIMIZE TABLE " . $row[‘Tables_in_’ . $config[‘dbname’] ] ;
  22. $db->query( $query );
  23. $path = $destination . "/{$row['Tables_in_' . $config['dbname'] ]}." . date("Y.m.d") . ".sql" ;
  24. /** Generamos un dump de la tabla */
  25. system( "mysqldump –opt -u {$config['username']} -p{$config['password']} -h {$config['host']} {$config['dbname']} {$row['Tables_in_' . $config['dbname'] ]} > $path " );
  26. }
  27. /** Comprimimos la carpeta con los dump de la fecha y borramos la carpeta */
  28. system( "tar zcf {$destination}.tar.gz {$destination}" );
  29. system( "rm -rf $destination" );
  30. $db->closeConnection();
  31. echo "ndone!nn";
  32. ? >

Antes de ejecutar el script tienen que crear la carpeta /home/backup/db y darle permisos de escritura

$ sudo mkdir -p /home/backup/db

$ sudo chmod -R a+rw /home/backup/db

lo agregamos al crontab y listo.

$ sudo vim /var/spool/cron/crontabs/root

Agregamos la siguiente linea para que se ejecute todos los dias a las 2:20 am
20 2 * * * /var/www/html/scripts/cronOptimize.php > /dev/null 2> /dev/null

Y listo

Recuerden que tienen que tener instalado php5-cli

$ sudo aptitude install php5-cli



Fuente: blog.pablo-morales.com

No hay comentarios: