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.