Linux - Sửa chữa các khối xấu trên mảng RAID1 bằng GPT


20

Tl; dr: làm cách nào để sửa một khối xấu trên 1 đĩa trong mảng RAID1?

Nhưng xin vui lòng đọc toàn bộ điều này cho những gì tôi đã thử và có thể có lỗi trong phương pháp của tôi. Tôi đã cố gắng chi tiết nhất có thể và tôi thực sự hy vọng có một số phản hồi

Đây là tình huống của tôi: Tôi có hai đĩa 2TB (cùng model) được thiết lập trong một mảng RAID1 được quản lý bởi mdadm. Khoảng 6 tháng trước tôi nhận thấy khối xấu đầu tiên khi SMART báo cáo. Hôm nay tôi nhận thấy nhiều hơn, và bây giờ tôi đang cố gắng sửa nó.

Trang HOWTO này dường như là một bài viết mà mọi người liên kết để sửa các khối xấu mà SMART đang báo cáo. Đó là một trang tuyệt vời, đầy đủ thông tin, tuy nhiên nó khá lỗi thời và không giải quyết được thiết lập cụ thể của tôi. Đây là cách cấu hình của tôi khác nhau:

  • Thay vì một đĩa, tôi đang sử dụng hai đĩa trong một mảng RAID1. Một đĩa báo lỗi trong khi đĩa kia ổn. HOWTO được viết chỉ với một đĩa, trong đó đưa ra nhiều câu hỏi khác nhau như 'tôi có sử dụng lệnh này trên thiết bị đĩa hoặc thiết bị RAID' không?
  • Tôi đang sử dụng GPT, mà fdisk không hỗ trợ. Thay vào đó, tôi đã sử dụng gdisk và tôi hy vọng rằng nó sẽ cung cấp cho tôi cùng thông tin mà tôi cần

Vì vậy, hãy đi xuống nó. Đây là những gì tôi đã làm, tuy nhiên nó dường như không hoạt động. Xin vui lòng kiểm tra lại các tính toán và phương pháp của tôi cho các lỗi. Các lỗi báo cáo đĩa là / 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

Với điều này, chúng tôi tập hợp rằng lỗi nằm trên LBA 3212761936. Sau HOWTO, tôi sử dụng gdisk để tìm khu vực bắt đầu được sử dụng sau này để xác định số khối (vì tôi không thể sử dụng fdisk vì nó không hỗ trợ 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

Sử dụng tunefstôi tìm kích thước khối được 4096. Sử dụng thông tin này và tính toán từ HOWTO, tôi kết luận rằng khối trong câu hỏi là ((3212761936 - 2048) * 512) / 4096 = 401594986.

Sau đó, HOWTO hướng dẫn tôi debugfsxem liệu khối này có được sử dụng không (tôi sử dụng thiết bị RAID vì nó cần một hệ thống tập tin EXT, đây là một trong những lệnh khiến tôi bối rối vì lúc đầu, tôi không biết có nên sử dụng / dev / sda hoặc / dev / md0):

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

Vì vậy, khối 401594986 là không gian trống, tôi sẽ có thể viết lên nó mà không gặp vấn đề gì. Tuy nhiên, trước khi viết cho nó, tôi cố gắng đảm bảo rằng nó, thực sự, không thể đọc được:

# 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

Nếu khối không thể đọc được, tôi sẽ không mong đợi nó hoạt động. Tuy nhiên, nó làm. Tôi lặp lại sử dụng /dev/sda, /dev/sda1, /dev/sdb, /dev/sdb1, /dev/md0, và + -5 đến số khối để tìm kiếm xung quanh các khối xấu. Tất cả đều hoạt động. Tôi nhún vai và tiếp tục thực hiện ghi và đồng bộ hóa (Tôi sử dụng / dev / md0 vì tôi đã tìm cách sửa đổi một đĩa và không phải đĩa kia có thể gây ra sự cố, theo cách này cả hai đĩa đều ghi đè lên khối xấu):

# 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 

Tôi hy vọng rằng việc ghi vào khối xấu sẽ khiến các đĩa gán lại khối thành một khối tốt, tuy nhiên việc chạy thử nghiệm SMART khác lại cho thấy khác:

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

Quay lại hình vuông 1. Về cơ bản, làm cách nào để sửa một khối xấu trên 1 đĩa trong mảng RAID1? Tôi chắc chắn mình đã không làm gì đó chính xác ...

Cảm ơn thời gian và sự kiên nhẫn của bạn.


CHỈNH SỬA 1:

Tôi đã thử chạy thử nghiệm SMART dài, với cùng một LBA trở lại là xấu (sự khác biệt duy nhất là nó báo cáo 30% còn lại thay vì 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

Tôi cũng đã sử dụng badblocks với đầu ra sau đây. Đầu ra là lạ và dường như bị định dạng sai, nhưng tôi đã thử kiểm tra các số được xuất dưới dạng các khối nhưng gỡ lỗi cho lỗi

# 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

Không chắc chắn nơi để đi từ đây. badblockschắc chắn tìm thấy một cái gì đó, nhưng tôi không biết phải làm gì với thông tin được trình bày ...


CHỈNH SỬA 2

Thêm lệnh và thông tin.

Tôi cảm thấy như một thằng ngốc quên bao gồm điều này ban đầu. Đây là giá trị SMART cho /dev/sda. Tôi có 1 Current_Pending_Sector và 0 Offline_Uncncable.

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

Theo một trong những câu trả lời: có vẻ như tôi đã chuyển đổi seekskipcho dd. Tôi đã sử dụng tìm kiếm vì đó là những gì được sử dụng với HOWTO. Sử dụng lệnh này gây ra ddtreo: # dd if = / dev / sda1 of = / dev / null bs = 4096 Count = 1 Skip = 401594986

Sử dụng các khối xung quanh khối đó (..84, ..85, ..87, ..88) dường như chỉ hoạt động tốt và sử dụng / dev / sdb1 với khối cũng 401594986đọc tốt (như mong đợi khi đĩa đó vượt qua kiểm tra SMART ). Bây giờ, câu hỏi mà tôi có là: Khi viết lên khu vực này để gán lại các khối, tôi có sử dụng /dev/sda1hay /dev/md0không? Tôi không muốn gây ra bất kỳ vấn đề nào với mảng RAID bằng cách ghi trực tiếp vào một đĩa và không có bản cập nhật đĩa khác.

CHỈNH SỬA 3

Viết vào khối trực tiếp sản xuất lỗi hệ thống tập tin. Tôi đã chọn một câu trả lời giải quyết vấn đề nhanh chóng:

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

Cảm ơn mọi người đã giúp đỡ. =)


Bạn đã có thể đọc khối, vì vậy nó không bị hỏng. Do đó, không có lĩnh vực tái phân bổ. Tôi đã kiểm tra tính toán khối fs của bạn và nó có vẻ hợp pháp. Khi tôi thực hiện phân bổ khối xấu, tôi phát hiện ra rằng đôi khi kiểm tra ngắn thông minh không báo cáo chính xác khối vi phạm. Trong khi đó, bạn có thể chạy thử nghiệm ngoại tuyến dài smartctl -t long /dev/sdavà xem LBA của lỗi đầu tiên có thay đổi không.
Jari Laamanen

1
Hãy thử /sbin/badblocks -sv /dev/sdakiểm tra đĩa.
jippie

Tôi đã thực hiện cả hai đề xuất và đã cập nhật bài viết phù hợp. Vẫn bị kẹt. = /
blitzmann

Có phải smartctl báo cáo số lượng hiện tại không phải là zero_Pending_Sector không? Là Offline_Uncncable có thể khác không?
mgorven

Vui lòng thêm trạng thái mảng vào câu hỏi:sudo mdadm -D /dev/md0
psusi

Câu trả lời:


20

Tất cả những câu trả lời "chọc khu vực" này, khá thẳng thắn, điên rồ. Họ có nguy cơ (có thể ẩn) tham nhũng hệ thống tập tin. Nếu dữ liệu đã biến mất, vì đĩa đó được lưu trữ bản sao duy nhất, nó sẽ hợp lý. Nhưng có một bản sao hoàn toàn tốt trên gương.

Bạn chỉ cần có md sợ chà gương. Nó sẽ nhận thấy khu vực xấu và viết lại nó tự động.

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

Bạn cần đặt đúng thiết bị vào đó (ví dụ: md0 thay vì mdX). Điều này sẽ mất một lúc, vì nó làm toàn bộ mảng theo mặc định. Trên một kernel đủ mới, trước tiên bạn có thể viết số sector thành sync_min / sync_max, để giới hạn nó chỉ ở một phần của mảng.

Đây là một hoạt động an toàn. Bạn có thể làm điều đó trên tất cả các thiết bị sợ hãi của bạn. Trong thực tế, bạn nên làm điều đó trên tất cả các thiết bị sợ hãi của bạn, thường xuyên. Bản phân phối của bạn có khả năng xuất xưởng với một cronjob để xử lý việc này, có lẽ bạn cần phải làm gì đó để kích hoạt nó?


Tập lệnh cho tất cả các thiết bị RAID trên hệ thống

Một thời gian trước, tôi đã viết kịch bản này để "sửa chữa" tất cả các thiết bị RAID trên hệ thống. Điều này đã được viết cho các phiên bản kernel cũ hơn, nơi chỉ 'sửa chữa' sẽ sửa chữa khu vực xấu; bây giờ chỉ cần kiểm tra là đủ (sửa chữa vẫn hoạt động tốt trên các hạt nhân mới hơn, nhưng nó cũng sao chép lại / xây dựng lại tính chẵn lẻ, không phải lúc nào cũng như bạn muốn, đặc biệt là trên các ổ đĩa flash)

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

Nếu bạn muốn làm checkthay vì repair, thì khối đầu tiên (chưa được kiểm tra) này sẽ hoạt động:

    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

Cảm ơn vì điều này. Gần đây tôi đã trở lại vấn đề này với hy vọng cuối cùng sẽ giải quyết nó. Tôi đã viết thư cho khối / dev / md0 và tôi đã gặp vấn đề về hệ thống tập tin, nhưng rất may sau vài giờ khủng bố và khởi động vào các vỏ khôi phục, tất cả đều được sửa chữa mà không có dataloss. Tôi sẽ thử phương pháp của bạn trước và hy vọng điều này sẽ giúp tôi thoát khỏi khu vực đang chờ xử lý. =)
blitzmann

Làm thế nào bạn có thể biết khi chà hoàn thành? Sẽ cat /sys/block/mdX/md/sync_actionđọc 'nhàn rỗi' khi hoàn thành?
Jon Cram

@JonCram có, và bạn có thể xem trạng thái bằng cat /proc/mdstathoặc nếu bạn muốn viết kịch bản đó,/sys/…/sync_completed
derobert

5

Tôi đã gặp khá nhiều vấn đề tương tự với mảng RAID1. Khu vực xấu đã ở ngay đầu một trong các phân vùng - sector 16 of / dev / sdb2. Tôi đã làm theo các hướng dẫn ở trên: sau khi xác minh rằng khối logic 2 không được sử dụng bởi hệ thống tệp và cẩn thận để tìm kiếm dd và bỏ qua đúng cách, và loại bỏ 1 khối hệ thống tệp:

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

Điều này đã làm gì? Nó đã không sửa chữa khu vực xấu. Điều này, bây giờ tôi biết, là vì / dev / md0 không ánh xạ trực tiếp vào / dev / sdb2, bạn phải tính đến RAID DATA OFFSET! Thêm về điều này dưới đây. Những gì nó đã làm là một con rùa nhỏ nhưng có khả năng tàn phá trên hệ thống tập tin của tôi. Hóa ra khối logic 2 của / dev / md0 chứa siêu dữ liệu hệ thống tệp hữu ích và vẫn ổn trên cả hai đĩa, cho đến khi tôi vượt qua cả hai bản sao bằng cách ghi vào / dev / md0. May mắn thay, e2fsck -y / dev / md0 đã khắc phục sự cố (sau khi đưa ra một lượng đầu ra đáng báo động) mà không mất dữ liệu rõ ràng. Bài học rút ra: nếu debugfs icheck nói 'không tìm thấy khối', điều đó không nhất thiết có nghĩa là các lĩnh vực tương ứng không được sử dụng.

Quay lại phần bù dữ liệu: sử dụng mdadm để tìm phần bù như thế này:

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

Trong trường hợp này, phần bù dữ liệu là 262144 cung 512 byte. Nếu bạn dd từ / dev / md0 và so sánh nó với dữ liệu từ phân vùng thô với độ lệch là 131072K, bạn sẽ thấy chúng khớp với nhau. Vì vậy, trong trường hợp của tôi, khối logic 2 (các phần 16--23) của / dev / sdb2 thậm chí không có trong hệ thống tệp; Chúng nằm trong siêu khối RAID, mà bạn có thể đọc ở đây: https://ston.wiki.kernel.org/index.php/RAID_superblock_formats - đối với phiên bản 1.2, nó bao gồm 256 byte + 2 byte cho mỗi thiết bị trong mảng , tất cả bắt đầu từ 4096 byte, vì vậy trong trường hợp của tôi, khu vực xấu đã không được sử dụng. Các lĩnh vực tương ứng của / dev / sdc2 (nửa còn lại của mảng RAID1) bằng 0 nên tôi cho rằng sẽ an toàn khi làm điều này:

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

Nó đã làm việc!


OP đây. Cảm ơn bạn cho thông tin này. Khi vấn đề này xảy ra với tôi, tôi đã thực hiện bước nhảy vọt và không tham gia vào khối / dev / md0. Ý tưởng tồi, như tôi đã tình cờ làm hỏng hệ thống tập tin của tôi. Rất may sau một thời gian sửa chữa vô duyên, tất cả dường như không có dataloss. Nhưng với sự hoảng loạn ban đầu tôi hoàn toàn quên mất bài đăng này. Gần đây tôi đã thiết lập máy chủ của mình trong căn hộ mới của mình và đây là một trong những điều trong danh sách việc cần làm của tôi một lần nữa và tôi cảm ơn bạn vì sự hiểu biết của bạn về vấn đề này. Tôi sẽ cập nhật OP khi tôi tìm hiểu thêm về vấn đề này. =)
blitzmann

2

Nếu chạy debian, rất có thể bạn có một công việc trong /etc/cron.d/mdadm. Điều này sẽ chạy /usr/share/mdadm/checkarray --cron --all --idle --quiet chủ nhật đầu tiên của mỗi tháng. Chạy thủ công khi bạn gặp lỗi phần cứng không chính xác để tiến hành viết lại.


Vâng, khi chạy nó bằng tay bạn có thể muốn rời đi --cron.
derobert

1

Bạn trộn lẫn các ddlập luận của bạn . seeklàm cho nó tìm đến phần bù được chỉ định trong đầu ra . Bạn muốn skipchặn trên đầu vào .


Cảm ơn bạn! Tôi đã cập nhật bài viết gốc để bao gồm dữ liệu từ đây. Nếu bạn có thể cho tôi biết cách sửa khối từ đây, tôi nghĩ tôi sẽ cấp cho bạn câu trả lời. (Tôi không chắc mình nên viết trực tiếp /dev/sda1/hoặc sử dụng /dev/md0để ghi đè lên khối) =)
blitzmann

@Ryan, viết thư cho md0 nên là cách để đi, mặc dù sda1 cũng nên hoạt động.
psusi

0

Nếu bạn có sw-raid1 và bạn viết dữ liệu cho một trong các thành viên trực tiếp, bạn sẽ có một cuộc đột kích bị hỏng ngay lập tức. KHÔNG ghi dữ liệu vào sdaX hoặc sdbX nếu chúng là một phần của mdX. Nếu bạn ghi vào mdX, bạn sẽ có dữ liệu được sao chép vào cả hai ổ đĩa, nếu bạn đọc từ mdX, bạn sẽ có dữ liệu được đọc từ một trong các ổ đĩa ..

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.