• 记一个调用Proc_GetObject的古怪问题


    有个朋友问过这么一个问题, 说访问站点页面有点慢. 经过排查, 发现问题出在SQL上.

    抓了Profiler Trace, 发现ConfigDB里有很多的对存储过程dbo.Proc_GetObject的调用. 进一步排查发现, 每调用一个页面, 都会有几千个这样的调用, 连settings.aspx也是如此.

    陈列一些事实如下:

    SharePoint每次加载一个页面, 都要去确保一下当前站点上所有的Feature都已经被加载. SharePoint会先得到这个站点上所有feature的guid, 然后先去本地的cache里去捞取这些对象(存储在很多xml文件中).

    Windows Server 2003中, 本地cache的位置在:

            Drive:\Documents and Settings\All Users\Application Data\Microsoft\SharePoint\Config\GUID

    Windows Server 2008中, 本地cache的位置在:

            Drive:\ProgramData\Microsoft\SharePoint\Config\GUID

    如果某些对象在本地的cache里找不到, 那么就会到ConfigDB里去捞取.

    使用下面的语句来搜索某个GUID

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    Declare  @SearchStr uniqueidentifier
    Set @SearchStr = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
    
    BEGIN
    
          CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
    
          SET NOCOUNT ON
    
          DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
          SET  @TableName = ''
          SET @SearchStr2 = @SearchStr
    
          WHILE @TableName IS NOT NULL
          BEGIN
                SET @ColumnName = ''
                SET @TableName = 
                (
                      SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
                      FROM INFORMATION_SCHEMA.TABLES
                      WHERE             TABLE_TYPE = 'BASE TABLE'
                            AND   QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
                            AND   OBJECTPROPERTY(
                                        OBJECT_ID(
                                              QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
                                              ), 'IsMSShipped'
                                               ) = 0
                )
    
                WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
                BEGIN
                      SET @ColumnName =
                      (
                            SELECT MIN(QUOTENAME(COLUMN_NAME))
                            FROM INFORMATION_SCHEMA.COLUMNS
                            WHERE             TABLE_SCHEMA      = PARSENAME(@TableName, 2)
                                  AND   TABLE_NAME  = PARSENAME(@TableName, 1)
                                  AND   DATA_TYPE IN ('uniqueidentifier')
                                  AND   QUOTENAME(COLUMN_NAME) > @ColumnName
                      )
          
                      IF @ColumnName IS NOT NULL
                      BEGIN
                            INSERT INTO #Results
                            EXEC
                            (
                                  'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                                  FROM ' + @TableName + ' (NOLOCK) ' +
                                  ' WHERE ' + @ColumnName + ' LIKE ' + '''' + @SearchStr2 + ''''
                            )
                      END
                END   
          END
    
          SELECT ColumnName, ColumnValue FROM #Results
          Drop Table #Results
    END

    把Profiler Trace中的GUID拿到ConfigDB里一搜, 没有任何结果.

    把该GUID拿到ContentDB里一搜, 发现这个GUID存在于Features表上.

    至此, 问题就比较清楚了.

    在这套环境中, 有很多的Feature只存在于ContentDB里, 但是在ConfigDB里却不存在. 所以就造成很多feature称为orphan.

    加载页面的时候, SharePoint试图加载这些feature, 但是在本地cache里捞不到, 于是就去ConfigDB里通过调用Proc_GetObject找, 也没找到. 由于这些feature并不十分重要, 所以页面也还是正常的加载起来了. 但是, 以后每次加载任何页面都会有这么多的Proc_GetObject调用出现, 由于这样的feature实在是太多了, 所以就影响了performance.

    解决方案

    ==============

    移除掉这些orphan的feature就可以了.

    怎么移除呢?

    欧洲有个巨牛的牛人叫做Stefan, 他公开了两个命令行的工具, 一个可以扫描feature, 另一个可以移除feature. 链接如下:

    http://code.msdn.microsoft.com/WssAnalyzeFeatures/Release/ProjectReleases.aspx?ReleaseId=886

    http://code.msdn.microsoft.com/WssRemoveFeatureFrom/Release/ProjectReleases.aspx?ReleaseId=887

    合并这两个工具中的逻辑, 每发现一个orphan的feature, 就delete掉一个.

    问题就解决了.

  • 相关阅读:
    JDK1.0-缓冲流
    笔试错误1
    JVM 垃圾收集(转)
    Trie树和后缀树(转,简化)
    海量数据处理(转,简化)
    Struts2 内核之我见(转) -(主要是拦截器链和过滤链介绍和源码及其设计模式)
    phpize增加php模块
    Ubuntu下SVN安装和配置
    Linux下SVN配置hook经验总结
    Kruakal 算法——练习总结
  • 原文地址:https://www.cnblogs.com/awpatp/p/1820798.html
Copyright © 2020-2023  润新知