CORRECTIF : Un repositionnement (ROLLBACK) sur un point d'enregistrement induit une assertion et des erreurs

Traductions disponibles Traductions disponibles
Numéro d'article: 294902 - Voir les produits auxquels s'applique cet article
Ancien nº de publication de cet article : F294902
N° DE BOGUE : 352501 (SHILOH_bugs)
Agrandir tout | Réduire tout

Symptômes

Si un client affecte la première page, la page racine et la page firstIAM d'une table dans le cadre d'une transaction utilisateur, et qu'il utilise la commande ROLLBACK pour effectuer un repositionnement sur un point d'enregistrement au sein de cette même transaction, il se peut qu'un message d'erreur 3624 (assertion de la version commerciale) s'affiche et que la connexion du client avec SQL Server soit interrompue. Le message d'erreur suivant est retourné dans l'Analyseur de requêtes si celui-ci est utilisé comme client :
Serveur : Msg 3624, Niveau 20, État 1, Ligne 1

Emplacement : page.cpp:2777
Expression : rowLength >= offset + deleteLength
SPID : 51
ID du processus : 596

Connexion interrompue
En outre, des erreurs 3448, 3314 et des vidages de pile peuvent apparaître dans le journal des erreurs de SQL Server.

Cause

Dans SQL Server 2000, les tables sont créées sous la forme de tables vides. Cela signifie que lors de la création d'une table, aucune page ne lui est affectée. Des pages sont affectées à une table lorsque des données sont insérées dans celle-ci.

C'est pourquoi le scénario ci-dessous peut conduire à une assertion et à des messages d'erreur :
  • Une transaction utilisateur est lancée avec l'instruction BEGIN TRAN.
  • Une table est créée avec l'instruction CREATE TABLE.
  • Un point d'enregistrement est spécifié dans la transaction.
  • Des instructions DML (Data Manipulation Language) sont appliquées à la table mentionnée au deuxième point de la liste, aboutissant à l'affectation de la première page, la page racine et la page firstIAM à cette table.
  • La commande ROLLBACK est utilisée pour effectuer un repositionnement sur le point d'enregistrement mentionné au troisième point de la liste.
  • Des instructions DML supplémentaires sont appliquées à la table mentionnée au deuxième point de la liste.
Ce problème se produit lorsque les instructions DML supplémentaires mentionnées au dernier point de la liste ne réaffectent pas de pages à la table. Les instructions DML ne réaffectent pas de pages à la table car, en se basant sur les informations provenant d'un cache SQL Server non valide, elles considèrent que des pages ont déjà été affectées à la table. Le cache SQL Server n'est pas au courant du fait que les instructions DML qui ont affecté des pages à la table ont été repositionnées.

Résolution

Pour résoudre ce problème, procurez-vous le dernier Service Pack pour SQL Server 2000. Pour plus d'informations, consultez l'article suivant dans la Base de connaissances Microsoft :
290211 INF : Procédure d'obtention du dernier Service Pack pour SQL Server 2000

Statut

Microsoft a confirmé l'existence de ce problème dans SQL Server 2000. Ce problème a été corrigé dans le Service Pack 1 de SQL Server 2000.

Plus d'informations

Un point d'enregistrement est un marqueur au sein d'une transaction qui définit un emplacement auquel une transaction peut revenir en cas d'annulation conditionnelle d'une partie de celle-ci. Pour plus d'informations sur les points d'enregistrement, consultez la rubrique " SAVE TRANSACTION " dans la documentation en ligne SQL Server.

Pour reproduire le problème, exécutez le script suivant :
use master
go
create database repro
go
use repro
go
-- use tempdb
go
begin tran
go
create table t1 (i1 int null)
create table t2 (i2 int null)
go
-- SIMPLE WITH CHECK
--
create view vt as
  select * from t1 where i1 between 1 and 10
  with check option
go

save tran empty
go
insert vt values(1)       -- OK
insert vt values(5)       -- OK
insert vt values(10)      -- OK
insert vt values(0)       -- FAIL (<1)
insert vt values(11)      -- FAIL (>10)
insert vt values(null)    -- FAIL (null)
go
rollback tran empty
go

-- WITH CHECK JOIN
--
create 
view vt as
  select * from t1 inner join t2 on t1.i1 = t2.i2
  with check option
go

insert vtJN(i1) values(1)	-- FAIL (no match)
insert t2(i2) values(1)		-- OK (prime row)
insert vtJN(i1) values(1)	-- FAIL (no match)

Voici le vidage de pile réduit pour cette assertion sur la version commerciale 8.00.194 :
-------------------------------------------------------------------------------
Vidage de pile réduit
77F97AC6 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)
-------------------------------------------------------------------------------
Voici un vidage de pile réduit avec une erreur 3448 sur la version commerciale 8.00.194 :
-------------------------------------------------------------------------------
Vidage de pile réduit
77F97AC6 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    Erreur : 3448, Gravité : 21, État : 1
2001-03-30 03:08:44.56 spid51    Impossible d'annuler l'enregistrement du journal (5:23:99), 
                                 pour l'ID de transaction (0:157), sur la page (1:76), 
                                 base de données 'repro' (ID de base de données 7). 
                                 Informations sur la page : LSN = (5:23:96), type = 1. 
                                 Informations sur le journal : OpCode = 4, contexte 1..
2001-03-30 03:08:44.56 spid51    ex_raise2: Exception générée, majeure=34, mineure=48, 
                                 gravité=25, en tentative de création d'un pile de symptômes

Propriétés

Numéro d'article: 294902 - Dernière mise à jour: vendredi 7 novembre 2003 - Version: 4.1
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft SQL Server 2000 Standard
Mots-clés : 
kbbug kbfix kbsqlserv2000bug kbsqlserv2000sp1fix KB294902
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com