Linux - Відновлення поганих блоків на масиві RAID1 за допомогою GPT


20

Tl; dr: як би я поступив про виправлення поганого блоку на 1 диску в масиві RAID1?

Але, будь ласка, прочитайте всю цю справу щодо того, що я вже намагався, і можливих помилок у своїх методах. Я намагався бути максимально детальним, і я дуже сподіваюся на відгуки

Така моя ситуація: у мене є два диски 2 ТБ (одна і та ж модель), встановлені в масиві RAID1, яким керує mdadm. Близько 6 місяців тому я помітив перший поганий блок, коли SMART повідомив про це. Сьогодні я помітив більше, і зараз намагаюся це виправити.

Здається, ця сторінка HOWTO є однією статтею, до якої всі посилаються, щоб виправити погані блоки, про які повідомляє SMART. Це чудова сторінка, повна інформації, проте вона досить застаріла і не стосується моїх налаштувань. Ось як відрізняється мій конфігурація:

  • Замість одного диска я використовую два диски в масиві RAID1. Один диск повідомляє про помилки, а інший добре. HOWTO написаний з урахуванням лише одного диска, який викликає різні питання, такі як "чи я використовую цю команду на дисковому пристрої чи на пристрої RAID"?
  • Я використовую GPT, який fdisk не підтримує. Я використовував gdisk замість цього, і сподіваюся, що він дає мені ту саму інформацію, яка мені потрібна

Отже, давайте перейдемо до цього. Це те, що я зробив, проте, схоже, це не працює. Будь ласка, двічі перевіряйте мої розрахунки та метод на наявність помилок. Помилки звітності на диску / dev / sda:

# smartctl -l selftest /dev/sda
smartctl 5.42 2011-10-20 r3458 [x86_64-linux-3.4.4-2-ARCH] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF READ SMART DATA SECTION ===
SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed: read failure       90%     12169         3212761936

З цього ми бачимо, що помилка знаходиться на LBA 3212761936. Слідуючи HOWTO, я використовую gdisk, щоб знайти стартовий сектор, який буде використаний пізніше для визначення номера блоку (оскільки я не можу використовувати fdisk, оскільки він не підтримує GPT):

# gdisk -l /dev/sda
GPT fdisk (gdisk) version 0.8.5

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 3907029168 sectors, 1.8 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): CFB87C67-1993-4517-8301-76E16BBEA901
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 3907029134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048      3907029134   1.8 TiB     FD00  Linux RAID

Використовуючи, tunefsя знаходжу розмір блоку 4096. Використовуючи цю інформацію та обчислення HOWTO, я роблю висновок, що йдеться про блок ((3212761936 - 2048) * 512) / 4096 = 401594986.

Потім HOWTO спрямовує мене debugfsперевірити, чи використовується блок (я використовую пристрій RAID, оскільки йому потрібна файлова система EXT. Це була одна з команд, яка мене збила з пантелику, оскільки я, спочатку, не знаю, чи варто використовувати / dev / sda або / dev / md0):

# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs:  open /dev/md0
debugfs:  testb 401594986
Block 401594986 not in use

Отже, блок 401594986 - це порожній простір, я повинен мати можливість без проблем писати через нього. Перш ніж писати до нього, я намагаюся переконатися, що він справді не може бути прочитаний:

# dd if=/dev/sda1 of=/dev/null bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000198887 s, 20.6 MB/s

Якби не вдалося прочитати блок, я б не очікував, що це спрацює. Однак це робить. Я повторюю , використовуючи /dev/sda, /dev/sda1, /dev/sdb, /dev/sdb1, /dev/md0, і ± 5 до номера блоку для пошуку навколо поганого блоку. Це все працює. Я знижую плечима і йду вперед і здійснюю запис і синхронізацію (я використовую / dev / md0, тому що я зрозумів, що зміна одного диска, а не інший може спричинити проблеми, таким чином обидва диски замінюють поганий блок):

# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000142366 s, 28.8 MB/s
# sync 

Я б очікував, що запис у поганий блок призведе до того, щоб диски перевлаштували цей блок на хороший, проте виконання іншого тесту SMART показує інакше:

# 1  Short offline       Completed: read failure       90%     12170         3212761936

Повернутися до квадрата 1. Отже, в основному, як я можу виправити поганий блок на 1 диску в масиві RAID1? Я впевнений, що я щось не зробив правильно ...

Дякуємо за ваш час та терпіння.


EDIT 1:

Я намагався провести довгий тест SMART, з тим самим LBA, який повертається як поганий (різниця лише в тому, що він повідомляє, що 30% залишається замість 90%):

SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Extended offline    Completed: read failure       30%     12180         3212761936
# 2  Short offline       Completed: read failure       90%     12170         3212761936

Я також використовував погані блоки із наступним результатом. Вихід є дивним і, здається, відформатованим, але я спробував перевірити числа, витіснені як блоки, але налагодження видає помилку

# badblocks -sv /dev/sda
Checking blocks 0 to 1953514583
Checking for bad blocks (read-only test): 1606380968ne, 3:57:08 elapsed. (0/0/0 errors)
1606380969ne, 3:57:39 elapsed. (1/0/0 errors)
1606380970ne, 3:58:11 elapsed. (2/0/0 errors)
1606380971ne, 3:58:43 elapsed. (3/0/0 errors)
done
Pass completed, 4 bad blocks found. (4/0/0 errors)
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs:  open /dev/md0
debugfs:  testb 1606380968
Illegal block number passed to ext2fs_test_block_bitmap #1606380968 for block bitmap for /dev/md0
Block 1606380968 not in use

Не впевнений, куди піти звідси. badblocksВиразно щось знайшли, але я не впевнений, що робити з представленою інформацією ...


EDIT 2

Більше команд та інформації.

Я відчуваю, що ідіот забув включити це оригінально. Це значення SMART для /dev/sda. У мене є 1 Current_Pending_Sector та 0 Offline_Uncorrectable.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   100   100   051    Pre-fail  Always       -       166
  2 Throughput_Performance  0x0026   055   055   000    Old_age   Always       -       18345
  3 Spin_Up_Time            0x0023   084   068   025    Pre-fail  Always       -       5078
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       75
  5 Reallocated_Sector_Ct   0x0033   252   252   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x002e   252   252   051    Old_age   Always       -       0
  8 Seek_Time_Performance   0x0024   252   252   015    Old_age   Offline      -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       12224
 10 Spin_Retry_Count        0x0032   252   252   051    Old_age   Always       -       0
 11 Calibration_Retry_Count 0x0032   252   252   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       75
181 Program_Fail_Cnt_Total  0x0022   100   100   000    Old_age   Always       -       1646911
191 G-Sense_Error_Rate      0x0022   100   100   000    Old_age   Always       -       12
192 Power-Off_Retract_Count 0x0022   252   252   000    Old_age   Always       -       0
194 Temperature_Celsius     0x0002   064   059   000    Old_age   Always       -       36 (Min/Max 22/41)
195 Hardware_ECC_Recovered  0x003a   100   100   000    Old_age   Always       -       0
196 Reallocated_Event_Count 0x0032   252   252   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   100   100   000    Old_age   Always       -       1
198 Offline_Uncorrectable   0x0030   252   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0036   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x002a   100   100   000    Old_age   Always       -       30
223 Load_Retry_Count        0x0032   252   252   000    Old_age   Always       -       0
225 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       77

# mdadm -D /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Thu May  5 06:30:21 2011
     Raid Level : raid1
     Array Size : 1953512383 (1863.01 GiB 2000.40 GB)
  Used Dev Size : 1953512383 (1863.01 GiB 2000.40 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Tue Jul  3 22:15:51 2012
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : server:0  (local to host server)
           UUID : e7ebaefd:e05c9d6e:3b558391:9b131afb
         Events : 67889

    Number   Major   Minor   RaidDevice State
       2       8        1        0      active sync   /dev/sda1
       1       8       17        1      active sync   /dev/sdb1

Відповідно до однієї з відповідей: здавалося б, я перейшов seekі skipна dd. Я використовував пошук, як це те, що використовується з HOWTO. Використання цієї команди призводить ddдо зависання: # dd, якщо = / dev / sda1 of = / dev / null bs = 4096 count = 1 пропуск = 401594986

Використання блоків навколо цього (..84, ..85, ..87, ..88), здається, працює чудово, а також використання / dev / sdb1 з блоком 401594986читається також добре (як і очікувалося, коли цей диск пройшов тестування SMART ). Тепер, питання, яке у мене є: Коли я пишу над цією областю для перепризначення блоків, чи використовувати я /dev/sda1чи /dev/md0? Я не хочу викликати жодних проблем з масивом RAID, записуючи безпосередньо на один диск і не оновлюючи інший диск.

EDIT 3

Запис у блок безпосередньо створює помилки файлової системи. Я вибрав відповідь, яка швидко вирішила проблему:

# 1  Short offline       Completed without error       00%     14211         -
# 2  Extended offline    Completed: read failure       30%     12244         3212761936

Дякую всім, хто допомагав. =)


Ви змогли прочитати блок, тому він не пошкоджений. Отже, немає перерозподілених секторів. Я перевірив ваш розрахунок блоку fs і, здається, законний. Коли я робив погані перерозподіли блоку, я виявив, що іноді розумний короткий тест не повідомляє про блоку, що порушує, правильно. Тим часом ви можете запустити тривалий тест в режимі офлайн smartctl -t long /dev/sdaі побачити, чи зміниться LBA першої помилки.
Ярі Лааманен

1
Спробуйте /sbin/badblocks -sv /dev/sdaперевірити диск.
jippie

Я зробив обидві пропозиції і відповідно оновив публікацію. Ще застрягли. = /
blitzmann

Чи повідомляє smartctl про ненульовий рахунок Current_Pending_Sector? Чи не-нульове значення "Offline_Uncorrectable"?
mgorven

Будь ласка, додайте статус масиву до питання:sudo mdadm -D /dev/md0
psusi

Відповіді:


20

Усі ці відповіді "тріскають сектор", відверто кажучи, божевільні. Вони ризикують (можливо, приховано) пошкодити файлову систему. Якщо дані вже не було, тому що на цьому диску зберігалася єдина копія, було б розумно. Але на дзеркалі є ідеально хороша копія.

Вам просто потрібно, щоб mdraid вичистив дзеркало. Він помітить поганий сектор і перепише його автоматично.

# echo 'check' > /sys/block/mdX/md/sync_action    # use 'repair' instead for older kernels

Потрібно помістити туди потрібний пристрій (наприклад, md0 замість mdX). Це займе деякий час, оскільки це робить за замовчуванням весь масив. На новому достатньому ядрі можна спочатку записати номери секторів для sync_min / sync_max, щоб обмежити його лише частиною масиву.

Це безпечна операція. Ви можете це зробити на всіх своїх пристроях mdraid. Насправді, ви повинні робити це на всіх своїх пристроях mdraid, регулярно. Ваш дистрибутор, ймовірно, постачається з кронштейном, щоб впоратися з цим, можливо, вам потрібно щось зробити, щоб це ввімкнути?


Сценарій для всіх RAID-пристроїв у системі

Якось назад я написав цей сценарій, щоб "відремонтувати" всі RAID-пристрої в системі. Це було написано для старих версій ядра, де лише «ремонт» виправить поганий сектор; тепер достатньо лише перевірити перевірку (ремонт усе ще працює добре на новіших ядрах, але також повторно копіює / відновлює паритет, що не завжди є тим, що вам потрібно, особливо на флеш-накопичувачах)

#!/bin/bash

save="$(tput sc)";
clear="$(tput rc)$(tput el)";
for sync in /sys/block/md*/md/sync_action; do
    md="$(echo "$sync" | cut -d/ -f4)"
    cmpl="/sys/block/$md/md/sync_completed"

    # check current state and get it repairing.
    read current < "$sync"
    case "$current" in
        idle)
            echo 'repair' > "$sync"
            true
            ;;
        repair)
            echo "WARNING: $md already repairing"
            ;;
        check)
            echo "WARNING: $md checking, aborting check and starting repair"
            echo 'idle' > "$sync"
            echo 'repair' > "$sync"
            ;;
        *)
            echo "ERROR: $md in unknown state $current. ABORT."
            exit 1
            ;;
    esac

    echo -n "Repair $md...$save" >&2
    read current < "$sync"
    while [ "$current" != "idle" ]; do
        read stat < "$cmpl"
        echo -n "$clear $stat" >&2
        sleep 1
        read current < "$sync"
    done
    echo "$clear done." >&2;
done

for dev in /dev/sd?; do
    echo "Starting offline data collection for $dev."
    smartctl -t offline "$dev"
done

Якщо ви хочете зробити checkзамість цього repair, то цей (неперевірений) перший блок повинен працювати:

    case "$current" in
        idle)
            echo 'check' > "$sync"
            true
            ;;
        repair|check)
            echo "NOTE: $md $current already in progress."
            ;;
        *)
            echo "ERROR: $md in unknown state $current. ABORT."
            exit 1
            ;;
    esac

Дякую за це. Нещодавно я повернувся до цієї проблеми, сподіваючись нарешті її вирішити. Я писав у блок / dev / md0, і у мене виникли проблеми з файловою системою, але, на щастя, після кількох годин терору та завантаження в оболонки відновлення все було ремонтом без втрати даних. Спершу я спробую ваш метод, і, сподіваюся, це позбавить мене від очікуваного сектора. =)
blitzmann

Як можна визначити, коли скраб закінчений? Чи буде cat /sys/block/mdX/md/sync_actionчитати "простою", коли закінчиться?
Джон Крам

@JonCram так, і ви можете переглядати стан, cat /proc/mdstatабо якщо ви хочете його сценарію,/sys/…/sync_completed
derobert

5

У мене просто була така ж проблема з масивом RAID1. Поганий сектор опинився на початку одного з розділів - сектора 16 / dev / sdb2. Я дотримувався наведених вище вказівок: перевіривши, що логічний блок 2 не використовується файловою системою, і будьте обережні, щоб DD шукати та пропускати правильний шлях, і нулював 1 блок файлової системи:

# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=2

Що це зробив? Це не виправило поганий сектор. Зараз я знаю, це тому, що / dev / md0 не відображається безпосередньо в / dev / sdb2, ви повинні врахувати RAID ДАННИЙ ОФСЕТ! Детальніше про це нижче. Що це зробило - це невелика, але потенційно руйнівна робота моєї файлової системи. Виявляється, що логічний блок 2 / / dev / md0 містив корисні метадані файлової системи і був чудовий на обох дисках, поки я не вибився з обох копій, записавши в / dev / md0. На щастя, e2fsck -y / dev / md0 усунув проблему (після виведення тривожної кількості вихідних даних) без видимих ​​втрат даних. Урок засвоєний: якщо налагодження icheck каже, що "блок не знайдено", це не обов'язково означає, що відповідні сектори не використовуються.

Назад до зміщення даних: використовуйте mdadm, щоб знайти таке зміщення:

# mdadm --examine /dev/sdb2
/dev/sdb2:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : ef7934b9:24696df9:b89ff03e:b4e5a05b
           Name : XXXXXXXX
  Creation Time : Sat Sep  1 01:20:22 2012
     Raid Level : raid1
   Raid Devices : 2

 Avail Dev Size : 1953241856 (931.38 GiB 1000.06 GB)
     Array Size : 976620736 (931.38 GiB 1000.06 GB)
  Used Dev Size : 1953241472 (931.38 GiB 1000.06 GB)
    Data Offset : 262144 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : f3b5d515:446d4225:c2191fa0:9a9847b8

    Update Time : Thu Sep  6 12:11:24 2012
       Checksum : abb47d8b - correct
         Events : 54


    Device Role : Active device 0
    Array State : AA ('A' == active, '.' == missing)

У цьому випадку зміщення даних становить 262144 секторів у 512 байт. Якщо ви входите з / dev / md0 і порівнюєте його з даними з необробленого розділу зі зміщенням 131072K, ви виявите, що вони відповідають. Тож у моєму випадку логічний блок 2 (сектори 16--23) / dev / sdb2 навіть не існує у файловій системі; вони знаходяться в суперблоку RAID, про який ви можете прочитати тут: https://raid.wiki.kernel.org/index.php/RAID_superblock_formats - для версії 1.2 він складається з 256 байт + 2 байти на пристрій у масиві , починаючи з 4096 байт, тому в моєму випадку поганий сектор не використовувався. Відповідні сектори / dev / sdc2 (інша половина масиву RAID1) дорівнюють нулю, тому я вважав, що це буде безпечно:

# dd if=/dev/zero of=/dev/sdb2 bs=4096 count=1 seek=2

Це спрацювало!


ОП тут. Дякую за цю інформацію Коли ця проблема виникла у мене, я здійснив стрибок і викреслив блок на рівні / dev / md0. Погана ідея, оскільки мені трапилось також зламати свою файлову систему. На щастя після нечестивого часу на ремонт, все здавалося добре без втрати даних. Але з початковою панікою я зовсім забув про цю посаду. Нещодавно я налаштував свій сервер у своїй новій квартирі, і це ще одна з речей у моєму списку тодо, і я дякую вам за ваше розуміння проблеми. Я оновлю ОП, коли я обійдусь копати на цьому трохи більше. =)
бліцман

2

Якщо ви працюєте з debian, ви, швидше за все, маєте роботу в /etc/cron.d/mdadm. Це триватиме в /usr/share/mdadm/checkarray --cron --all --idle --quiet першу неділю кожного місяця. Запустіть це вручну, коли у вас з’являються непоправні апаратні помилки, щоб прискорити перезапис.


Ну, працюючи з ним вручну, ви, мабуть, хочете відмовитися --cron.
дероберт

1

Ви змішали свої ddаргументи. seekзмушує його шукати вказане зміщення у виході . Ви хотіли skipблокувати на вході .


Дякую! Я оновив оригінальний пост, щоб включити дані цього. Якщо ви могли б сказати мені, як виправити блок звідси, я думаю, я дам вам відповідь. (Я не впевнений, чи варто мені писати безпосередньо в /dev/sda1/або використовувати /dev/md0для перезаписування блоку) =)
blitzmann

@Ryan, написання на md0 має стати дорогою, хоча sda1 також має працювати.
psusi

0

Якщо у вас є sw-raid1 і ви записуєте дані одному з членів безпосередньо, у вас буде негайно зіпсований рейд. НЕ записуйте дані в sdaX або sdbX, якщо вони є частиною mdX. Якщо ви пишете на mdX, дані будуть скопійовані на обидва диски, якщо ви прочитаєте з mdX, дані будуть прочитані з одного з дисків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.