1 Reply Latest reply: Aug 6, 2012 11:23 AM by Laurenfoutz-Oracle RSS

    Lock leak in BerkeleyDB 5.x

    954013
      I have a problem with Berkeley DB version 5.x (up to latest 5.3.21), hope someone can help.

      Steps to reproduce:

      1. Create a queue.
      2. In a transaction push more items to the queue than max_lockers/max_objects. This fails.
      3. Abort the transaction.
      4. Create a cursor on the queue.
      5. First() the cursor. Now this fails with "Not enough space -- Lock table is out of available object entries".

      It appears that the locks are not released after the above steps. In Berkeley DB 4 everything works fine, the cursor just points to the head of an empty queue.

      Following is the Python3 script to reproduce the problem.
      -----------------------------------------
      from os import path as os_path
      from bsddb3 import db as bsddb
      from tempfile import mkdtemp

      # CREATE AN ENVIRONMENT

      env = bsddb.DBEnv()
      env.set_tx_max(1)
      env.set_lk_max_locks(16384)
      env.set_lk_max_lockers(8192)
      env.set_lk_max_objects(8192)
      env.set_flags(bsddb.DB_AUTO_COMMIT | bsddb.DB_TXN_NOWAIT, 1)

      dir = mkdtemp()
      env.open(dir, bsddb.DB_CREATE | bsddb.DB_PRIVATE | bsddb.DB_INIT_LOCK | bsddb.DB_INIT_MPOOL | bsddb.DB_INIT_TXN | bsddb.DB_INIT_LOG)

      # CREATE A QUEUE

      q = bsddb.DB(env)
      q.open(os_path.join(dir, "queue"), None, bsddb.DB_QUEUE, bsddb.DB_CREATE)

      # PUSH MORE RECORDS THAN ALLOWED

      txn = env.txn_begin(None, bsddb.DB_TXN_NOWAIT)
      try:
      for i in range(8192):
      q.append(b"", txn)
      except MemoryError: # expecting and ignoring MemoryError, transaction is aborted
      txn.abort()
      else:
      assert False, "SHOULD NOT SEE ME" # make sure it happened

      # AS THE TRANSACTION HAS BEEN ABORTED, THE QUEUE IS EMPTY

      txn = env.txn_begin(None, bsddb.DB_TXN_NOWAIT)
      crs = q.cursor(txn)

      print("AND NOW FOR THE FAILURE:")
      print("************************")

      crs.first()
      -----------------------------------------