GNU/Linux >> Tutoriales Linux >  >> Linux

¿Comportamiento de rsync con un archivo que aún se está escribiendo?

Si Apache está escribiendo un archivo de algún tipo en un lugar y no ha terminado de escribirlo y luego rsync entra en acción, rsync copiará lo que sea que esté allí.

Lo que significa que si Apache está tratando con un archivo de 5 MB, solo se escriben 2 MB y rsync se activa, se copiará el archivo parcial de 2 MB. Entonces ese archivo parecería estar "corrompido" en el servidor de destino.

Dependiendo del tamaño de los archivos que esté usando, puede usar el --inplace opción en rsync hacer lo siguiente:

Esta opción cambia la forma en que rsync transfiere un archivo cuando es necesario actualizar los datos del archivo:en lugar del método predeterminado de crear una nueva copia del archivo y moverla a su lugar cuando se completa, rsync escribe los datos actualizados directamente en el archivo de destino.

El beneficio de esto es que si un archivo de 5 MB solo tiene 2 MB copiados en la primera ejecución, la próxima ejecución recuperará 2 MB y continuará copiando el archivo hasta que se hayan colocado los 5 MB completos.

Lo negativo es que podría crear una situación en la que alguien acceda al servidor web mientras se copia un archivo y luego vería un archivo parcial. En mi opinión rsync funciona mejor en su comportamiento predeterminado de almacenar en caché un archivo "invisible" y luego moverlo a su lugar de inmediato. Pero --inplace es bueno para escenarios en los que los archivos grandes y las restricciones de ancho de banda pueden obstaculizar la copia fácil de un archivo grande desde el principio.

Dicho esto, afirmas esto; el énfasis es mío:

Cada cinco minutos tiene cron ejecutar rsync…

Entonces, ¿supongo que tiene algún script bash para administrar este trabajo cron? Bueno, la cosa es rsync es lo suficientemente inteligente como para copiar solo los archivos que deben copiarse. Y si tiene un script que se ejecuta cada 5 minutos, parece que está tratando de evitar tener rsync pisar unos a otros si va más rápido. Es decir, si lo ejecutó cada minuto, existe el riesgo de que uno o más de los rsync los procesos seguirían ejecutándose debido al tamaño del archivo o la velocidad de la red y el siguiente proceso simplemente competiría con él; una condición de carrera.

Una forma de evitar esto es envolver todo el rsync comando en un script bash que busca un bloqueo de archivo; a continuación se muestra un marco de script de bash repetitivo que utilizo para casos como este.

Tenga en cuenta que algunas personas recomendarán usar flock pero desde flock no está instalado en algunos sistemas que uso, y paso mucho entre Ubuntu (que lo tiene) y Mac OS X (que no lo tiene), uso este marco simple sin ningún problema real:

LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'

if mkdir ${LOCK_DIR} 2>/dev/null; then
  # If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
  echo $$ > ${PID_FILE}

  echo "Hello world!"

  rm -rf ${LOCK_DIR}
  exit
else
  if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
    # Confirm that the process file exists & a process
    # with that PID is truly running.
    echo "Running [PID "$(cat ${PID_FILE})"]" >&2
    exit
  else
    # If the process is not running, yet there is a PID file--like in the case
    # of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
    rm -rf ${LOCK_DIR}
    exit
  fi
fi

La idea es ese núcleo general, donde tengo echo "Hello world!" —es donde está el corazón de su guión. El resto es básicamente un mecanismo/lógica de bloqueo basado en mkdir . Una buena explicación del concepto está en esta respuesta:

mkdir crea un directorio si aún no existe, y si existe, establece un código de salida. Más importante aún, hace todo esto en una sola acción atómica, lo que lo hace perfecto para este escenario.

Entonces, en el caso de su rsync proceso, recomendaría usar este script simplemente cambiando el echo comando a su rsync dominio. Además, cambia el LOCK_NAME a algo como RSYNC_PROCESS y entonces estás listo para irte.

Ahora con tu rsync envuelto en este script, puede configurar el trabajo cron para que se ejecute cada minuto sin ningún riesgo de una condición de carrera donde dos o más rsync los procesos están luchando para hacer lo mismo. Esto le permitirá aumentar la velocidad o rsync actualizaciones que no eliminarán el problema de la transferencia de archivos parciales, pero ayudarán a acelerar el proceso general para que el archivo completo se pueda copiar correctamente en algún momento.


Sí, y el archivo podría estar dañado si rsync está leyendo el archivo al mismo tiempo que se está escribiendo.

Puedes probar esto:https://unix.stackexchange.com/a/2558

También puede escribirlo con lsof:

lsof /path/to file

Un código de salida de 0 significa que el archivo está en uso y un código de salida de 1 significa que no hay actividad en ese archivo.


Linux
  1. ¿Transferencias de archivos más inteligentes que Rsync?

  2. ¿Es seguro usar Rsync mientras se actualiza la fuente?

  3. ¿Reemplazar nueva línea con Nul?

  4. ¿Cómo generar un archivo e ignorar las líneas que comienzan con "?"?

  5. ¿Es seguro abrir un archivo que está siendo escrito por un script en ejecución?

Comando WC de Linux con ejemplos

Firmas digitales con GnuPG

Todavía trabajando con cajas de gnomos

Recuperar el archivo eliminado que se está escribiendo actualmente

¿Determinar si el archivo está en proceso de escritura?

¿mv con comodín sigue siendo atómico?