라이브 프로덕션 데이터베이스에서 테이블 변경


24

대부분의 "인기"(MySQL, Postgres ...) 데이터베이스 시스템은 라이브 프로덕션 데이터베이스의 테이블 변경 (열 유형 추가, 삭제 또는 변경)을 어떻게 처리합니까?

나는 알고 올바른 방법은 백업 모든 일정 중단 시간과 변경 사항을 다음합니까.

그러나 ... 현재 데이터베이스 시스템은 아무것도 멈추지 않고 이러한 온라인 작업을 지원합니까? (방금 변경 / 삭제되는 열을 참조하는 쿼리가 지연 될 수 있음)

ALTER TABLE...실시간으로 실행되는 데이터베이스에서 방금 수행하면 어떻게됩니까? 이런 일이 발생하면 모든 것이 멈추나요? 데이터가 손상 될 수 있습니까? 기타

다시 말하지만, 나는 주로 Postgres 또는 MySQL을 언급하고 있습니다.

(그리고, 그렇습니다. "올바른 방법", 일 백업, 다운 틴 일정 예약 등을하기 전에이 작업을 수행해야 할 때마다 ...하지만 이런 종류와 일을 "빠르게 수행 할 수 있는지"알고 싶습니다. dirty "또는 실제로"빠른 라이브 및 더러운 "스키마 변경을 지원하는 DB 시스템이있는 경우)


단지 제안 누군가 페이스 북 스크립트에서 MySQL을위한 온라인 스키마 변경 (튜토리얼과 여기 소스 여기가 ) ... ... 그것을 할 "해키"방법의 설정을 자동화하는 좋은 방법처럼 보인다 누구도 그것을 사용하고있다 비슷한 생산?


3
참고 : "올바른 방법"은 PostgreSQL이 아니라 MySQL과 관련이 있습니다. PostgreSQL의 "올바른 방법"은 일반적으로 매우 쉽지만 관련이 있습니다. 를 사용 pg_reorg하면보다 어려운 시나리오에 도움 이 될 수 있습니다.
Sean

나는 가능한 많은 전략을 설명하는 누군가와 함께 이것에 대한 자세한 비디오를 갖고 싶었습니다.
Sandeepan Nath

답변:


22

ALTER TABLEPostgreSQL에서을 발행 하면를 포함하여 모든 것을 차단 하는 ACCESS EXCLUSIVE잠금 이 걸립니다SELECT . 테이블이 재 작성, 새로운 요구하지 않는 경우,이 잠금은 매우 브리핑을 할 수있다 UNIQUE, CHECK또는 FOREIGN KEY제약 등 고가의 풀 테이블 스캔 검증 할 필요가 없습니다를

의심스러운 경우 일반적으로 시도해보십시오! PostgreSQL의 모든 DDL은 트랜잭션 방식이므로 ALTER TABLE너무 오래 걸리고 다른 쿼리를 보류하기 시작하면 취소하는 것이 좋습니다. 다양한 명령에 필요한 잠금 수준 은 잠금 페이지에 설명되어 있습니다.

일반적으로 느리게 작동하는 일부 작업은 가동 중단없이 안전하게 수행 할 수 있도록 속도를 높일 수 있습니다. 당신은 테이블이있는 경우 예를 들어, t당신이 열을 변경할 customercode integer NOT NULLtext고객이 코드는 이제 시작해야하는 모든 고객을 결정했기 때문에 X, 당신은 쓸 수 있습니다 :

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

...하지만 다시 작성하기 위해 전체 테이블을 잠급니다. 으로 열을 추가하는 것도 마찬가지 DEFAULT입니다. 긴 잠금을 피하기 위해 몇 가지 단계를 수행 할 수 있지만 애플리케이션은 임시 복제에 대처할 수 있어야합니다.

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

이것은 단지 방지 할 쓰기t과정에서를; 잠금 이름 EXCLUSIVE은 제외하고 모든 것을SELECT 배제한다는 점에서 다소 기만적입니다 . ACCESS EXCLUSIVE모드는 제외 절대적으로 everyting있는 유일한 하나입니다. 잠금 모드를 참조하십시오 . 이 작업에 필요한 잠금 업그레이드로 인해이 작업이 교착 상태 롤백 될 수있는 위험이 ALTER TABLE있지만 최악의 경우 다시 수행해야합니다.

당신은 그 잠금을 피하고에서 트리거 기능을 작성하여 라이브 모든 일을 할 수있는 t그 때마다 INSERT또는 UPDATE자동으로 채 웁니다 온다 customercode_new에서 customercode.

또한 기본 제공 도구가 CREATE INDEX CONCURRENTLY있으며 ALTER TABLE ... ADD table_constraint_using_indexDBA가 동시성 친화적 인 방식으로 작업을 더 느리게 수행하여 독점 잠금 시간을 줄일 수 있도록 설계되었습니다.

pg_reorg도구 또는 후속 도구 pg_repack는 일부 테이블 재구성 작업에도 사용될 수 있습니다.


1
@Craig가 말한 핵심은 "재 작성이 필요하지 않은 경우"였습니다. 사용하여 ALTER TABLE t ADD COLUMN i INT로크가 획득되면 고속 동작 (전형적으로 <1ms의)이다. 그러나 잠금을 획득하면 연결이 대기 될 수 있으므로 "무료"는 아니지만 ... MySQL에서 수행하는 것보다 세상이 더 낫습니다. NOT NULL제약 조건을 추가하는 것은 더 어렵고 마음의 위엄이 아닙니다.
Sean

pg_repack개량 된 후계자 인 컨센서스 인 것 같습니다 pg_reorg.
Erwin Brandstetter

기본적으로 (또는 계산 된) 덜 "차단"방식으로 열을 추가하는 것과 관련하여 좋은 대답은 전체 새 테이블을 생성하고 이전 테이블을 차단하여 삽입 / 업데이트 / 삭제하지만 새 테이블을 선택하고 채우는 것입니다. 마지막으로 이전 테이블에서 간단한 독점 잠금을 실행하여 선택하고 삭제 한 다음 새 이름을 이전으로 바꿉니다. 시나리오에 따라 기존의 인서트를 막지 않고 새로운 인서트를 채울 수 있으며 diff를 해결하는 동안 독점 잠금 장치를 실행할 수 있습니다 (소망하게 몇 개의 새로운 레코드 삽입)
jean

7

Percona는 온라인 스키마 변경을 수행하기위한 자체 도구를 개발했습니다.

이 도구를 pt-online-schema-change라고합니다.

트리거가 포함되므로 설명서를주의해서 읽으십시오.

문서에 따르면 수행 된 주요 작업은 다음과 같습니다.

  • 위생 검사
  • 청킹
  • 온라인 스키마 변경
    • 임시 테이블 생성 및 변경
    • 테이블에서 임시 테이블로 변경 사항 캡처
    • 테이블에서 임시 테이블로 행 복사
    • 테이블과 임시 테이블을 동기화
    • 테이블과 임시 테이블 스왑 / 이름 바꾸기
    • 대청소

고마워, 더 신뢰할 수있는 페이스 북의 접근 방식의 "판매 된"버전처럼 보인다 ...
NeuronQ

자체 MySQL 서버를 실행하는 경우 pt-online-schema-change를 사용하는 것이 좋습니다. Percona Tools 2.2부터 슬프게도 AWS에서 RDS / Aurora를 지원하지 않습니다. pt-online-schema-change는 소스 테이블에 트리거를 삽입하여 행 (MyISAM의 우선 순위가 낮음)을 대상 table_temp에 복사하고 모든 행이 소스와 대상 사이에서 동기화 될 때 하나의 빠른 잠금 삭제 및 끝에 이름 바꾸기를 수행합니다. 테이블.
phpguru

6

시스템을 종료하고 한 번에 모든 변경을 수행하는 것은 매우 위험 할 수 있습니다. 문제가 발생하고 자주 발생하는 경우 쉽게 되돌릴 수있는 방법이 없습니다.

애자일 개발자는 때때로 테이블을 수정하고 읽을 때 다운 타임없이 테이블을 리팩토링해야합니다.

롤백이 매우 쉬운 몇 가지 위험이 낮은 단계에서 변경이 이루어 지므로 다음과 같은 접근 방식은 위험이 낮습니다.

  • 테이블에 액세스하는 모든 모듈에 자동화 된 테스트가 포함되어 있는지 확인하십시오.
  • 새 테이블을 만듭니다. 이전 테이블과 새 테이블을 모두 수정하도록 이전 테이블을 수정하는 모든 절차를 변경하십시오.
  • 기존 데이터를 새로운 구조로 마이그레이션하십시오. 서버의 전체 성능에 심각한 영향을 미치지 않도록 작은 배치로 수행하십시오.
  • 데이터 마이그레이션이 성공했는지 확인하십시오.
  • 이전 표에서 일부 선택 절차를 새 절차로 리디렉션하십시오. 자동 테스트를 사용하여 변경된 모듈이 여전히 올바른지 확인하십시오. 그들의 성능이 수용 가능한지 확인하십시오. 변경된 절차를 배포하십시오.
  • 모든 보고서가 새 테이블을 사용할 때까지 이전 단계를 반복하십시오.
  • 새 테이블에만 액세스 할 수 있도록 테이블을 수정하는 프로 시저를 변경하십시오.
  • 이전 테이블을 아카이브하고 시스템에서 제거하십시오.

우리는이 접근 방식을 여러 번 사용해 가동 중단없이 대형 라이브 프로덕션 테이블을 변경했으며 전혀 문제가 없었습니다.


3
대단하지만 ... 내가 피하려고하는 "고통"의 유형입니다 :)
NeuronQ

@NeuronQ " 쉬운 방법은 없습니다 "– Postgres에는 다음과 같은 것들이 있습니다. 단순히 모든 것을 거래에 넣고 rollback무언가 잘못되었을 경우.
a_horse_with_no_name

2

예, 많은 최신 데이터베이스를 사용하면 null을 추가하거나 제거하는 것과 같이 열을 추가하거나 열의 특성을 변경할 수 있습니다.

열을 삭제하면 데이터가 손실되지만 손상에 대한 두려움은 없습니다.



-1

ALTER TABLE명령문으로 발생하는 문제에 대한 질문을 처리하려면 변경 범위에 따라 다릅니다. 특정한 경우, 최소한 MS SQL Server에서 새 열을 추가하면 엔진이 테이블의 임시 사본을 작성하는 동안 새 테이블 정의를 작성하고 데이터를 다시 삽입합니다. 변경 기간 동안 사용자는 테이블에 액세스 할 수 없습니다.

MSSQL 서버에 대한 특정 작업의 예는 다음과 같습니다. http://support.microsoft.com/kb/956176/en-us

정확한 구현은 공급 업체 설명서를 통해 확인해야 할 것이지만 다른 RMDB에는 비슷한 방법이 있다고 가정합니다.


-1 이것은 SQL Server에 대해 완전히 잘못된 것입니다. "적어도 MS SQL Server에서 새 열을 추가하면 엔진이 새 테이블 정의를 만드는 동안 테이블의 임시 복사본을 만든 다음 데이터를 다시 삽입합니다. 거기에 "
AK

@ AlexKuznetsov-앞의 줄을 보았고 나열된 사례 중 일부와의 링크는 이것이 항상 일어나는 것은 아니라는 것을 분명히합니다. 나는 이것을 더 잘 반영하기 위해 문장을 수정했다.
SchmitzIT

1
SQL Server 자체의 동작이 아니라 GUI의 동작 인 SSMS에 대해 언급하고 있습니다. 링크를 따라 가면 T-SQL을 직접 사용하여 DDL을 변경하는 것이 좋습니다. SSMS는 DDL을 변경하기위한 좋은 도구가 아닙니다.
AK

@ AlexKuznetsov-나는 위험을 감수하지 말고 낙담이 아니라는 기사를 읽었습니다. 어쨌든, 나는 GUI 비트에 대한 기사를 링크하지 않았지만 기본 데이터 구조의 변경으로 인해 임시 테이블을 생성하는 ALTER 문으로 이어지는 일부 작업의 표시로 사용했습니다. T-SQL에서 직접 명령문을 발행 할 때 똑같은 것이 적용되는지 테스트하지는 않았지만 프로세스는 매우 유사하며 SL 서버는 배후에서 레거시를 수행한다고 생각합니다.
SchmitzIT

프로파일 러를 시작하고 ALTER TABLE 문을 직접 실행하고 무슨 일이 일어나고 있는지 확인할 수 있습니다. 그런 다음 대화 상자를 통해 테이블을 변경하고 실행중인 명령을 직접 확인할 수 있습니다.
AK
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.