Spark <[EMAIL PROTECTED]> writes:
> Maybe somebody can comeup with change to the code that can implement this??

ok, the change is in cvs. I also included a diff below.

Please let us know if this makes things any better (or worse).

Walter

===================================================================
RCS file: /afs/andrew.cmu.edu/system/cvs/src/cyrus/lib/cyrusdb_db3.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- cyrusdb_db3.c       2001/01/02 05:53:47     1.16
+++ cyrusdb_db3.c       2001/05/01 18:31:45     1.17
@@ -91,12 +91,14 @@
 
 static int init(const char *dbdir, int myflags)
 {
-    int r;
+    int r, do_retry = 1;
     int flags = 0;
 
     assert(!dbinit);
 
-    if (myflags & CYRUSDB_RECOVER) flags |= DB_RECOVER;
+    if (myflags & CYRUSDB_RECOVER) {
+      flags |= DB_RECOVER | DB_CREATE;
+    }
 
     if ((r = db_env_create(&dbenv, 0)) != 0) {
        syslog(LOG_ERR, "DBERROR: db_appinit failed: %s", db_strerror(r));
@@ -130,7 +132,8 @@
 #endif
 
     /* what directory are we in? */
-    flags |= DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL | 
+ retry:
+    flags |= DB_INIT_LOCK | DB_INIT_MPOOL | 
             DB_INIT_LOG | DB_INIT_TXN;
 #if DB_VERSION_MINOR > 0
     r = dbenv->open(dbenv, dbdir, flags, 0644); 
@@ -138,6 +141,26 @@
     r = dbenv->open(dbenv, dbdir, NULL, flags, 0644); 
 #endif
     if (r) {
+        if (do_retry && (r == ENOENT)) {
+         /* Per sleepycat Support Request #3838 reporting a performance problem: 
+
+               Berkeley DB only transactionally protects the open if you're
+               doing a DB_CREATE.  Even if the Cyrus application is opening
+               the file read/write, we don't need a transaction.  I see
+               from their source that they are always specifying DB_CREATE.
+               I bet if they changed it to not specifying CREATE and only
+               creating if necessary, the problem would probably go away.
+
+            Given that in general the file should exist, we optimize the most 
+            often case: the file exists.  So, we add DB_CREATE only if we fail 
+            to open the file and thereby avoid doing a stat(2) needlessly. Sure, it 
+            should be cached by why waste the cycles anyway?
+         */
+         flags |= DB_CREATE;
+         do_retry = 0;
+         goto retry;
+        }
+
        syslog(LOG_ERR, "DBERROR: dbenv->open '%s' failed: %s", dbdir,
               db_strerror(r));
        return CYRUSDB_IOERROR;

Reply via email to