Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 27/06/2015, à 21:53

Autiwa

[Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Bonjour,

Devenant parano sur la corruption de données ces derniers temps, j'ai viré mon RAID1 (miroir) pour faire une solution maison afin de m'assurer que les fichiers ne sont pas corrompus. En effet, il m'est déjà arrivé plusieurs fois de trouver un fichier .jpg "rose", signe de corruption, et ça me plait vraiment moyen. j'ai aussi appris récemment que le mirroring ne permettait absolument pas de se prémunir de la corruption de données.

En résumé, j'ai donc deux partitions, la normale, et une partition miroir, les deux en ext4.

Actuellement, je stocke la liste des sommes md5 de chaque fichier sur chacune des deux partitions, et je compare.

Petit soucis, j'utilise md5deep afin de produire le fichier, et il faut environ 6h (400 minutes) pour chaque partition.

Savez-vous si cette durée est optimisable, soit en changeant de soft, soit de technique?

Je peux poster mon script si ça aide, mais il est expérimental pour l'instant. Je suis aussi ouvert à d'autres suggestions concernant le problème de corruption.

Cordialement,
Autiwa

Dernière modification par Autiwa (Le 12/07/2015, à 07:38)


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#2 Le 29/06/2015, à 08:12

grim7reaper

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Salut,

Quand tu lances md5deep tu as les CPUs à 100% ?
Si oui, alors tu es limité par l’algorithme (passer à un algo plus rapide type SipHash ou xxHash pourrait te faire gagner du temps).
Si non, alors tu es limité pas les I/O (tu as combien de fichiers ? La taille moyenne est petite ?) et dans ce cas faudrait réduire les I/O et c’est plus contraignant (mais faisable).

Mais bon, le plus inquiétant dans l'histoire ça reste ces histoires de corruptions, faudrait trouver leur origine (si le FS ou le disque commence à faiblir, ça sent pas bon…)

Hors ligne

#3 Le 29/06/2015, à 09:17

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Bonjour,

Merci de ta réponse !

En fait, j'ai eu quelques fichiers corrompus, dont des fichiers brut de mon reflex. Les corruptions me semblent faire partie du processus normal d'un disque dur, raison pour laquelle sur les serveurs, des solutions en RAID6 avec redondance sont mises en place.

De mon coté, avec md5deep, je ne saurais te répondre. En effet, hier j'ai lancé un test, et ça n'a pas fonctionné. J'utilise subprocess.Popen dans un script python pour lancer deux fois md5deep, une fois sur chaque partition. J'ai supposé que la limitation venait des i/O, et je me suis donc dit que je pourrais faire ça en 6 heures en tout (contre 12h si j'avais dû le faire en séquentiel). Mais j'ai eu des problèmes de buffer je crois, et je ne sais pas trop à quoi c'est dû puisque je redirige l'output directement dans la commande, il n'y a donc rien dans stdout et stderr de la commande Popen normalement.

Concernant les fichiers, j'en ai 230 000 environ. Beaucoup sont assez petits, quelques centaines de Ko. Quelques milliers sont autour de 20 Mo, et quelques centaines de gros fichiers (quelques centaines de Mo).


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#4 Le 30/06/2015, à 08:53

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Salut,

Je me permets de réagir juste sur un petit bout de ton message, qui malheureusement est assez symptomatique...

j'ai aussi appris récemment que le mirroring ne permettait absolument pas de se prémunir de la corruption de données.

Le mirroring n'est pas une solution de protection de données, empêchant la perte de données.
C'est une solution de haute disponibilité, permettant à la machine de continuer à fonctionner si un disque dur meurt.


-----


Enfin, concernant ta problématique à la base, pourquoi bricoler toi-même une solution de mirroring ?
Pourquoi n'utilises-tu pas un logiciel de sauvegarde, pour sauvegarder le contenu du premier disque sur le second ?
... en plus tu aurais la possibilité de retrouver l'historique de tes fichiers.

Hors ligne

#5 Le 30/06/2015, à 09:35

claudius01

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Bonjour,

tiramiseb a écrit :

Enfin, concernant ta problématique à la base, pourquoi bricoler toi-même une solution de mirroring ?
Pourquoi n'utilises-tu pas un logiciel de sauvegarde, pour sauvegarder le contenu du premier disque sur le second ?
... en plus tu aurais la possibilité de retrouver l'historique de tes fichiers.

Comme rsync par exemple ;-)

Hors ligne

#6 Le 30/06/2015, à 09:41

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

claudius01: NON !

rsync n'est pas un logiciel de sauvegarde, c'est un outil de synchronisation.

Je pensais plutôt à rsnapshot ou rdiff-backup.

Hors ligne

#7 Le 30/06/2015, à 11:06

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Effectivement, c'est une bonne remarque. Mais comme dit plus haut, rsync fait de la sauvegarde, il ne se préoccupe pas de la corruption de fichier. S'il existe déjà des logiciels qui font ce que je souhaite faire avec mon script, je suis preneur, bien entendu. Ça ne m'amuse pas de réinventer la roue, surtout quand ça roule pas.

Concernant mon script, je l'ai de nouveau fait tourner hier, et le md5deep bugue. Je ne sais pas pourquoi, mais il s'interromp en plein milieu, sans planter, juste, il attend indéfiniment. J'imagine que c'est un soucis avec subprocess.Popen (ou subprocess.call), mais pas trouvé de solution pour l'instant.

Si vous connaissez des logiciels qui font ça, je veux bien les noms en tout cas, moi j'ai pas trouvé. Mais je ne suis pas intéressé plus que ça par des logiciels qui font du versioning, parce que j'ai déjà 800Go de données, j'ai pas envie de tout faire exploser pour des versions qui ne m'intéressent finalement pas.

Les deux logiciels, rsnapshot et rdiff-backup ne me semblent pas gérer la corruption. Et c'est un peu mon problème. Il existe des tonnes de solution de sauvegarde, mais aucune n'aborde explicitement le problème de la corruption de données, ce qui est au final est la seule chose qui m'intéresse en fait.


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#8 Le 30/06/2015, à 11:17

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Je vois ton approche.

Pourquoi appeler md5deep à partir d'un code en Python plutôt que de l'implémenter en Python ?
On trouve des trucs intéressants en cherchant "python md5deep" sur Google.

Hors ligne

#9 Le 30/06/2015, à 12:11

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Tout simplement parce que je ne savais pas que ça existait. J'ai cherché pour md5sum, puis je me suis tourné vers find, et enfin vers md5deep. Mais je voulais éviter de trop rester en python pour que ça ne cause pas de lenteur. La commande md5deep met 6h, donc le moindre ralentissement python, une boucle ou autre, ça m'aurait tout fait exploser.

Mais ces solutions, à conditions qu'elles soient rapides et proches du C, me semblent très intéressantes. Ça me permettra de passer outre la limitation de subprocess.

Merci de l'info !

Si j'arrive à faire un code pratique, je le posterai sûrement, ça pourrait servir à d'autres.


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#10 Le 30/06/2015, à 12:32

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Mais je voulais éviter de trop rester en python

Dans ce cas, ne fais pas du tout de python wink

Hors ligne

#11 Le 30/06/2015, à 12:48

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Je ne me voyais pas coder ça en C non plus. Le Python pour moi, c'est le fashion, mais le cœur du calcul et du temps passé doit être dans un langage machine, rapide et optimisé.


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#12 Le 30/06/2015, à 23:07

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

grim7reaper a écrit :

Quand tu lances md5deep tu as les CPUs à 100% ?
Si oui, alors tu es limité par l’algorithme (passer à un algo plus rapide type SipHash ou xxHash pourrait te faire gagner du temps).
Si non, alors tu es limité pas les I/O (tu as combien de fichiers ? La taille moyenne est petite ?) et dans ce cas faudrait réduire les I/O et c’est plus contraignant (mais faisable).

Pour répondre à la question plus haut, md5deep consomme environ 10% de mon CPU. C'est donc bien le disque dur qui limite. La seule chose où je peux gagner, et c'est ce que j'essaie de faire, c'est lancer les deux md5deep en même temps sur les deux disques. Comme ça ça calcule en parallèle puisque les écritures sur les deux disques ne se saturent pas entre elles.


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#13 Le 04/07/2015, à 17:14

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Bon, mon code plante, enfin plutôt les process md5deep attendent indéfiniment. Je sais pas ce qu'ils foutent. Dès fois ça marche, le plus souvent ça ne fonctionne pas, et je n'ai aucune idée de pouvoir ça se met en "wait forever".


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#14 Le 12/07/2015, à 07:38

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Le soucis de md5deep était l'utilisation de "named pipe" par quod libet. rsync les copiait, md5deep attendait indéfiniment. Mon script fonctionne. Il faut environ 7h pour comparer les sommes md5 de la totalité de ma partition, qui fait 900Go (pour environ 250 000 fichiers).

Voici le script, si jamais c'est utile à certains. Il faudra l'adapter bien sûr, en particulier les noms des partitions, et la configuration du SMTP qui envoie les mails récapitulatifs.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Script to be sure that all files in a given partition are coherent with their expected md5sum. 
# A spare disk/parition need to exist, for data duplication

import pdb
import os
import subprocess
import shutil
import smtplib # Import smtplib for the actual sending function
from email.mime.text import MIMEText # Import the email modules we'll need
import time
import logging # To create a log file
import datetime
import sys
import glob
import socket # To get the hostname

# Variables to be SET : 
# gmail_user and gmail_pwd in the send_mail function
## You can as well define your own smtp server. 
# backup and spare need to be set. 

documents = "/media/autiwa/documents"
backup = "/media/autiwa/spare"

t_start = time.time()

def cmd_exists(cmd):
    return subprocess.call("type " + cmd, shell=True, 
        stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0

def run(command, error=False):
	"""launch a system command in a terminal. 
	
	Argument:
	command : The desired command (string)
	error : True or False. If True, stderr and return_code are returned. 
	if not, an error will cause the function to crash and display an error message
	
	Dependance:
	Module subprocess is used and must be imported with: 
	import subprocess
	
	Return: 
	if error=False -> return: process_stdout /!\ exit() if error
	if error=True -> return: (process_stdout, process_stderr, return_code) 
	
	Example:
	stdout = run("ls")
	(process_stdout, process_stderr, return_code) = run("ls", error=True)
	
	"""
	if (type(command) != str):
		print("Error: command expected to be a string. But instead, type=%s" % type(command))
		exit()
	
	process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
	# Compared to "wait", communicate allow the use of pipes for stderr and stdout
	# and handle correctly the cases of huge outputs.
	(process_stdout, process_stderr) = process.communicate()
	return_code = process.poll()
	# there is .poll() or .wait() but I don't remember the difference. For 
	# some kind of things, one of the two was not working
	
	process_stdout = process_stdout[:-1] # We suppress the last '\n' of the output
	
	if error:
		return (process_stdout, process_stderr, return_code)
	else:
		if (return_code != 0):
			print("Error: command '%s' failed." % command)
			print("variable available: process_stdout, process_stderr, return_code")
			pdb.set_trace()
			exit()
		
		return process_stdout

def get_dict_md5(filename, excluded_files):
	"""From a filename containing md5deep output, 
	we retrieve a dictionnary making the correspondance 
	between the path of a file (key) and its md5sum (value)
	"""
	object_file = open(filename, 'r')
	lines = object_file.readlines()
	object_file.close()

	md5_list = {}
	for line in lines:
		md5sum = line[0:32]
		str_date = line[33:52]
		file_path = line[54:-1] # We exclude the trailing "\n"
		# We don't want to check new files because they don't exist in the old md5 files. 
		# We don't want to check files that are excluded by rsync
		if not((file_path in excluded_files) or (any(x in file_path for x in exclude_folder))):
			
			date_elem = [ int(elem) for elem in str_date.split(":")]
			file_date = datetime.datetime(*date_elem)
			md5_list[file_path] = (md5sum, file_date)

	return md5_list

def displayTime(time):
  """Will format the given time in seconds to display hours and minutes if needed. 
  
  Hence, 1200 seconds will display as 20 min
  
  Input:
  time: number of seconds
  
  Output: string formating of the given time, using hours and minutes if needed"""

  time = float(time)
  
  nb_hours = int(time / 3600)
  time = time - nb_hours * 3600
  
  nb_minutes = int(time / 60)
  time = time - nb_minutes * 60
  
  nb_seconds = round(time, 2)
  
  # We construct the string
  str_time = ''
  if (nb_hours != 0):
    str_time += "%dh " % nb_hours
  if (nb_minutes != 0):
    str_time += "%dmin " % nb_minutes
  str_time += "%.1fs" % nb_seconds
  return str_time

def send_mail(message, title):
	"""preconfigured function to send an e-mail. 
	"""
	me = "%s@%s" % (os.getlogin(), socket.gethostname())
	to = "Your_email@adress.com"

	gmail_user = ''
	gmail_pwd = '' # application password generated specifically
	smtpserver = smtplib.SMTP("smtp.gmail.com",587)
	smtpserver.ehlo()
	smtpserver.starttls()
	smtpserver.ehlo
	smtpserver.login(gmail_user, gmail_pwd)

	msg = MIMEText(message)

	msg['Subject'] = title
	msg['From'] = me
	msg['To'] = to

	smtpserver.sendmail(me, to, msg.as_string())

	smtpserver.close()

home = os.path.expanduser("~")
logging.basicConfig(filename=os.path.join(home, "sync_storage.log"), filemode='w') # the previous logFile is erased if it already existed.
log = logging.getLogger("sync_storage.py")
log.setLevel(logging.DEBUG) #set verbosity to show all messages of severity >= DEBUG
report_message = ""
key_problem = ""
corruption_problem = ""
changed_problem = ""

exclude_folder = ["lost+found", ".Trash-1000"]

new_md5 = "checklist.md5"
old_md5 = "checklist_old.md5"
rsync_filename = "rsync_changed_files.log"

log.info("%s" % datetime.datetime.today())
log.info("From %s to %s" % (documents, backup))

if not(os.path.exists(documents)):
	log.warning("%s do not exist." % documents)
	exit()

if not(os.path.exists(backup)):
	log.warning("%s do not exist." % backup)
	exit()

if (not(cmd_exists("md5deep"))):
	log.warning("Error: md5deep is not installed.")
	exit()

isProblem = False
isTest = False
problem_message = """AIM : Backup documents into a spare partition. 
In addition, will check the md5sum of each and every files to ensure 
that no corruption occured through time. Of course, corruption is checked only between 
already existing copies of a given files. Freshly copied files are skiped.

The script can take various arguments:
(no spaces between the key and the values, only separated by '=')
 * test : Will compare the existing md5sum without actually computing them. 
          Will only compare the checksum.md5 files of each partition
 * help : display a little help message on HOW to use various options.

EXAMPLE:
To see the current help message:
 > %s help 
 
 To launch only the compare features, without actually 
 syncing (rsync) or computing (md5deep):
 > %s 
 """ % (__file__, __file__)


value_message = "/!\ Warning: %s does not need any value, but you defined '%s=%s' ; value ignored."

# We get arguments from the script
for arg in sys.argv[1:]:
	try:
		(key, value) = arg.split("=")
	except:
		key = arg
		value = None
	if (key == 'test'):
		isTest = True
		if (value != None):
			print(value_message % (key, key, value))
	elif (key == 'help'):
		isProblem = True
		if (value != None):
			print(value_message % (key, key, value))
	else:
		print("the key '%s' does not match" % key)
		isProblem = True

if isProblem:
	print(problem_message)
	exit()

if not(isTest):
	if os.path.isfile(os.path.join(documents, new_md5)):
		shutil.move(os.path.join(documents, new_md5), os.path.join(documents, old_md5))

	if os.path.isfile(os.path.join(backup, new_md5)):
		shutil.move(os.path.join(backup, new_md5), os.path.join(backup, old_md5))

if not(os.path.isfile(os.path.join(backup, old_md5))):
	log.warning("The old md5sum file doesn't exist (%s)" % os.path.isfile(os.path.join(backup, old_md5)))

if not(os.path.isfile(os.path.join(documents, old_md5))):
	log.warning("The old md5sum file doesn't exist (%s)" % os.path.isfile(os.path.join(documents, old_md5)))

if not(isTest):
	ellapsed_time = time.time() - t_start
	log.info("Initialisation (%s)" % displayTime(ellapsed_time))
	log.info("%s Code start" % datetime.datetime.today())
	t_start = time.time()

	ellapsed_time = time.time() - t_start
	log.info("Backup of $HOME finished (%s)" % displayTime(ellapsed_time))
log.info("Rsync starting")
t_start = time.time()

# The option -i display item changes. 
# the option --dry-run will display output without doing anything. Perfect to test a command before running the actual backup.
# This command will copy the modified and new files, as well as deleting those that were suppressed in the reference partition.
# This command will not modified corrupted files on either side (and that was the initial problem)
#~ command = 'rsync --dry-run -avi --delete %s/ %s/ --filter "- lost+found" --filter "- .Trash-1000"' % (documents, backup)

if not(isTest):
	exclude_template = ["--filter \"- %s\"" for i in exclude_folder]
	command = 'rsync -avi --delete %s/ %s/ %s' % (documents, backup, " ".join(exclude_template))
	rsync_stdout = run(command)

	# Storing rsync info just in case
	object_file = open(os.path.join(documents, rsync_filename), 'w')
	object_file.write(rsync_stdout)
	object_file.close()
	
	shutil.move(os.path.join(documents, rsync_filename), os.path.join(documents, rsync_filename))
else:
	object_file = open(os.path.join(documents, rsync_filename), 'r')
	rsync_stdout = object_file.read()
	object_file.close()

lines = rsync_stdout.split("\n")
# Delete the first line
del(lines[0])

# Delete the 3 trailing lines
for i in range(3):
	del(lines[-1])

changed_files = []
for line in lines:
	# If folder, we skip
	if (line[-1] != "/"):
		changed_files.append("./%s" % line[12:])

# Adding the output files into the excluded list
# md5 checkfiles can't be compared because the file order in which 
# the md5 is processed is different each time
changed_files.append("./%s" % new_md5)
changed_files.append("./%s" % old_md5)
changed_files.append("./%s" % rsync_filename)



ellapsed_time = time.time() - t_start
log.info("Rsync finished (%s)" % displayTime(ellapsed_time))
log.info("md5deep starting")
t_start = time.time()

#~ -r recursive mode
#~ -l relative path instead of absolute
#~ md5deep_command = "md5deep -rl . > %s" % new_md5
#~ -o f is the expert mode. In this case, we selected to test only the files
#~ I had a problem with a named pipe that is excluded with this option
doc_command = ["md5deep", "-rlt", "-o f", "."]
spare_command = ["md5deep", "-rlt", "-o f", "."]

# À tester pour débuguer:
# md5deep -rl -j0 -o f . > checklist.md5

if not(isTest):
	# md5deep on a 900GB (250 000+ files) takes around 7 hours
	# Here, we launch md5deep on both partition simultaneously, 
	# since they're not on the same hard drive.
	document_output = open(os.path.join(documents, new_md5), 'w')
	document_error = open(os.path.join(documents, "md5_error.log"), 'w')

	# Currently, if we want relative paths to work in md5deep, we must specify "." 
	# in the path. So we must chdir to the desired directory beforehand. 
	# I submitted a bug issue, but to make this work, I did this trick.
	os.chdir(documents)
	doc_process = subprocess.Popen(doc_command, stdout=document_output, stderr=document_error, bufsize=-1)

	backup_output = open(os.path.join(backup, new_md5), 'w')
	backup_error = open(os.path.join(backup, "md5_error.log"), 'w')
	os.chdir(backup)
	spare_process = subprocess.Popen(spare_command, stdout=backup_output, stderr=backup_error, bufsize=-1)

	doc_code = doc_process.wait()
	log.info("%s [%d]" % (doc_command, doc_code))

	spare_code = spare_process.wait()
	log.info("%s [%d]" % (spare_command, spare_code))

	document_output.close()
	document_error.close()
	backup_output.close()
	backup_error.close()

ellapsed_time = time.time() - t_start
log.info("md5deep finished (%s)" % displayTime(ellapsed_time))

log.info("Check md5 on documents")
t_start = time.time()

# We check md5 on documents
doc_new_md5 = get_dict_md5(os.path.join(documents, new_md5), excluded_files=changed_files)
doc_old_md5 = get_dict_md5(os.path.join(documents, old_md5), excluded_files=changed_files)

for key in doc_old_md5.iterkeys():
	try:
		if (doc_new_md5[key][0] != doc_old_md5[key][0]):
			if (doc_new_md5[key][1] > doc_old_md5[key][1]):
				changed_problem += "%s has changed\n" % os.path.join(documents, key[2:])
			else:
				corruption_problem += "%s is corrupted\n" % os.path.join(documents, key[2:])
	except KeyError:
		key_problem += "key:%s doesn't exist in old %s checklist.\n" % (key, documents)
		
ellapsed_time = time.time() - t_start
log.info("Check md5 on documents finished (%s)" % displayTime(ellapsed_time))
log.info("Check md5 on backup")
t_start = time.time()

# We check md5 on spare
spare_new_md5 = get_dict_md5(os.path.join(backup, new_md5), excluded_files=changed_files)
spare_old_md5 = get_dict_md5(os.path.join(backup, old_md5), excluded_files=changed_files)

for key in spare_old_md5.iterkeys():
	try:
		# First we compare md5sum. Then we compare the file time that 
		# must be equal for the corruption problem to be assessed
		if (spare_new_md5[key][0] != spare_old_md5[key][0]):
			if (spare_new_md5[key][1] > spare_old_md5[key][1]):
				changed_problem += "%s has changed\n" % os.path.join(backup, key[2:])
			else:
				corruption_problem += "%s is corrupted\n" % os.path.join(backup, key[2:])
	except KeyError:
		key_problem += "key:%s doesn't exist in old %s checklist.\n" % (key, backup)

ellapsed_time = time.time() - t_start
log.info("Check md5 on backup finished (%s)" % displayTime(ellapsed_time))
log.info("Comparing documents and backup")
t_start = time.time()

# We compare md5 between documents and spare
for key in doc_new_md5.iterkeys():
	try:
		if (doc_new_md5[key][0] != spare_new_md5[key][0]):
			if (doc_new_md5[key][1] > spare_new_md5[key][1]):
				changed_problem += "%s has changed\n" % key
			else:
				corruption_problem += "%s is different in both partition\n" % key
	except KeyError:
		key_problem += "key:%s doesn't exist in new %s checklist.\n" % (key, backup)
		
ellapsed_time = time.time() - t_start
log.info("Comparing documents and backup finished (%s)" % displayTime(ellapsed_time))

if (corruption_problem == ""):
	corruption_problem += "No corruption detected."

report_message += "%s\n" % corruption_problem
report_message += "%s\n" % changed_problem
report_message += "%s\n" % key_problem


# In case of corrupted file, we send a report by e-mail
if (report_message != ""):
	send_mail(message=report_message, title="sync_storage report")

log.info("%s End of script" % datetime.datetime.today())

Merci pour votre aide en tout cas,
Autiwa


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#15 Le 12/07/2015, à 07:43

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Tu as essayé de le profiler pour voir si tu peux le rendre plus performant ?

Hors ligne

#16 Le 12/07/2015, à 07:58

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Non, je n'ai pas essayé, mais le script en lui même ne prend que quelques secondes, c'est le lancement de md5deep (un binaire donc) qui prend 7h. Et de ce que j'ai compris, c'est vraiment les accès disque qui limitent, puisque chaque instance de md5deep est à 10% CPU à peu près.

Donc je ne suis pas certain que ce soit ultra optimisable. En tout cas, je ne suis pas capable d'optimiser md5deep, puisque ce n'est pas moi qui le développe. J'imagine qu'il sera toujours beaucoup plus rapide que n'importe quelle version "à la mano" qui fait la même chose.


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#17 Le 12/07/2015, à 08:39

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Oké je vois.
Ouais ça doit être les accès disque, alors.

Bah optimise : mets 1 To en SSD... juste pour les sauvegardes lol

Hors ligne

#18 Le 12/07/2015, à 12:19

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

J'ai pas l'budget pour un SSD d'1To. Sinon, ça ferait un moment que j'en aurait un pour mon système, au lieu de mon 110Go actuel.

De plus, dans l'éventualité où je le ferais, il me faudrait 2 SSD d'1To. Ça ne sert à rien qu'un md5deep se finisse en 1h si l'autre met toujours 7h, puisque les deux tournent en parallèle.


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne

#19 Le 12/07/2015, à 13:18

tiramiseb

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Spa faux. Voilà, y'a plus qu'à faire un financement participatif pour acheter 2 To de SSD tongue

Hors ligne

#20 Le 12/07/2015, à 17:27

Autiwa

Re : [Resolu] corruption de donnée: md5 d'une grande quantité de fichiers

Siouplay, à vot' bon cœur, pour lutter contre la corruption !


Pensez à éditer le titre du sujet (en éditant le premier message) pour rajouter un "[Résolu]" ça évite à ceux qui veulent donner un coup de main, d'ouvrir un sujet où il n'y a plus d'aide à donner.

Hors ligne