ALTER INDEX ALL REBUILDは、各インデックスを個別に再構築するよりも単純な復旧モデルでより多くのトランザクションログ領域を使用しますか?


18

トランザクションログの領域が不足したため、SQL Server 2012での「ALTER INDEX ALL REBUILD」操作は失敗しました。インデックスは再編成または再構築されたことがないため、ほぼすべてのインデックスで断片化が80%を超えています。

DBは単純な復旧モデルを使用します。「ALL」形式のコマンドによって実行される各インデックス操作に続いて、次のインデックス再構築の前にトランザクションログデータがフラッシュされると想定しました。それは実際にどのように機能するのですか、またはインデックスの再構築は単一のトランザクションの一部であるかのように記録されますか?

言い換えると、各再構築を個別に実行するスクリプトを記述することにより、トランザクションログの増加を減らすことができますか?考慮すべき他の要因はありますか?


2
明示的なデータとは反対に、特定のSQLコマンドはDBエンジンによって単一のアトミックトランザクションと見なされると想定します。この場合、理論をかなり簡単にテストできます。最大のインデックスを取得し、それを再構築してみてください。それが成功した場合、ログが複数の再構築からの情報を蓄積していると仮定するのは合理的です。失敗した場合は、ログにスペースを追加する必要があります(どちらかの方法で問題が発生したため)、または再構築する代わりにそのインデックスを再編成する必要があります(t-ログ)。
RDFozz

はい、これをタイプし終えたときに思いついたのですが(ゴム製のアヒル効果)、確認を得て、同じように考えるかもしれない他の人にそれを残すのが最善だと思いました。私はこの環境で実験したくないので、おそらくログにスペースを追加することになります。
Googleが失敗する

回答:


16

「ALL」形式のコマンドによって実行される各インデックス操作に続いて、次のインデックス再構築の前にトランザクションログデータがフラッシュされると想定しました。それは実際にどのように機能するのですか、またはインデックスの再構築は単一のトランザクションの一部であるかのように記録されますか?

1)ログのフラッシュ:SIMPLE復旧モデルは、すべてのトランザクションの後ではなく、チェックポイントでログをクリアします。(詳細情報へのリンク

2a)すべて再構築:はい、すべて再構築は単一のトランザクションとして機能します。内部のインデックスの再構築には独自のトランザクションがありますが、全体の操作は最後まで完全にはコミットされません。そのため、個々のインデックスを再構築する(および場合によってはCHECKPOINTコマンドを発行する)ことにより、ログファイルの増加を制限できます。

2b)証明!ここに、デモスクリプトがあります。(2016 devに構築)最初に、テーブルとインデックスを使用してテストデータベースをセットアップします。

USE master
GO

CREATE DATABASE Test_RebuildLog
GO

ALTER DATABASE Test_RebuildLog
SET RECOVERY SIMPLE
GO

USE Test_RebuildLog
GO

CREATE TABLE IndexTest
(ID int identity(1,1),
a char(1),
b char(1))

CREATE CLUSTERED INDEX CIX_IndexTest_ID ON IndexTest(ID)
CREATE INDEX IX_IndexTest_a ON IndexTest(a)
CREATE INDEX IX_IndexTest_b ON IndexTest(b)

INSERT IndexTest
(a,b)
VALUES ('a','b'),('z','y'),('s','r')

これで、すべてを再構築し、個別に再構築する間のログアクティビティを比較できます。

CHECKPOINT
GO
ALTER INDEX ALL ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

CHECKPOINT
GO
ALTER INDEX CIX_IndexTest_ID ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_a ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_b ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

最初の開いているトランザクション(私にとってはトランザクションID 0000:000002fa)は、REBUILD ALLが終了するまでコミットされませんが、インデックスごとの再構築では、それらが連続してコミットされることに注意してください。


わあ、本当に詳細な対応に感謝します!それは、いわば、フードの下で何が起こっているのかを見る素晴らしい方法です。
Googleが

うまく説明しました。
Ramakant Dadhichi

4

現状では、これは単一のトランザクションです。


6
DBA.SEへようこそ!一般に、ベストアンサーは単純な主張ではなく、ドキュメントや記事からの情報、または(多くの場合、より良い)個人的な経験によって示されたアンサーを裏付けています。そのような裏付けを提供するために、あなたの答えを広げることはできますか?
RDFozz

2
@RDFozz公正なコメントですが、Pedroのプロファイルを見ましたか?ソースコードへのアクセスは、おそらく個人的な経験や文書よりも権威があると考えられます。:-)
アーロンバートランド

3
@AaronBertrand-告白しましたが、しませんでした。SQL Serverチームの一員であることは確かに資格があると思います。それでも、答えでそれを参照する価値があります。いずれにしても、+ 1。
RDFozz

3

この質問は、オフラインでの再構築には簡単です。もちろん、単一のトランザクションです。操作が各インデックスを独自のトランザクションに分割した場合に発生する大混乱を想像してください。コミット時にロック解除してから再取得する必要があるためです。重要なテーブルSCH-Mロックが解放されたときに、インデックスが削除され、新しいインデックスが作成される可能性がありますが、ステートメントはそのような場合をどのように処理しますか?言うまでもなく、テーブルはドロップされる可能性があり、2つのトランザクション間で再作成されることさえあります!テーブルが削除され、同じオブジェクトIDで別のテーブルが作成される場合を含みます(はい、発生する可能性があります)...

インデックスの再構築がオンライン再構築である場合に何が起こるかを言うために質問を増補するとどうなりますか?単一のトランザクションですか、それとも複数ですか?実際にはいくつかの内部トランザクションが関係しているため、答えは複雑です。ただし、重要な点は、操作全体(ALTERステートメント)にまたがる全体的なアーカイブトランザクションがあり、これによりログが固定される(切り捨てできない)ため、それに応じて操作を計画し、約1.6倍のデータを許可する必要がありますFULL復旧モードのサイズ、またはBULK_LOGGED / SIMPLEモードの0.2xデータサイズ。詳細については、リンクされたペーパーを参照してください。

オフラインビルドがオンラインモードと同じ内部トランザクションを使用せず、操作を分割しないのはなぜでしょうか?個々のインデックス操作間でテーブルが変更/削除されることについて言及した問題(つまり、テーブル 'スキーマの安定性')では、ステートメントの全期間にわたってテーブルにSCH-Sを保持するトランザクションが必要です。このトランザクションはリカバリ中にもSCH-Sを保持する必要があるため、ログに記録する必要があります。そのため、ログを固定し、ステートメントの全期間にわたって切り捨てを防ぐBEGIN XACTログレコードがあります。この特定の問題はSQL 2016-2017の時間枠(SQL Azureのログサイズの問題のため)で対処されていましたが、どのような進展があったのかわかりません。プレビュー中のようです:再開可能なオンラインインデックスの再構築は、SQL Server 2017 CTP 2.0のパブリックプレビューです


0

はい、非常に大きなテーブルで同じ問題が発生しました。ALTER INDEX ALLを発行するたびに、トランザクションログは大きくなりますが、ALTER INDEXを個別に発行すると、ログ領域の使用量は少なくなります。


0

オンラインインデックス作成には、フルリカバリモードでのインデックスサイズの1.6倍が必要であるというRemusの以前の応答は正しくありません。FULLの下でオンラインでインデックスを再構築するために必要なトランザクションログ領域の割合は非常に高くなる可能性があり、特にトランザクションログが圧縮されないため再構築されるインデックスが圧縮される場合、インデックスのサイズが何倍にもなります。これだけでも、FULLでのオンライン再構築中のトランザクションロギングがインデックスのサイズの少なくとも数倍になる可能性があることを明確にする必要があります。Microsoftによって完全に文書化されていないが、多くの場合行ごとに60バイトと推定されるtlogレコードオーバーヘッドを追加し、完全な回復の下でのオンラインインデックス再構築中のロギングの比例サイズは、特に再構築中のインデックスのサイズの数倍インデックスは圧縮されています


-1

現在のストレージに基づいて最大のインデックスを再構築できるかどうかを判断する最良の方法は、Rdfozzが正しいことです。dm_exec_requests操作(またはSQLプロファイラー)の実行中に実行するだけで、すべてのインデックスが再構築されているかどうかを確認できます。また、復旧モデルを一括ログ記録に変更することを検討します。これは私がしていることであり、まだウィンドウの間にトランザクションログのバックアップがあります。下記の記事https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxを参照して ください


2
OPは、DBがすでにSIMPLE復旧モデルを使用していると述べていることに注意してください。これは、トランザクションが完了するのに十分な時間だけトランザクションをログに保持します。一括ログに切り替えても改善はありません。
RDFozz

あなたの全く正しい。謝罪いたします。
ADTJOB
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.