最近、MS SQL Serverデータベースの1つがSuspectに切り替わり、ログにエラーメッセージが記録されました。
メッセージ7105、レベル22、状態9、行14
データベースID 6、ページ(1:386499)、LOBデータ型ノードのスロット0は存在しません。 これは通常、データページ上のコミットされていないデータを読み取ることができるトランザクションによって発生します。 DBCC CHECKTABLEを実行します。
データベースはEmergencyに転送され、DBCC CHECKDBを実行しようとしましたが、実行はすぐに中断されました。
メッセージ8921、レベル16、状態1、行13
チェックは終了しました。 ファクトの収集中に障害が検出されました。 おそらくtempdbのスペースが不足しているか、システムテーブルに一貫性がありません。 以前のエラーを確認してください。
メッセージ7105、レベル22、状態9、行13
データベースID 6、ページ(1:386499)、LOBデータ型ノードのスロット0は存在しません。 これは通常、データページ上のコミットされていないデータを読み取ることができるトランザクションによって発生します。 DBCC CHECKTABLEを実行します。
DBCC CHECKALLOCコマンドは同様のエラーで中断されました。 SQL Serverがバージョン9.0.1399であったため、すべてが複雑でした。 RTM、更新なし。
TABLOCKヒントを使用し、トランザクション分離レベルを明示的に上げようとしても、何も起こりませんでした(tempdbで十分なディスク容量があり、WITH ESTIMATEONLYでDBCC CHECKALLOCが同じエラーで失敗しました)。 データベースが破損しているサーバーにSPをロールバックしたくはありませんでした。また、問題の特定のオブジェクトが完全に理解不能でした。 さらに、msdb.dbo.suspect_pagesには1つのレコードがありましたが、ページ番号はDBCC CHECKDBが印刷したものとは異なっていたため、DBCC CHECKDBメッセージは現実とほとんど関係がないように思われました。
DBCC CHECKDBの指示に従ってDBCC CHECKTABLEを実行するには、テーブルを知っている必要があります。 そして、長い検索の後、1つの命令
が見つかりました 。
ご注意エラーメッセージとコードのテーブル番号が一致しないことをおpoび申し上げます。 ログからエラーを取得し、その後、別のライブベースのテスト環境でコードを実行しました。
以下のアルゴリズムを使用して、DBCC CHECKDBおよびsuspect_pagesから両方のページのobject_idを決定しました。 問題はsuspect_pagesのページにありました
最初に行うことは、(破損したデータベースのコンテキストで)
DBCC PAGE (database_id、file_id、page_id、printopt)を実行することです。
DBCC TRACEON (3604); DBCC PAGE(5, 1, 3242342, 0) DBCC TRACEOFF (3604);
どちらか:
DBCC PAGE(5, 1, 3242342, 0) WITH TABLERESULTS.
運がよければ(またはライブベースでプレイしている場合)、結果として、Metadata:ObjectIdフィールドと、実際には目的のobject_idが表示されます。

ただし、私たちのようにあなたが幸運でない場合、以下が表示されます:
メタデータ:=オフラインDBでは使用不可
メタデータが利用できない場合、すべてが失われるわけではありません。この場合、m_objIdフィールド(AllocUnitId.idObj)が必要です。 m_objId = 255の場合、問題は、記事を閉じて何か他のものを探すことです(可能な限りすべてのスクリプトを作成し、データを削除するか、DBCC CHECKDBを "recovery"パラメーターで盲目的に実行するなど)。
スクリーンショットは、m_objId = 9931、つまり 続けることができます。
次に、割り当てユニットIDを計算するために少し計算する必要があります(割り当てユニットの詳細については、
こちらを参照してください )。
割り当てユニットID = m_objid * 65536 +(2 ^ 56)
私たちの場合:
割り当てユニットID = 9931 * 65536 +(2 ^ 56)= 72057594688765952
したがって、Allocation Unit IDを知っていると、
sys.allocation_unitsシステムビューにあるものを確認できます。
SELECT * FROM sys.allocation_units WHERE allocation_unit_id = 72057594688765952

そして、そこに、タイプ= 1または3(IN_ROW_DATA、ROW_OVERFLOW_DATA)の場合、列container_id = sys.partitions.hobt_id(「ヒープまたはBツリーID」)、つまり リクエストを実行できます:
SELECT * FROM sys.partitions WHERE hobt_id = 72057594661437440

そして、ここにはすでに正しいobject_idとindex_idがあります。 これで、sys.objectsとsys.indexesにあるものを確認して、実行するだけです。
SELECT OBJECT_NAME(object_id)
幸いなことに、実際の状況とここの両方で、非クラスターインデックスが再構築された後、すべてが正常に戻ったことが確認されました(実際、いいえ、それは別の話です)。
参照 :
DBCC PAGEの使用方法SQL Serverページレベルの破損のトラブルシューティングと修正割り当て単位とは何ですか?ページIDからテーブル名を見つけるsys.allocation_units