linux

4개의 디스크가 있는 mdadm RAID10을 RAID5로 마이그레이션하는 방법

Debian Buster에서 Linux의 mdadm을 기반으로 하는 소프트웨어 RAID10이 있습니다. 원래 RAID10이 최고의 성능을 가지고 있다는 것을 알았습니다. 하지만 더 많은 공간이 필요하고 쓰기 성능을 +50% 공간과 교환하는 데 동의합니다.

# 고양이 /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4]
md1 : active raid10 sdd1[5] sda1[4] sdb1[1] sdc1[2]
      3899738112 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
      bitmap: 3/30 pages [12KB], 65536KB chunk

unused devices: <none>

이 스토리지는 NFS를 통해 제공되며 이상적으로는 다운타임 없이 RAID를 변환할 수 있습니다. 예, 백업이 있고 장애가 중요하지 않지만 작동한다면 중단 없이 마이그레이션하지 않겠습니까?

프로세스를 설명하는 2012년 기사를 찾았습니다. 명령은 매우 올바른 것으로 판명되었습니다. 당시 작성자는 mdadm 유틸리티(또는 아마도 커널 드라이버)가 첫 번째 명령으로 시스템을 즉시 중단시키는 문제가 있었습니다. 이 문제는 그 이후로 수정된 것 같습니다.

https://www.tummy.com/blogs/2012/03/29/changing-a-raid-10-into-a-raid-5/

mdadm의 RAID10→RAID5에서 직접 경로가 없습니다. 대신 먼저 RAID0을 저하시켜야 합니다.

# mdadm --grow /dev/md1 --level=0 --raid-devices=2
mdadm: /dev/md1: could not set level to raid0

이것은 즉시 효과가 있었고 2개의 장치에 장애가 발생하여 어레이에서 제거되었습니다. 불행히도 RAID 레벨은 RAID0으로 설정되지 않았습니다. dmesg 는 다음을 보여주었습니다.

md/raid0:md1: All mirrors must be already degraded!
md: md1: raid0 would not accept array

문제는 sysfs 가 어레이 가 성능이 저하 되지 않은 것으로 보고했지만 실제로는 mdadmcat /proc/mdstat 가 올바르게 표시되었다는 것입니다.

# cat /sys/block/md1/md/degraded
0

NFS 서버를 중지하고, 파일 시스템을 마운트 해제하고, LUKS 장치를 닫고, RAID 어레이를 중지하고, RAID 어레이를 재조립하고 모든 서비스를 다시 시작하는 것과 같이 이 문제를 해결할 다른 방법을 찾지 못했습니다. 그 후 성능이 저하된 것으로 올바르게 보고되었으며 RAID0으로 변환될 수 있습니다.

그런 다음 RAID5를 사용하여 4개의 장치로 다시 늘릴 수 있습니다.

# mdadm --grow /dev/md1 --level=5 --raid-devices=5 --add /dev/sdb1 /dev/sdd1

이전과 달리 cat /proc/mdstat 는 진행 중인 "rebuild"가 아니라 "reshape"를 표시했습니다. 이것은 꽤 오랜 시간(약 10시간)이 걸렸고 시스템은 RAID10 재구축 중보다 훨씬 느리게 응답했습니다. 리빌드 시간을 위해 그대로 두었습니다.

reshape가 완료되어 RAID5가 깨끗하고 속도가 좋습니다. 측정할 때 실수를 했을 수도 있지만 읽기 속도가 이전에 기록했던 것보다 빠르고 쓰기 속도도 허용됩니다.

# 고양이 /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] 
md1 : active raid5 sdd1[5] sdb1[3] sda1[4] sdc1[7]
      5849607168 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]

unused devices: <none>

(면책 조항: 마이그레이션이 이미 완료되었을 때 전체 스토리가 작성되었습니다. 실제 명령과 오류 메시지를 설명하기 위해 신중하게 노력했지만 사소한 실수가 있을 수 있습니다. 전체 프로세스는 설명된 대로 작동했습니다.)




(아직) 테스트되지 않았지만(아래 단계에 대한 중요한 데이터를 신뢰하지 않음) 사용 가능한 공간이 증가하고 mdadm --grow 가 "RAID10 레이아웃이 성장 작업에 너무 복잡함"이라고 말하는 시나리오에 대한 아이디어는 다음과 같습니다.

  1. MD를 중지
  2. md의 각 파티션의 처음 몇 개의 MiB를 백업합니다(RAID 수퍼 블록이 각 파티션의 시작 부분 근처에 있다고 가정).
  3. 슈퍼 블록을 닦아
  4. 파티션을 사용하여 --assume-clean 을 사용하여 RAID5(또는 기타 RAID) 생성
  5. md의 각 파티션에 대한 스냅샷을 생성합니다(예: https://gist.github.com/jowagner/b36024636140ddf453c12eaf6e590b5d 참조 ).
  6. 2단계에서 파티션의 백업을 파티션의 스냅샷으로 복원합니다.
  7. 스냅샷에서 RAID10 조립
  8. dd 에서 RAID5로 모든 데이터를 추가합니다. 2개의 스트라이프 크기의 최소 공배수를 사용하는 것이 성능에 가장 좋지만 모든 블록 크기가 해야 합니다. 처음 몇 개의 읽기는 5단계에서 기록된 Copy-On-Write 데이터에서 가져오기 때문에 쓰기로 인해 손상되지 않습니다. 나머지 읽기는 각 파티션의 쓰기에서 안전 거리를 두고 있기 때문에 손상되지 않습니다(따라서 사용 가능한 공간이 증가하는 시나리오에 대한 이 아이디어의 제한).
  9. RAID10 중지
  10. 스냅샷 삭제

이것은 스냅샷이 스냅샷에 대한 쓰기를 COW 장치로 리디렉션하기만 하고 원본 장치에 대한 쓰기가 COW 장치에 저장될 이전 데이터의 복사본을 트리거하지 않는다고 가정합니다. 공간이 필요합니다).

또한 이전 RAID의 수퍼 블록이 각 파티션의 끝 근처에 있는 경우 3단계 전에 이러한 데이터도 백업해야 합니다. 검색할 적절한 위치와 데이터 양을 계산합니다. 몇 줄의 Python을 사용하고 싶지만 이를 수행할 수 있는 명령줄 도구가 있을 것입니다.