Commit e36429c1 authored by John Esmet's avatar John Esmet Committed by Yoni Fogel

[t:4542] comment how zombies work with dbremove and the rollback code


git-svn-id: file:///svn/toku/tokudb@41718 c7de825b-a66e-492c-adef-691d508d4ae1
parent 133b3238
...@@ -44,7 +44,10 @@ toku_commit_fdelete (u_int8_t file_was_open, ...@@ -44,7 +44,10 @@ toku_commit_fdelete (u_int8_t file_was_open,
r = 0; r = 0;
goto done; goto done;
} }
assert(r == 0); // must still be open (toku_brt_remove_on_commit() incremented refcount) // file must be open now if it was open when the fdelete was logged,
// because the txn that created it opened it and noted it.
// XXX this does not look true "must still be open (toku_brt_remove_on_commit() incremented refcount)"
assert(r == 0);
{ {
(void)toku_cachefile_get_and_pin_fd(cf); (void)toku_cachefile_get_and_pin_fd(cf);
assert(!toku_cachefile_is_dev_null_unlocked(cf)); assert(!toku_cachefile_is_dev_null_unlocked(cf));
...@@ -111,6 +114,9 @@ toku_rollback_fcreate (FILENUM filenum, ...@@ -111,6 +114,9 @@ toku_rollback_fcreate (FILENUM filenum,
r = 0; r = 0;
goto done; goto done;
} }
// file must be open, because the txn that created it opened it and
// noted it, so another client trying to close it would force it
// to become a zombie.
assert(r == 0); assert(r == 0);
{ {
(void)toku_cachefile_get_and_pin_fd(cf); (void)toku_cachefile_get_and_pin_fd(cf);
...@@ -571,6 +577,9 @@ toku_rollback_change_fdescriptor(FILENUM filenum, ...@@ -571,6 +577,9 @@ toku_rollback_change_fdescriptor(FILENUM filenum,
r = 0; r = 0;
goto done; goto done;
} }
// file must be open, because the txn that created it opened it and
// noted it, so another client trying to close it would force it
// to become a zombie.
assert(r==0); assert(r==0);
fd = toku_cachefile_get_and_pin_fd(cf); fd = toku_cachefile_get_and_pin_fd(cf);
......
...@@ -2759,12 +2759,21 @@ toku_env_dbremove(DB_ENV * env, DB_TXN *txn, const char *fname, const char *dbna ...@@ -2759,12 +2759,21 @@ toku_env_dbremove(DB_ENV * env, DB_TXN *txn, const char *fname, const char *dbna
r = toku_db_del(env->i->directory, child, &dname_dbt, DB_DELETE_ANY, TRUE); r = toku_db_del(env->i->directory, child, &dname_dbt, DB_DELETE_ANY, TRUE);
if (r == 0) { if (r == 0) {
if (using_txns) { if (using_txns) {
// this writes an fdelete to the transaction's rollback log.
// it is removed if the child txn aborts after any error case below
r = toku_brt_remove_on_commit(db_txn_struct_i(child)->tokutxn, &iname_dbt); r = toku_brt_remove_on_commit(db_txn_struct_i(child)->tokutxn, &iname_dbt);
assert_zero(r); assert_zero(r);
//Now that we have a writelock on dname, verify that there are still no handles open. (to prevent race conditions) //Now that we have a writelock on dname, verify that there are still no handles open. (to prevent race conditions)
if (r==0 && env_is_db_with_dname_open(env, dname)) if (r==0 && env_is_db_with_dname_open(env, dname))
r = toku_ydb_do_error(env, EINVAL, "Cannot remove dictionary with an open handle.\n"); r = toku_ydb_do_error(env, EINVAL, "Cannot remove dictionary with an open handle.\n");
if (r==0) { if (r==0) {
// we know a live db handle does not exist.
//
// if there exists a zombie, make sure that it is due to
// checkpoint by trying to get a table lock. we can't
// remove a db that live txns reference, but it's okay
// to deal with the fact that its pinned for checkpoint
// further down the stack.
DB* zombie = env_get_zombie_db_with_dname(env, dname); DB* zombie = env_get_zombie_db_with_dname(env, dname);
if (zombie) if (zombie)
r = toku_db_pre_acquire_table_lock(zombie, child, TRUE); r = toku_db_pre_acquire_table_lock(zombie, child, TRUE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment