가동 중지 시간이 거의 없거나 전혀없는 매우 큰 mysql 테이블의 열 수정


18

mysql 5.1에서 테이블을 정기적으로 변경해야하며 주로 열을 추가해야합니다. alter table 명령으로 매우 간단합니다. 그러나 내 테이블에는 현재 최대 4 천만 행이 있으며 빠르게 커지고 있습니다. 따라서 이러한 테이블 변경 명령은 몇 시간이 걸립니다. 몇 달 안에 그들은 추측하는 데 며칠이 걸릴 것입니다.

Amazon RDS를 사용하고 있기 때문에 슬레이브 서버를 가지고 놀고 마스터로 승격시킬 수 없습니다. 따라서 다운 타임이 최소화 된 상태에서이를 수행 할 수있는 방법이 있다면 제 질문입니다. 사용자가 DB를 계속 사용할 수 있다면 몇 시간 또는 며칠이 걸리는 작업은 신경 쓰지 않습니다 ... 열을 추가하는 동안 적어도 읽을 수 있습니까? 내 앱이 쓰려고하면 어떻게 되나요? 삽입 또는 업데이트? 즉시 실패하면 실제로 그렇게 나쁘지 않고 중단되어 DB 서버에 문제가 발생하면 큰 문제가됩니다.

이것은 상당히 일반적인 스케일링 문제 여야합니다. 모든 사람이 열을 추가해야합니다. 일반적으로 프로덕션 DB에서 수행되는 작업은 무엇입니까? 슬레이브-> 마스터 마이그레이션?

업데이트 -나는 innodb 스토리지 엔진을 사용하고 있다고 언급하는 것을 잊었다.


1
누군가가 여전히 답을 찾고있는 경우 .. blog.staginginstance.com/… ^^
Coder anonymous

답변:


10

mysql 5.1에서 테이블을 정기적으로 변경해야하며 주로 열을 추가해야합니다.

하지마 아니야 하지마 이 때 그것은 매우 드문 경우이어야한다 이제까지 필요.

데이터가 실제로 정규화되었다고 가정하면 문제를 해결하는 올바른 방법은 기본 테이블과 1 : 1 관계를 가진 새 테이블을 추가하는 것입니다 (새 테이블에 대한 의무는 아님).

정기적으로 열을 추가해야하는 것은 일반적으로 정규화되지 않은 데이터베이스의 표시기입니다. 스키마가 정규화되지 않은 경우 수정해야하는 문제입니다.

마지막으로 스키마가 실제로 정규화되고 실제로 열을 계속 추가 해야하는 경우 :

  1. 데이터베이스에 타임 스탬프 열이 있거나 복제 로그를 생성하는지 확인하십시오.
  2. 테이블의 사본 (B)을 만듭니다 (A).
  3. B에 새 열을 추가하십시오 (여전히 myisam으로 차단됩니다)
  4. 거래 비활성화
  5. 원래 테이블의 이름을 다른 것으로 바꾸십시오 (백업).
  6. 원래 테이블 이름으로 새 테이블 이름을 바꿉니다 (B).
  7. 작업 시작부터 복제 로그 또는 백업 테이블에서 트랜잭션 재생
  8. 거래를 가능하게합니다.

2
단계별 접근 방식에 감사드립니다. 테이블을 수정하는 것이 일반적이지 않습니까? 대신 새 열을 사용하여 다른 열을 추가하고 (열을 추가 해야하는 경우) 1 : 1 관계에서 원래 큰 테이블을 참조하도록 할 수 있습니다. 그러나 모두 1 개의 테이블에 있어야 할 때 15 개의 매우 큰 1 : 1 테이블을 갖는 것은 옳지 않은 것 같습니다. 물론 인덱싱 문제는 말할 것도없이 쿼리 성능도 저하됩니다. 나는 전문가는 아니지만 데이터베이스는 상당히 정규화되어 있으며 정기적으로 수정해야하는 것이 당연한 것 같습니다.
apptree

2
"테이블을 수정하는 것이 일반적이지 않습니까?" - 예.
symcbean

1
아니요. 그러나 주요 소프트웨어 업그레이드의 일부가 아닌 정기적으로 이런 일이 발생하면 모든 테이블이 먼저 있어야한다는 사실을 깨닫지 못하도록 누군가를 해고해야한다고 주장 할 수 있습니다. 여기서 문제 / 트릭은 "한 달에 한 번"이 아니라 "일반적으로"입니다.
TomTom

22
개발자, 특히 신생 기업 및 젊은 회사에서 일하는 개발자로서 symcbean 및 @TomTom에 덜 동의했습니다. 사물 변경, 제품 변경, 비즈니스 목표 변경 및 데이터베이스 구조 변경이 필요합니다. 좋은 DBA 서비스를 제공한다는 것은 그러한 변화에 "예"라고 말한 다음이를 효과적으로 구현하는 방법을 알아내는 것을 의미합니다. 고도로 표준화 된 데이터베이스는 오래 전에 죽은 개념입니다. 성능이 저하되고 개발주기가 느려집니다.
pents90

4
테이블을 바꾸는 것은 드문 일입니까 ??? 아마도 대기업이나 민첩한 팀에서 자주 발생하는 요구 사항은 다음과 같습니다.
tibo

12

나는 최근에 이것을해야했다. 아마존이 권장하는 것은 Percona Toolkit을 사용하는 것입니다. 나는 그것을 다운로드하고 다음과 같은 것을 실행할 수 있었다 :

./pt-online-schema-change h=databasenameHostName,D=databasename,t=tablename --recursion-method=none --execute --user username --password password --alter "MODIFY someColumn newDataType"

그리고 그것은 잘 작동합니다. 프로세스에 남은 시간이 얼마인지 알려줍니다.

실제로 새 열이있는 새 테이블을 만든 다음 기존 데이터를 복사합니다. 또한 새 데이터가 새 테이블로 푸시되도록 트리거를 작성합니다. 그런 다음 테이블 이름을 자동으로 바꾸고 이전 테이블을 삭제하면 업데이트를 기다리는 동안 다운 시간없이 새 열로 시작 및 실행됩니다.


Percona 팀은 pt-online-schema-change 도구에 필요한 RDS 매개 변수 그룹 (SET GLOBAL log_bin_trust_function_creators = 1이 RDS에서 작동하지 않음)을 통해 log_bin_trust_function_creators 기능을 활성화하는 방법에 대한 간단한 설명을 가지고 있습니다. 자세한 내용 : percona.com/blog/2016/07/01/pt-online-schema-change-amazon-rds
user1652110

그것은 나를 위해 일했다
Adiii

4

symcbean확실한 권장 사항을 제공 합니다 .

질문에 대답하기 위해 영향을 완화하는 가장 쉽고 가장 좋은 방법은 여러 데이터베이스를 복제하는 것입니다. 활성에서 복제를 중지하는 적절한 장애 조치 절차가있는 이중 마스터로 활성에 영향을주지 않고 비활성을 변경할 수 있습니다.

단일 라이브 데이터베이스에서이 작업을 수행 하고이 답변 에서 자세히 설명한 절차와 유사한 절차를 사용하여 영향을 최소화 할 수 있습니다. 분명히 이것은 symcbean이 설명한 것과 유사하지만 기술적 세부 사항을 포함합니다. 타임 스탬프뿐만 아니라 auto_increment 필드도 사용할 수 있습니다.

궁극적으로 데이터 세트가 너무 커지면 OLTPOLAP 데이터베이스 간의 보관도 고려해야 합니다. 적절하게 디자인 할 경우 트랜잭션 데이터 세트가 너무 클 필요는 없습니다.


2

매뉴얼에서 : http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

대부분의 경우 ALTER TABLE은 원래 테이블의 임시 복사본을 만듭니다. MySQL은 변경 사항을 복사본에 통합 한 다음 원래 테이블을 삭제하고 새 테이블의 이름을 바꿉니다. ALTER TABLE이 실행되는 동안 다른 세션에서 원본 테이블을 읽을 수 있습니다. 새 테이블이 준비 될 때까지 테이블에 대한 업데이트 및 쓰기가 중단 된 다음 업데이트 실패없이 자동으로 새 테이블로 리디렉션됩니다.

따라서 독서는 잘 작동합니다. 쓰기가 중단되지만 나중에 실행됩니다. 이를 방지하려면 소프트웨어를 수정해야합니다.


그래서이 작업을 수행하고 지금 수정하고있는 테이블에 쓰는 내 사이트 부분을 비활성화했습니다. 지금까지 몇 가지 "잠금 대기 시간 초과를 초과했습니다. 트랜잭션을 다시 시작하십시오"예외가 발생했습니다. 그러나 그들은 순수하게 읽기 작업을하고있었습니다 ...
apptree

0

나는 거의 65GB 인 트랜잭션 테이블 중 하나를 변경 해야하는 비슷한 상황에 처해 있습니다. 나는 두 가지 해결책을 듣는다

  1. 똑바로 ALTER를 사용하여 실행 (X 시간 또는 일 수)
  2. 데이터베이스에 타임 스탬프 열이 있거나 복제 로그를 생성하는지 확인하십시오.
    • 테이블의 사본 (B)을 만듭니다 (A).
    • B에 새 열을 추가하십시오 (여전히 myisam으로 차단됩니다)
    • 거래 비활성화
    • 원래 테이블의 이름을 다른 것으로 바꾸십시오 (백업).
    • 원래 테이블 이름으로 새 테이블 이름을 바꿉니다 (B).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.