2012-10-19 6 views
8

MySQL 데이터베이스의 크기는 최대 17   GB까지이며 3 천 8 백만 개의 항목이 있습니다. 현재로서는 하나의 열 (varchar 40에서 varchar 80까지)의 크기를 늘리고 더 많은 열을 추가해야합니다.수백만 개의 항목이있는 테이블에서 MySQL 테이블 구조를 효율적으로 변경하려면 어떻게해야합니까?

많은 필드는 변경해야하는 것을 포함하여 색인이 생성됩니다. 응용 프로그램이 작동하는 데 필요한 고유 한 쌍의 일부입니다. 어제 변경을 시도하면서 쿼리를 마무리하지 않고 거의 4 시간 동안 실행했습니다. 중단을 중단하고 서비스를 다시 가동하기로 결정했습니다.

이 크기의 항목을 변경하는 가장 효율적인 방법은 무엇입니까?

이러한 항목 중 많은 항목도 오래되었으며 항목을 조각내어 정리할 수있는 좋은 방법이 있지만 표를 훨씬 쉽게 관리 할 수있는 크기로 만들면이 문제를 해결하는 데 도움이 될 수 있습니다.

+0

흥미 롭습니다. 나는이 질문을 따른다. – Gianmarco

답변

2

MySQL 5.1에서는 다시 5.5를 사용하여 전체 테이블을 다시 작성하지 않고 구조를 수정하기 위해 특정 변경 문이 향상되었습니다 (http://dev.mysql.com/doc/refman/5.5/en/alter-table.html - 내부 검색). 이것의 가용성은 여러분이 만들고있는 엔진의 종류와 변화에 따라 다르지만, InnoDB Plugin의 가치가 가장 높습니다. 테이블 전체가 다시 작성되지만 특정 변경 사항이있는 경우

이러한 문제가 발생하면 일반적으로 복제본 데이터베이스를 활용하려고합니다. 추가 및 제거하지 않는 한 먼저 복제본에 대해 DDL을 실행 한 다음 복제본을 마스터 역할로 승격시키기위한 일시적인 중단을 예약 할 수 있습니다. RDS를 사용하는 경우 복제본 인스턴스 http://aws.amazon.com/about-aws/whats-new/2012/10/11/amazon-rds-mysql-rr-promotion/에 대한 권장 용도 중 하나입니다.

일부 다른 대안은 다음과 같습니다 :

  • 원하는 구조 (테이블 잠금을 피하기 위해 사용 INTO OUTFILE)와 함께 새 테이블에 레코드의 하위 집합을 선택. 완료되면 유지 보수 창과 REPLACE INTO 또는 UPDATE 초기 데이터 복사 이후 원본 테이블에서 변경된 모든 레코드를 예약 할 수 있습니다. 업데이트가 완료되면 두 테이블 중 RENAME TABLE...이 변경 사항을 래핑합니다.
  • Percona의 pt-online-schema-change : http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html과 같은 도구를 사용하십시오. 이 도구는 트리거와 함께 작동하므로 변경하려는 테이블에 이미 트리거가있는 경우 필요에 맞지 않을 수 있습니다.
3

새 테이블을 다른 이름 (예 : NewTable)으로 원하는 새 구조로 만듭니다. , 수행이 후

INSERT INTO NewTable (field1, field2, etc...) SELECT field1, field2, ... FROM OldTable 

당신은 이전 테이블을 삭제하고 원래 이름

에 새 테이블의 이름을 바꿀 수 있습니다 :

그런 다음 다음 쿼리를 사용하여 이전 테이블에서이 새 테이블에 데이터를 삽입

DROP TABLE `OldTable`; 
RENAME TABLE `NewTable` TO `OldTable` ; 

매우 큰 테이블에서이 접근법을 시도했으며 테이블을 변경하는 것보다 훨씬 빠릅니다.

6

몇 가지 선택 사항이 있습니다.

어쨌든이 작업을 수행하기 전에 백업을 받아야합니다.

하나의 가능성은 오프라인으로 서비스를 가져 와서 시도한 것처럼 작동합니다. 그렇게한다면 핵심 점검과 제약 조건을 해제해야합니다.

ALTER TABLE bigtable DISABLE KEYS; 
SET FOREIGN_KEY_CHECKS=0; 
ALTER TABLE (whatever); 
ALTER TABLE (whatever else); 
... 
SET FOREIGN_KEY_CHECKS=1; 
ALTER TABLE bigtable ENABLE KEYS; 

이렇게하면 ALTER TABLE 작업이 더 빨라질 수 있습니다. ENABLE KEYS를 수행하면 인덱스가 즉시 재생성됩니다.

또 다른 가능성는, 당신이 원하는 새로운 스키마를 새 테이블을 만들 새 테이블의 키를 사용하지 않도록, 다음 할 @Bader가 제안하고 기존 테이블의 내용을 삽입하는 것입니다.

새 테이블을 만든 후에는 키를 다시 활성화 한 다음 이전 테이블의 이름을 "old_bigtable"과 같은 이름으로 바꾸고 새 테이블의 이름을 "bigtable"로 바꿉니다.

새 테이블을 채우는 동안 서비스를 온라인 상태로 유지할 수 있습니다. 그러나 그것은 제대로 작동하지 않을 수 있습니다.

세 번째 가능성은 거대한 테이블을 플랫 파일로 덤프 한 다음 새 레이아웃으로 새 테이블에로드하는 것입니다. 이는 테이블 백업을 무료로 받는다는 점을 제외하면 두 번째 가능성과 거의 같습니다. SELECT DATA INTO OUTFILELOAD DATA INFILE을 사용하여 매우 빠르게 만들 수 있습니다. 이를 위해서는 서버 시스템의 파일 시스템에 대한 액세스 권한이 있어야합니다.

모든 경우에 제약 조건과 키를 비활성화했다가 다시 사용하면 빠르게 진행됩니다.

+1

첫 번째 것은 내가 원하는 것처럼 들린다. 나는 amzaon rds 인스턴스의 몇 시간 전에 돌아가고 다른 시도를 시도하기 전에 이것을 시도 할 것이라고 생각한다. – marioatlp

+2

주말에이 작업을 해본 후이 방법의 문제점은 innodb이 키를 사용하지 못하게한다는 것입니다. – marioatlp

관련 문제