Forma más limpia de eliminar archivos en Linux que incluyen una marca de fecha como parte del nombre del archivo

8

Tengo un nuevo requisito para purgar archivos de volcado de MySQL que tienen más de 30 días. Los archivos utilizan una convención de nomenclatura de "all-mysql-YYYYMMDD-HHMM.dump". Los archivos se encuentran en el sistema de archivos montado en SAN, por lo que la restauración no es un problema, pero desafortunadamente el espacio en disco es limitado y se llena rápidamente, por lo que requiere una intervención humana frecuente.

Ejemplo de nombres de archivos

  • all-mysql-20130324-2330.dump
  • all-mysql-20130325-2330.dump
  • all-mysql-20130326-2330.dump

Mi primer pensamiento fue usar "find" dentro de un script por lotes con -mtime +30, sin embargo, los tiempos de modificación no se pueden garantizar y algunos de los archivos más antiguos podrían evadir la fecha de purga :)

Creé el siguiente script BASH, pero esperaba que hubiera una forma más limpia de realizar esta operación.

#!/bin/bash

STARTING_DIR=$(pwd)

FILE_PREFIX=all-mysql-
BACKUP_DIR=/opt/backup/mysql/dumps
ARCHIVE_WINDOW_DAYS=30

cd $BACKUP_DIR

# Create YYYYMMDD datestamp for Today - $ARCHIVE_WINDOW_DAYS
ARCHIVE_WINDOW_IN_SECS=$(echo "$(date +%s) - (${ARCHIVE_WINDOW_DAYS} * 86400)" | bc)
PURGE_BEFORE_DATE=$(date -d @${ARCHIVE_WINDOW_IN_SECS} +%Y%m%d)

for backup_file in $FILE_PREFIX*
do
    # Trim prefix, time portion of date stamp, and file extension
    # from $backup_file to allow numeric comparison against YYYYMMDD
    backup_trim_tmp=${backup_file#${FILE_PREFIX}}
    backup_trimmed=${backup_trim_tmp%-****.dump}

    if [ ${PURGE_BEFORE_DATE} -gt ${backup_trimmed} ]
    then
        rm $backup_file
    fi
done

cd $STARTING_DIR
TP
fuente
3
Me parece perfectamente adecuado, y no puedo ver una forma más simple de hacer la conversión de fecha que la que realmente tomaste. :)
tink
@tink - Gracias. No puedo evitar pensar que había una solución única para esto. Estaba más preocupado por otros mantenedores que viven más en JavaLand que en BASHland. Quizás la única preocupación es el problema del "Año 2038" entonces :)
TP
2
¿No es logrotateuna solución más limpia?
ott--
2
Para cosas como estas también debe haber una protección (no elimine las copias de seguridad antiguas cuando por alguna razón no haya nuevas).
frostschutz
@ott: esa podría ser una opción si funciona bien en userland. Desafortunadamente, a nosotros (los ingenieros de aplicaciones) no se nos permiten privilegios de root ni su, así que si alguno escupe en syslog o requiere algún otro privilegio de superusuario, estaremos en la oscuridad. Es un fastidio, pero es la política reinante :(
TP

Respuestas:

3

Otra forma de eliminar todos excepto los últimos 30 archivos:

rm $(ls -r | tail -n +31)

O aquí hay una versión más corta del guión en la publicación original:

cd /opt/backup/mysql/dumps
d=$(date -r $(($(date +%s)-30*86400)) +%Y%m%d)
for f in all-mysql-*; do
    [[ ${f#all-mysql-} < $d ]] && rm $f
done
Lri
fuente
La opción 1 no tomaría en cuenta las copias de seguridad provisionales que podrían generar más de 30 archivos, pero la opción 2 era lo que esperaba lograr (un script más conciso). Sin embargo, el refactor de secuencia de comandos publicado produjo un error, por lo que cambié la línea de asignación de fecha a d = $ (fecha -d @ $ (($ (fecha +% s) -30 * 86400)) +% Y% m% d ) y funcionó de manera idéntica al guión en la publicación original.
TP
date -d no funcionó en OS X, pero -r también parece tener un significado diferente en la fecha gnu.
Lri
Sip. Otra trampa de GNU vs BSD :)
TP
1

Si desea eliminar todo excepto los últimos 30 archivos:

rm `echo " " all-mysql-*.dump | sed -r -e 's/( [^ ]+){0,30}$//'`

Eso cumpliría su requisito siempre que haya una copia de seguridad por día, y el esquema de nombres permanezca como está (es decir, orden alfabético = orden cronológico, sin espacios en los nombres de archivo).

Usted solicitó específicamente una frase en uno de sus comentarios. Personalmente me gusta escribir más cosas. Este revestimiento es un poco peligroso (si el sed falla, todo se elimina).

Frostschutz
fuente
Actualmente, podría haber múltiples copias de seguridad (volcados) por día para actualizar el QA y los entornos locales. Tal vez deletrearlo y jugar seguro es el mejor enfoque.
TP
Podrías subirlo a 40 o 50 archivos (sin embargo, puedes permitirte muchos espacio de almacenamiento). Si tuviera un sistema de archivos separado para esas copias de seguridad, incluso podría asignar el espacio libre y ejecutar solo la primera copia de seguridad cuando no hay suficiente espacio disponible.
frostschutz