Si Apache écrit un fichier quelconque à un endroit donné et ne l'a pas encore terminée et alors rsync
coups de pied dans, rsync
va copier ce qui est assis là.
Cela signifie que si Apache a affaire à un fichier de 5 Mo, seulement 2 Mo sont écrits et rsync
démarre, le fichier partiel de 2 Mo sera copié. Donc, ce fichier semblerait être "corrompu" sur le serveur de destination.
Selon la taille des fichiers que vous utilisez, vous pouvez utiliser le --inplace
option dans rsync
faire ce qui suit:
Cette option change la manière dont rsync transfère un fichier lorsque les données du fichier
doit être mis à jour: au lieu de la méthode par défaut de créer un nouveau
copie du fichier et mise en place à la fin, rsync
à la place, écrit les données mises à jour directement dans le fichier de destination.
L'avantage de ceci est que si un fichier de 5 Mo a seulement 2 Mo copiés lors de la première utilisation, la prochaine exécution sera prise à 2 Mo et continuera à copier le fichier jusqu'à ce que les 5 Mo complets soient en place.
L'inconvénient est que cela pourrait créer une situation dans laquelle une personne accède au serveur Web pendant la copie d'un fichier et voit alors un fichier partiel. À mon avis rsync
fonctionne mieux dans son comportement par défaut consistant à mettre en cache un fichier «invisible», puis à le déplacer immédiatement. Mais --inplace
convient aux scénarios où des fichiers volumineux et des contraintes de bande passante peuvent empêcher un fichier volumineux d'être facilement copié depuis le début.
Cela dit, vous déclarez ceci; L'accent est à moi:
Toutes les cinq minutes cron a lancé rsync…
Donc, je suppose que vous avez un script bash en place pour gérer ce travail cron? Eh bien, la chose est rsync
est suffisamment intelligent pour ne copier que les fichiers à copier. Et si vous avez un script qui s'exécute toutes les 5 minutes, il semble que vous essayez d'éviter d'avoir rsync
marchez les uns sur les autres si ça va plus vite. Cela signifie que si vous le courez toutes les minutes, il existe un risque qu’un ou plusieurs des rsync
les processus seraient toujours en cours d'exécution en raison de la taille du fichier ou de la vitesse du réseau et le processus suivant serait simplement en concurrence avec celui-ci; une condition de course.
Une façon d’éviter cela est d’envelopper tout votre rsync
commande dans un script bash qui recherche un verrou de fichier; Vous trouverez ci-dessous un framework de script bash que j'utilise dans de tels cas.
Notez que certaines personnes recommanderont d’utiliser flock
mais depuis flock
n’est pas installé sur certains systèmes que j’utilise - et j’ai beaucoup de sauts entre Ubuntu (qui le possède) et Mac OS X (qui ne le fait pas beaucoup) - j’utilise ce cadre simple sans problème réel:
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
L’idée est ce noyau général — où j’ai echo "Hello world!"
- est où le coeur de votre script est. Le reste est essentiellement un mécanisme / logique de verrouillage basé sur mkdir
. Une bonne explication du concept est dans cette réponse :
mkdir crée un répertoire s'il n'existe pas encore, et s'il existe,
il définit un code de sortie. Plus important encore, il fait tout cela en un seul
action atomique le rendant parfait pour ce scénario.
Donc dans le cas de votre rsync
processus, je recommanderais d’utiliser ce script en changeant simplement le echo
commande à votre rsync
commander. Aussi, changez le LOCK_NAME
à quelque chose comme RSYNC_PROCESS
et puis vous êtes prêt à partir.
Maintenant avec votre rsync
encapsulé dans ce script, vous pouvez configurer le travail cron pour qu'il s'exécute toutes les minutes sans risque rsync
les processus se battent pour faire la même chose. Cela vous permettra d’augmenter la vitesse ou rsync
mises à jour qui n'élimineront pas le problème des fichiers partiels en cours de transfert, mais qui contribueront à accélérer le processus global afin que le fichier complet puisse être copié correctement à un moment donné.
lsyncd
. Il vous permet d’avoir des «dossiers actifs» qui tiennent vraiment compte de leur activité, puis d’agir sur ces fichiers lorsque des modifications sont apportées. j'utilisersync
beaucoup comme indiqué dans ma réponse, mais j'utiliselsyncd
pour les cas nécessitant une forme d'action non cron / plus immédiate.Oui - et le fichier peut être corrompu si rsync le lit en même temps que le fichier.
Vous pouvez essayer ceci: https://unix.stackexchange.com/a/2558
Vous pouvez également le script avec lsof:
Un code de sortie de 0 signifie que le fichier est en cours d'utilisation et un code de sortie de 1 signifie qu'il n'y a aucune activité sur ce fichier.
la source