mysqldump y gzip mostrando progreso
En un artículo anterior comentaba la posibilidad de generar un archivo gzip a partir de un volcado de la base de datos MySQL con mysqldump. Ese proceso tenía un inconveniente, y es que desconocemos el estado del progreso de esa copia de seguridad. Para bases de datos pequeñas no es un problema, pero cuando crece, nos podemos quedar esperando un rato largo, y sin información.
pv para mostrar el progreso de mysqldump
Esta es la novedad de hoy: una herramienta para mostrar el progreso dentro de una
pipe de proceso. El funcionamiento es la mar de sencillo. Si tienes un archivo medianamente grande, prueba la instrucción:
cat file.txt | pv -cN cat > file2.txt
La instrucción anterior muestra información sobre la transferencia de bytes por la cañería del proceso. No está mal, ¿no?
Así que si tomamos el ejemplo del anterior artículo:
mysqldump -u [usuario] -p[clave] [base_de_datos] | gzip > [copiaseguridad.sql.gz]
Podemos modificarla para tener lo siguiente:
mysqldump -u [usuario] -p[clave] [base_de_datos] | gzip | pv -cN gzip > [copiaseguridad.sql.gz]
Progreso de mysqldump conociendo el tamaño del origen
Pero claro, lo anterior nos indica cuánto tamaño estamos procesando, pero cuánto nos falta (qué porcentaje queda pendiente). Así que vamos a intentarlo. Para conseguirlo, es obvio que necesitamos un dato clave: el total del archivo a procesar. Sí, estás en lo cierto: es un pequeño chasco porque a veces no tenemos ese dato. Pero tenemos algunas opciones. Por ejemplo, podríamos tener el tamaño del último backup, y con ello podríamos tener una aproximación suficiente. Por ejemplo, para el caso de un archivo sql llano, tenemos lo siguiente:
$ cat dump.sql | pv -cN cat -s $(du -sb dump.sql | awk '{print $1}') > dump2.sql
cat: 347MB 0:00:06 [27,7MB/s] [==================> ] 43% ETA 0:00:07
Vale bien, ¿y todo esto qué es? Pues desglosándolo por partes:
- cat dump.sql: vuelca el contenido del archivo a la cañería.
- pv
- -cN cat -> muestra el progreso del comando cat.
- -s $(du -sb dump.sql | awk '{print $1}') -> Mira el tamaño del archivo dump.sql (du -sb) y se queda sólo con el primer dato de la primer file que sale en pantalla (print $1), que son los bytes del tamaño.
Con esto, estamos ejecutando algo equivalente a si lo indicáramos nosotros directamente, que en el caso del archivo que he utilizado es:
$ pv -cN cat -s 828997215
Trasladando esto a nuestra operación anterior, tenemos:
mysqldump -u [usuario] -p[clave] [base_de_datos] | gzip | pv -cN gzip -s $(gzip -l copiaseguridad-anterior.sql.gz | tail -n 1 | awk '{print $2}') > [copiaseguridad.sql.gz]
La diferencia respecto al caso anterior es que utilizamos la instrucción gzip -l, que nos indica la lista de archivos que hay en un archivo gz (en nuestro caso sólo hay uno), tras lo cual extraemos los bytes que ocupa descomprimido. Con esto no tenemos un dato exacto, pero sí aproximado, especialmente si la base de datos es grande (el incremento entre backups acaba siendo cada vez menor).
Así que nada, a partir de ahora tienes la información sobre en qué punto estás... en tus backups ;-)