LoginSignup
2
1
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

RAID5 が崩壊した時のデータサルベージメモ

Last updated at Posted at 2024-01-07

概要

RAID5 を構成するディスク4台の内、1台が物理故障でアクセス不可となった結果、 RAID 内のデータに全くアクセスできなくなってしまった時のデータサルベージのメモです。通常、 RAID5 であればディスク1台の故障に耐えられるはずですが、1台の故障で何故か RAID が崩壊してしまいました。
似たような状況に陥った人の参考にしてもらったり、後学のために有識者の方からマサカリを投げてもらえればと思い記事にしておきます。

ちなみにこの記事を参考にして発生したいかなる損害も私は責任を負いません。全て自己責任にて実施してください。より確実にデータを復旧したい場合はおとなしくデータ復旧サービスに依頼しましょう。

環境

  • 自宅鯖 (NAS)
  • OpenMediaVault 5.6
  • ソフトウェア RAID (md-raid) による RAID5
  • RAID 内のファイルシステム: ext4

起きた事

初動

外出先で自宅鯖のサービスが稼働していないことに気づく。スマホから SSH で接続してみると RAID が I/O Error で停止していることが判明。その時の /proc/mdstat は次の通り。

# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md0 : active raid5 sdb[4](S) sdd[3](S) sda[0](S)
      29298917376 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/0] [____]
      bitmap: 11/73 pages [44KB], 65536KB chunk

unused devices: <none>

・・・なんかおかしいぞ・・・?

RAID のマウントポイントを確認してみるも、当たり前のように I/O Error となる。

自宅鯖のサービスはこの RAID の上にデータを保持しているため、 RAID の不調によってサービスも停止していると判断。以前のバージョンの OpenMediaVault を利用していた際に、 HDD エンクロージャーが急に切断される事象が多発した経験があり、それが再発した可能性を考える。ただ sdc が消えている点と残りの sda, sdb, sdd が全て (S) になっている点は気がかり・・・

スマホからではオペレーションしづらいので、 cat /proc/mdstat の結果だけをファイルに保存して systemctl reboot を実行。これで RAID が無事復旧することをお祈り・・・したんだけれども、一向に SSH がつながらない・・・

SSH がつながらず、外出先からは何もできなくなってしまったので、何も見なかったことにした。

■ この時点の振り返り

  • cat /proc/mdstat の結果を記録しておいたのは後から非常に役に立った。
    ほぼデフォルトのパラメータではあったが、復旧の際に確信をもってトライすることができた。
  • mdadm --detail /dev/md0 を実行し、その結果を記録しておくべきだった。
    致命的ではなかったが /proc/mdstat に出力されない情報をロストしてしまった。
  • mdadm --examine /dev/sda 等を実行し、その結果を記録しておくべきだった。
    この後、この時点では正常な HDD へのアクセスも I/O Error でできなくなっていたという思い込みで復旧を続けたが、今考えれば根拠が薄かったと思う。

状況確認(レスキューモード)

帰宅後に自宅鯖を見てみると、レスキューモードで起動していた。確認してみると RAID がスタートできておらず、 /etc/fstab に記載された RAID のデバイスをマウントできていないようだった。

この時の /proc/mdstat は次の通り。

# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md0 : inactive sdd[3](S) sda[0](S) sdb[4](S)
      29298917376 blocks super 1.2
       
unused devices: <none>

なんか表示がシンプルになってしまっている・・・

mdadm --detail /dev/md0 は次の通り。

# mdadm --detail /dev/md0 
/dev/md0:
           Version : 1.2
        Raid Level : raid0
     Total Devices : 3
       Persistence : Superblock is persistent

             State : inactive
   Working Devices : 3

              Name : openmediavault:volume1  (local to host openmediavault)
              UUID : 9e3ad5fb:c8e80c01:67ace5ae:2c2dcbf3
            Events : 7238835

    Number   Major   Minor   RaidDevice

       -       8        0        -        /dev/sda
       -       8       48        -        /dev/sdd
       -       8       16        -        /dev/sdb

ちょっとまって Raid Level : raid0 とか言ってるんですが?あなた RAID5 のはずですよね?

mdadm --examine /dev/sda は次の通り。

# mdadm --examine /dev/sda
/dev/sda:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x9
     Array UUID : 9e3ad5fb:c8e80c01:67ace5ae:2c2dcbf3
           Name : openmediavault:volume1  (local to host openmediavault)
  Creation Time : Sun Sep  3 20:56:35 2017
     Raid Level : raid5
   Raid Devices : 4

 Avail Dev Size : 19532611584 (9313.88 GiB 10000.70 GB)
     Array Size : 29298917376 (27941.63 GiB 30002.09 GB)
    Data Offset : 262144 sectors
   Super Offset : 8 sectors
   Unused Space : before=262056 sectors, after=0 sectors
          State : clean
    Device UUID : 89015277:ddf9ad4d:14e7af9e:ae8f37af

Internal Bitmap : 8 sectors from superblock
    Update Time : Fri Nov 24 13:23:54 2023
  Bad Block Log : 512 entries available at offset 72 sectors - bad blocks present.
       Checksum : 647fa998 - correct
         Events : 7238835

         Layout : left-symmetric
     Chunk Size : 512K

   Device Role : spare
   Array State : .... ('A' == active, '.' == missing, 'R' == replacing)

よかったこっちは Raid Level : raid5 になっている。ところで Device Role : spare ってなんで? Array State : .... ってヤバくない?あと bad blocks present. が良い味出してる。 /dev/sdb, /dev/sdd も似たような感じだった。流石に bad blocks present. はなかったけど。

smartctl -a /dev/sda は次の通り。

# smartctl -a /dev/sda
(中略)
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000b   100   100   016    Pre-fail  Always       -       0
  2 Throughput_Performance  0x0004   130   130   054    Old_age   Offline      -       108
  3 Spin_Up_Time            0x0007   165   165   024    Pre-fail  Always       -       409 (Average 389)
  4 Start_Stop_Count        0x0012   100   100   000    Old_age   Always       -       181
  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000a   100   100   067    Old_age   Always       -       0
  8 Seek_Time_Performance   0x0004   128   128   020    Old_age   Offline      -       18
  9 Power_On_Hours          0x0012   093   093   000    Old_age   Always       -       54596
 10 Spin_Retry_Count        0x0012   100   100   060    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       44
 22 Helium_Level            0x0023   100   100   025    Pre-fail  Always       -       100
192 Power-Off_Retract_Count 0x0032   094   094   000    Old_age   Always       -       7897
193 Load_Cycle_Count        0x0012   094   094   000    Old_age   Always       -       7897
194 Temperature_Celsius     0x0002   240   240   000    Old_age   Always       -       27 (Min/Max 20/65)
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age   Always       -       0
(後略)

稼働時間が54,596時間ってすごいな・・・6年以上動きっぱなし。いつ壊れても不思議ではない。他は過去に温度が65度まで到達したことがあるのと、 Spin_Up_Time が Average より遅くなっているのが気になるくらいかなぁ。

状況確認(障害 HDD)

自宅鯖をパワーオフして、 RAID 上に表示されなくなった /dev/sdc のディスクを別のマシンにつなぎなおす。

・・・うん、カッコンカッコン言って一向にアクセスできない。完全に物理故障だわコレ。めでたく3万円台(新品価格)の文鎮が完成しました。やったね!

この HDD は /dev/sda の HDD と同じタイミングで買ったものだから、6年以上稼働したようだ。天寿は全うしたと言ってもいいだろう。

そして、故障した /dev/sdc を接続しないまま自宅鯖の電源を入れなおしたところ、それまで /dev/sdd と認識されていた HDD が /dev/sdc と認識されるようになり、この後のデータ復旧のペースを落とすのであった・・・

状況整理

ここまで確認した内容から状況を整理してみる。

  • 自宅鯖が稼働している中、物理的に HDD が1つ故障した。
    • 故障したことにより、この HDD へのアクセスが刺さったままになった?
  • この故障に引っ張られて、正常な HDD へのアクセスもできなくなった?
    • HDD エンクロージャー (TS431U) で利用されているコントローラは、 lsusb で確認すると JMS567 だった。
    • もしかしたら HDD の故障に伴い、コントローラがすべての HDD の応答を返せない状況になってしまったのかもしれない。
  • そんなこんなで自宅鯖の RAID5 は崩壊したようだ。
  • 正常な HDD も I/O Error で読み書きができず、再起動後も RAID を開始できなかったので、正常な HDD の中には データが破損せずに確実に残っている ハズ。
    • 一部ダーティーキャッシュが同期されていないとかあるかもしれないけど、激しくディスクアクセスするようなシステムじゃないので可能性も影響も少。
    • ただ、正常な HDD に bad block があるとか言っているから、経年劣化により読みだせない領域等が無いかはちょっと心配。
  • この障害の10カ月ほど前に /dev/sdb のディスクが故障したことがある。
    • この時は RAID 自体に特に不具合なく、 HDD を交換しただけだった。
    • 1年で HDD が2本も故障した。やはり寿命か。
    • 正常な HDD もいつ壊れるかわからない。3本残った内の1本でも壊れればおしまい。
  • バックアップシステムは永遠の TBC (To be constructed) なので存在しない。
    • 奇跡的に手動でバックアップを取った HDD を見つけたけど、数年前のバックアップな上、データ容量的に一部のバックアップに留まっているので本当に最終手段。

データ復旧対応

バックアップ作成

という訳で何よりも最優先はバックアップの取得となる。あれこれ試行錯誤しているうちに、残っているデータを破壊してしまっては元も子もないし、正常な HDD もいつ寿命を迎えるかわからない・・・

幸いなことに、 Kubernetes のストレージとして使おうかなと思って買っておいた同型の HDD が丁度3本あったのでこれをバックアップへ転用することにする。

バックアップは確かこんな感じで取ったハズ。 Enter キーを押す前に「if と of を間違えたらアウト・・・」と5回ぐらいつぶやいてから実行したような気がする。

# dd if=/dev/sda of=/dev/sdX bs=1024M status=progress

HDD 1本あたり17時間くらい掛かったと記憶。大体160MB/sくらい。3本をシーケンシャルにバックアップすると2日以上掛かってしまう。ここは正常な HDD が故障しないようにと完全なお祈りタイムだ。

バックアップした HDD には、それぞれどの HDD のバックアップを取得したのかを付箋に書いて張っておく。

無事、正常な HDD 3本のバックアップを取れたので、この後は崩壊した RAID からデータをサルベージするための試行錯誤を行っていく。

データサルベージ

概要

結論から言うと、崩壊した RAID 内のデータにアクセスできるようになるまで障害発生から丸っと1か月かかった。だって30TBものデータ領域を持つ RAID の復旧だもの・・・データコピーだけでも時間がかかるし、それなりに機材の購入が必要で待ち時間が多かった。

いろいろ試行錯誤したが、最終的に採った戦略は次のように「仮想マシンで RAID5 の正常な Superblock を作成し、自宅鯖の HDD に移植する」方式にした。

  1. Proxmox VE でデータサルベージ用の仮想マシンを作成する。
  2. 10TB の仮想ディスクを4本作れて、スナップショットも取れるデータストアを用意する。
    • データストアのために別途 10TB の HDD を5本用意し、 ZFS で RAID0 を組んだ。
    • が、実際にスナップショットを取ろうとしたらディスク容量不足だったので、更に1本追加して計6本で約 60TB のデータストアを作った。
    • 当初はバックアップした HDD の内容を仮想ディスクにコピーして、そこから試行錯誤しようと思ったのでスナップショットを取れることが重要だった。
      • しかし、機材不調によりコピーに何度も失敗したのでこのやり方を止めた。
      • 最終的にスナップショットはあまり使わなかった。
  3. 10TB の仮想ディスクを4本作成する。
  4. 仮想マシンに 10TB の仮想ディスク4本を接続し、 md-raid で RAID5 を構成する。
  5. 仮想マシンの RAID5 のリビルド完了を待つ。
  6. リビルドが完了したら、3番目の HDD (自宅鯖で物理故障した /dev/sdc 相当) を remove する。
  7. 1, 2, 4番目の HDD (それぞれ自宅鯖の /dev/sda, /dev/sdb, /dev/sdd 相当) の RAID の superblock をダンプする。
  8. ダンプした superblock を自宅鯖にコピーし、 /dev/sda, /dev/sdb, /dev/sdd にそれぞれ書き込む。
  9. 自宅鯖の RAID を再開し、マウントする。

復旧用仮想環境構築

概要のこの辺の話。

  1. Proxmox VE でデータサルベージ用の仮想マシンを作成する。
  2. 10TB の仮想ディスクを4本作れて、スナップショットも取れるデータストアを用意する。
    • データストアのために別途 10TB の HDD を5本用意し、 ZFS で RAID0 を組んだ。

Proxmox VE は個人の検証環境として、今回障害が発生した自宅鯖とは別のマシンで既に運用中なので詳細は略。

ただ、 Proxmox VE は WebUI からは RAID0 のデータストアを構築できないようになっていたので注意が必要だった。 ZFS on Linux - Proxmox VE に記載されている通りにやればいいだけだったけれども。気が向けば別記事で書く。

仮想ディスク作成

概要のこの辺の話。

  1. 10TB の仮想ディスクを4本作成する。

まずは自宅鯖の HDD のディスクサイズを確認する。

# fdisk /dev/sda <<< p
(略)

Created a new DOS disklabel with disk identifier 0x3d6c764d.

Command (m for help): Disk /dev/sda: 9.1 TiB, 10000831348736 bytes, 19532873728 sectors
Disk model: 0EFAX-68LHPN0   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x3d6c764d

Command (m for help): 

10000831348736 bytes とあるので、これを 1,073,741,824 (1073741824 = 1024^3) で割る。丁度 9,314GiB となったけど、他のディスクでも割り切れるのかはわからない。

Proxmox VE にて仮想ディスク4本をそれぞれ計算した 9,314GiB として作成する。

復旧用 RAID 構築

概要のこの辺の話。

  1. 仮想マシンに 10TB の仮想ディスク4本を接続し、 md-raid で RAID5 を構成する。
  2. 仮想マシンの RAID5 のリビルド完了を待つ。

作成した仮想ディスクを、復旧用の仮想マシンに接続して仮想マシンを起動する。

仮想マシンが起動したら、 fdisk /dev/sdX <<< p と打って 10000831348736 bytes, 19532873728 sectors のあたりが一致していることを確認。仮想ディスクのデバイス名は自宅鯖のデバイス名と一致しないので混乱しないように整理しながら慎重に進めよう。

仮想ディスクのサイズに問題がなければ、 RAID を構築する。

# mdadm --create salvage --level=5 --raid-devices=4 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi1 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi2 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi3 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi4 --data-offset=131072

ここでは --data-offset=131072 の指定が肝だった。これは自宅鯖の正常な HDD を mdadm --examine /dev/sdX したときに出力された Data Offset : 262144 sectors の半分の値なのだが、どういう理由で --data-offset=262144 ではなく --data-offset=131072 なのかわかっていない。

このコマンドを実行した後、自動的にリビルドが開始される。

この間に mdadm --examine /dev/sdX を実行し、自宅鯖の HDD で確認した結果と比較して次の項目が一致していることを確認しておく。

  • Version : 1.2
  • Raid Level : raid5
  • Raid Devices : 4
  • Avail Dev Size : 19532611584 (9313.88 GiB 10000.70 GB)
  • Array Size : 29298917376 (27941.63 GiB 30002.09 GB)
  • Data Offset : 262144 sectors
  • Super Offset : 8 sectors
  • Internal Bitmap : 8 sectors from superblock
  • Layout : left-symmetric
  • Chunk Size : 512K

確認が終わったらあとはリビルドが完了するまで正座待機。

復旧用 RAID を障害機の状態に合わせる

概要のこの辺の話。

  1. リビルドが完了したら、3番目の HDD (自宅鯖で物理故障した /dev/sdc 相当) を remove する。

リビルドが完了したら、自宅鯖で障害が起きた HDD と同じナンバーの仮想ディスクを mdadm --remove する。私は初動で mdadm --detail /dev/md0 をする前に OS を再起動してしまったため、故障した HDD が本当に RAID の3番目のディスクか確証を持てていなかったが、 sda ~ sdd まで順番に認識されているだけと思い込むことにして作業を進めた。

仮想マシンで HDD を remove するコマンドは次の通り。 /dev/sdX の指定は障害が発生した HDD と仮想マシンのデバイス名の認識によって変わるので注意。

# mdadm --remove /dev/md/salvage /dev/sdX

仮想マシンで mdadm --detail /dev/md/salvage を実行し、意図した箇所の仮想ディスクが removed になっていれば OK. イメージとしてはこんな感じ。

    Number   Major   Minor   RaidDevice State
       0       8        0        0      active sync   /dev/sda
       1       8       16        1      active sync   /dev/sdb
       -       0        0        2      removed
       4       8       32        3      active sync   /dev/sdc

復旧用 RAID の Superblock をダンプ

概要のこの辺の話。

  1. 1, 2, 4番目の HDD (それぞれ自宅鯖の /dev/sda, /dev/sdb, /dev/sdd 相当) の RAID の superblock をダンプする。

RAID の Superblock をダンプする前にまずは RAID を停止しておきましょう。

# mdadm --stop /dev/md/salvage

RAID を停止したら dd コマンドで各仮想ディスクの RAID の Superblock をダンプしていく。ここでは、 sdX を仮想ディスクのデバイス名、 sdY を自宅鯖の対応する HDD のデバイス名とする。

# dd if=/dev/sdX of=salvage_raid_superblock_sdY.bin bs=12K count=1

これを remove した仮想ディスク以外の仮想ディスクに対して行う。

bs=12K となる理由はよくわかってない・・・ RAID superblock formats - Linux Raid Wiki によると、次のように記載されているので bs=4K が適切と思ったけど、それで作ったダンプファイルだと自宅鯖の HDD に書き込んでも mdadm --examine の結果が書き込む前と変わらなかったんだよね・・・

Sub-Version Superblock Position on Device
0.9 At the end of the device
1.0 At the end of the device
1.1 At the beginning of the device
1.2 4K from the beginning of the device

bs=12K とした理由はなんとなくの勘なんだけど、 bs=12287 としたときと bs=12288 としたときで mdadm --examine の結果が変わったのでそんなにハズレでもないのかなと思っている。

bs=12287 の時 (エラーになる)

# dd if=/dev/sdX of=salvage_raid_superblock_sdY.bin bs=12287 count=1
# mdadm --examine salvage_raid_superblock_sdX.bin
mdadm: No md superblock detected on salvage_raid_superblock_sdY.bin

bs=12288 の時 (結果が出力される)

# dd if=/dev/sdX of=salvage_raid_superblock_sdY.bin bs=12288 count=1
# mdadm --examine salvage_raid_superblock_sdY.bin
salvage_raid_superblock_sdX.bin:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x1
     Array UUID : c8b39bbf:bb058499:77cf0b3b:ec0bed37
           Name : raid-rebuild-test-02:salvage
(以下略)

自宅鯖の RAID をマウント

概要のこの辺の話。

  1. ダンプした superblock を自宅鯖にコピーし、 /dev/sda, /dev/sdb, /dev/sdd にそれぞれ書き込む。
  2. 自宅鯖の RAID を再開し、マウントする。

まずは仮想マシンでダンプした RAID の Superblock である salvage_raid_superblock_sdY.bin を全て自宅鯖に転送する。転送方法は scp でも ftp でも USB メモリでも何でもよい。

自宅鯖の RAID が停止していることを確認する。停止していなければ mdadm --stop /dev/md0 辺りで停止しておこう。

自宅鯖の RAID が停止したら、転送してきた RAID の Superblock を、 RAID を構成する正常な HDD にそれぞれダンプしていく。次のコマンドでは sdY が正常な HDD のデバイス名となる。

# dd if=salvage_raid_superblock_sdY.bin of=/dev/sdY

RAID の Superblock を正常な HDD にダンプした時点で勝手に RAID が開始されているかもしれない。私の環境ではいつの間にか RAID が開始されていた。この時の RAID のデバイス名は /dev/md127/dev/md/<mdadm --examine の Name の値> (この例だと /dev/md/raid-rebuild-test-02:salvage) になっているかもしれない。

試しにマウントしてみる。手に汗握る瞬間だ。

# mount /dev/md/raid-rebuild-test-02\:salvage /mnt

マウントできたのならひとまずおめでとう。でも安心するのはまだ早い。

試行錯誤や検証を行っている中で、 RAID5 を組みなおすときに HDD の順序を間違えたらどうなるか検証してみたことがあった。結果としては、「そもそもマウントができない」ケースと「マウントはできるがファイルが壊れている」ケースを確認できた。

つまりマウントができてもファイルが壊れていないことを確認するまでは安心できない。とりあえず数十MBクラスのファイルが壊れていないことを確認できればいいんじゃないだろうか。知らんけど。

データサルベージ

マウントができ、ファイルの破損がないことの確認までできたのなら後は良しなにデータを救い出していこう。

別 HDD や別マシンにコピー、あるいは故障した HDD の代わりを追加して RAID を完全復旧するのも良いでしょう。ただしここも無事に完了するまでお祈りタイムですがね!

まとめ

事前にやっておけばよかった事

  • しっかりと定期的にバックアップを取っておくこと

わからなかった事

  • 障害発生時に正常なディスクが全て Spare 扱いになってしまった理由がわからなかった。
    正常なディスクの I/O も止まってしまったのであれば、 Spare とマークする事すらできないはずではないのか?再起動後、レスキューモードに入った時点で書き込み可能になったとしても、正常な HDD が3本と故障した HDD が1本あるだけなのだから、 Spare とマークせずに普通に RAID を開始できるのではないだろうか・・・
  • mdadm --create する際に --data-offset=131072 と指定する必要があった理由がわからなかった。
    なぜ mdadm --examine で表示される Data Offset の半分の値なのか・・・
  • RAID の Superblock をダンプするのに bs=4K ではなく bs=12K (?) とする必要があった理由がわからなかった。

振り返り

  • RAID の中のデータを見れなくても、データは正常な HDD の中に確実に残っているという確信があったのはよかった。
    っていうかそれが無かったら諦めてた。
  • 富豪戦略を採ったせいで 10TB の HDD が12本もある逸般の誤家庭になってしまった。文鎮化した HDD も含めると14本。
    • なお、サルベージの為に購入した HDD は、新しく NAS を構築しそちらに組み込む模様。
    • そのうえで現行の NAS をバックアップに降格させることで、バックアップシステムは永遠の TBC (To be constructed) 問題を解決する予定。
  • 暫定的とはいえ、 HDD 6本の RAID0 を作った事と、更にその中に RAID5 を構築したことは我ながら意味不明すぎて笑った。
  • もうちょっとさっくりと記事を書くつもりが長くなってしまった。
  • echo idle > /sys/block/md0/md/sync_action ってやってれば一発で直ったんじゃないか説: linux - mdadm: drive replacement shows up as spare and refuses to sync - Server Fault

おしまい。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1