가동 중지 시간을 최소화하면서 큰 테이블에 rowversion 열을 추가하는 방법


21

SQL Server 2008 이상을 사용하여 간단히 큰 테이블에 rowversion 열을 추가하고 싶습니다.

ALTER TABLE [Tablename]
ADD Rowversion [Rowversion] NOT NULL

그런 다음 테이블을 너무 오래 업데이트 할 수 없습니다.

이 다운 타임을 줄이기 위해 어떤 전략을 사용할 수 있습니까? 나는 무엇이든 고려할 것이다. 물론 단순할수록 좋습니다. 그러나 나는 어떤 전략을 고려할 것입니다.

내 생각은 최후의 수단으로 트리거에 의해 유지 관리되는 복사 준비 테이블을 유지하고 준비 테이블을 원래 테이블로 sp_rename 할 수 있다는 것입니다. 그러나 나는 더 간단하고 쉬운 것을 기대하고 있습니다.

답변:


26

동일한 스키마와 rowversion 열을 사용하여 새 테이블을 작성하고 모두 통합을 수행하는 두 테이블 위에보기를 추가하십시오. 사람들에게 뷰를 사용하고 기본 테이블 및 뷰에 대해 트리거 대신 트리거를 작성하도록하십시오.

삽입은 새 테이블로 전송되고 업데이트는 데이터를 새 테이블로 이동하고 삭제는 두 테이블 모두에 적용되어야합니다.

그런 다음 백그라운드에서 배치 이동을 수행하여 한 번에 많은 레코드를 새 테이블로 이동하십시오. 이 작업이 진행되는 동안에도 동시성 문제가 발생할 수 있으며 일부 실행 계획이 있지만 이동 중에 온라인 상태를 유지할 수 있습니다.

이상적으로는 금요일 오후에 프로세스를 시작하여 최종 사용자에 대한 영향을 최소화하고 월요일 아침 전에 처리를 시도하십시오. 일단 배치되면 뷰를 새 테이블 만 가리 키도록 변경할 수 있으며 복잡한 실행 계획이 사라집니다. 이상적으로

데이터가 일괄 적으로 마이그레이션 될 때 트리거가 발생하지 않도록하려면 트리거에서 삭제 / 삽입 된 테이블의 행 수를 확인하고 일괄 처리의 행 수에 가까운 경우 활동을 건너 뜁니다.


마지막으로 Michael은 더 안정적인 계획을 얻기 위해 뷰를 건너 뛰고 원래 테이블에서 삭제하지 않기로 결정했습니다. 트레이드 오프는 본질적으로 두 개의 테이블 사본을 보유하고있었습니다. 그는 그것을 일련의 블로그 게시물 로 바꾸었다 .


7

미리 계획 할 시간이 있다면 훨씬 쉬운 해결책이 있습니다 ... (일반적으로)

긴 잠금은 스토리지 계층에서 페이지 분할로 인해 발생합니다. 그래서 당신의 자신의 일정에 따라 그들을 강제로.

  1. datatype을 사용하여 NULL 가능 임시 열을 추가하십시오 VARBINARY(8).
  2. 데이터베이스에서 사용 가능한 여유 시간을 찾아 필드에 유효한 값으로 기존 레코드의 배치를 업데이트하십시오. ( 0x0000000027F95A5B예를 들어)
  3. 업데이트는 필요한 페이지 분할을 강제로 수행하고 테이블에 더 많은 공간을 할당합니다.
  4. 잡히면 임시 열을 삭제하고 (할당 된 스토리지를 건드리지 않음) rowversion 열을 추가하십시오.
  5. 페이지 분할이 없으며 값을 채울만큼 오래 걸리는 잠금이 필요합니다.

나는 이것을 10 분 안에 150M 행 테이블에 rowversion 열을 추가하는 데 성공적으로 사용했습니다.

주의 사항 ... varchar 필드가 큰 테이블이있는 경우 (특히 varchar(max)) SQL Server는 새로 사용 가능한 공간을 재사용하는 대신 테이블을 다시 작성하기로 결정합니다. 아직도 그 주위에 방법을 찾으려고 노력하고 있습니다.


흥미롭게도 내 질문에 "너무 긴"의미가 무엇인지 명시하지 않은 것 같습니다. 시나리오에 30 분 이상이 걸리고 10 분이 허용되는 경우이 솔루션이 작동합니다. 필자의 시나리오는 다운 타임 제로를 달성하거나보다 구체적으로 10 초 미만을 달성하는 것과 관련이 있으며, 이는 브렌트의 답변에 의해 달성됩니다.
Michael J Swart

1

경우] TIMESTAMP당신이 추가가 NULLABLE:

  1. VARBINARY(8)열 추가
  2. 데이터로 채 웁니다.

채워진 후, 방금 추가하고 채운 열에 대해 연속적인 SQL 문 DROP에서 VARBINARY(8)열을 추가하십시오 TIMESTAMP NULL.


경우] TIMESTAMP당신이 추가가 NOT NULLABLE:

  1. BINARY(8)열 추가
  2. 데이터로 채 웁니다.

이 채워진 후, 다시 SQL 문에 뒤에, 열 당신은 추가 인구와 열입니다.DROPBINARY(8)ADD THE TIMESTAMP NOT NULL

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