1. 문제 인식(ex. 콘솔에 500 에러가 떠요)
- 구글클라우드로 booktalk 인스턴스 생성 후, 팀원들 모두가 사용 및 조회가 가능한 MySQL 데이터베이스를 만들어두었고,
백엔드 팀원 2명 간에 서로 연결이 잘 됨을 확인했고,
데이터들도 제대로 잘 들어가고 조회 및 삭제 등 SQL문이 문제없이 작동됨을 확인했으나,
다음날이면 데이터베이스 자체가 소리소문없이 사라져있는 상황 발생
2. 증상 구체화 - 언제, 어디서, 어떤 상황에서 발생하는지 확인(항상 발생? 특정 조건에서만 발생)(ex. 회원가입할 때 이메일을 빠뜨리면 500 에러가 나요)
- 언제: 전날 DB 작업을 잘 하고 난 다음날
- 어디서: MySQL workbench에서
- 어떤 상황에서 발생: DB를 보려고 workbench를 들어가면 전날까지 작업한 booktalk 데이터베이스 자체가 사라져있음을 2차례나 발견
3. 로그 & 메시지 확인 - 스택 트레이스나 에러 메시지를 읽어서 어디서 문제가 발생했는지 단서 잡기
- 구글클라우드를 처음 사용해보아서 뭐가 원인인지 정확히 모르겠어서, 우선 구글클라우드 내 booktalk 인스턴스에 우리가 하지 않은 동작이나 작업이 포착되었나 확인해보았다.
4. 원인 추측 및 코드 추적 - 관련된 코드, 데이터, 설정, 네트워크 요청 등을 역추적 / 디버깅 도구 사용
- booktalk 인스턴스 -> 작업(데이터베이스 인스턴스가 현재 실행 중이거나 완료된 작업의 로그입니다.)
에 들어가 우리가 하지 않은 작업이 자동으로 무언가 된 게 있나 확인해보았더니,
매일 밤 새벽 3시경 모두가 잠들어있어서 활동이 없을 시간에 자동으로 백업을 하는 듯 했다.생성 시간 완료시간 유형 상태 2025. 7. 25. AM 8:39:57 2025. 7. 25. AM 8:39:58 업데이트 업데이트 완료 2025. 7. 25. AM 3:03:50 2025. 7. 25. AM 3:05:21 백업 백업 완료 2025. 7. 24. AM 3:19:32 2025. 7. 24. AM 3:21:04 백업 백업 완료
그리고 아직 팀원 중 아무도 일어나서 작업을 하지 않았을 아침 8:39에 업데이트 라는 작업도 자동으로 한 걸 확인했다.
5. 문제를 좁혀 나가기 - 의심되는 부분을 주석 처리 / 최소 단위로 테스트 / console.log()나 breakpoint로 값 흐름 추적
- 그래서 업데이트 라는 작업에서 자동으로 우리의 데이터베이스를 삭제시키는 활동이 있었는지를 확인하려고,
booktalk 인스턴스 -> 로그 탐색기에서 아래 명령어로 확인해보았다.
(cloudsql.databases.delete 항목이 있다면 누가 삭제한 거라고 함)
resource.type="cloudsql_database"
protoPayload.methodName="cloudsql.instances.update" OR "cloudsql.instances.restoreBackup" OR "cloudsql.databases.delete"
하지만 없었다.
- 그래서 다른 명령어로 DB가 사라진 정확한 시점, 원인, 실행 주체를 알아보려고 했다.
- restoreBackup - 누가 백업 복원했는지
- databases.delete - DB가 삭제된 시점
- DROP DATABASE - Prisma나 쿼리로 삭제됐는지
- update - 인스턴스 업데이트로 인한 영향
resource.type="cloudsql_database"
(protoPayload.methodName="cloudsql.instances.restoreBackup"
OR protoPayload.methodName="cloudsql.databases.delete"
OR protoPayload.methodName="cloudsql.instances.update"
OR textPayload:("DROP DATABASE")
)
하지만 DB 삭제 관련 로그가 없었다.
cloudsql.databases.delete 혹은 textPayload contains "DROP DATABASES" 가 무조건 나왔어야 하는데..
- DB를 다룬 팀원 모두가 DB를 삭제시키는 명령어는 아무도 치지 않았기 때문에, 우리가 db 관련 명령어를 친 것 중 잘못 된 것이 있는지 확인하는 것이 마지막 희망이었다..
- 우리는 DB스키마가 변경되거나 해서 db를 새로 동기화시켜야 할 때에 이 순서대로 명령어를 쳤다.
npx prisma generate
npx prisma migrate dev
6. 원인 발견 시 수정 - 버그가 발생한 원인을 찾으면 코드/로직/환경을 수정 → 수정 후 재현테스트로 문제가 진짜 해결됐는지 확인
- 결국 우리는 저기까지 확인 한 후, 무엇이 원인인지 파악하지 못한 채로 미해결로 놔둔 채
새 booktalk2 라는 인스턴스를 생성 후 다시 처음부터 DB를 만들고 사용하고 있었다. - 그런데, 나중에서야 알게되었는데, 내가 DB스키마를 변경해서 또 다시 이 명령어를 친 순간,
npx prisma generate
- 순식간에 DB가 사라져있는 걸 발견했다. 드디어 원인을 찾은 것이다!!!!!!!!!!!
우리가 아무 생각 없이 왜 쳐야하는지도 모르는 상황에서 친 명령어 한 줄로 계속 DB를 초기화시키고 있었던 것이다.
7. 재발 방지 - 테스트 코드 작성(가능하면) & 문서화(어떤 문제가 왜 발생했고 어떻게 고쳤는지 기록)
- 이 사실을 발견 즉시, 백엔드 팀원과 공유하고, 이 이후에는 그냥 다른 복잡한 것 다 생각치 말고,
이 명령어 하나로만 하기로 정했다.
npx prisma db push
결국 이 문제의 원인은 우리가 `npx prisma migrate dev` 명령어를 실행하면서 DB가 드롭되고 새로 생성되는 과정에서,
데이터베이스 전체가 소리소문없이 초기화되고 있었던 것이었다.
이 명령어는 개발 환경에서는 마이그레이션을 위해 기존 DB를 삭제할 수 있다는 사실을 알지 못했기 때문에 반복적으로 같은 실수를 저질렀던 것이다.
이후 우리 팀은 데이터 유실을 방지하기 위해 `npx prisma db push` 명령어만 사용하기로 결정했다.
이 명령어는 DB를 삭제하지 않고 가능한 변경사항만 강제로 반영해 주므로, 초기 개발 단계에서는 상대적으로 안전하다.
물론 `db push`는 마이그레이션 이력이 남지 않아 협업이나 배포 시 문제가 될 수 있지만,
지금은 개발 초기 단계이고, 구조가 자주 바뀌는 상황이므로 팀원 간 합의 하에 이 방식을 유지하고 있다.
나중에 서비스가 안정화되면, 마이그레이션 파일을 관리하며 배포 가능한 구조로 전환하는 것이 필요할 것이다.
✅ npx prisma generate 가 하는일
이 명령어는 데이터베이스에 아무 작업도 하지 않습니다.
이 명령어의 기능:
- schema.prisma 파일에 정의된 모델을 기준으로,
- node_modules/,prisma 폴더에 Prisma Client를 생성합니다.
- 즉, 타입이 포함된 DB 접근용 JavaScript/TypeScript 코드를 자동으로 만들어주는 도구
사용 시점:
- schema.prisma 파일이 바뀐 경우 (모델 추가/수정 등)
- Prisma Client가 프로젝트에 처음 설치되었을 때
- 배포 후, 새롭게 프로젝트를 받아온 후 (node_modules가 없을 때)
💡 주의할 점: 이 명령어는 DB를 수정하거나 초기화하지 않습니다.
👉 그래서 generate 명령어만으로 DB가 날아간 것은 아닙니다.
✅ npx prisma migrate dev vs npx prisma db push
이 두 명령어가 DB에 변경사항을 반영한다는 점은 같지만, 방식과 목적이 다릅니다.
💥 npx prisma migrate dev
기능:
- 마이그레이션 파일(migrations/ 폴더)을 생성함
- 해당 마이그레이션을 DB에 적용함
- 개발 환경에서 사용하기 좋음
특징:
- 기존 DB를 드롭(drop)하고 다시 생성하는 동작이 옵션 없이 기본 포함될 수 있음 (특히 dev 환경에서)
- 그래서 기존 데이터가 모두 사라질 수 있음
- 마이그레이션 히스토리를 관리하므로 팀 협업 시 좋음
내부적으로 실행되는 과정:
- 현재 DB 상태 확인
- 모델과 차이점 분석
- 새 마이그레이션 SQL 파일 생성
- (기존 DB 삭제 가능)
- 새 구조로 재생성
📛 이 명령어 때문에 DB가 날아간 것입니다!
💥 npx prisma db push
기능:
- schema.prisma 의 모델을 즉시 DB에 강제로 반영
- 마이그레이션 파일을 생성하지 않음
- 데이터 삭제 없이 가능한 선에서 스키마를 맞춤
특징:
- 가볍고 빠름
- 간단한 프로젝트나 테스트용 DB에 적합
- 마이그레이션 기록이 없어서 협업, 배포 시 추적 불가
예시 동작
- 새 컬럼 추가 -> OK
- 테이블 삭제 -> OK
- 기존 필드 제거 -> OK
- 단, DB 구조만 맞추고 변경 이력은 남지 않음
✅ 우리 팀이 db push만 사용하는 경우, 문제 될 수 있는 점은?
단기적: ❌ 큰 문제 없음
- 개발 초기 단계, 빠르게 스키마 실험하는 데 적합
- 우리처럼 DB가 종종 날아가거나 구조가 계속 바뀌는 상황에서는 더 안전함
장기적: ⚠️ 다음과 같은 리스크 발생
| 문제 | 설명 |
| ❌ 변경 이력 없음 | 누가 언제 무슨 변경을 했는지 알 수 없음 |
| ❌ 협업 시 충돌 가능 | 팀원이 다른 구조를 push하면 엉킬 수 있음 |
| ❌ 프로덕션 배포 불가 | 실서비스에서는 마이그레이션 이력이 꼭 필요함 |
| ❌ rollback 불가능 | 잘못된 변경을 복구할 수 있는 수단이 없음 |
'개발공부 > error.log' 카테고리의 다른 글
| [TIL] gcp Cloud SQL 랜섬웨어 복구중 - VM, VPC네트워크, 서브넷 생성 근데 이게 뭘까? (3) | 2025.08.13 |
|---|---|
| [BookTalk 팀프로젝트 트러블슈팅2] 구글클라우드 인스턴스 내 데이터베이스가 매일 사라지는 사건 2!재발생! (3) | 2025.08.04 |
| [TIL]우와... JavaScript 클래스 에서 계속 ts 에러 뜨던거 2시간동안 챗쥐피티랑 씨름하면서 해결 못한거 멘토님이 해결함 (2) | 2024.09.12 |
| 숫자야구 day3 해결중... (0) | 2024.09.12 |
| [코딩애플 2022 new 리액트] 4강 하다가 난관 봉착 (2) | 2024.08.29 |