メイン コンテンツへスキップ
サポート
Microsoft アカウントでサインイン
サインインまたはアカウントを作成してください。
こんにちは、
別のアカウントを選択してください。
複数のアカウントがあります
サインインに使用するアカウントを選択してください。

この記事では、Microsoft SQL Server 2014 でクラスター化インデックスを作成するときに発生する問題について説明します。 この記事では、この問題の 解決方法 について説明します。

概要

Microsoft SQL Server 2014 で、クラスター化された列ストアインデックスをスキャンするクエリを使用すると、まれな条件下で、一部のクエリ結果が返されることがあります。この問題は、次の操作が実行されたときに発生します。

手順 1

Transact-sql ステートメント [INSERT または BULK INSERT] は、クラスター化された列ストアインデックスを持つテーブルにデータを挿入します。 この操作では、次の条件が適用されます。

  • Transact-sql ステートメントが [行間] のしきい値に達すると、セグメント S1 がある行 # R1 が終了します。

  • セグメント S1 はローカル辞書 D1 をポイントします。

  • ステートメントでは、新しい行と行の挿入が続行されます。

  • 行名 R1 が閉じている場合、ローカル辞書 D1 も閉じる必要はありません。 Dictionary D1 でも利用可能な領域がある場合は、そのまま開いたままにして、新しい行を作成します。

手順 2

Transact-sql ステートメントが新しい行を終了する前に異常終了するか、取り消された場合は、次の条件が適用されます。

  • 外部のトランザクションとは独立してコミットする subtransactions で、列ストアのメタデータの変更が発生します。

  • この時点では、行システム R1 は、"工事中" または "表示されない状態" のシステムテーブルに保持され、セグメント S1 は dictionary D1 を参照します。

  • 辞書 D1 のシステムテーブルで作成された行がありません。 これは、Transact-sql ステートメントに既存の行を閉じる機会がないためです。 そのため、既存の行は保持されます。

手順3

一般的な状況では、Transact-sql ステートメントの終了後に tuple mover のバックグラウンドタスクが開始された場合、バックグラウンドタスクは非表示の行の R1 とセグメント S1 を削除します。 新しい Transact-sql ステートメントが開始され、新規のローカル辞書を必要とする新しいセグメント S3 を持つ行 # R3 が作成された場合は、dictionary D1 の内部 ID を再利用することはできません。 これは、列ストアのインメモリ状態が使用されている辞書 Id を追跡しているためです。 そのため、セグメント S3 は新しいディクショナリ D2 を参照します。注: この手順の条件は、一般的な条件です。 そのため、破損は発生しません。

手順4

タプルムーバタスクが有効になる前に (手順3で説明したように)、SQL Server が辞書 D1 のインメモリ状態を失った場合、この記事で説明されている問題が発生します。注意事項

  • このイベントは、次のいずれかの理由で発生します。

    • SQL Server エクスペリエンスメモリのオーバーロード、および辞書 D1 のメモリ内のコンテンツはメモリから削除されます。

    • SQL Server のインスタンスが再起動されます。

    • クラスター化された列ストアインデックスを含むデータベースがオフラインになり、オンラインに戻ります。

  • いずれかのイベントが発生した後、SQL Server によってメモリ内の構造が再読み込みされると、辞書 D1 とその内部 ID が存在するレコードはありません。 これは、Transact-sql ステートメントが終了するか、または実行されたときに、dictionary D1 がシステムテーブルに保持されなかったためです。

  • タプルムーバのバックグラウンドタスクがこの時点で開始された場合、手順3で説明されている条件が適用されるため、エラーは発生しません。

  • タプルムーバのバックグラウンドタスクが開始される前に (前の箇条書き項目に対して)、新しい行を作成すると、SQL Server によって新しいディクショナリの D1 に同じ内部 ID が割り当てられます。

  • タプルムーバのバックグラウンドタスクは、前のアクションの後で開始されると、非表示の行 R1 とそのセグメント S1 を新しい辞書 D1 と共に削除します。 これは、組ムーバで、新しいディクショナリ D1 と、S1 による参照が同じであると見なされるために発生します。注: この状況が発生した場合、行 # R3 のコンテンツを照会することはできません。

解決方法

この問題は、SQL Server の次の累積的な更新プログラムで最初に修正されました。

Sql server 2014 SP1 の累積的な更新プログラム1のsql server 2014 の累積更新プログラム 8この問題の修正プログラムは、次の一般的な配布リリース (GDR) 更新プログラムにも含まれています。

SQL Server 2014 QFE のセキュリティ更新プログラム  この更新プログラムには、累積更新プログラム8、この重要な修正プログラム、および必須の MS15 058 セキュリティ更新プログラムが含まれています。SQL Server 2014 GDR 用のセキュリティ更新プログラム  この更新プログラムには、MS15 から058までの重要な修正プログラムと累積的なセキュリティの修正が含まれています。SQL Server 2014 Service Pack 1 GDR のセキュリティ以外の更新プログラム  この更新プログラムには、この重要な修正のみが含まれています。

SQL Server 用の新しい累積更新プログラムには、以前の累積的な更新プログラムに含まれていたすべての修正プログラムとすべてのセキュリティ修正が含まれています。 SQL Server の最新の累積的な更新プログラムを参照してください。

詳細情報

エラー メッセージ現在影響を受けているデータベースで、この修正プログラムを適用した後に DBCC CHECKDB を実行すると、次のエラーメッセージが表示されます。

メッセージ5289、レベル16、状態1、行1、テーブル ' t ' の ' cci ' には、ディクショナリのデータ値と一致しないデータ値が1つ以上含まれています。 バックアップからデータを復元します。

現在影響を受けているデータベースで、この修正プログラムを適用した後に、影響を受けるテーブルをスキャンするクエリを実行すると、次のエラーメッセージが表示されます。

メッセージ5288、レベル16、状態1、行1の列ストアインデックスには、ディクショナリ内のデータ値と一致しないデータ値が1つ以上含まれています。 詳細については、DBCC CHECKDB を実行してください。

このようなエラーが発生した場合は、影響を受けていない列/行グループのデータを一括エクスポートし、クラスター化された列ストアインデックスを削除または作成した後で、データを再読み込みして、破損していないデータを保存できます。 トレースフラグ10207を有効にして5288エラーを抑制し、破損した rowgroups をスキップする以前の動作に戻す必要があります。 注:この行 # R3 のエラーメッセージ5288と5289は、セグメント S3 を持っています。 トレースフラグ10207は、不足している辞書 D1 の影響を受けない行 # R3 のセグメントを抽出するために使用されます。

影響を受けるデータベースのクエリ列ストアインデックスを含むデータベースがこの問題の影響を受けているかどうかを確認するには、次のクエリを実行します。

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 を実行しているサーバー上の列ストアインデックスを含むすべてのデータベースに対して実行する必要があります。 空の結果セットは、データベースに影響がないことを示します。

  • 新しい rowgroups を作成したり、既存の rowgroups の状態を変更したりするアクティビティがない場合は、このクエリを期間中に実行します。 たとえば、次のアクティビティは、rowgroups の状態を変更できます。インデックスの作成、インデックスの再編成、一括挿入、タプルムーバによるデルタストアの圧縮。 クエリを実行する前に、トレースフラグ634を使って、バックグラウンドの tuple ムーバタスクを無効にすることができます。 バックグラウンドタスクを無効にするには、次のコマンドを使用します。 DBCC TRACEON (634,-1)。 クエリの実行が完了したら、次のコマンドを使用してバックグラウンドタスクを再度有効にしてください。 DBCC TRACEOFF (634,-1)。また、このクエリを実行しているときに、列ストアインデックスを使用するテーブルにデータを挿入するための一括挿入/BCP/選択コマンドがないことを確認します。クエリで誤検知が返されないようにするには、以下の手順を使用することをお勧めします。

状態

マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。

ヘルプを表示

その他のオプションが必要ですか?

サブスクリプションの特典の参照、トレーニング コースの閲覧、デバイスのセキュリティ保護方法などについて説明します。

コミュニティは、質問をしたり質問の答えを得たり、フィードバックを提供したり、豊富な知識を持つ専門家の意見を聞いたりするのに役立ちます。

この情報は役に立ちましたか?

言語の品質にどの程度満足していますか?
どのような要因がお客様の操作性に影響しましたか?
[送信] を押すと、Microsoft の製品とサービスの改善にフィードバックが使用されます。 IT 管理者はこのデータを収集できます。 プライバシーに関する声明。

フィードバックをいただき、ありがとうございます。

×