diff --git a/src/tests/directory_lock.c b/src/tests/directory_lock.c index 01a0f5699e1..ca58ff8085f 100755 --- a/src/tests/directory_lock.c +++ b/src/tests/directory_lock.c @@ -173,11 +173,23 @@ int test_main (int argc, char * const argv[]) { CKERR(r); r = env->open(env, ENVDIR, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r); - DB *db; + DB* db; + DB* db2; DB_TXN* txna = NULL; DB_TXN* txnb = NULL; + + // + // transactionally create dictionary + // + r = env->txn_begin(env, NULL, &txna, 0); CKERR(r); + r = db_create(&db2, env, 0); CKERR(r); + r = db2->open(db2, txna, "foo2.db", NULL, DB_BTREE, DB_CREATE|DB_IS_HOT_INDEX, 0666); CKERR(r); + verify_excl_ops_fail(env, db2); + r = txna->commit(txna, 0); CKERR(r); + + // // transactionally create dictionary // @@ -326,6 +338,7 @@ int test_main (int argc, char * const argv[]) { r = txnb->abort(txnb); CKERR(r); r = db->close(db, 0); CKERR(r); + r = db2->close(db2, 0); CKERR(r); r = env->close(env, 0); CKERR(r); return 0; diff --git a/src/ydb.c b/src/ydb.c index 5f64e717d8b..9759c3abd51 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -4382,6 +4382,7 @@ toku_db_open(DB * db, DB_TXN * txn, const char *fname, const char *dbname, DBTYP if (dbtype!=DB_BTREE && dbtype!=DB_UNKNOWN) return EINVAL; int is_db_excl = flags & DB_EXCL; unused_flags&=~DB_EXCL; int is_db_create = flags & DB_CREATE; unused_flags&=~DB_CREATE; + int is_db_hot_index = flags & DB_IS_HOT_INDEX; unused_flags&=~DB_IS_HOT_INDEX; //We support READ_UNCOMMITTED and READ_COMMITTED whether or not the flag is provided. unused_flags&=~DB_READ_UNCOMMITTED; @@ -4435,7 +4436,13 @@ toku_db_open(DB * db, DB_TXN * txn, const char *fname, const char *dbname, DBTYP create_iname_hint(dname, hint); iname = create_iname(db->dbenv, id, hint, -1); // allocated memory for iname toku_fill_dbt(&iname_dbt, iname, strlen(iname) + 1); - r = toku_db_put(db->dbenv->i->directory, child, &dname_dbt, &iname_dbt, DB_YESOVERWRITE); // DB_YESOVERWRITE for performance only, avoid unnecessary query + // + // DB_YESOVERWRITE for performance only, avoid unnecessary query + // if we are creating a hot index, per #3166, we do not want the write lock in directory grabbed. + // directory read lock is grabbed in toku_db_get above + // + u_int32_t put_flags = DB_YESOVERWRITE | ((is_db_hot_index) ? DB_PRELOCKED_WRITE : 0); + r = toku_db_put(db->dbenv->i->directory, child, &dname_dbt, &iname_dbt, put_flags); } // we now have an iname @@ -4484,6 +4491,7 @@ db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, u_int32_t flags, flags&=~DB_READ_UNCOMMITTED; flags&=~DB_READ_COMMITTED; flags&=~DB_SERIALIZABLE; + flags&=~DB_IS_HOT_INDEX; if (flags & ~DB_THREAD) return EINVAL; // unknown flags if (is_db_excl && !is_db_create) return EINVAL;