[FIX] セーブポイントにロールバックするとアサーションおよびエラーが発生

この記事は、以前は次の ID で公開されていました: JP294902
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
現象
クライアントが、ユーザー トランザクション内でテーブルの先頭ページ、ルート ページ、および先頭 IAM ページを割り当て、その後 ROLLBACK コマンドを使用してこのトランザクション内のセーブポイントにロールバックすると、エラー メッセージ 3624 (リテール アサーション) が表示され、SQL Server へのクライアント接続が終了することがあります。クエリ アナライザがクライアントとして使用されていると、クエリ アナライザに次のエラー メッセージが返されます。
サーバー : メッセージ 3624、レベル 20、状態 1、行 1

Location: page.cpp:2777
Expression: rowLength >= offset + deleteLength
SPID: 51
Process ID: 596

接続が解除されました
さらに、エラー 3448 と 3314、およびスタック ダンプが SQL Server エラー ログ ファイルに出力されることがあります。
原因
SQL Server 2000 では、テーブルは空のテーブルとして作成されます。これは、テーブルが作成されるときに、そのテーブルに割り当てられるページがないことを意味します。データがテーブルに挿入されるときに、ページがテーブルに割り当てられます。

そのため、次の状況でアサーションおよびエラー メッセージが表示されることがあります。
  • BEGIN TRAN ステートメントによりユーザー トランザクションが開始されます。
  • CREATE TABLE ステートメントによりテーブルが作成されます。
  • セーブポイントがトランザクション内で指定されます。
  • DML (データ操作言語) ステートメントが、2 番目の操作で作成したテーブルに適用されます。これによって、テーブルの先頭ページ、ルートページ、および先頭 IAM ページが割り当てられます。
  • ROLLBACK コマンドにより、3 番目の操作で指定したセーブポイントにロールバックされます。
  • 別の DML ステートメントが、2 番目の操作で作成したテーブルに適用されます。
この問題は、上記の最後の操作で使用した DML ステートメントによって、テーブルにページが再度割り当てられない場合に発生します。DML ステートメントによってテーブルにページが再度割り当てられないのは、不正な SQL Server キャッシュからの情報に基づき、テーブルにページが既に割り当てられていると判断されるからです。SQL Server キャッシュには、テーブルにページを割り当てた DML ステートメントがロールバックされたという情報が反映されていません。
解決方法
この問題を解決するために、SQL Server 2000 の最新の Service Pack の適用をお願いいたします。
最新の SQL Server サービスパックのダウンロードおよびインストールについて詳しくは以下をご覧下さい。

http://www.microsoft.com/japan/sql/download/default.asp (日本語版)
http://www.microsoft.com/sql/downloads/default.htm (英語版)
状況
弊社では、これを Microsoft SQL Server version 2000 の問題として確認しています。
この問題は、Microsoft SQL Server version 2000 Service Pack 1 で修正されています。
詳細
セーブポイントはトランザクション内のマーカーで、トランザクションの一部が条件付きで取り消された場合に、トランザクションを戻す位置を定義します。セーブポイントの詳細については、SQL Server Books Online の「SAVE TRANSACTION」のトピックを参照してください。

問題を再現するには、以下のスクリプトを実行します。
use mastergocreate database reprogouse reprogo-- tempdb を使用しますgobegin trangocreate table t1 (i1 int null)create table t2 (i2 int null)go-- CHECK オプションを使用して単純にビューを作成します--create view vt as  select * from t1 where i1 between 1 and 10  with check optiongosave tran emptygoinsert vt values(1)	-- OKinsert vt values(5)	-- OKinsert vt values(10)	-- OKinsert vt values(0)	-- 失敗 (<1)insert vt values(11)	-- 失敗 (>10)insert vt values(null)	-- 失敗 (null)gorollback tran emptygo-- CHECK オプションを使用して結合します--create view vtJN as  select * from t1 inner join t2 on t1.i1 = t2.i2  with check optiongoinsert vtJN(i1) values(1)	-- 失敗 (一致なし)insert t2(i2) values(1)		-- OK (元の行)insert vtJN(i1) values(1)	-- 失敗 (一致なし)
以下は、製品版ビルド 8.00.194 でのこのアサーションの短い形式のスタック ダンプです。
-------------------------------------------------------------------------------Short Stack Dump77F97AC6 Module(ntdll+00017AC6) (ZwGetContextThread+0000000B)0092569E Module(sqlservr+0052569E) (utassert_fail(enum UTASSERT_TYPE,char const *,char const *,int,char const *,...)+000002E9)00843FAC Module(sqlservr+00443FAC) (Page::ModifyRow(int,unsigned int,unsigned int,unsigned int,void const *,unsigned int,class XdesId const *)+000000D0)0042DEAB Module(sqlservr+0002DEAB) (PageRef::ModifyRow(struct BUF *,int,unsigned int,unsigned int,unsigned int,void const *,enum ETabStatus,int,class XDES *,void const *,unsigned int)+0000033A)0041CC24 Module(sqlservr+0001CC24) (AllocationReq::AllocatePages(void)+00000690)0041B777 Module(sqlservr+0001B777) (AllocationReq::Allocate(void)+00000078)0043EF30 Module(sqlservr+0003EF30) (AllocateHeapPage(struct CINSTABLE *)+0000007D)0080C76D Module(sqlservr+0040C76D) (AllocatePageForInsert(class SDES *,struct INDEX *)+000000CD)0043461A Module(sqlservr+0003461A) (FreeSpaceScan::GetNextPage(struct BUF * *)+000003B0)00434A1B Module(sqlservr+00034A1B) (FindExistingFreeSpace(class SDES *,struct INDEX *,unsigned int,int &)+000000B8)004348AD Module(sqlservr+000348AD) (ncinsert(class SDES * volatile,unsigned char *,int,class Scan_rid &)+00000081)00418543 Module(sqlservr+00018543) (rowinsert(class SDES * volatile,void *,int,unsigned char)+00000118)004185E0 Module(sqlservr+000185E0) (insert(class SDES *,void *,int)+00000013)00433D8F Module(sqlservr+00033D8F) (RowsetSS::InsertRow(unsigned long,unsigned long,void *,unsigned long *)+00000201)0042EE6A Module(sqlservr+0002EE6A) (CValRow::SetDataX(unsigned long *,class CXVariant *)+00000025)00431C2F Module(sqlservr+00031C2F) (CEs::FastMoveEval(unsigned long *,class CEsExec *,class CXVariant *)+00000039)00433FD6 Module(sqlservr+00033FD6) (CQScanScalarInsert::GetRow(unsigned long *,unsigned long *)+00000035)0042C85E Module(sqlservr+0002C85E) (CQScanNLJoin::GetRow(unsigned long *,unsigned long *)+00000112)004C09E1 Module(sqlservr+000C09E1) (CQScanAssert::GetRow(unsigned long *,unsigned long *)+0000001B)00427985 Module(sqlservr+00027985) (CQueryScan::GetRow(unsigned long *,unsigned long *)+00000014)00426F64 Module(sqlservr+00026F64) (CStmtQuery::ErsqExecuteQuery(class CMsqlExecContext *,class CEsComp const *,class CEsComp const *,unsigned long *,int,int)const +000003C4)0042EA36 Module(sqlservr+0002EA36) (CStmtDML::XretExecuteNormal(class CMsqlExecContext *)const +000002F0)0042E82D Module(sqlservr+0002E82D) (CStmtDML::XretExecute(class CMsqlExecContext *)const +0000001C)004160DB Module(sqlservr+000160DB) (CMsqlExecContext::ExecuteStmts(class ExecutionContext *)+0000027E)00415765 Module(sqlservr+00015765) (CMsqlExecContext::Execute(class CCompPlan *,class CParamExchange *)+000001C7)00415410 Module(sqlservr+00015410) (CSQLSource::Execute(class CParamExchange *)+00000343)005A683F Module(sqlservr+001A683F) (CStmtPrepQuery::XretExecute(class CMsqlExecContext *)const +00000211)004160DB Module(sqlservr+000160DB) (CMsqlExecContext::ExecuteStmts(class ExecutionContext *)+0000027E)00415765 Module(sqlservr+00015765) (CMsqlExecContext::Execute(class CCompPlan *,class CParamExchange *)+000001C7)00415410 Module(sqlservr+00015410) (CSQLSource::Execute(class CParamExchange *)+00000343)00459A54 Module(sqlservr+00059A54) (language_exec(struct srv_proc *)+000003C8)004175D8 Module(sqlservr+000175D8) (process_commands(struct srv_proc *)+000000E0)410735D0 Module(UMS+000035D0) (ProcessWorkRequests(class UmsWorkQueue *)+00000264)4107382C Module(UMS+0000382C) (ThreadStartRoutine(void *)+000000BC)7800BEA1 Module(MSVCRT+0000BEA1) (_beginthread+000000CE)77E92CA8 Module(KERNEL32+00012CA8) (CreateFileA+0000011B)-------------------------------------------------------------------------------
以下は、製品版ビルド 8.00194 でのエラー 3448 を含む短い形式のスタック ダンプです。
-------------------------------------------------------------------------------Short Stack Dump77F97AC6 Module(ntdll+00017AC6) (ZwGetContextThread+0000000B)00926069 Module(sqlservr+00526069) (ex_raise2(int,int,int,int,void *,char *)+00000174)0046C368 Module(sqlservr+0006C368) (ex_raise(int,int,int,int,...)+00000063)008686FE Module(sqlservr+004686FE) (FixPageForUndo(class PageRef &,class DBTABLE *,class LSN const &,enum LatchBase::LATCH_TYPE,class PageLog const &)+00000098)00863962 Module(sqlservr+00463962) (XdesRMReadWrite::UndoPageOperation(class PageLog const *,class LSN const &,int)+0000032B)00440FBA Module(sqlservr+00040FBA) (XdesRMReadWrite::RollbackToLsn(class LSN const &,class LogIterBackLink &,class IndexErrorTable *,int)+000002EB)00865932 Module(sqlservr+00465932) (XdesRMFull::RollbackNested(int)+00000143)0086062F Module(sqlservr+0046062F) (XactRM::RollbackNestedXact(int)+0000009E)0085DEB5 Module(sqlservr+0045DEB5) (FullXactImpBase::RollbackNestedXact(int)+00000037)0064089F Module(sqlservr+0024089F) (CMsqlXact::RollbackNestedXact(enum CMsqlXact::ReadWriteMode,int)+00000017)006403DD Module(sqlservr+002403DD) (CAutoMsqlXact::RollbackNestedXact(void)+00000032)0062F2D1 Module(sqlservr+0022F2D1) (CStmtDML::XretExecuteNormal(class CMsqlExecContext *)const +00000456)0042E82D Module(sqlservr+0002E82D) (CStmtDML::XretExecute(class CMsqlExecContext *)const +0000001C)004160DB Module(sqlservr+000160DB) (CMsqlExecContext::ExecuteStmts(class ExecutionContext *)+0000027E)00415765 Module(sqlservr+00015765) (CMsqlExecContext::Execute(class CCompPlan *,class CParamExchange *)+000001C7)00415410 Module(sqlservr+00015410) (CSQLSource::Execute(class CParamExchange *)+00000343)005A683F Module(sqlservr+001A683F) (CStmtPrepQuery::XretExecute(class CMsqlExecContext *)const +00000211)004160DB Module(sqlservr+000160DB) (CMsqlExecContext::ExecuteStmts(class ExecutionContext *)+0000027E)00415765 Module(sqlservr+00015765) (CMsqlExecContext::Execute(class CCompPlan *,class CParamExchange *)+000001C7)00415410 Module(sqlservr+00015410) (CSQLSource::Execute(class CParamExchange *)+00000343)00459A54 Module(sqlservr+00059A54) (language_exec(struct srv_proc *)+000003C8)004175D8 Module(sqlservr+000175D8) (process_commands(struct srv_proc *)+000000E0)410735D0 Module(UMS+000035D0) (ProcessWorkRequests(class UmsWorkQueue *)+00000264)4107382C Module(UMS+0000382C) (ThreadStartRoutine(void *)+000000BC)7800BEA1 Module(MSVCRT+0000BEA1) (_beginthread+000000CE)77E92CA8 Module(KERNEL32+00012CA8) (CreateFileA+0000011B)-------------------------------------------------------------------------------2001-03-30 03:08:44.56 spid51    エラー : 3448、レベル : 21、状態 : 12001-03-30 03:08:44.56 spid51    ログ レコード (5:23:99) を元に戻せませんでした。トランザクション ID (0:157)、ページ (1:76)、データベース 'repro' (データベース ID 7)。 ページ情報 : LSN = (5:23:96)、型 = 1。ログ情報 : OpCode = 4、コンテキスト 1。2001-03-30 03:08:44.56 spid51    ex_raise2: Exception raised, major=34, minor=48, severity=25, attempting to create symptom dump
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 294902 (最終更新日 2001-06-14) をもとに作成したものです。

プロパティ

文書番号:294902 - 最終更新日: 01/16/2015 22:12:51 - リビジョン: 2.1

  • Microsoft SQL Server 2000 Standard Edition
  • kbnosurvey kbarchive kbbug kbfix kbsqlserv2000bug kbsqlserv2000sp1fix KB294902
フィードバック