운영 환경을 망가뜨리지 않는 마이그레이션

마이그레이션이 로컬 환경에서는 완벽하게 작동합니다. 규모가 작아 보여서 금요일 오후 6시에 배포를 진행합니다. 그런데 배포가 멈춰버립니다. 혹은 더 최악의 상황으로, 800만 개의 행이 있는 테이블이 40초 동안 잠기면서 사이트가 다운됩니다.

마이그레이션은 운영 환경에서 다르게 동작합니다. 로컬 데이터베이스는 비어 있고 빠르지만, 운영 데이터베이스에는 실제 데이터와 활성 사용자가 있습니다.

운영 환경의 재앙을 피하려면 다음 규칙을 따르세요.

  • 항상 작동하는 down 메서드를 작성하세요 모든 마이그레이션에는 up 함수와 down 함수가 필요합니다. down 함수는 up 함수를 정확히 되돌려야 합니다. 롤백을 작성할 수 없다면 마이그레이션이 너무 복잡한 것입니다. 푸시하기 전에 로컬에서 migrate를 실행한 후 migrate:rollback을 실행하여 테스트하세요.

  • 기존 마이그레이션을 절대 수정하지 마세요 이전 마이그레이션 파일에서 컬럼 크기를 수정하고 싶을 수도 있습니다. 하지만 그렇게 하지 마세요. Laravel은 서버에서 해당 파일을 다시 실행하지 않습니다. 대신 구조를 변경하기 위한 새로운 마이그레이션을 생성하세요. 마이그레이션은 변경 사항의 기록입니다. 이전 장을 다시 쓰는 대신 새로운 장을 추가하는 것입니다.

  • nullable 또는 기본값을 사용하세요 기존 데이터가 있는 테이블에 NOT NULL 컬럼을 추가하면 오류가 발생합니다. 데이터베이스는 기존 행에 어떤 값을 넣어야 할지 알 수 없기 때문입니다.

대신 다음과 같은 방법을 사용하세요: • 새 컬럼을 nullable로 만듭니다. • 기본값을 설정합니다. • 컬럼이 필수(required)여야 한다면 세 단계로 진행하세요: nullable로 생성한 뒤, 데이터를 채우고, 그 다음 NOT NULL로 변경합니다.

  • 데이터 손실은 영구적입니다 dropColumn 명령은 데이터를 영구적으로 삭제합니다. 롤백을 통해 컬럼을 다시 만들 수는 있지만, 그 안의 데이터는 사라집니다. 컬럼을 삭제하기 전에 백업을 확인하세요. 더 안전한 방법은 먼저 코드에서 해당 컬럼의 사용을 중단하고, 몇 주를 기다린 다음 데이터베이스에서 제거하는 것입니다.

  • 스키마 변경과 데이터 업데이트를 분리하세요 마이그레이션 내부에서 User::all()을 실행하면 수백만 개의 행이 메모리에 로드되어 배포 중에 시스템이 다운될 수 있습니다. 마이그레이션 중에 반드시 데이터를 업데이트해야 한다면, chunkById를 사용하여 레코드를 작은 배치 단위로 처리하세요.

  • 파이프라인에서는 force 플래그를 사용하세요 Laravel이 확인을 요청하면 자동화된 배포 파이프라인이 멈춰버릴 수 있습니다. 배포 스크립트에는 다음 명령어를 사용하세요: php artisan migrate --force

  • 테이블 잠금(Table Lock)을 주의하세요 대규모 테이블의 컬럼을 변경하거나 인덱스를 추가하면 해당 테이블이 잠깁니다. 이는 서비스 중단(downtime)을 초래합니다. 매우 큰 테이블의 경우, 온라인 스키마 변경 도구를 찾아보거나 트래픽이 적은 시간에 변경 작업을 수행하세요.

푸시 전 체크리스트:down 메서드가 작동하는가? • 로컬에서 롤백을 테스트했는가? • 기존 마이그레이션을 수정하는 대신 새로운 마이그레이션을 생성하고 있는가? • 새 컬럼이 nullable이거나 기본값이 설정되어 있는가? • 컬럼을 삭제하기 전에 백업을 해두었는가?

Source: https://dev.to/denisgusto1/migrations-que-nao-quebram-em-producao-o-guia-que-ninguem-te-deu-363o