"올바른 성장과 따뜻한 나눔"이 있는 넥스트리
우리팀은 소스 버전관리와 회귀테스트 지속적인 통합은 비교적 잘 되고 있습니다. 그런데 관리가 잘 되고 있지 않는 부분이 데이터베이스 스키마입니다. 물론 ERD도 있고 DDL이나 기초데이터를 Subversion에서 관리하고 있지만 자동통합은 아직 요원합니다.
현재 상황
우리팀의 개발환경은 개인 환경, 통합용 환경 그리고 운영 환경 3개로 분리되어 있습니다.
개인 환경(개발자 PC)에서 개발/테스트를 완료하고 commit하면, 통합환경에서는 subversion에서 CI를 통해 빌드하여 통합환경으로 옮겨지고, 개발이 끝나 릴리즈한 버전은 운영환경으로 이관됩니다.
데이터베이스 스키마 변경이 없을 때에는 대부분 자동화되어 문제가 없는데 스키마 변경할 때는 스키마 변경 DDL을 만들어 일일이 각 환경에 수작업으로 적용해주어야 합니다. 그리 자주 있는 일은 아니지만 실수하기 쉽고 문제가 발생했을때 시간을 낭비하는 요소가 됩니다.
솔루션을 찾았다
데이터베이스 변경 관리를 체계적으로 자동화해 주는 open source(LGPL)로 LiquiBase가 있습니다. 대략적인 feature는 아래와 같습니다. (http://www.liquibase.org/)
- 확장성
- 여러 개발자의 변경을 병합
- 코드 브렌치
- 여러 데이터베이스 지원
- 운영 데이터와 다양한 테스트 데이터셋 관리
- 안전한 클러스터 데이터베이스 업그레이드
- 자동 업데이트 또는 DBA가 직접 적용할 수 있도록 SQL 스크립트 생성
- 업데이트를 롤백하는 기능
- 데이터베이스끼리 비교(diff)하는 기능
- 기존 데이터베이스에서 시작할 수 있도록 change log를 생성하는 기능
- 데이터베이스 변경 문서 생성
여기에서는 기본적인 사용방법과 작동방법을 설명합니다.
준비할 것들
Ant, Maven, Spring 등... 여러 방법으로 사용할 수 있는데 여기서는 command line에서 사용하는 방법을 설명합니다. http://www.liquibase.org/download -> 여기에서 다운로드 받고 적당한 디렉토리에 풀어놓습니다.
그리고 그 디렉토리를 path에 추가합니다. 여기에 liquibase.bat 파일이 있는데 이게 실행 파일입니다.
여기서는 MySQL을 대상으로 할 것입니다. test라는 계정과 test라는 데이터베이스를 만들어 놓습니다.
Java로 만든 도구이며 JDBC 드라이버가 필요합니다. MySQL JDBC 드라이버를 구합니다.
작업 디렉토리
적당한 작업 디렉토리를 만들어 아래 내용으로 liquibase.properties 파일을 만듭니다.
#liquibase.properties
driver: com.mysql.jdbc.Driver
classpath: mysql-connector-java-5.0.8-bin.jar
url: jdbc:mysql://localhost/test
username: test
password: test
LiquiBase가 관리할 데이터베이스 정보를 설정합니다. command line에서 옵션으로 줄 수도 있지만 이 파일을 만들어 놓는 것이 편합니다.
그리고 MySQL JDBC 드라이버를 작업 디렉토리에 넣습니다. 설정에서 보면 classpath에 JDBC 드라이버를 잡은 것을 볼 수 있습니다.
첫번째 Change log
드디어 작업할 때가 왔습니다. LiquiBase는 데이터베이스 변경을 XML로 관리합니다. 그리고 변경의 단위를 changeset이라고 합니다. 우선 첫번째 changset을 작업디렉토리에 changelog.xml라는 이름으로 만들어 봅니다.
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet id="1" author="dykim">
<createTable tableName="employee">
<column name="id" type="int">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(50)">
<constraints nullable="false"/>
</column>
<column name="active" type="boolean" defaultValue="1"/>
</createTable>
</changeSet>
</databaseChangeLog>
employee 테이블을 하나 만들었습니다. 그리고 작업 디렉토리로 이동하여 다음과 같은 명령을 입력합니다.
c:\tmp\db\liquibase --changeLogFile=changelog.xml update
DB를 살펴보면 위의 changeset에서 정의한 것처럼 employee 테이블이 만들어졌을 겁니다.
그리고 databasechangelog와 databasechangeloglock이 생긴걸 볼 수 있습니다. 이 테이블이 LiquiBase가 데이터베이스를 관리하는 테이블입니다. 이중 databasechangelog 내용을 보면 현재 changeset id 1번이 dykim에 의해 적용되었다는 뜻입니다.
두 번째 Change log
changeset을 두 개 더 추가해 보겠습니다. 또는 changlog를 update해 보니 누군가 아래와 같이 추가했다고 보시면 됩니다.
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet id="1" author="dykim">
<createTable tableName="employee">
<column name="id" type="int">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(50)">
<constraints nullable="false"/>
</column>
<column name="active" type="boolean" defaultValue="1"/>
</createTable>
</changeSet>
<changeSet id="2" author="dykim">
<addColumn tableName="employee">
<column name="fixed_salary" type="float" />
<column name="bonus" type="float" />
</addColumn>
</changeSet>
<changeSet id="3" author="dykim">
<dropColumn tableName="employee" columnName="bonus" />
</changeSet>
</databaseChangeLog>
마찬가지로 동일한 명령을 수행합니다.
c:\tmp\db\liquibase --changeLogFile=changelog.xml update
id 2, 3 changeset이 적용되어 employee 테이블에 컬럼이 추가되었다가 삭제된 결과를 볼 수 있을 겁니다. databasechangelog를 보면 changeset이 적용된 로그를 볼 수 있습니다.
LiquiBase는 change log의 changeset들과 DB의 databasechangelog 테이블에 적용한 상태를 비교하여 DB 스키마를 관리해줍니다.
다른 개발자의 DB로...
다른 개발자가 위 change log를 subversion과 같은 버전관리에서 update를 받고 liquibase update를 하면 그 개발자 DB와 change log를 비교하여 필요한 changeset만 적용해 결국 모든 DB 스키마는 동일해질 것입니다.
other_test로 DB와 계정을 만들고 liquibase.properties 파일을 아래와 같이 고쳐봅니다.
#liquibase.properties
driver: com.mysql.jdbc.Driver
classpath: mysql-connector-java-5.0.8-bin.jar
url: jdbc:mysql://localhost/other_test
username: other_test
password: other_test
other_test DB에도 동일한 스키마가 생겼을 겁니다.
마찬가지로 통합 환경 그리고 운영환경에서도 동일한 방법으로 쉽게 DB를 update할 수 있습니다. 이제는 더 이상 앞에서 말한 수작업은 필요없으며 안전한 DB 스키마관리가 가능하게 되었습니다.
더 기쁜 일은 Ant, Maven 같은 환경을 통해 빌드 프로세스에 넣을 수 있어 완전한 자동화를 구축할 수 있습니다.
'개발환경' 카테고리의 다른 글
| Database 스키마 버전 관리 (2) | 2010/06/29 |
|---|---|
| 클라우딩 개발환경 (1) | 2010/03/18 |
| Continuum vs Hudson (0) | 2009/11/16 |
| Maven 기반 지속적인 통합의 최선의 실천방법들 (0) | 2009/11/12 |
| Maven 기반 개발환경에서 잊지 말고 해야 할 일 (0) | 2009/11/06 |
| 유용한 Java 프로그램 정적 분석기 - Find Bugs (1) | 2009/10/07 |



