개발, 테스트 및 프로덕션에서 데이터베이스를 어떻게 관리합니까?


171

개발, 테스트 및 프로덕션 서버간에 데이터베이스 스키마 및 데이터를 관리하는 방법에 대한 좋은 예를 찾으려고 고생했습니다.

설정은 다음과 같습니다. 각 개발자에게는 앱과 MySQL 데이터베이스를 실행하는 가상 머신이 있습니다. 그들이 원하는 것을하는 것은 그들의 개인 샌드 박스입니다. 현재 개발자는 SQL 스키마를 변경하고 SVN에 커밋 한 텍스트 파일로 데이터베이스를 덤프합니다.

항상 최신 커밋 된 코드를 실행하는 지속적인 통합 개발 서버를 구축하려고합니다. 지금 그렇게하면 각 빌드마다 SVN에서 데이터베이스를 다시로드합니다.

"릴리스 후보"를 실행하는 테스트 (가상) 서버가 있습니다. 테스트 서버에 배포하는 것은 현재 매우 수동 프로세스이며 일반적으로 SVN에서 최신 SQL을로드하고 조정해야합니다. 또한 테스트 서버의 데이터가 일치하지 않습니다. 마지막 개발자가 샌드 박스 서버에서 수행 한 테스트 데이터는 무엇이든 가능합니다.

모든 것이 고장 나는 곳은 프로덕션 환경에 대한 배포입니다. 라이브 데이터를 테스트 데이터로 덮어 쓸 수 없으므로 모든 스키마 변경 사항을 수동으로 다시 작성해야합니다. 데이터를 조작하기 위해 많은 스키마 변경 또는 변환 스크립트가있는 경우에는 실제로 문제가 발생할 수 있습니다.

문제가 스키마 일 뿐이라면 문제가 더 쉬울 수 있지만 보안 및 권한 테이블의 메타 데이터와 같이 개발 중에 업데이트되는 데이터베이스에 "기본"데이터가 있습니다.

이것이 지속적인 통합과 1 단계 빌드로 나아가는 데있어 가장 큰 장벽입니다. 어떻게 당신은 그것을 해결?


후속 질문 : 데이터베이스 버전을 추적하여 주어진 데이터베이스 인스턴스를 업그레이드하기 위해 실행할 스크립트를 어떻게 알 수 있습니까? Lance와 같은 버전 표가 표준 절차 아래에 언급되어 있습니까?


Tarantino를 참조 해 주셔서 감사합니다. .NET 환경에 없지만 DataBaseChangeMangement 위키 페이지 가 매우 유용 하다는 것을 알았습니다 . 특히이 파워 포인트 프레젠테이션 (.ppt)

*.sql주어진 디렉토리 의 스크립트 이름을 데이터베이스의 테이블과 비교하여 확인하고 파일 이름의 첫 번째 부분을 구성하는 정수를 기준으로 순서가없는 스크립트를 실행하는 Python 스크립트를 작성합니다 . 그것이 매우 의심스러운 솔루션이라면, 여기에 게시 할 것입니다.


이에 대한 작업 스크립트가 있습니다. 존재하지 않는 경우 DB 초기화 및 필요에 따라 업그레이드 스크립트 실행을 처리합니다. 기존 데이터베이스를 지우고 파일에서 테스트 데이터를 가져 오는 스위치도 있습니다. 약 200 줄이므로 게시하지 않습니다 (관심이 있다면 pastebin에 넣을 수는 있음).



"데이터베이스의 테이블에 대해 주어진 디렉토리에서 * .sql 스크립트의 이름을 확인하고 첫 번째 부분을 형성하는 정수를 기준으로 순서가없는 것을 실행하는 Python 스크립트를 작성하려고합니다. 이 파일 이름이 아주 간단한 해결책이라면 여기에 게시하겠습니다. " 플라이 웨이를 구현하는 것처럼 들립니다.
masterxilo

답변:


53

몇 가지 좋은 옵션이 있습니다. "백업 복원"전략을 사용하지 않습니다.

  1. 모든 스키마 변경 사항을 스크립팅하고 CI 서버가 해당 스크립트를 데이터베이스에서 실행하도록합니다. 현재 데이터베이스 버전을 추적 할 수있는 버전 테이블이 있으며 최신 버전 인 경우에만 스크립트를 실행하십시오.

  2. 마이그레이션 솔루션을 사용하십시오. 이러한 솔루션은 언어마다 다르지만 .NET의 경우 Migrator.NET을 사용합니다. 이를 통해 데이터베이스 버전을 정하고 버전 간 위아래로 이동할 수 있습니다. 스키마는 C # 코드로 지정됩니다.


28

개발자는 단순히 전체 데이터베이스를 소스 제어로 덤프하는 것이 아니라 작업하는 각 버그 / 기능에 대한 변경 스크립트 (스키마 및 데이터 변경)를 작성해야합니다. 이 스크립트는 현재 프로덕션 데이터베이스를 개발중인 새 버전으로 업그레이드합니다.

빌드 프로세스는 프로덕션 데이터베이스의 사본을 적절한 환경으로 복원하고 소스 제어에서 모든 스크립트를 실행하여 데이터베이스를 현재 버전으로 업데이트합니다. 모든 스크립트가 올바르게 실행되도록 매일 수행합니다.


13

Ruby on Rails가 어떻게 하는지를 살펴보십시오.

먼저 기본적으로 데이터베이스 스키마와 데이터를 버전 N에서 버전 N + 1로 (또는 버전 N + 1에서 N으로 다운 그레이드하는 경우) 변환하는 마이그레이션 파일이 있습니다. 데이터베이스에는 현재 버전을 알려주는 테이블이 있습니다.

테스트 데이터베이스는 단위 테스트 전에 항상 깨끗하게 정리되고 파일의 고정 데이터로 채워집니다.


10

Refactoring Databases : Evolutionary Database Design 책 은 데이터베이스 관리 방법에 대한 아이디어를 제공 할 수 있습니다. 짧은 버전은 http://martinfowler.com/articles/evodb.html 에서도 읽을 수 있습니다 .

하나의 PHP + MySQL 프로젝트에서 데이터베이스에 데이터베이스 개정 번호가 저장되어 있으며 프로그램이 데이터베이스에 연결되면 먼저 개정을 확인합니다. 프로그램에 다른 개정이 필요한 경우 데이터베이스 업그레이드를위한 페이지가 열립니다. 각 업그레이드는 PHP 코드로 지정되며 데이터베이스 스키마를 변경하고 모든 기존 데이터를 마이그레이션합니다.


5
  • 데이터베이스 이름을 다음과 같이 지정하십시오.- dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>DB 이름을 하드 코딩해서는 안됩니다
  • 따라서 동일한 물리적 서버에 다른 유형의 DB조차 배포 할 수 있습니다 (권장하지 않지만 리소스가 부족한 경우 ...
  • 자동으로 데이터를 이동할 수 있는지 확인하십시오
  • DB 작성 스크립트를 채우기와 분리 = 항상 DB를 처음부터 다시 작성하고 이전 DB 버전 또는 외부 데이터 소스에서 채우는 것이 가능해야합니다.
  • 코드에서 하드 코드 연결 문자열을 사용하지 마십시오 (구성 파일이 아닌 경우에도). 구성 파일 연결 문자열 템플릿에서 사용합니다.이 템플릿은 동적으로 채워집니다. 다시 컴파일해야하는 application_layer의 각 재구성은 BAD입니다.
  • 데이터베이스 버전 관리 및 DB 객체 버전 관리를 사용하십시오.
  • 각 DDL 변화를 추적하고 (일부 역사 테이블에 저장 여기 예 )
  • 매일 백업! 백업에서 손실 된 항목을 얼마나 빨리 복원 할 수 있는지 테스트합니다 (자동 저장 스크립트 사용)
  • DEV 데이터베이스와 PROD조차도 데이터와 관련하여 문제가 발생하는 것과 동일한 생성 스크립트를 가지고 있으므로 개발자가 정확한 제품 사본을 만들어 재생할 수 있습니다. 똥이 팬을 때리면 사고 방식과 비즈니스 프로세스 비용이 훨씬 저렴합니다. 따라서 코더가 합법적으로 징계를하라고 강제하십시오.

마지막 포인트는 실제로 기분입니다. 필요한 경우 프로젝트의 정의가 손상되었음을 나타냅니다. 개발은 생산 전에 주도해야합니다. 생산 데이터가 부작용을 유발하는 경우 더 큰 문제가 나타납니다. 생산 데이터를 정리하십시오. 또한 실시간 데이터가 개발 시스템에 있어야한다는 이유가있을 경우 데이터 보호 책임자에게 마지막 단계를 명시하십시오. 또한 생산 데이터의 정확한 사본은 개발 및 통합 속도를 크게 저하시킵니다. 그런 사치를 감당할 수 없다면 비용이 덜 드는 프로세스를 고려하십시오.
hakre

문제는 개발 과정에서 제어 흐름의 모든 코너 케이스와 프로덕션에서 일어날 데이터 품질의 변화를 상상할 수조차 없다는 것입니다. 당신이 큰 회사에 있다면, 일종의 데이터 스크램블링 및 / 또는 마스킹 솔루션보다 법적 문제가 있어야 복잡성을 추가 할 수 있지만 여전히 버그를 일으킨 데이터 품질 측면을 보존해야합니다 어쨌든 첫 번째 장소에서 ...
Yordan Georgiev

4

이것은 내가 끊임없이 불만족스러운 것입니다-이 문제에 대한 우리의 해결책입니다. 몇 년 동안 우리는 각 릴리스마다 별도의 변경 스크립트를 유지했습니다. 이 스크립트에는 마지막 프로덕션 릴리스의 델타가 포함됩니다. 응용 프로그램이 릴리스 될 때마다 버전 번호가 증가하여 다음과 같은 결과가 나타납니다.

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

새로운 개발을위한 트렁크 / 메인 라인과 버그 수정, 단기 개선 등을위한 두 가지 개발 라인을 유지하기 시작할 때까지 이것은 잘 작동했습니다. 필연적으로 지점의 스키마를 변경해야 할 필요성이 생겨났습니다. 이 시점에서 이미 트렁크에 dbChanges_n + 1.sql이 있었으므로 다음과 같은 구성표를 사용하게되었습니다.

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

다시, 이것은 우리가 언젠가 우리가 메인 라인에서 42 개의 델타 스크립트를보고 지점에서 10 개의 델타 스크립트를 볼 때까지 충분히 잘 작동했습니다. 아!

요즘 우리는 단순히 하나의 델타 스크립트를 유지하고 SVN 버전을 유지하도록합니다. 즉, 각 릴리스마다 스크립트를 덮어 씁니다. 그리고 우리는 브랜치에서 스키마를 변경하는 것을 꺼려합니다.

그래서 이것도 만족스럽지 않습니다. Rails에서 마이그레이션하는 개념이 정말 마음에 듭니다. LiquiBase에 상당히 매료되었습니다 . 증분 데이터베이스 리팩토링 개념을 지원합니다. 살펴볼 가치가 있으며 곧 자세히 살펴볼 것입니다. 아무도 경험이 없습니까? 귀하의 결과에 대해 매우 궁금합니다.


4

또한 SQL Compare 와 같은 도구를 사용하여 다양한 버전의 데이터베이스 간 차이점을 스크립팅하여 버전간에 빠르게 마이그레이션 할 수 있습니다.


3

OP와 매우 유사한 설정이 있습니다.

개발자는 프라이빗 DB를 사용하여 VM에서 개발합니다.

[개발자들은 곧 개인 지점에 투입 할 예정]

테스트는 다른 머신에서 실행됩니다 (실제로 서버에서 호스팅되는 VM에서) [곧 Hudson CI 서버에서 실행됩니다]

참조 덤프를 db에로드하여 테스트하십시오. 개발자 스키마 패치를 적용한 다음 개발자 데이터 패치를 적용하십시오.

그런 다음 장치 및 시스템 테스트를 실행하십시오.

생산자는 설치자로서 고객에게 배포됩니다.

우리가하는 일 :

샌드 박스 DB의 스키마 덤프를 가져옵니다. 그런 다음 SQL 데이터 덤프. 우리는 이것을 이전의 기준선과 비교합니다. 이 델타 쌍은 n-1을 n으로 업그레이드하는 것입니다.

덤프와 델타를 구성합니다.

따라서 버전 N CLEAN을 설치하려면 덤프를 빈 db로 실행하십시오. 패치하려면 중간 패치를 적용하십시오.

(Juha는 현재 DB 버전을 기록하는 테이블을 가지고 있다는 Rail의 아이디어가 좋으며 업데이트 설치를 덜 복잡하게 만들어야한다고 언급했습니다.)

베타 테스트 전에 델타 및 덤프를 검토해야합니다. 개발자가 DB에 테스트 계정을 삽입하는 것을 보았 으므로이 문제를 해결할 방법이 없습니다.


3

다른 포스터와 동의하는 것이 두렵습니다. 개발자는 변경 사항을 스크립트해야합니다.

대부분의 경우 간단한 ALTER TABLE이 작동하지 않고 기존 데이터도 수정해야합니다. 개발자는 마이그레이션이 필요한 항목에 대해 알아야하며 올바르게 스크립팅해야합니다 (물론 어느 시점에서 신중하게 테스트해야 함) 릴리스주기).

또한 어떤 의미가 있다면 개발자가 변경 사항에 대한 롤백을 스크립팅하여 필요한 경우 되돌릴 수 있습니다. 롤백이 오류없이 실행될뿐만 아니라 DB를 이전과 동일한 상태로 유지하도록 테스트해야합니다 (항상 가능하거나 바람직하지는 않지만 대부분 좋은 규칙 임) .

CI 서버에 연결하는 방법을 모르겠습니다. CI 서버에 알려진 빌드 스냅 샷이 있어야 할 수 있습니다.이 스냅 샷은 매일 밤 되 돌리며 그 이후로 모든 변경 사항을 적용합니다. 아마도 최선일 것입니다. 그렇지 않으면 깨진 마이그레이션 스크립트가 그날 밤의 빌드뿐만 아니라 이후의 모든 스크립트를 손상시킵니다.


1

dbdeploy를 확인하십시오. Java 및 .net 도구가 이미 사용 가능합니다. SQL 파일 레이아웃 및 스키마 버전 테이블에 대한 표준을 따르고 Python 버전을 작성할 수 있습니다.


1

우리는 명령 행 mysql-diff를 사용하고 있습니다 : 두 데이터베이스 스키마 (라이브 DB 또는 스크립트에서)의 차이를 ALTER 스크립트로 출력합니다. mysql-diff는 응용 프로그램 시작시 실행되며 스키마가 변경되면 개발자에게보고합니다. 따라서 개발자는 ALTER를 수동으로 작성할 필요가 없으며 스키마 업데이트는 반자동으로 수행됩니다.



0

Open DBDiff 에 연결하여 데이터베이스 스키마를 비교하고 마이그레이션 스크립트를 제안 하는 도구를 작성했습니다 . 데이터를 삭제하거나 수정하는 변경을 수행하면 오류가 발생하지만 스크립트에 대한 제안을 제공합니다 (예 : 새 스키마에서 열이 누락 된 경우 열의 이름이 변경되었는지 확인하고 xx-생성됨) 이름 바꾸기 문이 포함 된 script.sql.suggestion).

http://code.google.com/p/migrationscriptgenerator/ SQL Server에만 해당 두려운 일입니다. (또한 꽤 알파이지만 마찰이 매우 적습니다 (특히 Tarantino 또는 http://code.google 과 결합하는 경우) . .com / p / simplescriptrunner / )

내가 사용하는 방법은 .sln에 SQL 스크립트 프로젝트를 두는 것입니다. 또한 로컬로 변경하는 db_next 데이터베이스가 있습니다 (Management Studio 또는 NHibernate Schema Export 또는 LinqToSql CreateDatabase 등 사용 ). 그런 다음 _dev 및 _next DB를 사용하여 migrationscriptgenerator를 실행합니다. 마이그레이션을위한 SQL 업데이트 스크립트


0

oracle 데이터베이스에는 oracle-ddl2svn 도구를 사용 합니다.

이 도구는 다음 프로세스를 자동화

  1. 모든 DB 스키마에 대해 스키마 ddl 가져 오기
  2. 버전 관리하에 놓으십시오

수동으로 해결 된 인스턴스 간 변경

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.