모종닷컴

우린 서로 다른 버전을 바라보고 있었어..(with 테이블과 엔티티) 본문

Programming

우린 서로 다른 버전을 바라보고 있었어..(with 테이블과 엔티티)

모종 2022. 7. 20. 23:05
반응형
제가 다니고 있는 회사에서는 Flyway를 이용하여 테이블의 버전(?)을 관리하고 있습니다.

어플리케이션 내에 테이블의 수정 쿼리를 .sql 파일로 만들고 운영에 배포를 하면 flyway가 이 sql 파일을 데이터베이스에 대신 실행을 해줍니다. 예를 들어 테이블에 필요없는 컬럼이 존재하여 삭제를 해야 한다면 아래와 같은 sql을 만들고 배포를 하면 어플리케이션이 시작하는 타이밍에 flyway가 데이터베이스에 해당 sql 파일을 실행시켜줍니다.

ALTER TABLE test DROP COLUMN unused_col;

 

설명은 간단히 이정도로 마치고 실제 겪었던 이슈를 설명하도록 하겠습니다.

 

엔티티 명세와 테이블 명세가 달라요.

저희 회사에서는 현재 JPA를 사용하고 있어서 Entity 클래스가 따로 존재합니다. 그래서 위와 같이 컬럼 삭제 작업이 있는 경우 Entity가 존재하지 않는 컬럼을 바라보지 않도록 하기 위해 필드 삭제가 필요합니다.

@Entity
@Table(name = "test")
data class TestEntity(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L,

    @Column(name = "unused_col")
    val unusedCol: String, // 삭제되어야 할 필드
    
    ...

)

 

이러한 엔티티 수정을 작업을 거치치 않게 되면 어플리케이션에서는 해당 컬럼이 존재한다고 하고 쿼리에 해당 컬럼을 포함한 쿼리를 날리는데,  실제 데이터베이스 테이블에서는 컬럼이 삭제있는 상태라 오류를 발생시키기 때문입니다. 때문에 아래와 같은 에러를 마주하게 됩니다.

Unknown column 'test0_.unused_col' in 'field list'

컬럼있어요?

그럼 엔티티 수정이랑 SQL이랑 같이 작업해서 배포하면 되는거죠?

회사가 무중단 서비스를 제공하지 않는다고 하면 답은 '넵' 입니다. 허나.. 저희 회사의 경우 24시간 서비스가 늘 구동하고 있고, 무중단 배포를 사용하는 경우는 답은 '아니요'입니다.

 

회사에서는 고가용성을 위해 A, B 두개의 서버가 존재하며, blue-green 배포 방법을 사용하고 있습니다. 예를 들어 A 서버가 떠있는 동안 저희가 배포를 한다하면 B 서버를 띄운후 작업한 코드 버전으로 어플리케이션이 시작됩니다. 그러면 B 서버가 완전히 구동되기 전까지 이 사이에 들어오는 요청을 A가 계속 받게 되지요. B 서버가 데이터베이스 테이블 변경을 완료는 했으나 아직 다른 작업으로 인해 배포가 완료되지 않았다고 합시다. 이 순간이 바로 위에서 말했던 명세가 달라진 시점이죠. A 서버에는 아직 엔티티 수정이 이루어지지 않은 코드가 있는데, 데이터베이스는 B 서버 배포로 인해 테이블 명세가 달라졌으니까요. 

 

그렇다면 이러한 이슈를 피하기 위해 어떻게 해야할까요?

다른 정답이 있을 수도 있지만 저는 이걸 작업을 분리함으로써 해결하고 있습니다. 순서는 아래와 같습니다.

1. 엔티티만 수정한 작업을 먼저 배포한다.

2. 이어서 테이블 수정 sql 을 만든 작업을 배포한다.

첫번째 작업을 배포함으로써 어플리케이션이 해당 컬럼을 더이상 바라보지 않게 하고, 뒤이어 테이블 수정 작업을 배포하여 엔티티와 테이블간의 명세를 완전히 동기화할 수 있는것이죠.

 

ALTER TABLE .. DROP COLUMN 에 락이 걸리지 않나요?

ALTER TABLE ~ DROP COLUMN 에 락이 걸리지 않냐는 말이 있는데 MySQL의 버전에 따라 다릅니다. 5.5 이전 버전이라면 락이 걸릴 것 같네요.
https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html

 

반응형

'Programming' 카테고리의 다른 글

테스트 코드는 버그를 찢어  (0) 2022.07.29
Intellij Code Inspection 사용하기  (0) 2022.07.24
Batch Update 3편  (0) 2022.05.07
Batch Update 2편  (0) 2022.05.07
Batch Update 1편  (0) 2022.04.30