이 문서에서는 Microsoft SQL Server 2014에서 클러스터형 columnstore 인덱스를 쿼리 하는 동안 발생 하는 문제에 대해 설명 합니다. 이 문서에서는이 문제에 대 한 해결 방법을 제공 합니다.
요약
Microsoft SQL Server 2014에서 클러스터형 columnstore 인덱스를 검사 하는 쿼리를 사용 하는 경우 드문 조건에서 부분적인 쿼리 결과를 받을 수 있습니다. 이 문제는 다음 작업이 실행 되는 경우에 발생 합니다.
1단계
Transact-sql 문 [삽입 또는 일괄 삽입]은 클러스터형 columnstore 인덱스가 있는 테이블에 데이터를 삽입 합니다. 이 작업을 수행 하는 동안 다음 조건이 적용 됩니다.
-
Transact-sql 문이 rowgroup 임계값에 도달 하면이는 rowgroup R1을 닫고,이는 S1 이라는 세그먼트를 가집니다.
-
S1 세그먼트는 로컬 사전 D1을 가리킵니다.
-
문은 새 rowgroup R2에 계속 해 서 행을 삽입 합니다.
-
Rowgroup R1이 닫히면 로컬 사전 D1도 닫을 필요가 없습니다. 사전 D1에 사용 가능한 공간이 있으면이 공간을 열어 두고 새 rowgroup R2에 다시 사용할 수 있습니다.
2단계
Transact-sql 문이 비정상적으로 종료 되거나 취소 된 경우 새 rowgroup R2를 닫기 전에 다음 조건이 적용 됩니다.
-
외부 트랜잭션과 독립적으로 커밋되는 subtransactions에서 Columnstore 메타 데이터 변경이 발생 합니다.
-
이 시점에서 rowgroup R1은 시스템 테이블에서 "생성 중" 또는 보이지 않는 상태를 유지 하 고, 세그먼트 S1은 dictionary D1을 참조 합니다.
-
Dictionary D1의 시스템 테이블에서 만든 행이 없습니다. 이는 Transact-sql 문에 기존 행을 닫을 기회가 없기 때문입니다. 따라서 기존 행이 계속 됩니다.
3 단계
일반적인 경우에는 Transact-sql 문이 끝난 후에 튜플 동기 백그라운드 작업이 시작 되 면 백그라운드 작업이 보이지 않는 rowgroup R1 및 segment S1을 제거 합니다. 새 Transact-sql 문이 시작 되 고 새 로컬 사전이 필요한 새 세그먼트 S3이 있는 rowgroup R3를 만드는 경우 dictionary D1의 내부 ID를 다시 사용할 수 없습니다. 이는 columnstore의 메모리 내 상태는 사용 되는 사전 Id를 추적 하기 때문입니다. 따라서 세그먼트 S3은 새 dictionary D2를 참조 합니다.참고 이 단계의 조건은 일반적인 조건입니다. 따라서 손상은 발생 하지 않습니다.
4 단계
SQL Server가 튜플 이동 작업이 적용 되기 전에 사전 D1의 메모리 내 상태를 손실 하면 (3 단계에서 설명한 대로 수행 됨)이 문서에서 설명 하는 문제가 발생 합니다.참고
-
이 이벤트는 다음과 같은 이유로 발생 합니다.
-
SQL Server에서 메모리 오버 로드가 발생 하 고, dictionary D1의 메모리 내 내용이 메모리에서 제거 됩니다.
-
SQL Server 인스턴스가 다시 시작 됩니다.
-
클러스터형 columnstore 인덱스가 포함 된 데이터베이스가 오프 라인 상태가 되 고 다시 온라인 상태가 됩니다.
-
-
이러한 이벤트 중 하나가 발생 하 고 SQL Server에서 메모리 내 구조를 다시 로드 하는 경우 사전 D1 및 해당 내부 ID가 존재 하는 레코드가 없습니다. 이는 Transact-sql 문이 종료 되거나 conceled 때 사전 D1이 시스템 테이블에 보존 되지 않기 때문입니다.
-
이 시점에서 튜플 동기 백그라운드 작업이 시작 되 면 3 단계에서 설명 하는 조건이 적용 되므로 오류가 발생 하지 않습니다.
-
튜플 동기 백그라운드 작업이 시작 되기 전에 새 rowgroup R3이 생성 되는 경우 (이전 글머리 기호 항목 당) SQL Server는 새 사전 D1에 동일한 내부 ID를 할당 하 고 rowgroup R3의 세그먼트 S3에 대 한 dictionary D1을 참조 합니다.
-
이전 작업 이후에 튜플 동기 백그라운드 작업이 시작 되 면 표시 되지 않는 rowgroup R1 및 해당 세그먼트 S1이 새 dictionary D1과 함께 삭제 됩니다. 이는 튜플 이동 시 새 사전 D1과 S1 참조의 원래 사전 D1이 같은 것으로 간주 하기 때문에 발생 합니다.참고 이 문제가 발생 하면 rowgroup R3의 콘텐츠를 쿼리할 수 없습니다.
해결 방법
이 문제는 다음과 같은 SQL Server 누적 업데이트에서 처음 수정 되었습니다.
Sql server 2014 SP1 누적 업데이트 8 용 누적 업데이트 1( sql server 2014 )이 문제에 대 한 픽스는 다음 GDR (일반 배포 릴리스) 업데이트에도 포함 되어 있습니다.
SQL Server 2014 QFE에 대 한 보안 업데이트 이 업데이트에는 누적 업데이트 8,이 중요 한 수정 사항, 필수 MS15-058 보안 업데이트가 포함 되어 있습니다.SQL Server 2014 GDR 용 보안 업데이트 이 업데이트에는 MS15-058를 통한이 중요 한 수정 및 누적 보안 수정 사항이 포함 되어 있습니다.SQL Server 2014 서비스 팩 1 GDR 용 비보안 업데이트 이 업데이트에는이 중요 한 해결 방법이 포함 되어 있습니다.
각각의 새로운 새 누적 업데이트에는 이전 누적 업데이트에 포함 된 모든 핫픽스와 모든 보안 수정 사항이 포함 되어 있습니다. SQL Server의 최신 누적 업데이트를 참조 하세요.
추가 정보
오류 메시지현재 영향을 받는 데이터베이스에서이 수정 프로그램을 적용 한 후에 DBCC CHECKDB를 실행 하면 다음과 같은 오류 메시지가 나타납니다.
메시지 5289, 수준 16, 상태 1, 줄 1 클러스터 된 columnstore 인덱스 ' t e '에는 사전의 데이터 값과 일치 하지 않는 데이터 값이 하나 이상 있습니다. 백업에서 데이터를 복원 합니다.
현재 영향을 받는 데이터베이스에서이 수정 프로그램을 적용 한 후 영향을 받는 테이블을 검사 하는 쿼리를 실행 하면 다음과 같은 오류 메시지가 나타납니다.
메시지 5288, 수준 16, 상태 1, 줄 1 Columnstore 인덱스에 사전의 데이터 값과 일치 하지 않는 데이터 값이 하나 이상 있습니다. 자세한 정보를 보려면 DBCC CHECKDB를 실행 하세요.
이러한 오류가 표시 되는 경우에는 영향을 받지 않는 열/rowgroups의 데이터를 일괄적으로 내보낸 다음 클러스터형 columnstore 인덱스를 삭제 하거나 만든 후 데이터를 다시 로드 하 여 손상 되지 않은 데이터를 저장할 수 있습니다. 5288 오류를 표시 하지 않고 손상 된 rowgroups를 건너뛰는 이전 동작으로 되돌리려면 추적 플래그 10207을 사용 하도록 설정 해야 합니다. 참고세그먼트 S3이 있는이 rowgroup R3에 대 한 오류 메시지 5288 및 5289이 생성 됩니다. Trace flag 10207는 누락 된 사전 D1의 영향을 받지 않는 rowgroup R3 세그먼트를 추출 하는 데 사용 됩니다.
영향을 받는 데이터베이스 쿼리Columnstore 인덱스가 포함 된 데이터베이스가 이미이 문제의 영향을 받는지 여부를 확인 하려면 다음 쿼리를 실행 합니다.
select object_name(i.object_id) as table_name, i.name as index_name, p.partition_number, count(distinct s.segment_id) as damaged_rowgroups from sys.indexes i join sys.partitions p on p.object_id = i.object_id and p.index_id = i.index_id join sys.column_store_row_groups g on g.object_id = i.object_id and g.index_id = i.index_id and g.partition_number = p.partition_number join sys.column_store_segments s on s.partition_id = p.partition_id and s.segment_id = g.row_group_id where i.type in (5, 6) and s.secondary_dictionary_id <> -1 and g.state_description = 'COMPRESSED' and s.secondary_dictionary_id not in ( select dictionary_id from sys.column_store_dictionaries d where d.hobt_id = p.hobt_id and d.column_id = s.column_id ) group by object_name(i.object_id), i.name, p.partition_number
참고
-
SQL Server를 실행 하는 서버에서 columnstore 인덱스를 포함 하는 모든 데이터베이스에 대해이 쿼리를 실행 해야 합니다. 빈 결과 집합은 데이터베이스가 영향을 받지 않음을 나타냅니다.
-
새 rowgroups를 만들거나 기존 rowgroups의 상태를 변경할 활동이 없는 경우 기간 중에이 쿼리를 실행 합니다. 예를 들어 다음 작업은 rowgroups의 상태 (인덱스 빌드, 인덱스 재구성, 대량 삽입, 튜플 동기 저장소 압축)를 수정할 수 있습니다. 쿼리를 실행 하기 전에 추적 플래그 634를 사용 하 여 백그라운드 튜플 동기 작업을 사용 하지 않도록 설정할 수 있습니다. 이 명령을 사용 하 여 백그라운드 작업 (DBCC TRACEON (634,-1)을 사용 하지 않도록 설정 합니다. 쿼리 실행이 완료 되 면 DBCC TRACEOFF (634,-1)명령을 사용 하 여 백그라운드 작업을 다시 사용 하도록 설정 해야 합니다. 또한이 쿼리를 실행 하는 동안 columnstore 인덱스를 사용 하는 테이블에 데이터를 삽입 하는 대량 삽입/BCP/SELECT IN 명령이 없는지 확인 합니다. 이 단계를 사용 하 여 쿼리에서 가양성을 반환 하는 것을 방지 하는 것이 좋습니다.
상태
Microsoft는 "적용 대상" 절에 나열한 Microsoft 제품에서 이 문제를 확인했습니다.