Schlagwort-Archive: linux

Hetzner: SSD austauschen (Software-Raid)

Vorab: Wenn du eine SSD austauschen lassen möchtest, sichere vorher deine Daten!

Beim Hardware-Monitoring ist aufgefallen, dass eine SSD defekt ist (/dev/nvme1n0):

root@Summer ~ # smartctl -x /dev/nvme1n0
smartctl 6.6 2016-05-31 r4324 [x86_64-linux-4.15.0-91-generic] (local build)
Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Number:                       SAMSUNG MZVLB1T0HALR-00000
Serial Number:                      S3W6NX0M418294
Firmware Version:                   EXA7301Q
PCI Vendor/Subsystem ID:            0x144d
IEEE OUI Identifier:                0x002538
Total NVM Capacity:                 1,024,209,543,168 [1.02 TB]
Unallocated NVM Capacity:           0
Controller ID:                      4
Number of Namespaces:               1
Namespace 1 Size/Capacity:          1,024,209,543,168 [1.02 TB]
Namespace 1 Utilization:            357,733,105,664 [357 GB]
Namespace 1 Formatted LBA Size:     512
Local Time is:                      Mon Apr  6 13:09:45 2020 CEST
Firmware Updates (0x16):            3 Slots, no Reset required
Optional Admin Commands (0x0017):   Security Format Frmw_DL *Other*
Optional NVM Commands (0x001f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat
Maximum Data Transfer Size:         512 Pages
Warning  Comp. Temp. Threshold:     81 Celsius
Critical Comp. Temp. Threshold:     82 Celsius

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     7.02W       -        -    0  0  0  0        0       0
 1 +     6.30W       -        -    1  1  1  1        0       0
 2 +     3.50W       -        -    2  2  2  2        0       0
 3 -   0.0760W       -        -    3  3  3  3      210    1200
 4 -   0.0050W       -        -    4  4  4  4     2000    8000

Supported LBA Sizes (NSID 0x1)
Id Fmt  Data  Metadt  Rel_Perf
 0 +     512       0         0

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: FAILED!
- NVM subsystem reliability has been degraded

SMART/Health Information (NVMe Log 0x02, NSID 0xffffffff)
Critical Warning:                   0x04
Temperature:                        38 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    14%
Data Units Read:                    47,945,073 [24.5 TB]
Data Units Written:                 90,573,679 [46.3 TB]
Host Read Commands:                 2,105,427,344
Host Write Commands:                621,326,417
Controller Busy Time:               9,459
Power Cycles:                       17
Power On Hours:                     1,757
Unsafe Shutdowns:                   3
Media and Data Integrity Errors:    3
Error Information Log Entries:      6
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Temperature Sensor 1:               38 Celsius
Temperature Sensor 2:               65 Celsius

Error Information (NVMe Log 0x01, max 64 entries)
Num   ErrCount  SQId   CmdId  Status  PELoc          LBA  NSID    VS
  0          6     0  0x001b  0x4004      -            0     1     -
  1          5     0  0x001b  0x4004      -            0     -     -
  2          4     0  0x0013  0x4004      -            0     -     -

Erkennbar an dem SMART overall-health self-assessment test result: FAILED!

Zusammensetzung des Raids

Wie sich das Raid zusammensetzt, kann so nachvollzogen werden:

root@Summer ~ # cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [ra                                                                                                                                                             id10]
md0 : active raid1 nvme1n1p1[1] nvme0n1p1[0]
      33520640 blocks super 1.2 [2/2] [UU]

md2 : active raid1 nvme1n1p3[1] nvme0n1p3[0]
      965991744 blocks super 1.2 [2/2] [UU]
      bitmap: 5/8 pages [20KB], 65536KB chunk

md1 : active raid1 nvme1n1p2[1] nvme0n1p2[0]
      523264 blocks super 1.2 [2/2] [UU]

root@Summer ~ # mdadm --detail /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Thu Apr  2 10:05:08 2020
        Raid Level : raid1
        Array Size : 33520640 (31.97 GiB 34.33 GB)
     Used Dev Size : 33520640 (31.97 GiB 34.33 GB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

       Update Time : Mon Apr 20 09:07:59 2020
             State : clean
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : resync

              Name : rescue:0
              UUID : cac65013:57c54787:2f8ff4fa:81936179
            Events : 34

    Number   Major   Minor   RaidDevice State
       0     259        1        0      active sync   /dev/nvme0n1p1
       1     259        5        1      active sync   /dev/nvme1n1p1
root@Summer ~ # mdadm --detail /dev/md1
/dev/md1:
           Version : 1.2
     Creation Time : Thu Apr  2 10:05:08 2020
        Raid Level : raid1
        Array Size : 523264 (511.00 MiB 535.82 MB)
     Used Dev Size : 523264 (511.00 MiB 535.82 MB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

       Update Time : Wed Apr  8 04:59:04 2020
             State : clean
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : resync

              Name : rescue:1
              UUID : ee86009b:df03234e:95193d67:9be88f4d
            Events : 48

    Number   Major   Minor   RaidDevice State
       0     259        3        0      active sync   /dev/nvme0n1p2
       1     259        6        1      active sync   /dev/nvme1n1p2
root@Summer ~ # mdadm --detail /dev/md2
/dev/md2:
           Version : 1.2
     Creation Time : Thu Apr  2 10:05:08 2020
        Raid Level : raid1
        Array Size : 965991744 (921.24 GiB 989.18 GB)
     Used Dev Size : 965991744 (921.24 GiB 989.18 GB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

     Intent Bitmap : Internal

       Update Time : Mon Apr 20 09:38:16 2020
             State : clean
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : bitmap

              Name : rescue:2
              UUID : 1078b64b:e2e40a4e:59d44f2f:87fe237c
            Events : 2472

    Number   Major   Minor   RaidDevice State
       0     259        4        0      active sync   /dev/nvme0n1p3
       1     259        7        1      active sync   /dev/nvme1n1p3

Es gibt somit folgenden Aufbau:

  • /dev/md0
    • /dev/nvme0n1p1
    • /dev/nvme1n1p1
  • /dev/md1
    • /dev/nvme0n1p2
    • /dev/nvme1n1p2
  • /dev/md2
    • /dev/nvme0n1p3
    • /dev/nvme1n1p3

Da das Laufwerk /dev/nvme1n1 defekt ist, muss ich also aus dem jeweiligen Array (/dev/md0, /dev/md1 und /dev/md2) die jeweiligen Partitionen entfernen: z.B.mdadm /dev/md0 -r /dev/nvme1n1p1

Doch bevor ich die Partition entfernen kann, muss ich dem Raid in meinem Fall mitteilen, dass die Partitionen in einen fehlerhaften Zustand sind, was mit diesem Befehl gemacht wird: mdadm --manage /dev/md0 --fail /dev/nvme1n1p1 Das Raid hatte nämlich noch nicht mitbekommen, dass die Festplatte fehlerhaft ist (bei cat /proc/mdstat sind die beiden Partitionen pro Array als (U = Up, _ = Down) markiert: [UU]).

Entfernen vorbereiten

root@Summer ~ # mdadm --manage /dev/md0 --fail /dev/nvme1n1p1
mdadm: set /dev/nvme1n1p1 faulty in /dev/md0
root@Summer ~ # mdadm --manage /dev/md1 --fail /dev/nvme1n1p2
mdadm: set /dev/nvme1n1p2 faulty in /dev/md1
root@Summer ~ # mdadm --manage /dev/md2 --fail /dev/nvme1n1p3mdadm --manage /dev                                                                                                                                                             /md2 --fail /dev/nvme1n1p3^C
root@Summer ~ # mdadm --manage /dev/md2 --fail /dev/nvme1n1p3
mdadm: set /dev/nvme1n1p3 faulty in /dev/md2
root@Summer ~ # cat /proc/mdstat                                                                                                                                                                                                             Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [ra                                                                                                                                                             id10]
md0 : active raid1 nvme1n1p1[1](F) nvme0n1p1[0]
      33520640 blocks super 1.2 [2/1] [U_]

md2 : active raid1 nvme1n1p3[1](F) nvme0n1p3[0]
      965991744 blocks super 1.2 [2/1] [U_]
      bitmap: 5/8 pages [20KB], 65536KB chunk

md1 : active raid1 nvme1n1p2[1](F) nvme0n1p2[0]
      523264 blocks super 1.2 [2/1] [U_]

unused devices: <none>

Partitionen aus Raid entfernen

Nun können die Festplatten aus den drei Arrays entfernt werden:

root@Summer ~ # mdadm /dev/md0 -r /dev/nvme1n1p1
mdadm: hot removed /dev/nvme1n1p1 from /dev/md0
root@Summer ~ # mdadm /dev/md1 -r /dev/nvme1n1p2
mdadm: hot removed /dev/nvme1n1p2 from /dev/md1
root@Summer ~ # mdadm /dev/md2 -r /dev/nvme1n1p3
mdadm: hot removed /dev/nvme1n1p3 from /dev/md2

Der Austausch

Der Austausch der Hardware hat nach dem Abschicken des Formulars im Hetzner Robot wenige Minuten gedauert.

Neue Festplatte vorbereiten

Ich bin davon ausgegangen, dass die Bezeichnungen der Festplatten /dev/nvme0n1 bzw. /dev/nvme1n1 beim Austausch gleich bleibt, das war hier jetzt aber nicht der Fall, denn im Raid war plötzlich /dev/nvme1n1 eingebunden (und nicht mehr /dev/nvme0n1 wie vor dem Austausch):

root@Summer ~ # cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 nvme1n1p1[0]
      33520640 blocks super 1.2 [2/1] [U_]

md2 : active raid1 nvme1n1p3[0]
      965991744 blocks super 1.2 [2/1] [U_]
      bitmap: 8/8 pages [32KB], 65536KB chunk

md1 : active raid1 nvme1n1p2[0]
      523264 blocks super 1.2 [2/1] [U_]

unused devices: <none>

Neue Festplatte finden

Um diesen Verdacht zu bestätigen, schaute ich mir die Festplatten und deren Usage an (/dev/nvme0n1 hat weniger Festplattenspeicher verbraucht, was dafür spricht, dass das die neue Festplatte ist):

root@Summer ~ # nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1     S3W6NX0M910966       SAMSUNG MZVLB1T0HALR-00000               1          80.42  GB /   1.02  TB    512   B +  0 B   EXA7301Q
/dev/nvme1n1     S3W6NX0M418297       SAMSUNG MZVLB1T0HALR-00000               1         312.46  GB /   1.02  TB    512   B +  0 B   EXA7301Q

Sicherheitshalber schaute ich noch, wie die Partitionstabellen der beiden Festplatten aussehen:

root@Summer ~ # sfdisk --dump /dev/nvme1n1
label: dos
label-id: 0x30c08aef
device: /dev/nvme1n1
unit: sectors

/dev/nvme1n1p1 : start=        2048, size=    67108864, type=fd
/dev/nvme1n1p2 : start=    67110912, size=     1048576, type=fd
/dev/nvme1n1p3 : start=    68159488, size=  1932247728, type=fd


root@Summer ~ # sfdisk --dump /dev/nvme0n1
sfdisk: /dev/nvme0n1: does not contain a recognized partition table

Und nun war klar, dass /dev/nvme0n1 ohne Partitionstabelle die neue Festplatte ist.

Partitionstabellen kopieren

In einem Raid müssen die Partitionstabellen der jeweiligen Festplatten gleich sein, mit folgendem Befehl kopierte ich die Partitionstabelle von /dev/nvme1n1 (nicht getauscht) auf /dev/nvme0n1 (getauscht).

root@Summer ~ # sfdisk -d /dev/nvme1n1 | sfdisk /dev/nvme0n1
Checking that no-one is using this disk right now ... OK

Disk /dev/nvme0n1: 953.9 GiB, 1024209543168 bytes, 2000409264 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Created a new DOS disklabel with disk identifier 0x30c08aef.
/dev/nvme0n1p1: Created a new partition 1 of type 'Linux raid autodetect' and of size 32 GiB.
/dev/nvme0n1p2: Created a new partition 2 of type 'Linux raid autodetect' and of size 512 MiB.
/dev/nvme0n1p3: Created a new partition 3 of type 'Linux raid autodetect' and of size 921.4 GiB.
/dev/nvme0n1p4: Done.

New situation:
Disklabel type: dos
Disk identifier: 0x30c08aef

Device         Boot    Start        End    Sectors   Size Id Type
/dev/nvme0n1p1          2048   67110911   67108864    32G fd Linux raid autodetect
/dev/nvme0n1p2      67110912   68159487    1048576   512M fd Linux raid autodetect
/dev/nvme0n1p3      68159488 2000407215 1932247728 921.4G fd Linux raid autodetect

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Neue Partitionen zum Raid hinzufügen

Als nächster Schritt können die Partitionen zum Raid hinzugefügt werden_

root@Summer ~ # mdadm /dev/md0 -a /dev/nvme0n1p1
mdadm: added /dev/nvme0n1p1
root@Summer ~ # mdadm /dev/md1 -a /dev/nvme0n1p2
mdadm: added /dev/nvme0n1p2
root@Summer ~ # mdadm /dev/md2 -a /dev/nvme0n1p3
mdadm: added /dev/nvme0n1p3

Raid Synchronisierung prüfen

Nun synchronisiert sich das Raid, was bei mir (1 TB-Festplatte) etwa 1,5 Stunden dauert:

root@Summer ~ # cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 nvme0n1p1[2] nvme1n1p1[0]
      33520640 blocks super 1.2 [2/1] [U_]
      [====>................]  recovery = 24.8% (8315648/33520640) finish=2.0min speed=203572K/sec

md2 : active raid1 nvme0n1p3[2] nvme1n1p3[0]
      965991744 blocks super 1.2 [2/1] [U_]
        resync=DELAYED
      bitmap: 8/8 pages [32KB], 65536KB chunk

md1 : active raid1 nvme0n1p2[2] nvme1n1p2[0]
      523264 blocks super 1.2 [2/1] [U_]
        resync=DELAYED

unused devices: <none>

Bootloader installieren

Abschließend muss auf der getauschten Festplatte der Bootloader (Grub2) installiert werden:

root@Summer ~ # grub-install /dev/nvme0n1
Installing for i386-pc platform.
grub-install: warning: Couldn't find physical volume `(null)'. Some modules may be missing from core image..
grub-install: warning: Couldn't find physical volume `(null)'. Some modules may be missing from core image..
Installation finished. No error reported.

Abschließend

Ich bin wirklich kein Linx-Freak und habe großen Respekt vor solch einen Eingriff. Zudem hatte ich die Befürchtung, dass das System nicht bootet und ich ins Rescue komme. Das war zum Glück nicht der Fall, weil ich vor dem Austausch die Festplatten korrekt aus dem Raid-Array entfernt habe.

Da ich aber die Daten gesichert hatte, war ich auf der sicheren Seite und hätte die auf dem Server laufenden Dienste bei einem Fehlschlag woanders eingerichtet. Mir geholfen haben folgende Seiten:

In eigener Sache: Serverumzug erfolgreich

Dieses Blog ist gestern sehr reibungslos auf einen neuen, eigenen Server umgezogen. Da macht sich der Domainmanager auf Domainfactory bezahlt – dort einfach die Nameserver-Einträge ändern und nach ein paar Stunden läuft die Domain bereits auf dem neuen Server. Das einzig Problematische beim Umzug war, dass die Daten über eine DSL light-Verbindung übertragen werden mussten, das konnte schon mal etwas dauern.

[blackbirdpie id=“97360527432482816″]

An dieser Stelle möchte ich mich bei Sebastian bedanken, der mein Blog trotz des immensen Traffics (Sebastian: „Was machst du eigentlich auf Freakcommander? Ist das ’ne Tauschbörse?„) kostenlos gehostet hat.

Der Grund für den Umzug ist relativ naheliegend: Zum Einen ist der VServer bei Strato mit 7,90 EUR pro Monat erschwinglich. Zum Anderen habe ich nun volle Kontrolle über den Server und kann damit machen, was ich will *muuhhahaarrr* ;o)

MySQL-Import und pdflush

Vermutlich kommt jeder in gewissen Abständen an einen Punkt, an dem man absolutes Neuland betritt, da man mit seinem bisherigen Wissen nicht weiter kommt.

Das Problem

war, dass viele Datensätze (6 Mio) per PreparedStatements in eine Datenbank importiert werden müssen. An sich kann es kein Problem sein, 6 Mio Datensätze zu importieren, aber unser Server machte da nicht mit

  1. war das Wiki kurz nach Beginn des Datenimports nicht mehr erreichbar
  2. einige Zeit später machte der komplette Server die Grätsche

Wir mutmaßten, dass die Wiki-Datenbank auf irgendeine Weise mit dem Importvorgang in einen Konflikt gerät, da diese ja als erstes ausfiel. Dieser Verdacht war falsch, da lediglich die InnoDB der Wiki-Datenbank zum Ausfall führte. Nachdem das Wiki auf MyISAM umgestellt war, funktionierte das Wiki auch während des Imports problemlos.

Das zweite Problem blieb aber bestehen. Nach einigen Versuchen und der Installation von Diagnosetools stand fest, dass die Festplatte durch den pdflush Daemon so stark beansprucht wurde, dass es für andere Prozesse nicht mehr möglich war auf die Festplatte zuzugreifen.

Wir überlegten, die Einstellungen für den pdflush Daemon zu ändern, mir fiel aber vorher auf, dass mir bei der Programmierung des Imports ein Fehler unterlaufen war: Anstatt vor dem Import die Schlüssel zu deaktivieren

[code lang=’sql‘]ALTER TABLE … DISABLE KEYS[/code]

und nach dem Import die Schlüssel wieder zu aktivieren

[code lang=’sql‘]ALTER TABLE … ENABLE KEYS[/code]

waren durch einen Zeilenverrutscher die Schlüssel für eine Tabelle schon vor dem Import wieder aktiviert worden und genau das verursachte das Zusammenbrechen des Servers, weil die Indizes während des Imports neu berechnet werden mussten.