Résumé TL; DR : Traduisez un numéro de secteur md en décalages dans l' /dev/mdX
appareil, et comment enquêter avec xfs_db
. Le numéro de secteur est de sh->sector
en linux/drivers/md/raid5.c:handle_parity_checks5()
.
Je ne connais pas les internes de MD, donc je ne sais pas exactement quoi faire avec la sortie de la printk
journalisation que j'ai ajoutée.
Les décalages dans les composants (pour dd
ou un éditeur / visualiseur hexadécimal) seraient également intéressants.
Je suppose que je devrais poser cette question sur la liste de diffusion Linux-raid. Est-ce réservé aux abonnés ou puis-je publier sans m'abonner?
J'ai xfs directement sur le dessus de MD RAID5 de 4 disques sur mon bureau (pas de LVM). Un nettoyage récent a détecté une valeur non nulle mismatch_cnt
(8 en fait, car md fonctionne sur des pages de 4 Ko à la fois).
Il s'agit d'un RAID5, pas RAID1 / RAID10 où mismatch_cnt
! = 0 peut se produire pendant le fonctionnement normal . (Les autres liens au bas de cette page wiki peuvent être utiles à certaines personnes.)
Je pourrais simplement l'aveugler repair
, mais alors je n'aurais aucune idée du fichier pour vérifier une éventuelle corruption, en plus de perdre toute chance de choisir la façon de reconstruire. La réponse de Frostschutz à une question similaire est la seule suggestion que j'ai trouvée pour retrouver une différence dans le système de fichiers. C'est lourd et lent, et je préfère utiliser quelque chose de mieux pour le réduire à quelques fichiers en premier.
Correctif du noyau pour ajouter la journalisation
Bizarrement, la fonction de vérification de md ne signale pas où une erreur a été trouvée . J'ai ajouté un printk
fichier dans md / raid5.c pour se connecter sh->sector
à la if
branche qui s'incrémente mddev->resync_mismatches
danshandle_parity_checks5()
(minuscule patch publié sur github , basé à l'origine sur 4.5-rc4 de kernel.org.) Pour que cela soit correct pour une utilisation générale, il faudrait probablement évitez d'inonder les journaux dans les réparations avec beaucoup de discordances (peut-être uniquement si la nouvelle valeur de resync_mismatches
est <1000?). Peut-être aussi ne vous connectez que pour check
et non repair
.
Je suis à peu près sûr que j'enregistre quelque chose d'utile (même si je ne connais pas les internes MD!), Car la même fonction imprime ce numéro de secteur dans le cas de gestion des erreurs duswitch
.
J'ai compilé mon noyau modifié et l'ai démarré, puis j'ai relancé la vérification:
[ 399.957203] md: data-check of RAID array md125
...
[ 399.957215] md: using 128k window, over a total of 2441757696k.
...
[21369.258985] md/raid:md125: check found mismatch at sector 4294708224 <-- custom log message
[25667.351869] md: md125: data-check done.
Maintenant, je ne sais pas exactement quoi faire avec ce numéro de secteur. Est sh->sector * 512
une adresse linéaire à l'intérieur /dev/md/t-r5
(aka /dev/md125
)? S'agit-il d'un numéro de secteur dans chaque appareil composant (il fait donc référence à trois données et à un secteur de parité)? J'imagine ce dernier, car une disparité de parité dans RAID5 signifie que les secteurs N-1 du périphérique md sont en danger, décalés les uns des autres par l'unité de bande. Le secteur 0 est-il le tout début du périphérique composant, ou est-ce le secteur après le superbloc ou quelque chose? Y avait-il plus d'informations en ce handle_parity_checks5()
que j'aurais dû calculer / enregistrer?
Si je voulais obtenir uniquement les blocs incompatibles, est-ce correct?
dd if=/dev/sda6 of=mmblock.0 bs=512 count=8 skip=4294708224
dd if=/dev/sdb6 of=mmblock.1 bs=512 count=8 skip=4294708224
dd if=/dev/sda6 of=mmblock.2 bs=512 count=8 skip=4294708224
dd if=/dev/sdd of=mmblock.3 bs=512 count=8 skip=4294708224 ## not a typo: my 4th component is a smaller full-disk
# i.e.
sec_block() { for dev in {a,b,c}6 d; do dd if=/dev/sd"$dev" of="sec$1.$dev" skip="$1" bs=512 count=8;done; }; sec_block 123456
Je suppose que non, parce que j'obtiens 4k de zéros des quatre composants de raid, et 0^0 == 0
donc ça devrait être la parité correcte, non?
Un autre endroit que j'ai vu mentionner l'utilisation des adresses de secteur dans md est pour sync_min
et sync_max
(dans sysfs). Neil Brown sur la liste Linux-raid , en réponse à une question sur un disque défectueux avec des numéros de secteur hdrecover
, où Neil a utilisé le numéro de secteur du disque complet comme numéro de secteur MD. Ce n'est pas vrai, n'est-ce pas? Les numéros de secteur md ne seraient-ils pas relatifs aux périphériques composants (partitions dans ce cas), pas au périphérique complet dont la partition fait partie?
secteur linéaire en nom de fichier XFS:
Avant de réaliser que le numéro de secteur md était probablement pour les composants, pas pour le périphérique RAID, j'ai essayé de l'utiliser en lecture seule xfs_db
:
La très brève suggestion de Dave Chinner sur la façon de trouver comment XFS utilise un bloc donné ne semble pas du tout fonctionner pour moi. (Je m'attendais à une sorte de résultat, pour certains secteurs, car le nombre ne devrait pas dépasser la fin de l'appareil même si ce n'est pas le secteur qui ne correspond pas)
# xfs_db -r /dev/md/t-r5
xfs_db> convert daddr 4294708224 fsblock
0x29ad5e00 (699227648)
xfs_db> blockget -nv -b 699227648
xfs_db> blockuse -n # with or without -c 8
must run blockget first
hein? Qu'est-ce que je fais mal ici? Je suppose que cela devrait être une question distincte. Je vais remplacer cela par un lien si / quand je le demande ou trouver une réponse à cette partie ailleurs.
Mon RAID5 est essentiellement inactif, sans activité d'écriture et lecture minimale (et noatime
donc les lectures ne produisent pas d'écritures).
Des trucs supplémentaires sur ma configuration, rien d'important ici
Beaucoup de mes fichiers sont des vidéos ou d'autres données compressées qui donnent un moyen efficace de dire si les données sont correctes ou non (soit des sommes de contrôle internes au format de fichier, soit juste si elles décodent sans erreur). Cela rendrait cette méthode de bouclage en lecture seule viable, une fois que je connais le fichier à vérifier. Je ne voulais pas exécuter une différence à 4 voies de chaque fichier dans le système de fichiers pour trouver d'abord la non-concordance, lorsque le noyau a les informations nécessaires lors de la vérification et pourrait facilement les enregistrer.
mon /proc/mdstat
pour mon tableau de données en vrac:
md125 : active raid5 sdd[3] sda6[0] sdb6[1] sdc6[4]
7325273088 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]
bitmap: 0/19 pages [0KB], 65536KB chunk
Il se trouve sur des partitions sur trois disques Toshiba de 3 To et sur un disque WD25EZRS non partitionné à énergie verte (lent) que je remplace par un autre Toshiba. (Utilisation mdadm --replace
pour le faire en ligne sans lacunes de redondance. J'ai réalisé après une copie que je devais vérifier la santé du RAID avant et après, pour détecter les problèmes. C'est à ce moment-là que j'ai détecté le décalage. Il est possible que cela existe depuis longtemps , car j'ai eu quelques plantages il y a presque un an, mais je n'ai pas d'anciens journaux et mdadm ne semble pas envoyer de courrier à ce sujet par défaut (Ubuntu 15.10).
Mes autres systèmes de fichiers se trouvent sur des périphériques RAID10f2 fabriqués à partir de partitions antérieures sur les trois plus grands disques durs (et RAID0 pour / var / tmp). Le RAID5 est juste pour le stockage en vrac, pas /home
ou /
.
Mes lecteurs sont tous très bien: le nombre d'erreurs SMART est de 0 tous les compteurs de bloc défectueux sur tous les lecteurs, et les autotests SMART courts + longs ont réussi.
quasi-doublons de cette question qui n'ont pas de réponses:
- Quels morceaux sont incompatibles dans un tableau Linux md?
- http://www.spinics.net/lists/raid/msg49459.html
- MDADM mismatch_cnt> 0. Est-il possible d'identifier les blocs en désaccord?
- D'autres choses sont déjà liées en ligne, mais surtout l' idée de bouclage en lecture seule de frostschutz .
- scrubbing sur la page Arch wiki RAID
la source
mdadm -E /dev/xxx
..damaged
ou quelque chose, au lieu de simplement savoir qu'il y a probablement un fichier cassé quelque part.Réponses:
TL; DR sh-> sector est le nombre de secteurs dans les disques physiques après le début de la section de données
Installer
Voici une configuration de test simple pour illustrer:
Maintenant, pour commencer, obtenez un bloc non nul et écrasez-le
Assurez-vous que le cache dm / md est vidé en arrêtant / réassemblant le tableau et vérifiez:
Bloquer sur les disques
D'accord, vérifions d'abord que 16384 correspond à ce que nous avons écrit. Mon raid a une bande de 512k, donc je me suis assuré que j'écrivais quelque chose aligné pour être facile à assortir, nous avons écrit sur
1024*10240
ie0xa00000
.Votre patch donne les informations
16384
, une chose à savoir est que les données ne commencent pas à 0:C'est
printf "%x\n" $(((4096+16384)*512))
ce que dit0xa00000
aussi. Bien.Bloquer en md
Maintenant, pour arriver là où c'est sur la fin md, c'est en fait plus facile: c'est tout simplement la position donnée en temps de secteur
number_of_stripes
par exemple pour moi j'ai 4 disques (3 + 1) donc 3 bandes.Ici, cela signifie
16384*3*512
par exemple0x1800000
. J'ai assez bien rempli le disque, il est donc facile de vérifier simplement en lisant le disque et en recherchant 1k de zéros:Bloquer dans xfs
Cool. Voyons maintenant où cela se trouve dans xfs.
16384*3
est49152
(daddr prend le numéro de secteur):Assurément, les zéros sont dans ce fichier:
Si nous remplaçons ce fichier, les zéros disparaissent également dans / dev / raidme / rd0 avec le décalage correct (il suffit de le redéfinir avec un autre fichier). Si vous écrivez à nouveau dans / dev / raidme / rd0 (assurez-vous d'arrêter / redémarrer le tableau), les zéros sont de retour. Cela semble bon.
Il y a un autre problème cependant, si votre taille de bande est aussi grande que la mienne ici (512 Ko), nous n'avons pas un seul bloc à gérer, mais 1,5 Mo de données possibles corrompues ... Souvent, cela suffira dans un fichier unique, mais vous devez vérifier cela, de retour dans xfs_db. Rappelez-vous que l'inode précédente était 2052.
Un bloc a une taille de 4096 octets ici (voir
xfs_info
), donc nos 1,5 Mo sont 384 blocs. Notre segment corrompu est le bloc 6144 à 6528 - bien dans le premier segment de ce fichier.Une autre chose à regarder serait d'extraire les blocs à la main et de vérifier où les sommes de contrôle ne correspondent pas exactement, ce qui vous donnera, espérons-le, 3 morceaux plus petits à regarder.
Enfin à propos de votre patch, je ne suis pas moi-même un développeur md mais en tant qu'ancien utilisateur de raid5 mdadm, j'aurais été très intéressé. Je dirais que ça vaut vraiment la peine de pousser un peu. Le nettoyage que vous avez mentionné pourrait être utile et je suis sûr que les développeurs auront des commentaires une fois que vous aurez soumis un correctif, mais diable md doit être plus bavard sur ces erreurs!
la source
printf '%#x\n' $(( (259072+4294708224 )*512 ))
c'est0x20000000000
, ce qui n'est évidemment pas un hasard. (C'est 2TiB précisément. Je soupçonne des manigances de grub-install ou une sorte de truc MBR). Je ne l'aurais pas remarqué si je regardais simplement les décalages dans le périphérique MD pour trouver le fichier affecté. (BTW, le%#x
format ajoute le0x
préfixe pour vous.)xfs_db
dit simplementmust run blockget first
, même si je viens de le faire (exactement comme je l'ai posté dans la question), après avoir suivi votre exemple. Même si j'utiliseblockget -v -n -b 12884124672
pour lui donner un bloc spécifique. J'ai utilisédd
ethexdump
pour trouver qu'il y a en fait un décalage dans ce bloc, cependant. Trois sont tous nuls et le quatrième a un seul bit défini à 1 Ko dans la bande de 512 Ko. (Très pratique, je n'ai pas eu à trouver de moyen de bloquer XOR pour vérifier la redondance.)daddr
abord (avant blockget), je ne reçois pas de message d'erreur, juste aucune sortie dublockget -v -n
etblockuse -v -n
. Dans le cas où cela compte, mon xfsprogs est 3.2.1ubuntu1, et j'utilise Linux 4.2.0-36-generic (pas mon noyau patch -rc). Mon FS utilisecrc=1 isize=512
,naming =version 2 bsize=4096 ascii-ci=0 ftype=1
find -exec xfs_bmap -vpl {} +
pour rechercher un fichier contenant le bloc connu.