Raspberry Pi et corruption de carte SD

Hier soir, en voulant faire mes petites bidouilles quotidiennes sur mon Pi-serveur, j’ai eu la très mauvaise surprise de trouver une carte SD corrompue, après plusieurs mois de bons et loyaux (mais lents) services.

Récit de l’histoire, des symptômes, causes probables, et potentielles solutions.

1- Problèmatique de la carte SD
Mon Pi-serveur est utilisé en serveur domotique, il embarque entre autres Apache et MySQL. Le Pi reçoit et enregistre les données de 3 sondes sans fil (à base d’attiny) qui envoient leur télémétrie toutes les minutes. Ca représente environ 200ko de nouvelles données SQL par jour (3*60*24 = ~4300 entrées par jour). C’est peu, mais sur plusieurs mois, avec en plus mes incessantes bidouilles, plusieurs reinstalls, la carte SD 16Go classe 4 a été plutôt  sollicitée (pour une carte SD). D’autant qu’elle n’était déja pas toute jeune, provenant déja de mon ancien smatphone.

Une carte SD, ce n’est pas un disque dur : ses cycles de lecture/écriture sont limités. Les données sont stockées électroniquement dans des puces mémoire qui s’altèrent rapidement. Des mécanismes de correction d’erreur et de déplacement des blocs défectueux sont présents sur les cartes SD, pour augmenter un peu leur durée de vie, mais cette dernière reste très limitée : on parle de 5-10000 cycles d’écriture pour une carte SD actuelle (100 000 il y a 10 ans…).
A l’inverse, un disque dur (non SSD) peut tourner, avec de la chance, pendant des années. Les données sont inscrites magnétiquement sur des disques de céramique : tant que la mécanique et l’électronique tiennent, les données sont là.

Il faut se souvenir : un disque dur est conçu pour un ordinateur, une carte SD est conçue pour un appareil photo. Les contraintes ne sont pas les mêmes, la fiabilité non plus.

2- Symptômes
J’ai découvert le problème lorsqu’un apt-get install refusait d’installer le paquet téléchargé, même après des apt-get upgrade/clean/purge/etc. Téléchargement manuel du paquet, tentative d’installation, nouvelle erreur d’entrée/sortie. A ce moment, j’aurai dû commencer par sauvegarder ce qui était important, et faire un dump de la base SQL. J’ai préféré rebooter le Pi. Erreur : il n’est jamais reparti, SD corrompue.
J’ai néanmoins branché la SD dans un PC sous linux, les partitions ont été correctement reconnues. Mais à l’intérieur, il manquait tout un tas de fichiers. Dont la fameuse base SQL, évidemment.
Le fichier /var/log/dmesg, accessible, ne contient pas d’erreur particulière.
Le meilleur pour la fin : le mini-backup quotidien sur un disque dur réseau : corrompu aussi. Mmmmmmm…..

3- Récupération des données inaccessibles
Parmi les données corrompues/inaccessibles figurent surtout la base SQL, et le dossier WWW d’apache. Tous deux sont invisibles, vides, nada.
La solution est venue de l’utilitaire fsck présent dans presque toutes les distributions Linux.

Cette méthode n’est surement pas valable dans les cas de figure, j’ai certainement eu un peu de chance, mais elle mérite d’être tentée.

Tout d’abord, il faut trouver le nom de la carte SD, une fois branchée dans un PC linux :

sudo ls /dev


Votre carte SD devrait être listée avec un nom du genre :
mmcblk0
mmcblk0p1
mmcblk0p2
Ici, la carte SD physique est mmcblk0, p1 et p2 sont les partitions logiques. La partition qui nous intéresse est la deuxième, celle des données, p2. p1 est la partition de boot.
On va donc tenter de lancer fsck sur la carte SD :

sudo /sbin/fsck /dev/mmcblk0p2 -p -c -v


Si vous avez de la chance, cette première commande fonctionnera, et terminera sans erreur.
De mon coté, j’ai eu droit à

SD-RPI-16A: INCONSISTENCE INATTENDUE ; EXÉCUTEZ fsck MANUELLEMENT.
	(i.e., sans options -a ou -p)

Donc,

sudo /sbin/fsck /dev/mmcblk0p2 -c -v -y


Une bonne heure et des milliers de messages de secteurs corrompus plus tard :

SD-RPI-16A: ***** LE SYSTÈME DE FICHIERS A ÉTÉ MODIFIÉ *****

120058 inodes used (12.34%, out of 972944)
68 non-contiguous files (0.1%)
121 non-contiguous directories (0.1%)
# of inodes with ind/dind/tind blocks: 79/79/79
Extent depth histogram: 101533/31
1045698 blocks used (26.88%, out of 3890176)
0 bad blocks
1 large file

91375 regular files
9575 directories
3 character device files
1 block device file
7 fifos
4294967238 links
19090 symbolic links (18477 liens symboliques rapides)
2 sockets
————
119895 files

Il est temps d’aller voir le contenu de la carte : dossiers toujours vides. Mais à la racine de la carte, je note un dossier LOST+FOUND (à ouvrir en root). A l’intérieur, tout un tas d’autres dossiers, avec des noms du genre #12DS58. Une simple recherche avec le nom de fichiers connus et corrompus (index.php par exemple) m’indique rapidement l’emplacement de mes données perdues.
Sans y croire, j’éssaie de dézipper le backup du jour, présent dans un autre de ces dossiers : tout est là, et en excellent état… OUF !!!!
La carte SD, par contre, ne retournera pas dans un Pi, mais je pense qu’elle reste utilisable, sans y mettre de données critiques, évidemment.

4- Causes probables
Après avoir relancé mon pi-serveur sur une nouvelle SD, récupéré mes données www et SQL, j’ai pu vérifier une théorie :
la corruption de données a eu lieu exactement au moment du backup quotidien, je peux le voir sur les graphiques de mes 3 capteurs, qui s’arrêtent pile à 6 heures du matin. 6 heures du matin, c’est aussi, très exactement, l’heure du mini-backup : dump de la base SQL, zip du dossier www, ajout du backup dans un dossier « versionné », remplacement de l’ancien backup par le nouveau dans un dossier « last », et, enfin, copie sur un dossier réseau.
Je parierai que la carte s’est corrompue lors de la seconde copie, dans le dossier « last » : cette copie corrompue a été recopiée ensuite sur le lecteur réseau. Cette méthode de backup a une faille, à priori ^^

C’est donc, sans aucun doute, une grosse utilisation en écriture, qui a corrompu la carte.
Personne n’est à l’heure actuelle capable de dire si les cycles de lecture provoquent le même effet.

Une autre cause connue et indéniable de corruption de carte provient des arrêts brutaux du Pi, sans passer par un arrêt logiciel (halt). Oui, toi, au fond, qui éteins ton Pi en tirant sur le cable, c’est pour toi…

5- Solutions
Conscient de ce problème depuis le premier jour, j’ai bien fait attention, dans mes différents scripts, à solliciter le moins possible la carte SD. Ce, par différents moyens :
– redirection en RAM de tout ce qui est possible (j’en reparlerai)
– stockage des données SQL en RAM ou en json, et lecture/écriture dans la base seulement de temps en temps, par gros blocs
– désactivation des logs systèmes non critiques.

Même si toutes ces mesures sont utiles et rallongent la durée de vie de la carte, j’en suis convaincu, elles ne sont pas suffisantes.

D’autres solutions existent, mais aucune n’est universelle :
– partition boot sur carte SD, et partition données sur un disque externe USB : problème d’alimentation (le pi ne peut pas alimenter un disque dur, même 2.5″ auto-alimenté), perte de mobilité. De plus, un disque dur n’est pas non plus infaillible.
– backup régulier sur un lecteur réseau ou un NAS : bien effectué (lol), c’est une des solutions les plus sûres (avec un backup du backup, of course…). Seulement, le périphérique doit être accessible pour effectuer/restaurer le backup. Impossible donc en mobilité.
– backup régulier de SD à SD, directement sur le Pi : une des méthodes que j’utilise, qui me permet de cloner les « vieilles » SD sur les nouvelles, ou mettre à jour mes différents Pi sur une même base (le script fonctionne en incrémental). Le gros avantage est de pouvoir se promener avec une copie à jour dans la poche, et pouvoir faire un backup où/quand on veut. Lien du script Rpi-clone
– une dernière solution, extrème cette fois, est d’utiliser une variante de Raspbian, IPE | Industrial Perennial Environment. Cette distribution verrouille le système de fichiers en read-only et embarque les outils pour l’utiliser. Elle est conçue pour les environnements où les coupures de courant sont fréquentes, et tient sur une carte SD de 1Go.

Je pense que le mieux pour un Pi fixe, c’est un disque USB et backup sur un lecteur réseau. Pour le Pi mobile, je ne vois que le clonage de carte SD, et utiliser IPE si c’est envisageable… Et, dans tous les cas, utiliser un maximum d’astuces pour réduire l’utilisation de la SD… On y reviendra 😉

Et vous, quelle solution utilisez-vous pour sauvegarder vos Raspberry Pis ?

A propos Captain Stouf

Spécialiste en systèmes informatiques, Développeur matériel et logiciel, Inventeur, Maker : électronique, Systems on Chip, micro-controlleurs, Internet of Things, Modélisation / Scan / Impression 3D, Imagerie...

8 réflexions au sujet de « Raspberry Pi et corruption de carte SD »

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.