【问题标题】:Lock Table overflow issue in Progress 4GLProgress 4GL 中的锁表溢出问题
【发布时间】:2015-08-05 15:50:53
【问题描述】:

我面临一个锁表溢出问题,下面是它显示给我的错误,一旦显示它就会使代码崩溃。

锁表溢出,在服务器上增加-L (915)

我检查了错误号,它说我们需要在服务器启动之前修改 -L 值,默认设置为 500。但是,除非我是公司的数据库管理员,否则我不会想象我被授予更改该值的特权。 我试图做的是用所有链接的表记录(超过 25 个表链接到每个成员记录)清除大约 11k 的成员记录,同时将每个表备份到单独的文件中。所以大致它在进入成员for循环时实现了'EXCLUSIVE-LOCK',如下所示,

for each member
    EXCLUSIVE-LOCK:

    /* 
       Then find each linked records in a order.
       Extract them.
       Delete them.
    */   
    Finally it extracts the member.
    Delete member.

end.

当它达到一定数量的成员记录时,程序崩溃了。所以我不得不像批量运行它,

for each member
    EXCLUSIVE-LOCK:

    Increment a member count.
      When count = 1k
          then RETURN.
      /* 
       Then find each linked records in a order.
       Extract them.
       Delete them.
    */   
    Finally it extracts the member.
    Delete member.

end.

因此,实际上我最终运行相同的代码超过 11 次才能完成工作。我希望有人遇到过这个问题,如果你想分享一个长期的解决方案而不是我的临时解决方案,我会提供很大的帮助。

【问题讨论】:

    标签: locking progress-4gl openedge


    【解决方案1】:

    您需要为事务中的每条记录设置一个锁。否则其他用户可能会在您的事务提交之前进行冲突更改。

    在您的代码中,您有一个范围为外部 FOR EACH 的事务。因此,您需要为“成员”记录设置一个锁,并为与该成员关联的每个链接记录设置另一个锁。

    (由于您没有显示真实代码,因此您的实际代码也可能具有更广泛的事务范围......)

    锁表必须足够大以容纳所有这些锁。锁表也由所有用户共享——因此它不仅必须持有您的锁,而且还必须为其他人正在做的任何事情留出空间。

    FWIW -- 500 非常非常低。默认为8192。使用字母“l”的启动参数有两个,一个是大写,-L,一个是锁表,是一个服务器启动参数。小写字母 -l 是“本地缓冲区大小”,它是客户端参数。 (它控制有多少内存可用于局部变量。)

    “批处理”,正如您所做的那样,是确保没有一个进程使用太多锁的典型方法。但是,如果您的 -L 真的只有 500,那么 1,000 的批量大小就没有意义了。 100 更典型。

    更好的批处理方式:

    define buffer delete_member for member.
    define buffer delete_memberLink for memberLink.  /* for clarity I'll just do a single linked table... */
    
    for each member no-lock:  /* do NOT get a lock */
    
      batch_loop: do for delete_member, delete_memberLink while true transaction:
    
        b = 0.
    
        for each delete_memberLink exclusive-lock where delete_memberLink.id = member.id:
          b = b + 1.
          delete delete_memberLink.
          if b >= 100 then next batch_loop.
        end.
    
        find delete_member exclusive-lock where recid( delete_member ) = recid( member ).
    
        leave batch_loop.  /* this will only happen if we did NOT execute the NEXT */
    
      end.
    
    end.
    

    【讨论】:

      【解决方案2】:

      您还可以增加 -L 数据库启动参数以考虑您的一次性查询/删除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-18
        • 1970-01-01
        • 1970-01-01
        • 2014-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多