Advertisement

SharePoint 2010 Server Error: The URL "XXX" is invalid, it may refer to a nonexistent file or ...

阅读量:

最近在企业的SharePoint 2010 Web应用中的Content数据库出现损坏情况。经过专业的DBCC修复服务团队的专业处理后仍未能完全恢复。其中涉及一个重要的Library List文件存在异常现象具体表现为当有任何文件上传至SharePoint服务器时都会触发SharePoint Server错误提示

The URL XXX is invalid. It might refer to a nonexistent file or folder, or it might point to a valid file that isn't within the current Web environment.

经过多方查找和研究后发现,在SharePoint平台的日志中仍无法解决问题。通过查看SharePoint的Log日志系统捕获到了关键错误信息‘System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'AllUserData_PK'. Cannot insert duplicate key in object 'dbo.AllUserData'. The duplicate key value is (871ee5f1-191f-4408-ba80-6207309bb568, 0x, 1, 299626, 0, 1, 0). The statement has been terminated. ’。当尝试将附件上传至SharePoint Content DB中的AllUserData字段时,该主键由tp_ID、tp_ListId、tp_RowOrdinal、tp_DeleteTransactionId、tp(Level)、tp_IsCurrentVersion以及tp_CalculatedVersion七个字段构成。

再次审阅日志记录时意外发现了一条新的错误提示。该提示详细表明:执行名为".Net SqlClient Data Provider"的SQL语句时发生了断机现象,并且此次故障发生在该存储过程定义文件中的第475行位置处。这一现象令人 intriguing的是,在查看相关代码库时未发现任何明显的语法或逻辑缺陷。进一步排查后发现,在执行该存储过程的过程中触发了一个异常操作:"proc_AddListItem"这一特定名称所指涉的功能模块运行过程中出现了程序终止事件,并且此次故障发生在第475行处的具体SQL语句中被识别出来。经过仔细分析后确认,在这条 SQL 脚本指令中存在一个无法正确执行的插入操作:"INSERT INTO AllUserData...”。

现在已经确定需要检查哪个字段出现了问题。
在执行以下SQL脚本"select top 100 tp_ID, tp_ListId, tp_RowOrdinal, tp_DeleteTransactionId, tp_Level, tp_IsCurrentVersion, tp_CalculatedVersion from AllUserData where tp_ListId='08528312-E298-47C3-B756-04A7A0B65A78'"后发现查询结果返回的数据集包括:
所有符合条件的数据行中包含了详细的字段信息。
其中'...'代表特定的值或代码段。
该查询的主要目的是为了评估数据的整体完整性。

换句话说,在tp_ListId为一个List的情况下,在除了tp_ID变动之外的部分中,其他字段保持不变。因此,在这种情况下,冲突的字段必定是"tp_ID"。

距离成功越来越近了,在进一步检查日志信息时发现执行proc_AddListItem的语句。\n\n
EXEC @@iRet=proc\_AddListItem @WebId=@wssp51, @SiteId=@wssp52, @ListID=@wssp53, @ItemId=@@DoclibRowId, @UIVersion=@@DocUIVersion, @RowOrdinal=@wssp54, @DocIdAdded=@wssp55, @OnRestore=@wssp56, @Size=@wssp57, @ItemName=@wssp58, @ItemDirName=@DN OUTPUT, @ItemLeafName=@LN OUTPUT, @ItemDocType=@wssp59, UserId=@wssp60, Level=@@Level, TimeNow=@wssp61\n ,@tp\_ContentTypeId = @wssp62,\nv1=@vwsp63,\nv2=\(@vwsp64\),\nv3=@vwsp65\n\n
,@tp_ModerationStatus=@vwsp66, \ndataEvent=@vwsp67, \ acl=@vwsp68, \nUIVersion=@vwsp69, \nRowOrdinal=@vwsp70, \nDocIdAdded=@vwsp71, \nOnRestore=@vwsp72, \nSize=@vwsp73\n
,@ItemName=@vwsp74, \nItemDirName=\ (@DN OUTPUT),\nItemLeafName= (@LN OUTPUT),\nItemDocType= (@wwwspsp),\nUserId= (@wwwspsp),
Level= (@wwwspsp),
TimeNow= (@wwwspsp),
/@tp_ContentTypeID = (\ wwwspsp)
/@v1=( wwwspsp),
/@v2=( wwwspsp),
/@v3=( wwwspsp)
/@tp_ModerationStatus=( wwwspsp),
EventData=( wwwspsp),
Acl=( wwwspsp);

复制代码
    	发现了tp_id是从@@DoclibRowId这里得到的值。而@@DoclibRowId是通过执行另一个存储过程proc_GenerateNextId得到的,“EXEC @@DoclibRowId = proc_GenerateNextId @wssp8;” 执行proc_GenerateNextId发现老是返回一样的值299626,查看存储过程的内容发现@@DoclibRowId是通过Table Function "TVF_AllListsAux_UpdLock_ListId"得到的,在进一步查看这个Table Function,发现表AllListsAux是存放所以List的数量和编号信息的表。AllListsAux.[NextAvailableId]的值是299625,加1后得到的tp_id是299626,终于明白了,是Content DB出错后导致了该表中相应的ID没有做更新,所以之后的upload操作都产生主键冲突了问题。
复制代码
     	解决方法很简单,到AllUserData表中找到指定Library List的最大的tp_id,将该值写入到AllListAux表的NextAvailableId的字段就解决了。之后上传没有任何问题了。

全部评论 (0)

还没有任何评论哟~