Linux - GPT ile RAID1 dizisindeki bozuk blokları onarma


20

Tl; dr: RAID1 dizisindeki 1 diskteki bozuk bir bloğu nasıl düzeltebilirim?

Ama lütfen zaten denediklerim ve yöntemlerimdeki olası hatalar için her şeyi okuyun. Mümkün olduğunca ayrıntılı olmaya çalıştım ve gerçekten geri bildirim almayı umuyorum

Bu benim durumum: tarafından yönetilen bir RAID1 dizisi ayarlanmış iki 2 TB disk (aynı model) var mdadm. Yaklaşık 6 ay önce, SMART bildirdiğinde ilk kötü bloğu fark ettim. Bugün daha fazla fark ettim ve şimdi düzeltmeye çalışıyorum.

Bu NASIL sayfası , SMART'ın bildirdiği kötü blokları düzeltmek için herkesin bağlantı verdiği tek makale gibi görünüyor. Harika bir sayfa, bilgi dolu, ancak oldukça eski ve özel kurulumumu ele almıyor. Yapılandırmamın farkı:

  • Bir disk yerine, bir RAID1 dizisinde iki disk kullanıyorum. Bir disk hata verirken diğeri iyi durumda. NASIL belgesinde, 'Bu komutu disk aygıtında veya RAID aygıtında kullanabilir miyim?'
  • GPD kullanıyorum, hangi fdisk desteklemiyor. Bunun yerine gdisk kullanıyorum ve bunun bana ihtiyacım olan bilgiyi verdiğini umuyorum

Yani, aşağı inelim. Yaptığım şey bu, ancak işe yaramıyor gibi görünüyor. Lütfen hesaplamalarımı ve yöntemimi hatalar için tekrar kontrol etmekten çekinmeyin. Disk raporlama hataları: / 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

Bununla, hatanın LBA 3212761936'da bulunduğunu toplarız. NASIL belgesinin ardından, gdisk'i daha sonra blok numarasını belirlemede kullanılacak başlangıç ​​sektörünü bulmak için kullanıyorum (GPT'yi desteklemediğinden fdisk'i kullanamadığım için):

# 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

Kullanılması tunefsBen blokboyu olarak görüyorum 4096. Bu bilgileri ve NASIL belgesinden alınan hesaplamayı kullanarak, söz konusu bloğun olduğu sonucuna varıyorum ((3212761936 - 2048) * 512) / 4096 = 401594986.

NASIL daha sonra debugfsbloğun kullanımda olup olmadığını görmek için beni yönlendirir (bir EXT dosya sistemine ihtiyaç duyduğu için RAID cihazını kullanıyorum, bu ilk başta, / dev / sda veya / dev / md0):

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

Yani blok 401594986 boş alan, sorunsuz bir şekilde üzerine yazabilmeliyim. Buna yazmadan önce, gerçekten okunamayacağından emin olmaya çalışıyorum:

# 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

Blok okunamazsa, bunun çalışmasını beklemezdim. Ancak, öyle. Ben kullanarak tekrarı /dev/sda, /dev/sda1, /dev/sdb, /dev/sdb1, /dev/md0, ve + -5 blok numarasına kötü blok etrafında aramak için. Hepsi işe yarıyor. Omuzlarımı silkti ve devam edip yazma ve senkronize etme (/ dev / md0 kullanıyorum çünkü bir diski değiştirmeyi düşündüm ve diğer sorunlara neden olmayabilir, bu şekilde her iki disk de kötü bloğun üzerine yazıyor):

# 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 

Kötü bloğa yazmanın disklerin bloğu iyi bir atayacağını, ancak başka bir SMART testi çalıştırmanın farklı olacağını umuyorum:

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

Kareye dön 1. Öyleyse, RAID1 dizisindeki 1 diskteki bozuk bir bloğu nasıl düzeltirim? Eminim doğru bir şey yapmadım ...

Zamanınız ve sabrınız için teşekkürler.


DÜZENLEME 1:

Uzun bir SMART testi yapmaya çalıştım, aynı LBA kötü olarak geri döndü (tek fark% 90 yerine% 30 kaldı rapor ediyor):

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

Ben de aşağıdaki çıktı ile badblock kullandım. Çıktı garip ve yanlış biçimlendirilmiş gibi görünüyor, ancak blok olarak çıkan sayıları test etmeye çalıştım ama debugfs hata veriyor

# 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

Buradan nereye gideceğinden emin değilim. badblockskesinlikle bir şey buldum, ama sunulan bilgilerle ne yapacağımdan emin değilim ...


DÜZENLEME 2

Daha fazla komut ve bilgi.

Bunu başlangıçta eklemeyi unutan bir salak gibi hissediyorum. Bu için SMART değerleridir /dev/sda. 1 Current_Pending_Sector ve 0 Offline_Uncorrectable var.

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

Cevaplar biri gereğince: Öyle görünüyor ki ben anahtarı yaptım seekve skipiçin dd. Ben NASIL ile kullanılan şey olarak seek kullanıyordum. Bu komutu kullanmanız ddaskıda kalmaya neden olur : = / dev / sda1 / = / dev / null bs = 4096 sayısı = 1 atlama = 401594986

Bunun etrafındaki blokları kullanmak (..84, ..85, ..87, ..88) gayet iyi çalışıyor ve blok ile / dev / sdb1 kullanmak 401594986da iyi okuyor (diskin SMART testini geçmesi beklendiği gibi) ). Şimdi, sorum şu: Blokları yeniden atamak için bu alanın üzerine yazarken, /dev/sda1ya da kullanacak /dev/md0mıyım? Doğrudan bir diske yazıp diğer disk güncellemesine sahip olmadan RAID dizisi ile ilgili herhangi bir soruna neden olmak istemiyorum.

DÜZENLE 3

Bloğa doğrudan yazılan dosya sistemi hataları yazılır. Sorunu hızlı bir şekilde çözen bir cevap seçtim:

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

Yardım eden herkese teşekkürler. =)


Bloğu okuyabiliyordunuz, bu yüzden hasar görmedi. Dolayısıyla, yeniden tahsis edilmiş sektör yok. FS blok hesaplamanızı kontrol ettim ve yasal görünüyor. Kötü blok yeniden tahsisleri yaptığımda, bazen akıllı kısa testin rahatsız edici bloğu doğru bir şekilde rapor etmediğini öğrendim. Bu arada, uzun çevrimdışı testi çalıştırabilir smartctl -t long /dev/sdave ilk hatanın LBA'sının değişip değişmediğini görebilirsiniz.
Jari Laamanen

1
/sbin/badblocks -sv /dev/sdaDiski kontrol etmeyi deneyin .
jippie

Her iki öneriyi de yaptım ve gönderiyi buna göre güncelledik. Hala sıkışık. = /
blitzmann

Smartctl sıfırdan farklı bir Current_Pending_Sector sayısını bildiriyor mu? Offline_Uncorrectable sıfır değil mi?
mgorven

Lütfen soruya dizi durumunu ekleyin:sudo mdadm -D /dev/md0
psusi

Yanıtlar:


20

Tüm bu "sektörü dürtmek" cevapları açıkçası deli. Dosya sisteminin bozulması (muhtemelen gizli) riski vardır. Veriler zaten yok olsaydı, bu disk tek kopyayı sakladığı için makul olurdu. Ama aynada mükemmel bir kopya var.

Sadece mdraid'in aynayı ovması gerekir. Kötü sektörü fark edecek ve otomatik olarak yeniden yazacaktır.

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

Doğru cihazı buraya koymanız gerekir (örneğin, mdX yerine md0). Varsayılan olarak tüm diziyi yaptığı için bu işlem biraz zaman alacaktır. Yeterince yeni bir çekirdeğe, önce dizinin yalnızca bir bölümü ile sınırlamak için sektör sayılarını önce sync_min / sync_max öğesine yazabilirsiniz.

Bu güvenli bir işlemdir. Bunu tüm mdraid cihazlarınızda yapabilirsiniz. Aslında, gereken düzenli, tüm mdraid cihazlarda bunu. Dağıtımınız büyük olasılıkla bunun üstesinden gelmek için bir cronjob ile birlikte gönderilir, belki de etkinleştirmek için bir şeyler yapmanız gerekir?


Sistemdeki tüm RAID aygıtları için komut dosyası

Bir süre önce, sistemdeki tüm RAID aygıtlarını "onarmak" için bu komut dosyasını yazdım. Bu, yalnızca 'onarımın' kötü sektörü düzeltebileceği eski çekirdek sürümleri için yazılmıştır; Şimdi sadece kontrol yapmak yeterlidir (onarım yeni çekirdeklerde hala iyi çalışır, ancak pariteyi de yeniden kopyalar / yeniden oluşturur, bu da her zaman istediğiniz şey değildir, özellikle flash sürücülerde)

#!/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

checkBunun yerine yapmak istiyorsanız repair, bu (test edilmemiş) ilk blok çalışmalıdır:

    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

Bunun için teşekkür ederim. Son zamanlarda bu sorunu nihayet çözmeyi umarak döndüm. / Dev / md0 bloğuna yazdım ve dosya sistemi sorunları yaşadım, ama neyse ki birkaç saat sonra terör ve kurtarma kabuklarına önyükleme tüm veri kaybı olmadan onarım oldu. Önce yönteminizi deneyeceğim ve umarım bu beni bekleyen sektörden kurtaracaktır. =)
blitzmann

Fırçalamanın ne zaman tamamlandığını nasıl anlarsınız? Tamamlandığında cat /sys/block/mdX/md/sync_action'boşta' okuyacak mı?
Jon Cram

@JonCram evet, ve durumunu cat /proc/mdstatsenaryo ile veya senaryoyu izlemek istiyorsanız izleyebilirsiniz/sys/…/sync_completed
derobert

5

Bir RAID1 dizisi ile hemen hemen aynı sorunu yaşadım. Kötü sektör bölümlerden birinin başındaydı - / dev / sdb2'nin 16. sektörü. Yukarıdaki talimatları izledim: Mantıksal blok 2'nin dosya sistemi tarafından kullanılmadığını doğruladıktan ve dd araması ve doğru yolu atlamaya dikkat ederek ve 1 dosya sistemi bloğunu sıfırladık:

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

Bu ne yaptı? Kötü sektörü düzeltmedi. Bu, şimdi biliyorum, / dev / md0 doğrudan / dev / sdb2 ile eşleşmiyor, RAID DATA OFFSET'i hesaba katmanız gerekiyor! Bu konuda daha fazlası aşağıda. Yaptığı şey, dosya sistemimdeki küçük ama potansiyel olarak yıkıcı bir boktu. / Dev / md0 mantıksal bloğu 2'nin yararlı dosya sistemi meta verileri içerdiği ve / dev / md0 yazarak her iki kopyaya da sıkışıncaya kadar her iki diskte de iyi olduğu ortaya çıktı . Neyse ki, e2fsck -y / dev / md0 problemi (endişe verici bir çıktı çıkardıktan sonra) belirgin bir veri kaybı olmadan çözdü. Alınan ders: debugfs icheck 'blok bulunamadı' diyorsa, mutlaka ilgili sektörlerin kullanılmadığı anlamına gelmez.

Veri ofsetine geri dönün: Bu şekilde ofseti bulmak için mdadm kullanın:

# 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)

Bu durumda, veri ofseti 512 baytlık 262144 sektördür. / Dev / md0 dizininden gd alıp ham bölümdeki verilerle 131072K uzaklıkla karşılaştırırsanız, bunların eşleştiğini görürsünüz. Benim durumumda, / dev / sdb2'nin mantıksal blok 2'si (sektörler 16-23) dosya sisteminde bile değil; burada okuyabileceğiniz RAID süper bloğundalar : https://raid.wiki.kernel.org/index.php/RAID_superblock_formats - sürüm 1.2 için, dizideki cihaz başına 256 bayt + 2 bayttan oluşur , hepsi 4096 bayttan başlıyor, bu yüzden benim durumumda kötü sektör kullanılmadı. / Dev / sdc2 (RAID1 dizisinin diğer yarısı) karşılık gelen sektörleri sıfırdır, bu yüzden bunu yapmak güvenli olacağını düşündüm:

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

İşe yaradı!


OP burada. Bu bilgi için teşekkürler. Bu sorun benim için ortaya çıktığında, sıçramayı aldım ve / dev / md0 düzeyinde bloğu sıfırladım. Kötü fikir, dosya sistemimi de mahvettiğim için. Neyse ki tam zamanında bir zaman onarımından sonra, hiçbir veri kaybı olmadan iyi görünüyordu. Ama ilk panik ile bu yazıyı tamamen unuttum. Son zamanlarda sunucumu yeni daireme kurdum ve bu da yapılacaklar listemdeki şeylerden biri ve sorunla ilgili görüşleriniz için teşekkür ederim. Biraz daha kazmaya çalışırken OP'yi güncelleyeceğim. =)
blitzmann

2

Eğer debian koşmak büyük olasılıkla /etc/cron.d/mdadm bir iş var. Bu /usr/share/mdadm/checkarray --cron --all --idle --quiet , her ayın ilk pazar günü gerçekleşecek. Yeniden yazmayı hızlandırmak için düzeltilemez donanım hataları aldığınızda bunu manuel olarak çalıştırın.


Peki, manuel olarak çalıştırırken muhtemelen ayrılmak istersiniz --cron.
derobert

1

ddArgümanlarınızı karıştırdınız . çıktıdaseek belirtilen ofseti aramasına neden olur . Girdiyi engellemek istediniz .skip


Teşekkür ederim! Orijinal yayını, bundan veri içerecek şekilde güncelledim. Bloğu buradan nasıl düzeltebileceğimi söyleyebilirsen, sana cevap vereceğimi düşünüyorum. (Doğrudan bloğa yazmak /dev/sda1/veya yazmak için kullanmam gerekip gerekmediğinden emin değilim /dev/md0) =)
blitzmann

@Ryan, md0'a yazmanın yolu olmalı, sda1 de çalışmalı.
psusi

0

Bir sw-raid1'iniz varsa ve üyelerden birine doğrudan veri yazarsanız, derhal bozuk bir baskınınız olur. Bir mdX'in parçasıysa sdaX veya sdbX'e veri yazmayın. MdX'e yazarsanız, her iki sürücüye de kopyalanacaksınız, mdX'den okursanız, sürücülerden birinden okunan veri olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.