데이터베이스 마이그레이션 실행하기 (Running database migrations)
LiteFS에서 데이터베이스 마이그레이션을 실행하는 방법을 알려드려요. LiteFS는 단일 작성자(single-writer) 시스템이라 primary 노드만 데이터베이스에 쓸 수 있어요. auto-promotion과 write forwarding 두 가지 방식으로 마이그레이션을 처리할 수 있어요.
출처: 문서
본문
개요 (Overview)
LiteFS는 단일 작성자 시스템이므로 primary 노드만 데이터베이스에 쓸 수 있어요. 애플리케이션의 새 버전을 배포할 때 데이터베이스 마이그레이션을 실행해야 할 가능성이 높지만, 처음 배포되는 노드가 반드시 primary 노드가 되지는 않아요.
노드가 시작될 때 마이그레이션을 수행하는 데는 두 가지 옵션이 있어요: auto-promotion과 write forwarding.
자동 승격 (Auto-promotion)
배포할 때 마이그레이션을 실행하는 권장 방법은, candidate 노드가 클러스터에 연결되고 sync가 완료된 후 스스로 primary로 승격되도록 하는 거예요. 이는 구성에서 lease.promote 필드를 true로 설정한 다음 exec 명령 중 하나로 마이그레이션을 실행하면 돼요.
lease:
candidate: ${FLY_REGION == PRIMARY_REGION}
promote: true
exec:
- cmd: "rails db:migrate"
if-candidate: true
- cmd: "rails server"
이 예시 litefs.yml 구성에서는 리전(FLY_REGION)이 앱의 primary 리전(PRIMARY_REGION)과 같은 노드를 표시하고 있어요. 시작 시 그 노드들은 현재 primary 노드에 primary 인계(handoff)를 요청하고 스스로 primary가 돼요.
승격된 후에는, LiteFS가 candidate 노드에서 rails db:migrate 명령을 실행해요. 그런 다음 모든 노드에서 rails server를 실행해요.
마이그레이션은 각 candidate 노드에서 실행되므로 멱등적(idempotent)이어야 해요. 또한 replica 노드는 앱의 새 배포가 완료되기 전에 데이터베이스 업데이트를 받을 수 있으므로, 애플리케이션이 다음 버전의 데이터베이스 스키마에 대해 실행되는 것도 처리해야 해요.
run 명령 사용하기
배포와 별도로 마이그레이션을 수행하려면 candidate 노드에 로그인하고 -promote 플래그와 함께 litefs run을 사용할 수 있어요:
litefs run -promote -- /path/to/my_migration.sh
이렇게 하면 주어진 스크립트를 실행하기 전에 primary 인계를 수행해요.
쓰기 포워딩 (Write forwarding)
모든 LiteFS 노드는 primary 노드에서 쓰기를 중지하고 일시적으로 로컬 노드에서 쓰기를 수행할 수도 있어요. 그런 다음 이 변경사항은 primary 노드로 다시 포워딩되고 나머지 클러스터로 전파돼요.
원격 쓰기를 수행하려면 litefs run 명령과 -with-halt-lock-on 플래그를 사용해 잠그고 싶은 데이터베이스를 지정하면 돼요.
litefs run -with-halt-lock-on /litefs/db -- bin/rails db:migrate
이 명령은 primary 노드에 쓰는 것보다 느리므로, 작고 드문 트랜잭션을 위한 것이에요. HALT 잠금은 replica가 primary를 영구적으로 잠그지 않도록 30초로 제한된 후 자동으로 해제된다는 점을 알아두세요.
litefs-go 리포지토리에서 클라이언트 라이브러리의 참조 구현을 찾을 수 있어요.