KB3067257 - CORREÇÃO: Resultados parciais numa consulta de um índice columnstore agrupado no SQL Server 2014

Aplica-se a
SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use)

Este artigo descreve um problema que ocorre durante uma consulta de um índice columnstore clusterizado no Microsoft SQL Server 2014. Este artigo fornece uma resolução para este problema.

Resumo

Quando utiliza uma consulta que analisa um índice columnstore agrupado no Microsoft SQL Server 2014, poderá, em raras condições, receber resultados parciais da consulta.

Esse problema ocorre quando a seguinte operação é executada.

Etapa 1

Uma instrução Transact-SQL [INSERT ou BULK-INSERT] insere dados em uma tabela que tenha o índice columnstore clusterizado. Durante esta operação, aplicam-se as seguintes condições:

  • Quando a instrução Transact-SQL atinge o limite do grupo de linhas, ela fecha o grupo de linhas R1 que tem o segmento S1.
  • O segmento S1 aponta para o dicionário local D1.
  • A instrução continua a inserir linhas no novo grupo de linhas R2.
  • Quando o grupo de linhas R1 está fechado, o dicionário local D1 também não precisa ser fechado. Se o dicionário D1 ainda tiver espaço disponível, pode deixá-lo aberto e reutilizá-lo para o novo grupo de linhas R2.

Etapa 2

Se a instrução Transact-SQL for encerrada anormalmente ou cancelada antes de fechar o novo grupo de linhas R2, as seguintes condições se aplicam:

  • As alterações de metadados do Columnstore ocorrem em subtransações que são confirmadas independentemente da transação externa.
  • Neste ponto, o grupo de linhas R1 persiste na tabela do sistema em um estado "em construção" ou INVISÍVEL, e o segmento S1 referencia o dicionário D1.
  • Não é criada nenhuma linha na tabela do sistema para o dicionário D1. Isso ocorre porque a instrução Transact-SQL nunca tem a oportunidade de fechar a linha existente. Portanto, a linha existente persiste.

Etapa 3

Em uma situação típica, se a tarefa em segundo plano do movimentador de cadeia for iniciada depois que a instrução Transact-SQL terminar, a tarefa em segundo plano removerá o grupo de linhas invisível R1 e o segmento S1. Se uma nova instrução Transact-SQL for iniciada agora e criar o grupo de linhas R3 com um novo segmento S3 que requer um novo dicionário local, não será possível reutilizar a ID interna do dicionário D1. Isso ocorre porque o estado na memória do columnstore controla as IDs de dicionário usadas. Portanto, o segmento S3 fará referência ao novo dicionário D2.

Observação A condição nesta etapa é uma condição comum. Portanto, não ocorre nenhum dano.

Etapa 4

Se SQL Server perder o estado na memória do dicionário D1 antes que a tarefa de movimentação de cadeia de caracteres entre em vigor (e seja executada conforme descrito na Etapa 3), ocorrerá o problema descrito neste artigo.

Anotações

  • Este evento ocorre por qualquer um dos seguintes motivos:

    • SQL Server sofre sobrecarga de memória e os conteúdos na memória do dicionário D1 são removidos da memória.
    • A instância do SQL Server é reiniciada.
    • A base de dados que contém o índice columnstore agrupado fica offline e, em seguida, volta a ficar online.
  • Depois que qualquer um desses eventos ocorrer e SQL Server recarregar as estruturas na memória, não há registro de que um dicionário D1 e sua ID interna existiram. Isso ocorre porque o dicionário D1 não foi retido nas tabelas do sistema quando a instrução Transact-SQL foi encerrada ou ocultada.

  • Se a tarefa em segundo plano de movimentação de cadeia começar neste ponto, não ocorrerão erros porque as condições descritas na Etapa 3 se aplicam.

  • Se um novo grupo de linhas R3 for criado antes do início da tarefa em segundo plano do movimentador de tupla (de acordo com o item de marca anterior), SQL Server atribuirá a mesma ID interna ao novo dicionário D1 e fará referência ao dicionário D1 para o segmento S3 no grupo de linhas R3.

  • Quando a tarefa em segundo plano do movimentador de tupla começa após a ação anterior, ela remove o grupo de linhas invisível R1 e seus segmentos S1 juntamente com o novo dicionário D1. Isso ocorre porque o tupla mover considera que o novo dicionário D1 e o dicionário original D1 que S1 referencia são os mesmos.

    Observação Quando essa condição ocorre, você não pode consultar o conteúdo do grupo de linhas R3.

Resolução

O problema foi corrigido primeiro nas seguintes atualizações cumulativas para SQL Server:

Atualização cumulativa 1 para SQL Server 2014 SP1
        
         Atualização cumulativa 8 para SQL Server 2014
A correção para este problema também está incluída nas seguintes atualizações GDR (General Distribution Release):

Atualização de segurança para o SQL Server 2014 QFE  
Esta atualização inclui a Atualização Cumulativa 8, esta correção importante e as atualizações de segurança MS15-058 necessárias.

Atualização de segurança para SQL Server 2014 GDR  
Esta atualização inclui esta correção importante e correções de segurança cumulativas até à atualização MS15-058.

Atualização não relacionada à segurança para SQL Server 2014 Service Pack 1 GDR  
Esta atualização inclui apenas esta correção importante.

Sobre atualizações cumulativas para o SQL Server

Cada nova atualização cumulativa para SQL Server contém todos os hotfixes e todas as correções de segurança que foram incluídas com a atualização cumulativa anterior. Consulte as atualizações cumulativas mais recentes para SQL Server:

      

Mais informações

Mensagens de erroEm um banco de dados atualmente afetado, se você executar DBCC CHECKDB depois de aplicar essa correção, você receber a seguinte mensagem de erro:

Observação

Msg 5289, Nível 16, Estado 1, Linha 1
O índice de armazenamento de colunas agrupadas "cci" na tabela "t" tem um ou mais valores de dados que não correspondem aos valores de dados num dicionário. Restaure os dados a partir de uma cópia de segurança.

Numa base de dados atualmente afetada, quando executa uma consulta que analisa as tabelas afetadas depois de aplicar esta correção, recebe a seguinte mensagem de erro:

Observação

Msg 5288, Nível 16, Estado 1, Linha 1
O índice Columnstore tem um ou mais valores de dados que não correspondem aos valores de dados num dicionário. Execute DBCC CHECKDB para obter mais informações.

Se você receber esses erros, poderá salvar os dados não corrompidos exportando em massa os dados de colunas/grupos de linhas não afetados e, em seguida, recarregando os dados depois de descartar ou criar o índice columnstore clusterizado. Deve ativar o sinalizador de rastreio 10207 para suprimir o erro 5288 e reverter ao comportamento antigo de ignorar grupos de linhas danificados.

Observação As mensagens de erro 5288 e 5289 são geradas para este grupo de linhas R3 que tem segmento S3. O sinalizador de rastreamento 10207 é usado para extrair os segmentos do grupo de linhas R3 que não são afetados pelo dicionário D1 ausente.

Consulta para bancos de dados afetadosPara determinar se o banco de dados que contém índices columnstore já é afetado por esse problema, execute a seguinte consulta:

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 

Anotações

  • Tem de executar esta consulta em todas as bases de dados que contenham índices columnstore no servidor que está a executar o SQL Server. Um conjunto de resultados vazio indica que a base de dados não é afetada.

  • Execute esta consulta durante um período em que não existe nenhuma atividade que crie novos grupos de linhas ou altere o estado de grupos de linhas existentes. Por exemplo, as seguintes atividades podem modificar o estado de grupos de linhas: compilação de índice, reorganização de índice, inserção em massa, compactação de tupla compactando repositórios delta.

    Antes de executar a consulta, pode desativar a tarefa mover de cadeia de identificação em segundo plano utilizando o sinalizador de rastreio 634. Use este comando para desativar a tarefa em segundo plano: DBCC TRACEON ( 634 , -1 ). Depois de concluir a execução da consulta, lembre-se de reativar a tarefa em segundo plano utilizando o comando: DBCC TRACEOFF ( 634 , -1 ).

    Certifique-se também de que não existem comandos BULK INSERT/BCP/SELECT-INTO a inserir dados nas tabelas que utilizam o índice columnstore enquanto esta consulta está em execução.

    Recomenda-se que utilize estes passos para impedir que a consulta devolva falsos positivos.

Status

A Microsoft confirmou que este é um problema nos produtos da Microsoft listados na seção "Aplica-se a".