1

更新:我已发布: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 复制 mylivedb.nsf mycleandb.nsf 在 mycleandb.nsf 然后我删除了文档以将数据库减少到 650,000 个文档。

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

但我得到了一个:无法扩展 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 ...同样的事情。

然后运行 ​​a: load compact mycleandb.nsf -B ...同样的事情。

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

所以,我有一个数据库,我从中删除了文档,我可以打开它,它似乎可以运行,但我无法复制它。

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

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

明天我会 NotesPeek 看看是否还有删除存根,但我不确定如何继续。

如有任何意见或建议,我们将不胜感激。

4

2 回答 2

2

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

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

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

当在 docs + stubs 总数介于 2 到 300 万之间的数据库上运行时,它会得到“无法扩展 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 中执行此操作。当然,首先删除最新的存根与您在实践中想要执行的操作完全相反,但这种策略可能会解决 idtables 的限制。

于 2012-12-10T17:47:34.133 回答
0

http://www.ytria.com/有一个工具 ScanEZ,它具有轻松删除删除存根的功能。我不确定如果您按照 Richard 的建议达到内部 Notes 限制是否会有所帮助,但它可能值得一试。

于 2017-05-05T12:41:58.490 回答