Pull to refresh

Правильное приготовление и работа с ZFS под FreeBSD

Reading time15 min
Views45K
Некоторое время назад возникла задача построения достаточно вместительного массива для хранения оперативных инкрементальных бекапов. Причём тратить деньги особо не хотелось, а место было нужно. Решение было простым и достаточно удобным. Далее много текста.


За основу было взято шасси SuperChassis 825TQ-560LPB

В которое было вставлено 8 дисков Hitachi 1TB и контроллер LSI Logic SAS HBA SAS3081E-R. Мы заранее планировали схему без аппаратного рейда опираясь только на возможности ZFS.

Первая версия сервера на FreeBSD 7.2-STABLE прожила примерно около 3х месяцев, за это время отловились основные баги в виде ограничения используемой памяти vm.kmem_size и vfs.zfs.arc_max.
При недостатке выделяемой ядру памяти система падала в панику, при недостатке буферов arc_max очень сильно падала скорость работы. Для загрузки системы использовалась флешка размером 1GB, которая позволила спокойно менять версию системы простой заменой флешки с новой сборкой.

Схема построенного массива была основана на адресации по имени диска(устройства).
Далее по тексту будут вставки из dmesg и консольных команд работы.
mpt0: <LSILogic SAS/SATA Adapter> port 0x2000-0x20ff mem 0xdc210000-0xdc213fff,0xdc200000-0xdc20ffff irq 16 at device 0.0 on pci3
mpt0: [ITHREAD]
mpt0: MPI Version=1.5.20.0
mpt0: Capabilities: ( RAID-0 RAID-1E RAID-1 )
mpt0: 0 Active Volumes (2 Max)
mpt0: 0 Hidden Drive Members (14 Max)

da0 at mpt0 bus 0 scbus0 target 0 lun 0
da0: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da0: 300.000MB/s transfers
da0: Command Queueing enabled
da0: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da1 at mpt0 bus 0 scbus0 target 1 lun 0
da1: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da1: 300.000MB/s transfers
da1: Command Queueing enabled
da1: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da2 at mpt0 bus 0 scbus0 target 2 lun 0
da2: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da2: 300.000MB/s transfers
da2: Command Queueing enabled
da2: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da3 at mpt0 bus 0 scbus0 target 3 lun 0
da3: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da3: 300.000MB/s transfers
da3: Command Queueing enabled
da3: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da4 at mpt0 bus 0 scbus0 target 4 lun 0
da4: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da4: 300.000MB/s transfers
da4: Command Queueing enabled
da4: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da5 at mpt0 bus 0 scbus0 target 5 lun 0
da5: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da5: 300.000MB/s transfers
da5: Command Queueing enabled
da5: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da6 at mpt0 bus 0 scbus0 target 7 lun 0
da6: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da6: 300.000MB/s transfers
da6: Command Queueing enabled
da6: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da7 at mpt0 bus 0 scbus0 target 8 lun 0
da7: <ATA Hitachi HDE72101 A31B> Fixed Direct Access SCSI-5 device
da7: 300.000MB/s transfers
da7: Command Queueing enabled
da7: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
ugen3.2: <JetFlash> at usbus3
umass0: <JetFlash Mass Storage Device, class 0/0, rev 2.00/1.00, addr 2> on usbus3
umass0: SCSI over Bulk-Only; quirks = 0x0100
umass0:2:0:-1: Attached to scbus2
da8 at umass-sim0 bus 0 scbus2 target 0 lun 0
da8: <JetFlash Transcend 1GB 8.07> Removable Direct Access SCSI-2 device
da8: 40.000MB/s transfers
da8: 963MB (1972224 512 byte sectors: 64H 32S/T 963C)
Trying to mount root from ufs:/dev/ufs/FBSDUSB

В принципе всё более менее понятно. Есть контроллер, есть луны, есть диски, есть имена подключенных устройств к контроллеру.
backupstorage# zpool create storage raidz da0 da1 da2 da3 da4 da5 da6 da7
backupstorage# zpool status -v
  pool: storage
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1    ONLINE       0     0     0
            da0     ONLINE       0     0     0
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0
            da4     ONLINE       0     0     0
            da5     ONLINE       0     0     0
            da6     ONLINE       0     0     0
            da7     ONLINE       0     0     0

errors: No known data errors


Всё работает до тех пор пока не умирает один из дисков. У меня начал осыпаться седьмой диск и контроллер по timeout выкидывал его из массива. Причём уверенности в том, что посыпался сам диск у меня не было, потому что диски были абсолютно новыми и никаким нагрузкам не подвергались.
DFT от Hitachi ошибок не находила и говорила что всё в норме, только иногда подтормаживала. MHDD нашёл много секторов с временем доступа около 500 мс, после 50 таких секторов я диск просто поменял по гарантии.

Но диск это реально полбеды. Диск поборол, но вот проблемы пойманные при его сбоях заставили задуматься.

Проблема первая: Массив с нумерацией дисков не привязанной к лунам
ZFS в Solaris разрабатывалась с учётом привязки дисков к номерам контроллеров и лунам на этих контроллерах. В случае использования такой схемы учёта необходимо только заменить умерший диск и синхронизировать данные в массиве. В FreeBSD как и в Linux именование устройств обычно идёт прозрачное и не зависит от физического порта на контроллере. В этом на самом деле и заключается самая большая засада.
К примеру возьмём и вытащим из системы 5 диск, эмулируя аппаратный сбой на диске.
backupstorage# camcontrol rescan all
Re-scan of bus 0 was successful
Re-scan of bus 1 was successful
Re-scan of bus 2 was successful

mpt0: mpt_cam_event: 0x16
mpt0: mpt_cam_event: 0x12
mpt0: mpt_cam_event: 0x16
mpt0: mpt_cam_event: 0x16
mpt0: mpt_cam_event: 0x16
(da4:mpt0:0:4:0): lost device
(da4:mpt0:0:4:0): Synchronize cache failed, status == 0x4a, scsi status == 0x0
(da4:mpt0:0:4:0): removing device entry

backupstorage# zpool status -v
  pool: storage
 state: DEGRADED
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        storage     DEGRADED     0     0     0
          raidz1    DEGRADED     0     0     0
            da0     ONLINE       0     0     0
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0
            da4     REMOVED      0     0     0
            da5     ONLINE       0     0     0
            da6     ONLINE       0     0     0
            da7     ONLINE       0     0     0

Всё отлично. Контроллер увидел, что у него пропал диск и пометил его как отсутствующий.
Можно вставить новый диск и синхронизировать массив. НО если Вы перезагрузите сервер, то
вас ждёт очень интересная картина(я уберу лишнюю информацию из квотинга dmesg, чтобы не перегружать текстом экран)
da0 at mpt0 bus 0 scbus0 target 0 lun 0
da0: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da0: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da1 at mpt0 bus 0 scbus0 target 1 lun 0
da1: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da1: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da2 at mpt0 bus 0 scbus0 target 2 lun 0
da2: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da2: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da3 at mpt0 bus 0 scbus0 target 3 lun 0
da3: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da3: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da4 at mpt0 bus 0 scbus0 target 5 lun 0
da4: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da4: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da5 at mpt0 bus 0 scbus0 target 7 lun 0
da5: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da5: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
da6 at mpt0 bus 0 scbus0 target 8 lun 0
da6: <ATA Hitachi HDE72101 A31B> Fixed Direct Access SCSI-5 device
da6: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
SMP: AP CPU #1 Launched!
GEOM: da0: the primary GPT table is corrupt or invalid.
GEOM: da0: using the secondary instead -- recovery strongly advised.
GEOM: da1: the primary GPT table is corrupt or invalid.
GEOM: da1: using the secondary instead -- recovery strongly advised.
GEOM: da2: the primary GPT table is corrupt or invalid.
GEOM: da2: using the secondary instead -- recovery strongly advised.
GEOM: da3: the primary GPT table is corrupt or invalid.
GEOM: da3: using the secondary instead -- recovery strongly advised.
GEOM: da4: the primary GPT table is corrupt or invalid.
GEOM: da4: using the secondary instead -- recovery strongly advised.
GEOM: da5: the primary GPT table is corrupt or invalid.
GEOM: da5: using the secondary instead -- recovery strongly advised.
GEOM: da6: the primary GPT table is corrupt or invalid.
GEOM: da6: using the secondary instead -- recovery strongly advised.
ugen3.2: <JetFlash> at usbus3
umass0: <JetFlash Mass Storage Device, class 0/0, rev 2.00/1.00, addr 2> on usbus3
umass0: SCSI over Bulk-Only; quirks = 0x0100
umass0:2:0:-1: Attached to scbus2
da7 at umass-sim0 bus 0 scbus2 target 0 lun 0
da7: <JetFlash Transcend 1GB 8.07> Removable Direct Access SCSI-2 device
da7: 40.000MB/s transfers
da7: 963MB (1972224 512 byte sectors: 64H 32S/T 963C)
Trying to mount root from ufs:/dev/ufs/FBSDUSB
GEOM: da4: the primary GPT table is corrupt or invalid.
GEOM: da4: using the secondary instead -- recovery strongly advised.
GEOM: da5: the primary GPT table is corrupt or invalid.
GEOM: da5: using the secondary instead -- recovery strongly advised.
GEOM: da0: the primary GPT table is corrupt or invalid.
GEOM: da0: using the secondary instead -- recovery strongly advised.
GEOM: da1: the primary GPT table is corrupt or invalid.
GEOM: da1: using the secondary instead -- recovery strongly advised.
GEOM: da2: the primary GPT table is corrupt or invalid.
GEOM: da2: using the secondary instead -- recovery strongly advised.
GEOM: da3: the primary GPT table is corrupt or invalid.
GEOM: da3: using the secondary instead -- recovery strongly advised.
GEOM: da6: the primary GPT table is corrupt or invalid.
GEOM: da6: using the secondary instead -- recovery strongly advised.
GEOM: da4: the primary GPT table is corrupt or invalid.
GEOM: da4: using the secondary instead -- recovery strongly advised.

Что мы видим?
Мы видим что по сравнению с первым дампом dmesg, устройств стало 8 вместо 9 и флешка стала da7 вместо da8. ZFS начинает материться о том, что есть проблемы с чтением GPT меток и что всё плохо.
Zpool тупо развалился на глазах, так как нумерация дисков уехала на 1 вверх, что в свою очередь вызвало потерю массивом ориентиров для работы и путанице в метках дисков.
backupstorage# zpool status -v
  pool: storage
 state: UNAVAIL
status: One or more devices could not be used because the label is missing
        or invalid.  There are insufficient replicas for the pool to continue
        functioning.
action: Destroy and re-create the pool from a backup source.
   see: http://www.sun.com/msg/ZFS-8000-5E
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        storage     UNAVAIL      0     0     0  insufficient replicas
          raidz1    UNAVAIL      0     0     0  insufficient replicas
            da0     ONLINE       0     0     0
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0
            da4     FAULTED      0     0     0  corrupted data
            da5     FAULTED      0     0     0  corrupted data
            da6     FAULTED      0     0     0  corrupted data
            da6     ONLINE       0     0     0

Обратите внимание, что у нас 2!!! диска da6. Всё это потому, что у нас есть физический диск определенный как da6 и присутствует GPT метка da6 на диске который раньше был da6.

теперь попробуем воткнуть диск который вытащили.
backupstorage# camcontrol rescan all
Re-scan of bus 0 was successful
Re-scan of bus 1 was successful
Re-scan of bus 2 was successful

da8 at mpt0 bus 0 scbus0 target 4 lun 0
da8: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da8: 300.000MB/s transfers
da8: Command Queueing enabled
da8: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
GEOM: da8: the primary GPT table is corrupt or invalid.
GEOM: da8: using the secondary instead -- recovery strongly advised.

Диск определился, но стал da8. Мы конечно же можем попробовать перестроить массив, но ни к чему хорошему это не приведёт. Поэтому просто перегружаемся.
backupstorage# zpool status -v
  pool: storage
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1    ONLINE       0     0     0
            da0     ONLINE       0     0     0
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0
            da4     ONLINE       0     0     0
            da5     ONLINE       0     0     0
            da6     ONLINE       0     0     0
            da7     ONLINE       0     0     0

errors: No known data errors


После перезагрузки zfs спокойно находит все диски, немного ругается в лог и продолжает работать.

GEOM: da0: the primary GPT table is corrupt or invalid.
GEOM: da0: using the secondary instead -- recovery strongly advised.
GEOM: da1: the primary GPT table is corrupt or invalid.
GEOM: da1: using the secondary instead -- recovery strongly advised.
GEOM: da2: the primary GPT table is corrupt or invalid.
GEOM: da2: using the secondary instead -- recovery strongly advised.
GEOM: da3: the primary GPT table is corrupt or invalid.
GEOM: da3: using the secondary instead -- recovery strongly advised.
GEOM: da4: the primary GPT table is corrupt or invalid.
GEOM: da4: using the secondary instead -- recovery strongly advised.
GEOM: da5: the primary GPT table is corrupt or invalid.
GEOM: da5: using the secondary instead -- recovery strongly advised.
GEOM: da6: the primary GPT table is corrupt or invalid.
GEOM: da6: using the secondary instead -- recovery strongly advised.
GEOM: da7: the primary GPT table is corrupt or invalid.
GEOM: da7: using the secondary instead -- recovery strongly advised.
GEOM: da0: the primary GPT table is corrupt or invalid.
GEOM: da0: using the secondary instead -- recovery strongly advised.
GEOM: da2: the primary GPT table is corrupt or invalid.
GEOM: da2: using the secondary instead -- recovery strongly advised.
GEOM: da7: the primary GPT table is corrupt or invalid.
GEOM: da7: using the secondary instead -- recovery strongly advised.

resilver проходит практически безболезненно, так как у нас не было работы с данными на сломанном массиве.
GEOM: da0: the primary GPT table is corrupt or invalid.
GEOM: da0: using the secondary instead -- recovery strongly advised.
GEOM: da3: the primary GPT table is corrupt or invalid.
GEOM: da3: using the secondary instead -- recovery strongly advised.
====================

backupstorage# zpool status -v
  pool: storage
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Wed Nov 25 11:06:15 2009
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1    ONLINE       0     0     0
            da0     ONLINE       0     0     0
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0  512 resilvered
            da3     ONLINE       0     0     0  512 resilvered
            da4     ONLINE       0     0     0
            da5     ONLINE       0     0     0
            da6     ONLINE       0     0     0  512 resilvered
            da7     ONLINE       0     0     0  512 resilvered

errors: No known data errors

В общем мы убедились, что такая схема не очень надёжна при автоматической нумерации дисков в контроллере. Хотя если количество дисков не меняется — их можно переставлять в произвольном порядке. Массив будет работать исправно.

Проблема вторая: geomlabel на дисках.
Дабы попытаться решить проблему с именованием дисков было решено попробовать пометить их метками и уже метки добавить в массив. При создании метки на диске — она пишется в конец диска, при инициализации диска система считывает метки и создаёт виртуальные устройства /dev/label/имяметки.
backupstorage# zpool create storage raidz label/disk0 label/disk1 label/disk2 label/disk3 label/disk4 label/disk5 label/disk6 label/disk7
backupstorage# zpool status -v
  pool: storage
 state: ONLINE
 scrub: none requested
config:

        NAME             STATE     READ WRITE CKSUM
        storage          ONLINE       0     0     0
          raidz1         ONLINE       0     0     0
            label/disk0  ONLINE       0     0     0
            label/disk1  ONLINE       0     0     0
            label/disk2  ONLINE       0     0     0
            label/disk3  ONLINE       0     0     0
            label/disk4  ONLINE       0     0     0
            label/disk5  ONLINE       0     0     0
            label/disk6  ONLINE       0     0     0
            label/disk7  ONLINE       0     0     0

errors: No known data errors
backupstorage# ls /dev/label/disk*
/dev/label/disk0        /dev/label/disk2        /dev/label/disk4        /dev/label/disk6
/dev/label/disk1        /dev/label/disk3        /dev/label/disk5        /dev/label/disk7

Массив живёт нормально, теперь мы выдёргиваем disk1 и откладываем в сторону.

Перегружаем сервер и смотрим в лог.
GEOM: da0: corrupt or invalid GPT detected.
GEOM: da0: GPT rejected -- may not be recoverable.
GEOM: da1: corrupt or invalid GPT detected.
GEOM: da1: GPT rejected -- may not be recoverable.
GEOM: da2: corrupt or invalid GPT detected.
GEOM: da2: GPT rejected -- may not be recoverable.
GEOM: da3: corrupt or invalid GPT detected.
GEOM: da3: GPT rejected -- may not be recoverable.
GEOM: da4: corrupt or invalid GPT detected.
GEOM: da4: GPT rejected -- may not be recoverable.
GEOM: da5: corrupt or invalid GPT detected.
GEOM: da5: GPT rejected -- may not be recoverable.
GEOM: da6: corrupt or invalid GPT detected.
GEOM: da6: GPT rejected -- may not be recoverable.
GEOM: label/disk0: corrupt or invalid GPT detected.
GEOM: label/disk0: GPT rejected -- may not be recoverable.
GEOM: label/disk2: corrupt or invalid GPT detected.
GEOM: label/disk2: GPT rejected -- may not be recoverable.
GEOM: label/disk3: corrupt or invalid GPT detected.
GEOM: label/disk3: GPT rejected -- may not be recoverable.
GEOM: label/disk4: corrupt or invalid GPT detected.
GEOM: label/disk4: GPT rejected -- may not be recoverable.
GEOM: label/disk5: corrupt or invalid GPT detected.
GEOM: label/disk5: GPT rejected -- may not be recoverable.
GEOM: label/disk6: corrupt or invalid GPT detected.
GEOM: label/disk6: GPT rejected -- may not be recoverable.
GEOM: label/disk7: corrupt or invalid GPT detected.
GEOM: label/disk7: GPT rejected -- may not be recoverable.
da7 at umass-sim0 bus 0 scbus2 target 0 lun 0
da7: <JetFlash Transcend 1GB 8.07> Removable Direct Access SCSI-2 device
da7: 40.000MB/s transfers
da7: 963MB (1972224 512 byte sectors: 64H 32S/T 963C)
Trying to mount root from ufs:/dev/ufs/FBSDUSB
GEOM: da0: corrupt or invalid GPT detected.
GEOM: da0: GPT rejected -- may not be recoverable.
GEOM: da1: corrupt or invalid GPT detected.
GEOM: da1: GPT rejected -- may not be recoverable.
GEOM: label/disk2: corrupt or invalid GPT detected.
GEOM: label/disk2: GPT rejected -- may not be recoverable.
GEOM: da2: corrupt or invalid GPT detected.
GEOM: da2: GPT rejected -- may not be recoverable.
GEOM: label/disk3: corrupt or invalid GPT detected.
GEOM: label/disk3: GPT rejected -- may not be recoverable.
GEOM: da3: corrupt or invalid GPT detected.
GEOM: da3: GPT rejected -- may not be recoverable.
GEOM: label/disk4: corrupt or invalid GPT detected.
GEOM: label/disk4: GPT rejected -- may not be recoverable.
GEOM: da4: corrupt or invalid GPT detected.
GEOM: da4: GPT rejected -- may not be recoverable.
GEOM: label/disk5: corrupt or invalid GPT detected.
GEOM: label/disk5: GPT rejected -- may not be recoverable.
GEOM: da5: corrupt or invalid GPT detected.
GEOM: da5: GPT rejected -- may not be recoverable.

Но при всей ругани массив на поверку оказывается живой. с живой структурой и статусом DEGRADED, что намного лучше чем в первом случае.
backupstorage# zpool status
  pool: storage
 state: DEGRADED
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://www.sun.com/msg/ZFS-8000-9P
 scrub: none requested
config:

        NAME             STATE     READ WRITE CKSUM
        storage          DEGRADED     0     0     0
          raidz1         DEGRADED     0     0     0
            label/disk0  ONLINE       0     0     0
            label/disk1  REMOVED      0    94     0
            label/disk2  ONLINE       0     0     0
            label/disk3  ONLINE       0     0     0
            label/disk4  ONLINE       0     0     0
            label/disk5  ONLINE       0     0     0
            label/disk6  ONLINE       0     0     0
            label/disk7  ONLINE       0     0     0

errors: No known data errors
====================

Теперь мы зануляем диск который мы вытащили и вставим его обратно в систему.
Метка на диске записана в самом конце диска, поэтому штатное зануление начала диска нам ничем не поможет. придётся или нулить конец или просто диск целиком. Всё зависит от наличия у вас времени.
mpt0: mpt_cam_event: 0x16
mpt0: mpt_cam_event: 0x12
mpt0: mpt_cam_event: 0x16
da8 at mpt0 bus 0 scbus0 target 1 lun 0
da8: <ATA Hitachi HDT72101 A31B> Fixed Direct Access SCSI-5 device
da8: 300.000MB/s transfers
da8: Command Queueing enabled
da8: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)

Даём новому диску метку «disk8» и пытаемся заменить «умерший» диск новым.
backupstorage# ls /dev/label/
disk0   disk2   disk3   disk4   disk5   disk6   disk7   disk8

backupstorage# zpool replace storage label/disk1 label/disk8
cannot replace label/disk1 with label/disk8: label/disk8 is busy
backupstorage# zpool replace -f storage label/disk1 label/disk8
cannot replace label/disk1 with label/disk8: label/disk8 is busy

Система отказывается менять нам диск ссылаясь на его занятость. Заменить «умерший» диск можно только прямым именем устройства. Почему так сделано, я до конца не понял. Отбрасываем затею замены меток на новом диске и пробуем просто дать метку «disk1» новому диску.
backupstorage# glabel label disk1 da8

Теперь нам нужно сказать, что диск у нас вернулся в строй.
backupstorage# zpool online storage label/disk1
backupstorage# zpool status
  pool: storage
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://www.sun.com/msg/ZFS-8000-9P
 scrub: resilver completed after 0h0m with 0 errors on Wed Nov 25 18:29:17 2009
config:

        NAME             STATE     READ WRITE CKSUM
        storage          ONLINE       0     0     0
          raidz1         ONLINE       0     0     0
            label/disk0  ONLINE       0     0     0  6.50K resilvered
            label/disk1  ONLINE       0    94     1  10.5K resilvered
            label/disk2  ONLINE       0     0     0  6K resilvered
            label/disk3  ONLINE       0     0     0  3.50K resilvered
            label/disk4  ONLINE       0     0     0  6.50K resilvered
            label/disk5  ONLINE       0     0     0  6.50K resilvered
            label/disk6  ONLINE       0     0     0  5.50K resilvered
            label/disk7  ONLINE       0     0     0  3K resilvered

errors: No known data errors

Всё встаёт на свои места и после синхронизации можно сбросить статус пула на нормальный.
А вот тут начинается проблема. Так как метка диска сделанная glabel пишется в конец диска, то zfs в принципе не знает ничего о том, где она записана. И при полном заполнении диска перетирает эту метку. Диску в массиве присваивается физическое имя и мы возвращаемся к пункту 1 наших проблем.

Решение проблемы
Решение проблемы оказалось немного банальным и простым. Давным давно FreeBSD стала уметь делать GPT разделы на дисках больших объёмов. В FreeBSD 7.2 именование GPT разделов не работало и доступ к ним осуществлялся по прямому имени устройства /dev/da0p1(пример для первой партиции GPT)
В FreeBSD 8.0 в систему GPT меток было внесено изменение. И теперь GPT разделы можно именовать и обращаться к ним как к виртуальным устройствам через /dev/gpt/меткараздела.

Всё что нам реально необходимо сделать — это проименовать разделы на дисках и собрать из них массив. Как это сделать написано в ZFS Boot Howto которое очень быстро гуглится.
backupstorage# gpart create -s GPT ad0
backupstorage# gpart add -b 34 -s 1953525101 -i 1 -t freebsd-zfs -l disk0 ad0
backupstorage# gpart show
=>        34  1953525101  da0  GPT  (932G)
          34  1953525101    1  freebsd-zfs  (932G)
backupstorage# gpart show -l
=>        34  1953525101  da0  GPT  (932G)
          34  1953525101    1  disk0  (932G)
backupstorage# ls /dev/gpt
disk0

После создания GPT раздела по gpart show можно посмотреть где начинается и где заканчивается область данных на диске. Далее мы создаём этот раздел и даём ему метку «disk0».
Проделываем эту операцию для всех дисков в системе и собираем из полученных разделов массив.
backupstorage# zpool status -v
  pool: storage
 state: ONLINE
 scrub: none requested
config:

        NAME           STATE     READ WRITE CKSUM
        storage        ONLINE       0     0     0
          raidz1       ONLINE       0     0     0
            gpt/disk0  ONLINE       0     0     0
            gpt/disk1  ONLINE       0     0     0
            gpt/disk2  ONLINE       0     0     0
            gpt/disk3  ONLINE       0     0     0
            gpt/disk4  ONLINE       0     0     0
            gpt/disk5  ONLINE       0     0     0
            gpt/disk6  ONLINE       0     0     0
            gpt/disk7  ONLINE       0     0     0

errors: No known data errors

Сервер спокойно переживает любые перезагрузки и перестановку дисков, а также их замену с той-же меткой. Скорость работы данного массива по сети достигает 70-80 мегабайт в секунду. Локальная скорость записи на массив в зависимости от заполняемости буферов доходит до 200 мегабайт в секунду.

PS: при использовании gpt меток натолкнулся на странный глюк, что система не видела новую метку на диске, но потом это само собой прошло.
PPS: энтузиастам которые пробуют запустить FreeBSD 8.0 с флешки(если это еще не починили) — пригодится вот такой dirty hack.
Index: sys/kern/vfs_mount.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_mount.c,v
retrieving revision 1.308
diff -u -r1.308 vfs_mount.c
--- sys/kern/vfs_mount.c 5 Jun 2009 14:55:22 -0000 1.308
+++ sys/kern/vfs_mount.c 29 Sep 2009 17:08:25 -0000
@@ -1645,6 +1645,9 @@
options = NULL;
+ /* NASTY HACK: wait for USB sticks to appear */
+ pause("usbhack", hz * 10);
+
root_mount_prepare();
mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount),

В новом USB стеке при загрузке ядра USB устройства не всегда определяются вовремя и возникает ошибка при монтировании разделов системы.
Данный хак выставляет в системе таймаут в 10 секунд для ожидания готовности USB накопителя.

PPPS: если будут вопросы — задавайте.

Настройки loader.conf для машины с 2мя гигабайтами памяти.
vm.kmem_size=«1536M»
vm.kmem_size_max=«1536M»
vfs.zfs.arc_max=«384M»


© Aborche 2009
Tags:
Hubs:
Total votes 39: ↑36 and ↓3+33
Comments45

Articles