--- a/lib/cyrusdb.h
+++ b/lib/cyrusdb.h
@@ -69,7 +69,8 @@ enum cyrusdb_dbflags {
 
 enum cyrusdb_openflags {
     CYRUSDB_CREATE   = 0x01,	/* Create the database if not existant */
-    CYRUSDB_MBOXSORT = 0x02	/* Use mailbox sort order ('.' sorts 1st) */
+    CYRUSDB_MBOXSORT = 0x02,	/* Use mailbox sort order ('.' sorts 1st) */
+    CYRUSDB_UPGRADE  = 0x04	/* Do in place upgrade of Berkeley DB */
 };
 
 typedef int foreach_p(void *rock,
--- a/lib/cyrusdb_berkeley.c
+++ b/lib/cyrusdb_berkeley.c
@@ -228,6 +228,11 @@ static int init(const char *dbdir, int m
     r = (dbenv->open)(dbenv, dbdir, NULL, flags, 0644); 
 #endif
     if (r) {
+	if ((myflags & CYRUSDB_UPGRADE) && do_retry && (r == DB_VERSION_MISMATCH)) {
+	    flags |= DB_PRIVATE;
+	    do_retry = 0;
+	    goto retry;
+	}
         if (do_retry && (r == ENOENT)) {
 	  /* Per sleepycat Support Request #3838 reporting a performance problem: 
 
@@ -404,6 +409,29 @@ static int myopen(const char *fname, DBT
 
     *ret = NULL;
 
+    if (flags & CYRUS_UPGRADE) {
+	r = db_create(&db, dbenv, 0);
+	if (r != 0) {
+	    syslog(LOG_ERR, "DBERROR: upgrading %s (creating database handle): %s", fname, db_strerror(r));
+	    return CYRUSDB_IOERROR;
+	}
+
+	/* should we care for upgrades from db 3.0? */
+	r = db->upgrade(db, fname, 0);
+
+	if (r != 0) {
+	    syslog(LOG_ERR, "DBERROR: upgrading %s (upgrading from the old format, possible corruption): %s", fname, db_strerror(r));
+	    return CYRUSDB_IOERROR;
+	}
+
+	r = db-close(db, 0);
+
+	if (r != 0) {
+	    syslog(LOG_ERR, "DBERROR: upgrading %s (closing file after upgrade): %s", fname, db_strerror(r));
+	    return CYRUSDB_IOERROR;
+	}
+    }
+
     r = db_create(&db, dbenv, 0);
     if (r != 0) {
 	syslog(LOG_ERR, "DBERROR: opening %s (creating database handle): %s", fname, db_strerror(r));
