KB3067257-remediere: rezultate parțiale într-o interogare a unui index grupat columnstore în SQL Server 2014

Acest articol prezintă o problemă care apare în timpul unei interogări a unui index columnstore grupat în Microsoft SQL Server 2014. Acest articol oferă o rezolvare la această problemă.

Rezumat

Atunci când utilizați o interogare care scanează un index columnstore grupat în Microsoft SQL Server 2014, este posibil, sub condiții rare, să primiți rezultate parțiale ale interogării. Această problemă apare atunci când se execută operațiunea următoare.

Pasul 1

O instrucțiune Transact-SQL [Inserare sau INSERT masiv] Inserează date într-un tabel care are index grupat columnstore. În timpul acestei operațiuni, se aplică următoarele condiții:

  • Atunci când instrucțiunea Transact-SQL ajunge la pragul rowgroup, se închide rowgroup R1 care are segmentul S1.

  • Segmentul S1 indică spre dicționarul local D1.

  • Instrucțiunea continuă să insereze rânduri în noul rowgroup R2.

  • Atunci când rowgroup R1 este închis, dicționarul local D1 nu trebuie, de asemenea, să fie închis. Dacă dicționarul D1 încă mai are spațiul disponibil, îl puteți lăsa deschis și îl puteți reutiliza pentru noul rowgroup R2.

Pasul 2

Dacă instrucțiunea Transact-SQL este terminată anormal sau anulată înainte de a închide noul rowgroup R2, se aplică următoarele condiții:

  • Modificările de metadate columnstore apar în subtranzacțiile care se comit independent de tranzacția exterioară.

  • În acest moment, rowgroup R1 persistă în tabelul de sistem într-un "sub construcție" sau într-o stare invizibilă, iar segmentul referințe S1-dicționar D1.

  • Nu există niciun rând creat în tabelul sistem pentru dicționarul D1. Acest lucru se întâmplă deoarece instrucțiunea Transact-SQL nu are niciodată oportunitatea de a închide rândul existent. Prin urmare, rândul existent persistă.

Pasul 3

Într-o situație tipică, dacă activitatea de fundal tuplu Mover pornește după ce se termină instrucțiunea Transact-SQL, activitatea de fundal elimină invizibil rowgroup R1 și segmentul S1. Dacă se pornește acum o instrucțiune Transact-SQL nouă și creează rowgroup R3 care are un nou segment S3 care necesită un nou dicționar local, nu puteți reutiliza ID-ul intern de dicționar D1. Acest lucru se întâmplă deoarece starea în memorie a columnstore ține evidența ID-urilor de dicționar utilizate. Prin urmare, segment S3 va face referire la Noul dicționar D2.Notă Condiția din acest pas este o condiție comună. Prin urmare, nu are loc nicio corupție.

Pasul 4

Dacă SQL Server pierde starea în memorie a dicționarului D1 înainte ca activitatea tuplu Mover să aibă efect (și efectuează așa cum este descris la pasul 3), apare problema descrisă în acest articol.Note

  • Acest eveniment are loc pentru oricare dintre următoarele motive:

    • SQL Server se confruntă cu supraîncărcarea memoriei, iar conținutul din memoria dicționarului D1 este evacuat din memorie.

    • Instanța SQL Server este repornită.

    • Baza de date care conține indexul columnstore grupat este offline, apoi revine online.

  • După ce se întâmplă oricare dintre aceste evenimente și SQL Server reîncarcă structurile în memorie, nu există nicio înregistrare că a existat un dicționar D1 și ID-ul său intern. Acest lucru se întâmplă deoarece dicționarul D1 nu a fost reținut în tabelele de sistem atunci când instrucțiunea Transact-SQL a fost încheiată sau constatată.

  • Dacă activitatea de fundal tuplu Mover pornește în acest moment, nu se produc erori, deoarece se aplică condițiile descrise în pasul 3.

  • Dacă un nou rowgroup R3 este creat înainte să înceapă activitatea de fundal tuplu (per elementul marcator anterior), SQL Server atribuie același ID intern noului dicționar D1 și face referire la dicționarul D1 pentru segmentul S3 din rowgroup R3.

  • Atunci când activitatea de fundal tuplu Mover pornește după acțiunea anterioară, acesta scade invizibil rowgroup R1 și segmentele sale S1 împreună cu noul dicționar D1. Acest lucru se întâmplă deoarece tuplu Mover consideră că noul dicționar D1 și dicționarul inițial D1 care fac referire la S1 sunt aceleași.Notă Atunci când apare această condiție, nu puteți interoga conținutul rowgroup R3.

Rezolvare

Problema a fost remediată pentru prima dată în următoarele actualizări cumulative pentru SQL Server:

Actualizarea cumulativă 1 pentru SQL server 2014 SP1 Actualizare cumulativă 8 pentru SQL Server 2014Remedierea pentru această problemă este inclusă, de asemenea, în următoarele actualizări de lansare generală a distribuției (GDR):

Actualizare de securitate pentru SQL Server 2014 QFE  Această actualizare include actualizarea cumulativă 8, această remediere importantă și actualizările de securitate necesare pentru MS15-058.Actualizare de securitate pentru SQL Server 2014 RDG  Această actualizare include acest remediu important și remedieri de securitate cumulativă prin MS15-058.Actualizare nesecurizată pentru SQL Server 2014 Service Pack 1 GDR  Această actualizare include doar această remediere importantă.

Fiecare nouă actualizare cumulativă pentru SQL Server conține toate remedierile rapide și toate remedierile de securitate care au fost incluse în actualizarea cumulativă anterioară. Vedeți cele mai recente actualizări cumulative pentru SQL Server:

Mai multe informații

Mesaje de eroareÎntr-o bază de date afectată în prezent, dacă rulează DBCC CHECKDB după ce aplicați această remediere, veți primi următorul mesaj de eroare:

MSG 5289, nivel 16, stat 1, linie 1 grupată columnstore index ' CCI ' din tabel ' t ' are una sau mai multe valori de date care nu corespund valorilor de date dintr-un dicționar. Restaurați datele dintr-o copie de rezervă.

Într-o bază de date afectată în prezent, când se execută o interogare care scanează tabelele afectate după ce aplicați această remediere, primiți următorul mesaj de eroare:

MSG 5288, nivel 16, stat 1, indicele columnstore linie 1 are una sau mai multe valori de date care nu corespund valorilor de date dintr-un dicționar. Vă rugăm să rulați DBCC CHECKDB pentru mai multe informații.

Dacă primiți aceste erori, puteți să salvați datele nedeteriorate prin exportul în masă a datelor din coloanele/rowgroups neafectate, apoi să reîncărcați datele după ce fixați sau creați indexul columnstore grupat. Ar trebui să activați Trace Flag 10207 pentru a suprima eroarea 5288 și a reveni la comportamentul vechi al omiterii rowgroups deteriorate. Notă Mesajele de eroare 5288 și 5289 sunt generate pentru acest rowgroup R3 care are segment S3. Semnalizatorul de urmărire 10207 este utilizat pentru a extrage segmentele de rowgroup R3 care nu sunt afectate de dicționarul lipsă D1.

Interogare pentru bazele de date afectatePentru a determina dacă baza de date care conține columnstore indexs este deja afectată de această problemă, derulează următoarea interogare:

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 

Note

  • Trebuie să rulați această interogare pentru fiecare bază de date care conține columnstore indexs pe serverul care rulează SQL Server. Un set de rezultate necompletate indică faptul că baza de date nu este afectată.

  • Executați această interogare într-o perioadă în care nu există nicio activitate care să creeze noi rowgroups sau să modifice starea rowgroups existente. De exemplu, următoarele activități pot modifica starea rowgroups: index Build, index reorganizare, Inserare masivă, tuplu Mover prin comprimarea magazinelor Delta. Înainte de a executa interogarea, puteți să dezactivați activitatea de fundal tuplu Mover, utilizând semnalizatorul de urmărire 634. Utilizați această comandă pentru a dezactiva activitatea de fundal: DBCC TRACEON (634,-1). După ce interogarea termină de executat, nu uitați să reactivați activitatea de fundal utilizând comanda: DBCC TRACEOFF (634,-1). De asemenea, asigurați-vă că nu există comenzi INSERT/BCP/selectare în masă care inserează date în tabelele care utilizează indexul columnstore în timp ce rulează această interogare. Se recomandă să utilizați acești pași pentru a împiedica interogarea să returneze false-pozitive.

Stare

Microsoft a confirmat că aceasta este o problemă în produsele Microsoft enumerate în secțiunea „Se aplică la”.

Aveți nevoie de ajutor suplimentar?

Extindeți-vă competențele
Explorați instruirea
Fiți primul care obține noile caracteristici
Alăturați-vă la Microsoft Insider

V-a fost de ajutor această informație?

Vă mulțumim pentru feedback!

Vă mulțumim pentru feedback! Se pare că ar fi util să luați legătura cu unul dintre agenții noștri de asistență Office.

×