Configure db4 locks according to maxkeys and actually check maxkeys
authorJonathan McDowell <noodles@earth.li>
Tue, 29 Mar 2011 01:35:25 +0000 (18:35 -0700)
committerJonathan McDowell <noodles@earth.li>
Tue, 29 Mar 2011 01:35:25 +0000 (18:35 -0700)
  The number of db4 objects iin use is related to the maximum number of
  keys we return at once. Configure the locking subsystem accordingly
  and limit the number of returned keys to maxkeys.

  Significantly improves the reliability of the db4 backend on a large
  busy server.

keydb_db4.c

index 899075868b4d48df44cb4a49e2e6c03bcb1fb913..6fbf9da5392798159cac6e13682ea087f154ed16 100644 (file)
@@ -277,6 +277,7 @@ static void db4_initdb(bool readonly)
        int        i = 0;
        u_int32_t  flags = 0;
        struct stat statbuf;
        int        i = 0;
        u_int32_t  flags = 0;
        struct stat statbuf;
+       int        maxlocks;
 
        snprintf(buf, sizeof(buf) - 1, "%s/%s", config.db_dir,
                        DB4_UPGRADE_FILE);
 
        snprintf(buf, sizeof(buf) - 1, "%s/%s", config.db_dir,
                        DB4_UPGRADE_FILE);
@@ -329,6 +330,17 @@ static void db4_initdb(bool readonly)
                }
        }
 
                }
        }
 
+       /*
+        * Up the number of locks we're allowed at once. We base this on
+        * the maximum number of keys we're going to return.
+        */
+       maxlocks = config.maxkeys * 16;
+       if (maxlocks < 1000) {
+               maxlocks = 1000;
+       }
+       dbenv->set_lk_max_locks(dbenv, maxlocks);
+       dbenv->set_lk_max_objects(dbenv, maxlocks);
+
        /*
         * Enable deadlock detection so that we don't block indefinitely on
         * anything. What we really want is simple 2 state locks, but I'm not
        /*
         * Enable deadlock detection so that we don't block indefinitely on
         * anything. What we really want is simple 2 state locks, but I'm not
@@ -690,6 +702,10 @@ static int db4_fetch_key_text(const char *search,
        }
        llfree(wordlist, NULL);
        wordlist = NULL;
        }
        llfree(wordlist, NULL);
        wordlist = NULL;
+
+       if (keylist.count > config.maxkeys) {
+               keylist.count = config.maxkeys;
+       }
        
        db4_starttrans();
        for (i = 0; i < keylist.count; i++) {
        
        db4_starttrans();
        for (i = 0; i < keylist.count; i++) {