KB3067257 – OPRAVA: Částečné výsledky dotazu na clusterovaný index columnstore v SQL Server 2014

Platí pro
SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use)

Tento článek popisuje problém, ke kterému dochází během dotazu na index clusterovaného úložiště sloupců v systému Microsoft SQL Server 2014. Tento článek obsahuje řešení tohoto problému.

Shrnutí

Když použijete dotaz, který prohledává index clusterovaného úložiště sloupců v Microsoft SQL Server 2014, můžete ve výjimečných případech obdržet částečné výsledky dotazu.

K tomuto problému dochází při spuštění následující operace.

Krok 1

Příkaz Transact-SQL [INSERT nebo BULK-INSERT] vloží data do tabulky, která má clusterovaný index columnstore. Při této operaci platí následující podmínky:

  • Když příkaz Transact-SQL dosáhne mezní hodnoty skupiny řádků, zavře skupinu řádků R1, která má segment S1.
  • Segment S1 odkazuje na místní slovník D1.
  • Příkaz pokračuje vkládáním řádků do nové skupiny řádků R2.
  • Když je zavřená řádková skupina R1, nemusí být zavřený ani místní slovník D1. Pokud je ve slovníku D1 stále volné místo, můžete jej nechat otevřený a znovu jej použít pro novou skupinu řádků R2.

Krok 2

Pokud je příkaz Transact-SQL ukončen abnormálně nebo zrušen před zavřením nové skupiny řádků R2, platí následující podmínky:

  • Ke změnám metadat columnstore dochází v dílčích transakcích, které se potvrzují nezávisle na vnější transakci.
  • V tomto okamžiku skupina řádků R1 přetrvává v systémové tabulce ve stavu "ve výstavbě" nebo NEVIDITELNÝ a segment S1 odkazuje na slovník D1.
  • V systémové tabulce není vytvořen žádný řádek pro slovník D1. Důvodem je to, že příkaz Transact-SQL nemá nikdy příležitost uzavřít existující řádek. Existující řádek proto zůstane zachován.

Krok 3

V typické situaci, pokud se úloha na pozadí pro přesun řazené kolekce členů spustí po dokončení příkazu Transact-SQL, úloha na pozadí odebere neviditelnou skupinu řádků R1 a segment S1. Pokud je nyní spuštěn nový příkaz Transact-SQL a vytvoří skupinu řádků R3, která má nový segment S3, který vyžaduje nový místní slovník, nemůžete znovu použít interní ID slovníku D1. Důvodem je to, že stav columnstore v paměti sleduje ID slovníku, která se používají. Proto bude segment S3 odkazovat na nový slovník D2.

Poznámka: Podmínka v tomto kroku je běžná. Proto nedochází k žádnému poškození.

Krok 4

Pokud SQL Server ztratí stav v paměti slovníku D1 před tím, než se úloha přesunu řazené kolekce členů projeví (a provádí se způsobem popsaným v kroku 3), dojde k problému popsanému v tomto článku.

Poznámky

  • K této události dochází z některého z následujících důvodů:

    • SQL Server dochází k přetížení paměti a obsah slovníku D1 v paměti se vyřadí z paměti.
    • Instance SQL Server se restartuje.
    • Databáze, která obsahuje clusterovaný index columnstore, přejde do offline režimu a pak se vrátí do online režimu.
  • Jakmile dojde k některé z těchto událostí a SQL Server znovu načte struktury v paměti, neexistuje žádný záznam o tom, že existoval slovník D1 a jeho interní ID. Je to proto, že slovník D1 nebyl zachován v systémových tabulkách, když byl příkaz Transact-SQL ukončen nebo převeden.

  • Pokud se v tomto okamžiku spustí úloha přesunu řazené kolekce členů na pozadí, nedojde k žádným chybám, protože platí podmínky popsané v kroku 3.

  • Pokud se před spuštěním úlohy na pozadí pro přesun řazené kolekce členů vytvoří nová skupina řádků R3 (podle předchozí položky odrážky), přiřadí SQL Server novému slovníku D1 stejné interní ID a odkazuje na slovník D1 pro segment S3 ve skupině řádků R3.

  • Když se úloha na pozadí pro přesun řazené kolekce členů spustí po předchozí akci, vynechá neviditelnou skupinu řádků R1 a její segmenty S1 společně s novým slovníkem D1. K tomu dochází, protože přesun řazené kolekce členů považuje nový slovník D1 a původní slovník D1, na který odkazuje S1, za stejné.

    Poznámka: Když dojde k této podmínce, nelze dotazovat se na obsah skupiny řádků R3.

Řešení

Tento problém byl poprvé opraven v následujících kumulativních aktualizacích pro SQL Server:

Kumulativní aktualizace 1 pro SQL Server 2014 SP1
        
         Kumulativní aktualizace 8 pro SQL Server 2014
Oprava tohoto problému je také součástí následujících aktualizací GDR (General Distribution Release):

Aktualizace zabezpečení pro SQL Server 2014 QFE  
Tato aktualizace obsahuje kumulativní aktualizaci 8, tuto důležitou opravu a požadované aktualizace zabezpečení MS15-058.

Aktualizace zabezpečení pro SQL Server 2014 GDR  
Tato aktualizace obsahuje tuto důležitou opravu a kumulativní opravy zabezpečení prostřednictvím MS15-058.

Aktualizace netýkající se zabezpečení pro SQL Server 2014 Service Pack 1 GDR  
Tato aktualizace obsahuje jenom tuto důležitou opravu.

Informace o kumulativních aktualizacích pro SQL Server

Každá nová kumulativní aktualizace pro SQL Server obsahuje všechny opravy hotfix a všechny opravy zabezpečení, které byly součástí předchozí kumulativní aktualizace. Podívejte se na nejnovější kumulativní aktualizace pro SQL Server:

      

Další informace

Chybové zprávyPokud v databázi, která je aktuálně ovlivněna, spustíte po použití této opravy databázi DBCC CHECKDB, obdržíte následující chybovou zprávu:

Poznámka

Zpráva 5289, úroveň 16, stav 1, řádek 1
Clusterovaný index columnstore cci v tabulce t obsahuje jednu nebo více datových hodnot, které neodpovídají hodnotám dat ve slovníku. Obnovte data ze zálohy.

Když v aktuálně ovlivněné databázi spustíte dotaz, který po použití této opravy prohledá ovlivněné tabulky, zobrazí se následující chybová zpráva:

Poznámka

Zpráva 5288, úroveň 16, stav 1, řádek 1
Index columnstore obsahuje jednu nebo více datových hodnot, které neodpovídají datovým hodnotám ve slovníku. Další informace získáte spuštěním příkazu DBCC CHECKDB.

Pokud se zobrazí tyto chyby, můžete nepoškozená data uložit hromadným exportem dat neovlivněných sloupců nebo skupin řádků a následným opětovným načtením dat po vyřazení nebo vytvoření indexu clusterovaného columnstore. Měli byste povolit příznak sledování 10207, abyste potlačili chybu 5288 a vrátili se ke starému chování přeskakování poškozených skupin řádků.

Poznámka: Pro tuto skupinu řádků R3 se segmentem S3 jsou generovány chybové zprávy 5288 a 5289. Příznak sledování 10207 se používá k extrakci segmentů řádkové skupiny R3, které nejsou ovlivněny chybějícím slovníkem D1.

Dotaz na ovlivněné databázeChcete-li zjistit, zda databáze, která obsahuje indexy columnstore, je již tímto problémem ovlivněna, spusťte následující dotaz:

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 

Poznámky

  • Tento dotaz musíte spustit pro každou databázi, která obsahuje indexy columnstore na serveru, na kterém běží SQL Server. Prázdná sada výsledků označuje, že databáze není ovlivněna.

  • Tento dotaz spusťte během období, kdy neexistuje žádná aktivita, která by vytvořila nové skupiny řádků nebo změnila stav stávajících skupin řádků. Například následující aktivity mohou změnit stav skupin řádků: sestavení indexu, reorganizace indexu, hromadné vložení, přesun řazené kolekce členů komprese rozdílových úložišť.

    Před spuštěním dotazu můžete zakázat úlohu přesunu řazené kolekce členů na pozadí pomocí příznaku trasování 634. Chcete-li zakázat úlohu na pozadí, použijte tento příkaz: DBCC TRACEON ( 634 ; -1 ). Po dokončení provádění dotazu nezapomeňte znovu povolit úlohu na pozadí pomocí příkazu: DBCC TRACEOFF ( 634 ; -1 ).

    Také se ujistěte, že neexistují žádné příkazy BULK INSERT/BCP/SELECT-IN, které vkládají data do tabulek, které používají index columnstore, když je tento dotaz spuštěný.

    Tento postup se doporučuje použít, abyste zabránili vrácení falešně pozitivních výsledků dotazu.

Stav

Společnost Microsoft potvrdila, že se jedná o problém produktů Microsoft, které jsou uvedeny v sekci Platí pro.