MySQL의 트랜잭션 DDL 워크 플로우


25

나는 조금 DDL 문 (발견 놀랐다 alter table, create index등) 암시 적으로 MySQL의에서 현재 트랜잭션을 커밋합니다. MS SQL Server에서 온 트랜잭션에서 데이터베이스 변경 (로컬 된 롤백) 기능은 워크 플로에서 중요한 부분이었습니다. 지속적인 통합을 위해 어떤 이유로 든 마이그레이션이 실패한 경우 롤백이 사용되어 데이터베이스를 반 마이그레이션 된 상태로 두지 않았습니다.

마이그레이션 및 지속적인 통합으로 MySQL을 사용할 때 사람들이이 두 가지 문제를 어떻게 해결합니까?


SO에서 크로스를 게시했습니다. stackoverflow.com/q/28197013/614523 거기서 많은 사랑을 얻지 못했습니다.
sennett

1
지속적인 통합의 경우 알려진 상태에있는 전체 환경을 매우 빠르게 생성하는 방법으로 LVM 스냅 샷을 고려하십시오.
Rick James

5
Postgres로 언제든지 업그레이드 할 수 있습니다. SCNR (Transactional DDL)을 지원합니다.
a_horse_with_no_name

3
@a_horse_with_no_name에 동의합니다. 이것이 워크 플로 인 경우 다른 많은 멋진 기능과 함께 트랜잭션 DDL이 포함 된 PosgreSQL의 사용을 진지하게 고려하십시오.
Renzo

답변:


9

많은 사람들에게 MySQL Achilles의 발 뒤꿈치는 암묵적인 커밋입니다.

이 책 의 418 페이지 3 단락에 따르면

MySQL 5.0 인증 학습 가이드

다음 명령은 트랜잭션을 중단시킬 수 있습니다

  • ALTER TABLE
  • BEGIN
  • CREATE INDEX
  • DROP DATABASE
  • DROP INDEX
  • DROP TABLE
  • RENAME TABLE
  • TRUNCATE TABLE
  • LOCK TABLES
  • UNLOCK TABLES
  • SET AUTOCOMMIT = 1
  • START TRANSACTION

암시

MySQL과 관련하여 구성하는 CI (ContinuousIntegration) / SelfService 작업은 항상 트랜잭션 작업과 DDL 스크립트를 상호 배타적으로 만들어야합니다.

이것은 당신에게 패러다임을 만들 기회를 제공합니다

  • START TRANSACTION/COMMIT블록 으로 올바르게 격리 된 트랜잭션 지원
  • DDL을 직접 스크립팅하여 생성자 또는 소멸자와 같은 DDL을 실행하여 DDL 제어
    • 생성자 : 새로운 디자인으로 테이블을 만드는 DDL
    • 소멸자 : 테이블을 이전 디자인으로 되 돌리는 DDL
  • 한 작업에서 이러한 작업을 결합하지 마십시오

경고 : MyISAM을 사용하는 경우 암묵적 커밋이 아니라 롤백이 발생 해야하는 데이터 일관성 측면에서 트랜잭션을 중단시킬 수있는 항목 목록에 MyISAM을 추가 할 수 있습니다. 필요합니다.

왜 LVM이 아닙니까?

LVM 스냅 샷은 훌륭하며 많은 SQL 처리를 수행하지 않고 전체 데이터베이스 인스턴스를 복원하는 것이 이상적입니다. 그러나 MySQL의 경우 InnoDB와 MyISAM의 두 가지 스토리지 엔진을 고려해야합니다.

모든 InnoDB 데이터베이스

InnoDB 아키텍처 살펴보기 (Percona CTO Vadim Tkachenko의 사진 제공)

InnoDB 배관

InnoDB에는 많은 움직이는 부분이 있습니다

  • 시스템 테이블 스페이스
    • 데이터 사전
    • 이중 쓰기 버퍼 (데이터 일관성 지원, 응급 복구에 사용)
    • 버퍼 삽입 (2 차 비 고유 인덱스에 대한 버퍼 변경)
    • 롤백 세그먼트
    • Undo Space (가장 통제되지 않은 성장이 일어날 수있는 곳)
  • InnoDB 버퍼 풀
    • 더티 데이터 페이지
    • 더티 인덱스 페이지
    • 비 고유 인덱스 변경
  • 다른 중요한 메모리 캐시

버퍼 풀 및 메모리 캐시에 커밋되지 않은 변경 사항이있는 all-InnoDB 데이터베이스의 LVM 스냅 샷을 생성하면 LUN이 복원되고 mysqld가 시작되면 InnoDB 응급 복구가 필요한 데이터 세트가 생성됩니다.

ALL-InnoDB를위한 제안

스냅 샷을 작성하기 전에 MySQL을 종료 할 수있는 경우

    1. 운영 SET GLOBAL innodb_fast_shutdown = 0;
    1. 운영 SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 운영 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirty 가 0이거나 가능한 한 0에 가까워 질 때까지 3 단계를 반복 하십시오.
    1. service mysql stop
    1. LVM 스냅 샷 생성
    1. service mysql stop

종료 할 수 없지만 MySQL Live로 스냅 샷을 찍는 경우

    1. 운영 SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 운영 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirty 가 0 또는 가능한 0에 가까워 질 때까지 2 단계를 반복 하십시오.
    1. LVM 스냅 샷 생성
    1. 운영 SET GLOBAL innodb_max_dirty_pages_pct = 75;

모든 MyISAM 데이터베이스 또는 InnoDB / MyISAM 믹스

MyISAM은 액세스 할 때 열려있는 파일 핸들 수를 유지합니다. MySQL이 충돌하면 열린 파일 핸들 수가> 0 인 MyISAM 테이블이 충돌로 표시되고 데이터가 아무 문제가없는 경우에도 복구가 필요합니다.

MyISAM 테이블이 사용중인 데이터베이스의 LVM 스냅 샷을 작성하면 스냅 샷이 복원되고 mysqld가 시작될 때 하나 이상의 MyISAM 테이블을 복구해야합니다.

All-MyISAM 또는 InnoDB / MyISAM 믹스 제안

스냅 샷을 작성하기 전에 MySQL을 종료 할 수있는 경우

    1. 운영 SET GLOBAL innodb_fast_shutdown = 0;
    1. 운영 SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 운영 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirty 가 0이거나 가능한 한 0에 가까워 질 때까지 3 단계를 반복 하십시오.
    1. service mysql stop
    1. LVM 스냅 샷 생성
    1. service mysql stop

종료 할 수 없지만 MySQL Live로 스냅 샷을 찍는 경우

특정 InnoDB 테이블을 플러시 할 수 있습니다

    1. 운영 SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 운영 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirty 가 0 또는 가능한 0에 가까워 질 때까지 2 단계를 반복 하십시오.
    1. FLUSH TABLES innodb_tbl1,... FOR EXPORT;중요한 InnoDB 테이블에서 실행
    1. 운영 FLUSH TABLES WITH READ LOCK;
    1. LVM 스냅 샷 생성
    1. 운영 UNLOCK TABLES;
    1. 운영 SET GLOBAL innodb_max_dirty_pages_pct = 75;

MySQL 복제가 도움이 될 수 있습니까?

하나의 LVM 스냅 샷을 두 개의 서버로 복원하고 MySQL 마스터 / 슬레이브 복제를 설정할 수 있지만, 스냅 샷을 복원 할 때 추가적인 하우스 정리 소스가됩니다.

마스터에서 CI 작업을 실행하고 해당 작업이 적은 경우 특정 상황에서 복제가 시간을 절약 할 수 있습니다. STOP SLAVE;Slave에서 실행 하고 Master에서 CI 작업을 시작 START SLAVE;하고 Master의 데이터가 인증되면 Slave에서 실행할 수 있습니다.

CI 작업이 너무 많은 데이터를 경고하면 LVM 스냅 샷을 복원하고 복제를 처음부터 복원 할 수 있습니다. 이 작업을 자주 수행하는 경우 MySQL 복제를 설정하면됩니다.

마지막 생각들

  • 여러 DB 서버 (3 이상)를 사용하여 복원 및 회귀 테스트를 수행하는 것이 가장 좋습니다.
  • MyISAM을 유지할 필요가없는 경우 나머지 MyISAM 테이블을 InnoDB로 변환하십시오.
  • 데이터 내용이 민감한 경우 테스트를 시작하기 전에 스냅 샷을 복원 한 후 CI 작업을 실행하여 데이터를 제거해야합니다. 또는 이미 스크러빙 한 데이터를 사용하여 MySQL의 스냅 샷을 만들 수도 있습니다.

4

지속적인 통합에 대해 이야기한다면 개발 환경이라고 가정합니다. 이 경우 구조적 변경을 수행하는 사람은 다른 사람이 공통 라이브러리를 업데이트하는 것과 거의 같은 방식으로 다른 사람을 위해 일을 중단하지 않도록 테스트해야한다고 말합니다. 그러한 변경 사항을 커밋하기 전에 자신의 샌드 박스에서 테스트하십시오.

프로덕션 배포 프로세스에서는 일반적으로 개발, QA 또는 프로덕션 전 환경을 거쳐 코드 변경과 같은 방식으로 변경 사항을 테스트합니다.

이것은 MySQL에만 국한된 것이 아님에 유의하십시오. Oracle 데이터베이스는 'alter table'등을 발행 할 때 암시 적으로 COMMIT를 수행합니다.

이제 자신을 보호하려면 물론 미리 백업하거나 시스템에서 수행 할 수있는 경우 LVM 또는 파일 시스템 스냅 샷을 수행 할 수 있습니다. 민감한 작업을하기 전에 보안으로 지연 / 중지 할 수있는 슬레이브가있을 수도 있습니다.

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