Skip to content

hotfix: 운영 notification FCM 컬럼 누락 복구 (develop)#2311

Closed
taejinn wants to merge 3 commits into
developfrom
hotfix/2309-notification-fcm-columns
Closed

hotfix: 운영 notification FCM 컬럼 누락 복구 (develop)#2311
taejinn wants to merge 3 commits into
developfrom
hotfix/2309-notification-fcm-columns

Conversation

@taejinn

@taejinn taejinn commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

⚡ 간단 요약

  • 문제: develop(stage)은 V236 적용 후 baseline으로 전환됐지만, production은 V236 없이 baseline으로 전환되어 notification의 FCM 컬럼 3개가 누락됐고 애플리케이션이 기동하지 못했습니다.
  • 해결: production 복구용 repeatable migration을 develop에도 반영합니다. stage에서는 컬럼이 이미 있어 아무 작업도 하지 않으며, 다음 release에서도 수정이 유지됩니다.

🔍 문제 발생 배경

  • FCM 전송 결과를 저장하기 위해 #2283에서 notification 테이블에 다음 컬럼을 추가하는 V236 migration이 반영되었습니다.
    • is_push_success
    • fcm_error_code
    • fcm_messaging_error_code
  • 당시 stage DB는 V236까지 적용됐지만, production DB는 이전 배포 상태인 V235에 머물러 있었습니다.
  • 이후 #2290에서 stage 스키마를 기준으로 V1__baseline_schema.sql을 생성하고 기존 V1–V236 migration을 실행 경로에서 제외했습니다. 따라서 새 V1 파일에는 세 컬럼이 포함되어 있지만, production의 실제 테이블에는 아직 존재하지 않는 상태가 됐습니다.
  • release: 2026.07.21 배포 #2308 배포를 위해 production의 Flyway history를 V1 BASELINE으로 전환했을 때, Flyway는 비어 있지 않은 DB에서 V1 SQL을 실행하지 않고 BASELINE 기록만 생성했습니다.
  • 그 결과 새 애플리케이션은 Flyway 이후 Hibernate schema validation 단계에서 missing column [fcm_error_code] in table [notification] 오류로 기동에 실패했습니다.

이 PR은 production 복구용 hotfix와 동일한 변경을 develop에도 반영해, 이후 release에서 수정이 유실되거나 서로 다른 migration 정책이 생기지 않도록 하기 위한 PR입니다.


🚨 원인 정리

이 문제는 V1 baseline 파일의 컬럼 정의가 잘못된 것이 아니라, baseline 생성 기준이었던 stage와 전환 대상인 production의 migration 적용 상태가 달랐던 것이 원인입니다.

  1. stage: 기존 V236 적용 완료 → FCM 컬럼 존재
  2. production: 기존 V235 → FCM 컬럼 미존재
  3. 새 V1 baseline: stage 스키마를 반영하므로 FCM 컬럼 포함
  4. 기존 production DB: baseline-on-migrate=true에 의해 V1 SQL은 실행되지 않음
  5. Flyway history는 V1이지만 실제 스키마는 V1 baseline이 전제하는 상태보다 세 컬럼 부족

따라서 현재 필요한 작업은 새로운 기능을 위한 스키마 변경이 아니라, production 스키마를 이미 선언된 V1 baseline 상태와 일치시키는 복구 작업입니다.


🧭 해결 방법 검토

방법 검토 결과 판단
기존 V236을 다시 migration 경로에 추가 현재 main은 V1, develop은 V1–V4입니다. main에서 V236을 적용하면 이후 V2–V4가 현재 버전보다 낮아져 기본 설정에서 실행되지 않습니다. 제외
새로운 V5 versioned migration 추가 main이 V1에서 V5로 먼저 이동하므로 이후 develop의 V2–V4를 main에 반영할 때 동일한 순서 문제가 발생합니다. 제외
outOfOrder=true로 낮은 버전 실행 허용 환경별 migration 실행 순서가 달라지고, 재구축 시의 실행 순서와 production 이력이 일치하지 않게 됩니다. 제외
production DB에 수동 ALTER 실행 즉시 복구는 가능하지만 저장소와 Flyway history에 해결 근거가 남지 않고 다른 영속 환경의 동일 상태를 자동으로 처리하지 못합니다. 긴급 수동 복구안으로만 유지
멱등 repeatable migration 사용 버전이 없어 main V1과 develop V1–V4 모두에서 versioned migration 이후 실행할 수 있고, 컬럼 존재 여부에 따라 복구 또는 no-op 처리가 가능합니다. 선택

현재 분리된 migration 이력을 변경하지 않으면서 모든 환경에서 같은 파일을 안전하게 실행할 수 있다는 점에서 repeatable migration이 가장 영향 범위가 작고 재현 가능한 방법이라고 판단했습니다.


✅ 선택한 해결 방법

R__ensure_notification_fcm_columns.sql을 추가합니다.

  1. information_schema.COLUMNS에서 필요한 세 컬럼의 존재 여부를 확인합니다.
  2. 누락된 컬럼의 DDL만 동적으로 조합합니다.
  3. 누락 컬럼이 있으면 하나의 ALTER TABLE ... ALGORITHM=INSTANT로 추가합니다.
  4. 세 컬럼이 모두 존재하면 DO 0으로 종료합니다.
  5. Flyway가 파일명과 checksum을 history에 기록하므로 같은 내용은 다시 적용되지 않습니다.

ALGORITHM=INSTANT를 명시해 MySQL이 테이블 복사 방식으로 자동 전환하지 않고, instant ADD COLUMN을 지원하지 않는 조건에서는 즉시 실패하도록 했습니다. 세 컬럼은 모두 nullable이므로 기존 운영 애플리케이션과도 하위 호환됩니다.


🌍 환경별 동작

환경 현재 상태 hotfix 동작
production/main V1 BASELINE 기록, FCM 컬럼 누락 Hibernate 초기화 전에 세 컬럼 추가
stage/develop V1–V4 적용, FCM 컬럼 존재 컬럼 변경 없이 no-op
신규 로컬/CI DB V1–V4를 순서대로 실행하며 V1이 세 컬럼 생성 versioned migration 이후 repeatable은 no-op
일부 컬럼만 존재하는 DB 부분 적용 상태 존재하는 컬럼은 유지하고 누락된 컬럼만 추가

🧪 검증

MySQL 8.0.29와 실제 사용 중인 Flyway 9.16.3 조합으로 다음을 검증했습니다.

  • production과 같은 비어 있지 않은 DB를 V1 BASELINE 처리한 뒤 세 컬럼 복구
  • 신규 DB에서 develop의 V1–V4 전체 migration 실행 후 repeatable migration no-op
  • 동일 Flyway 인스턴스에서 두 번째 migrate() 실행 시 중복 적용 없음
  • 컬럼 타입, 길이, nullable 조건과 flyway_schema_history 기록 확인
  • 기존 DepartmentContactMigrationTest와 신규 migration 테스트 동시 실행

검증 명령:

  • ./gradlew test --tests in.koreatech.koin.acceptance.migration.NotificationFcmMigrationTest --tests in.koreatech.koin.acceptance.migration.DepartmentContactMigrationTest
  • ./gradlew build

GitHub build, Flyway version 검사, 위험 SQL 검사, PR 제목 검사도 모두 통과했으며 CodeRabbit에서도 actionable comment가 없었습니다.


💬 반영 방식

  • 동일한 hotfix/2309-notification-fcm-columns 브랜치에서 main PR과 develop PR을 각각 생성했습니다.
  • production 복구가 우선이므로 main PR을 먼저 병합하고 배포합니다.
  • 이후 이 develop PR을 병합해 다음 release에도 같은 migration이 유지되도록 합니다.
  • develop PR의 BEHIND 표시는 main에서 분기한 동일 hotfix 브랜치를 사용하는 기존 hotfix 방식에 따른 것입니다. main PR이 열려 있는 동안 develop을 hotfix 브랜치에 병합하면 main PR에 미배포 develop 변경이 섞이므로 Update branch를 수행하지 않습니다.

✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함됨
  • Reviewers / Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증 (API 키, 환경 변수, 개인정보 등)

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a repeatable Flyway migration that restores missing FCM columns on notification and an acceptance test covering baseline, full migration, column definitions, and Flyway history.

Changes

Notification FCM schema repair

Layer / File(s) Summary
Conditional FCM column migration
src/main/resources/db/migration/R__ensure_notification_fcm_columns.sql
Detects missing FCM columns, adds them with ALGORITHM=INSTANT, and executes a no-op when all columns already exist.
Baseline and full migration validation
src/test/java/in/koreatech/koin/acceptance/migration/NotificationFcmMigrationTest.java
Runs Flyway against a MySQL Testcontainers database through baseline and full migration paths, then verifies FCM column definitions and schema history entries.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The migration and MySQL integration test address the issue requirements: idempotent recovery, no-op when present, and rerun safety.
Out of Scope Changes check ✅ Passed The changes stay within the hotfix scope by adding the repeatable migration and verification tests only.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: recovering missing notification FCM columns in production.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/2309-notification-fcm-columns

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added 공통 백엔드 공통으로 작업할 이슈입니다. 버그 정상적으로 동작하지 않는 문제상황입니다. labels Jul 21, 2026
@github-actions
github-actions Bot requested review from dh2906 and kih1015 July 21, 2026 15:11
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

Unit Test Results

774 tests   771 ✔️  1m 44s ⏱️
187 suites      3 💤
187 files        0

Results for commit eddcbe7.

♻️ This comment has been updated with latest results.

@taejinn
taejinn requested review from DHkimgit and removed request for kih1015 July 21, 2026 15:57
@taejinn taejinn closed this Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

공통 백엔드 공통으로 작업할 이슈입니다. 버그 정상적으로 동작하지 않는 문제상황입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

운영 Flyway baseline 전환 이후 notification FCM 컬럼 누락

3 participants