无法从数据库中获取600,000个删除存根

时间:2012-12-10 13:41:58

标签: lotus-domino

更新:我发布了:show database mycleandb.nsf,我可以看到仍有835,000个删除存根。我似乎无法删除它们。

要点: 我们有一个大型数据库,我们现在可以开始削减到更易于管理的大小。 我删除了文件,但是我留下了一个数据库,看来我无法复制或复制,收到错误:无法扩展ID表 - 内存不足。

详情: 目前的实时数据库中有大约1,400,000个文档,我们可以立即将其减少到650,000个。通过一些进一步的设计\建筑工作,我们可以将其减少到300,000。此Web应用程序集群在5台服务器上,1台为应用程序“集线器”,3台HTTP \ SSO服务器位于反向代理后面,第5台服务器是外部服务的接入点。 HUB每30分钟启动一次PUSH \ PULL复制(没有文档限制),日志显示没有复制错误。为服务器上的运行时性能设置事务日志记录,在不在集群中的另一台后台服务器上执行备份。我们每天运行归档,每天归档大约1,500个文档。

到目前为止,近2年来,应用程序运行良好......除了几个噩梦之外:-)。但是,我们终于可以减少数据库了。

在任何工作之前,我操作系统备份了实时数据库,并将其复制到测试服务器。在测试服务器上,我做了一个:CL copy mylivedb.nsf mycleandb.nsf 在mycleandb.nsf中,我删除了文档以将DB减少到650,000个文档。

我所追求的只是一个新副本,而不是副本,请参阅下面的副本问题,所以我发出了另一个命令...给我一个没有删除存根的新副本,我的理解是COPY不复制del '存根: CL复制mycleandb.nsf mycleandbNEW.nsf ...这也确保了如果网络上有任何恶意副本,我们不会得到他的文档(并非我们所有的服务器都是8.5.3,所以我们不能使用数据库属性来设置切换删除存根的截止日期)

但是我得到了:无法扩展ID表 - 内存不足。 试过这个: CL copy mycleandb.nsf mycleandbNEW.nsf REPLICA ......同样的事情。

尝试在mycleandb.nsf找到的步骤: http://www-01.ibm.com/support/docview.wss?uid=swg21220384 ......同样的事情。

如此处所述,将清除间隔更改为0天,并将清除日期设置为将来: http://www-01.ibm.com/support/docview.wss?uid=swg21095683 ......同样的事情。

然后跑了一个: 加载紧凑的mycleandb.nsf -B ......同样的事情。

我在这里看过这个帖子,这是类似的情况,除了我们没有任何群集\复制问题......但是! http://www-10.lotus.com/ldd/nd85forum.nsf/DateAllFlatWeb/74d3e0f5467f843885257aaf0081abe5?OpenDocument

所以,我有一个DB我已经删除了文档,我可以打开它,它似乎功能,但我无法复制\复制它。

复制\群集问题: 我之前看到过这样的错误:无法扩展ID表 - 内存不足......而我所做的就是删除我们的主服务器之一,操作系统将数据库复制到服务器上,重启。

我总是使用Admin Client \ Dom控制台创建新的副本,但在这种情况下,每当我这样做时,都会使用文档充满数据库,但所有服务器上的清除间隔都是正确的。新的副本是从HUB服务器创建的,它每30分钟启动一次所有集群配对的PUSH \ PULL复制,所以如果这是一个删除存根问题,它会一直显示出来吗?

我明天将NotesPeek看看是否还有删除存根,但我不知道如何继续。

感激地收到任何意见或建议。

2 个答案:

答案 0 :(得分:2)

根据我的经验,当修改后的文档+存根的总数太高时,Domino中实际清除删除存根的代码无法工作。我认为这可能是一个限制,它在Notes API内部非常深入,结合必须使用的算法 - 这是查看在清除间隔日期之前修改的所有注释 - 可能是非常大的数字。

您最好的选择可能是制作本地非副本副本并重新部署。

我暂时研究了这个。我发现了一些使用Notes C API调用的LotusScript代码,用于清除在各种博客上发布的删除存根。 (我认为原始代码可能来自Rod Whitely,但我不确定。)我的版本代码如下。

当在一个数据库中运行时,文档+存根的总数大约在2到3百万之间,它会得到“无法扩展ID表 - 内存不足”。我从来没有联系IBM支持这个,因为它对我来说真的只是一个副项目。我最终只生成了生产数据库的非副本副本,然后将清除间隔设置得足够低,以便存根的数量永远不会再次变得太高。

Declare Private Sub IDDestroyTable Lib wAPIModule Alias "IDDestroyTable" _
( ByVal hT As Long)
Declare Private Function IDScan Lib wAPIModule Alias "IDScan" _
( ByVal hT As Long, ByVal F As Integer, ID As Long) As Integer
Declare Private Function NSFDbOpen Lib wAPIModule Alias "NSFDbOpen" _
( ByVal P As String, hDB As Long) As Integer
Declare Private Function NSFDbClose Lib wAPIModule Alias "NSFDbClose" _
( ByVal hDB As Long) As Integer
Declare Private Function NSFDbGetModifiedNoteTable Lib wAPIModule Alias "NSFDbGetModifiedNoteTable" _
( ByVal hDB As Long, ByVal C As Integer, ByVal S As Currency, U As Currency, hT As Long) As Integer
Declare Private Function NSFNoteDelete Lib wAPIModule Alias "NSFNoteDelete" _
( ByVal hDB As Long, ByVal N As Long, ByVal F As Integer) As Integer
Declare Private Function OSPathNetConstruct Lib wAPIModule Alias "OSPathNetConstruct" _
( ByVal NullPort As Long, ByVal Server As String, ByVal FIle As String, ByVal PathNet As String) As Integer
Declare Private Sub TimeConstant Lib wAPIModule Alias "TimeConstant" _
( ByVal C As Integer, T As Currency)

Function countAndDeleteStubsByOpenDatabase(db As NotesDatabase, deleteFlag As boolean) As Long

        If db Is Nothing GoTo bail

        Dim forever As Currency
        Dim last As Currency
        Dim hT As Long
        Dim RRV As Long
        Dim hDB As Long
        Dim path As String
        Dim nStubs As Long
        Dim ret As integer

        On Error GoTo bail  

        path = Space(1024)
        Call OSPathNetConstruct(0, db.Server, db.FilePath, path)
        Call NSFDbOpen(path, hDB)

        Call TimeConstant(2, forever)
        Call NSFDbGetModifiedNoteTable(hDB, &H7FFF, forever, last, hT)

        nStubs = 0

        ret = IDScan(hT, True, RRV)

        While Not (ret = 0)
            If RRV < 0 Then
                If (deleteFlag = true) Then 
                    NSFNoteDelete hDB, RRV And &H7FFFFFFF, &H0201 
                End If
                nStubs = nStubs + 1
            End If
            ret = IDScan(hT, False, RRV)
        Wend

        IDDestroyTable hT
        NSFDbClose hDB

        If deleteFlag = True Then
            Print "Deleted " + CStr(nStubs) + " stubs for " + db.Filepath  + " on " + db.Server
        Else
            Print "Counted " + CStr(nStubs) + " stubs for " + db.Filepath  + " on " + db.Server 
        End If


        countAndDeleteStubsByOpenDatabase = nStubs

        On Error GoTo 0

        Exit Function

        bail:
            Print "Unexpected error in countAndDeleteStubsByOpenDatabase. Line " + CStr(Erl) + " " + CStr(Err()) + " " + Error(Err())
            countAndDeleteStubsByOpenDatabase = 0

    End Function

我从未尝试过,但我也想到可以修改此代码,只搜索最近一天的存根,删除它们,然后再返回一天并获取最新信息但是,在LotusScript中可能并不容易做到这一点,因为您必须将C TIMEDATE结构作为货币字段处理。您可能必须在C中执行此操作。当然,首先删除最新的存根与您在实践中要执行的操作完全相反,但此策略可能会解决对idtable的限制。

答案 1 :(得分:0)

http://www.ytria.com/有一个工具ScanEZ,它具有轻松删除删除存根的功能。我不确定如果你像Richard所说的那样打击内部Notes限制会不会有帮助,但是值得一试。