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;