mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 03:51:50 +01:00
Addresses #2037 refs[t:2037] Add test to verify correct use of directory range locks."
git-svn-id: file:///svn/toku/tokudb.2037b@15681 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
d87b38ebd0
commit
28752b831d
1 changed files with 164 additions and 24 deletions
|
@ -77,17 +77,17 @@
|
|||
* create a, b, c
|
||||
* commit txn
|
||||
*
|
||||
* verify_abc() // verify a,b,c exist, c2 and x do not exist
|
||||
* verify_abcd() // verify a,b,c exist, c2 and x do not exist
|
||||
*
|
||||
* begin txn
|
||||
* perform_ops() // delete b, rename c to c2, create x
|
||||
* verify_ac2x() // verify a,c2,x exist, b and c do not
|
||||
* verify_ac2dx() // verify a,c2,x exist, b and c do not
|
||||
* abort txn
|
||||
* verify_abc() // verify a,b,c exist, c2 and x do not exist
|
||||
* verify_abcd() // verify a,b,c exist, c2 and x do not exist
|
||||
* begin_txn
|
||||
* perform_ops()
|
||||
* commit
|
||||
* verify_ac2x() // verify a,c2,x exist, b and c do not
|
||||
* verify_ac2dx() // verify a,c2,x exist, b and c do not
|
||||
*
|
||||
*
|
||||
* perform_ops() {
|
||||
|
@ -97,17 +97,18 @@
|
|||
* }
|
||||
*
|
||||
*
|
||||
* verify_abc() {
|
||||
* a,b,c exist, x, c2 do not exist
|
||||
* verify_abcd() {
|
||||
* a,b,c,d exist, x, c2 do not exist
|
||||
* }
|
||||
*
|
||||
*
|
||||
* verify_ac2x() {
|
||||
* a exists
|
||||
* verify_ac2dx() {
|
||||
* a exists
|
||||
* c2 exists
|
||||
* x exists
|
||||
* b does not exist
|
||||
* c does not exist
|
||||
* d exists
|
||||
* x exists
|
||||
* b does not exist
|
||||
* c does not exist
|
||||
* }
|
||||
*
|
||||
*
|
||||
|
@ -147,28 +148,32 @@ test_shutdown(void) {
|
|||
|
||||
// create dictionaries a.db, b.db, c.db
|
||||
static void
|
||||
create_abc(void) {
|
||||
create_abcd(void) {
|
||||
int r;
|
||||
DB_TXN * txn;
|
||||
DB * db_a;
|
||||
DB * db_b;
|
||||
DB * db_c;
|
||||
DB * db_d;
|
||||
|
||||
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
|
||||
r=db_create(&db_a, env, 0); CKERR(r);
|
||||
r=db_create(&db_b, env, 0); CKERR(r);
|
||||
r=db_create(&db_c, env, 0); CKERR(r);
|
||||
r=db_create(&db_d, env, 0); CKERR(r);
|
||||
|
||||
r=db_a->open(db_a, txn, "a.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_b->open(db_b, txn, "b.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_c->open(db_c, txn, "c.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_d->open(db_d, txn, "d.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
|
||||
r=db_a->close(db_a, 0); CKERR(r);
|
||||
r=db_b->close(db_b, 0); CKERR(r);
|
||||
r=db_c->close(db_c, 0); CKERR(r);
|
||||
|
||||
r=txn->commit(txn, 0); CKERR(r);
|
||||
|
||||
r=db_c->close(db_c, 0); CKERR(r); //Should work whether close is before or after commit. Do one after.
|
||||
r=db_d->close(db_d, 0); CKERR(r); //Should work whether close is before or after commit. Do one after.
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,15 +197,16 @@ perform_ops(DB_TXN * txn) {
|
|||
|
||||
|
||||
// verify that:
|
||||
// dictionaries a.db, b.db, c.db exist
|
||||
// dictionaries a.db, b.db, c.db, d.db exist
|
||||
// dictionaries x.db and c2.db do not exist
|
||||
static void
|
||||
verify_abc(void) {
|
||||
verify_abcd(void) {
|
||||
int r;
|
||||
DB_TXN * txn;
|
||||
DB * db_a;
|
||||
DB * db_b;
|
||||
DB * db_c;
|
||||
DB * db_d;
|
||||
DB * db_x;
|
||||
DB * db_c2;
|
||||
|
||||
|
@ -208,6 +214,7 @@ verify_abc(void) {
|
|||
r=db_create(&db_a, env, 0); CKERR(r);
|
||||
r=db_create(&db_b, env, 0); CKERR(r);
|
||||
r=db_create(&db_c, env, 0); CKERR(r);
|
||||
r=db_create(&db_d, env, 0); CKERR(r);
|
||||
r=db_create(&db_x, env, 0); CKERR(r);
|
||||
r=db_create(&db_c2, env, 0); CKERR(r);
|
||||
|
||||
|
@ -215,6 +222,7 @@ verify_abc(void) {
|
|||
r=db_a->open(db_a, txn, "a.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_b->open(db_b, txn, "b.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_c->open(db_c, txn, "c.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_d->open(db_d, txn, "d.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
|
||||
// should not exist:
|
||||
r=db_x->open(db_x, txn, "x.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR2(r, ENOENT);
|
||||
|
@ -223,6 +231,7 @@ verify_abc(void) {
|
|||
r=db_a->close(db_a, 0); CKERR(r);
|
||||
r=db_b->close(db_b, 0); CKERR(r);
|
||||
r=db_c->close(db_c, 0); CKERR(r);
|
||||
r=db_d->close(db_d, 0); CKERR(r);
|
||||
r=db_x->close(db_x, 0); CKERR(r);
|
||||
r=db_c2->close(db_c2, 0); CKERR(r);
|
||||
|
||||
|
@ -234,14 +243,16 @@ verify_abc(void) {
|
|||
// dictionary a.db exists
|
||||
// dictionaries b.db, c.db do not exist
|
||||
// dictionary c2.db exists
|
||||
// dictionary d.db exists
|
||||
// dictionary x.db exists
|
||||
static void
|
||||
verify_ac2x(DB_TXN * parent_txn) {
|
||||
verify_ac2dx(DB_TXN * parent_txn) {
|
||||
int r;
|
||||
DB_TXN * txn;
|
||||
DB * db_a;
|
||||
DB * db_b;
|
||||
DB * db_c;
|
||||
DB * db_d;
|
||||
DB * db_x;
|
||||
DB * db_c2;
|
||||
|
||||
|
@ -249,12 +260,14 @@ verify_ac2x(DB_TXN * parent_txn) {
|
|||
r=db_create(&db_a, env, 0); CKERR(r);
|
||||
r=db_create(&db_b, env, 0); CKERR(r);
|
||||
r=db_create(&db_c, env, 0); CKERR(r);
|
||||
r=db_create(&db_d, env, 0); CKERR(r);
|
||||
r=db_create(&db_x, env, 0); CKERR(r);
|
||||
r=db_create(&db_c2, env, 0); CKERR(r);
|
||||
|
||||
// should exist:
|
||||
r=db_a->open(db_a, txn, "a.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_c2->open(db_c2, txn, "c2.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_d->open(db_d, txn, "d.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_x->open(db_x, txn, "x.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
|
||||
// should not exist:
|
||||
|
@ -264,6 +277,7 @@ verify_ac2x(DB_TXN * parent_txn) {
|
|||
r=db_a->close(db_a, 0); CKERR(r);
|
||||
r=db_b->close(db_b, 0); CKERR(r);
|
||||
r=db_c->close(db_c, 0); CKERR(r);
|
||||
r=db_d->close(db_d, 0); CKERR(r);
|
||||
r=db_x->close(db_x, 0); CKERR(r);
|
||||
r=db_c2->close(db_c2, 0); CKERR(r);
|
||||
|
||||
|
@ -272,28 +286,152 @@ verify_ac2x(DB_TXN * parent_txn) {
|
|||
|
||||
|
||||
static void
|
||||
test_fileops(void) {
|
||||
test_fileops_1(void) {
|
||||
int r;
|
||||
DB_TXN *txn;
|
||||
|
||||
create_abc();
|
||||
verify_abc();
|
||||
create_abcd();
|
||||
verify_abcd();
|
||||
|
||||
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
|
||||
perform_ops(txn);
|
||||
verify_ac2x(txn); // verify that operations appear effective within this txn
|
||||
verify_ac2dx(txn); // verify that operations appear effective within this txn
|
||||
r=txn->abort(txn); CKERR(r);
|
||||
|
||||
// verify that aborted transaction changed nothing
|
||||
verify_abc();
|
||||
verify_abcd();
|
||||
|
||||
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
|
||||
perform_ops(txn);
|
||||
verify_ac2x(txn); // verify that operations appear effective within this txn
|
||||
verify_ac2dx(txn); // verify that operations appear effective within this txn
|
||||
r=txn->commit(txn, 0); CKERR(r);
|
||||
|
||||
// verify that committed transaction actually changed db
|
||||
verify_ac2x(NULL);
|
||||
verify_ac2dx(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
verify_locked_open(char * name) {
|
||||
int r;
|
||||
DB_TXN * txn;
|
||||
DB * db;
|
||||
|
||||
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
|
||||
r=db_create(&db, env, 0); CKERR(r);
|
||||
r=db->open(db, txn, name, 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO);
|
||||
CKERR2(r, DB_LOCK_NOTGRANTED);
|
||||
r=db->close(db, 0); CKERR(r); // always safe to close
|
||||
r=txn->abort(txn); CKERR(r);
|
||||
}
|
||||
|
||||
static void
|
||||
verify_locked_remove(char * name) {
|
||||
int r;
|
||||
DB_TXN * txn;
|
||||
|
||||
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
|
||||
r = env->dbremove(env, txn, name, NULL, 0);
|
||||
CKERR2(r, DB_LOCK_NOTGRANTED);
|
||||
r=txn->abort(txn); CKERR(r);
|
||||
}
|
||||
|
||||
static void
|
||||
verify_locked_rename(char * oldname, char * newname) {
|
||||
int r;
|
||||
DB_TXN * txn;
|
||||
|
||||
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
|
||||
r = env->dbrename(env, txn, oldname, NULL, newname, 0);
|
||||
CKERR2(r, DB_LOCK_NOTGRANTED);
|
||||
r=txn->abort(txn); CKERR(r);
|
||||
}
|
||||
|
||||
|
||||
// Purpose of test_fileops_2() is to verify correct operation of
|
||||
// directory range locks. It should not be possible to open or
|
||||
// rename or remove a dictionary that is marked for removal or
|
||||
// rename by another open transaction.
|
||||
static void
|
||||
test_fileops_2(void) {
|
||||
int r;
|
||||
DB_TXN * txn_a;
|
||||
|
||||
verify_ac2dx(NULL); // should still exist
|
||||
|
||||
// begin txn_a
|
||||
// remove a
|
||||
// create e
|
||||
// rename x->x2
|
||||
// rename c2->c3
|
||||
// open x2, c3, should succeed
|
||||
// close x2, c3
|
||||
{
|
||||
DB * db_e;
|
||||
DB * db_c3;
|
||||
DB * db_x2;
|
||||
|
||||
r=env->txn_begin(env, 0, &txn_a, 0); CKERR(r);
|
||||
r=db_create(&db_e, env, 0); CKERR(r);
|
||||
r=db_create(&db_x2, env, 0); CKERR(r);
|
||||
r=db_create(&db_c3, env, 0); CKERR(r);
|
||||
|
||||
r = env->dbremove(env, txn_a, "a.db", NULL, 0); CKERR(r);
|
||||
r=db_e->open(db_e, txn_a, "e.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r = env->dbrename(env, txn_a, "x.db", NULL, "x2.db", 0); CKERR(r);
|
||||
r = env->dbrename(env, txn_a, "c2.db", NULL, "c3.db", 0); CKERR(r);
|
||||
|
||||
r=db_x2->open(db_x2, txn_a, "x2.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
r=db_c3->open(db_c3, txn_a, "c3.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
|
||||
|
||||
r=db_e->close(db_e, 0); CKERR(r); // abort requires db be closed first
|
||||
r=db_x2->close(db_x2, 0); CKERR(r); // abort requires db be closed first
|
||||
r=db_c3->close(db_c3, 0); CKERR(r); // abort requires db be closed first
|
||||
|
||||
}
|
||||
|
||||
// within another transaction:
|
||||
// open a, should fail DB_LOCK_NOTGRANTED
|
||||
// open e, should fail DB_LOCK_NOTGRANTED
|
||||
// open x, should fail DB_LOCK_NOTGRANTED
|
||||
// open x2, should fail DB_LOCK_NOTGRANTED
|
||||
// open c2, should fail DB_LOCK_NOTGRANTED
|
||||
// open c3, should fail DB_LOCK_NOTGRANTED
|
||||
// remove a, e, x, x2, c2, c3 DB_LOCK_NOTGRANTED
|
||||
// rename a, e, x, x2, c2, c3 DB_LOCK_NOTGRANTED
|
||||
|
||||
verify_locked_open("a.db");
|
||||
verify_locked_open("e.db");
|
||||
verify_locked_open("x.db");
|
||||
verify_locked_open("x2.db");
|
||||
verify_locked_open("c2.db");
|
||||
verify_locked_open("c3.db");
|
||||
|
||||
verify_locked_remove("a.db");
|
||||
verify_locked_remove("e.db");
|
||||
verify_locked_remove("x.db");
|
||||
verify_locked_remove("x2.db");
|
||||
verify_locked_remove("c2.db");
|
||||
verify_locked_remove("c3.db");
|
||||
|
||||
verify_locked_rename("a.db", "z.db");
|
||||
verify_locked_rename("e.db", "z.db");
|
||||
verify_locked_rename("x.db", "z.db");
|
||||
verify_locked_rename("x2.db", "z.db");
|
||||
verify_locked_rename("c2.db", "z.db");
|
||||
verify_locked_rename("c3.db", "z.db");
|
||||
|
||||
verify_locked_rename("d.db", "a.db");
|
||||
verify_locked_rename("d.db", "e.db");
|
||||
verify_locked_rename("d.db", "x.db");
|
||||
verify_locked_rename("d.db", "x2.db");
|
||||
verify_locked_rename("d.db", "c2.db");
|
||||
verify_locked_rename("d.db", "c3.db");
|
||||
|
||||
|
||||
r=txn_a->abort(txn_a); CKERR(r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -302,7 +440,9 @@ test_main (int argc, char *argv[]) {
|
|||
parse_args(argc, argv);
|
||||
setup();
|
||||
print_engine_status(env);
|
||||
test_fileops();
|
||||
test_fileops_1();
|
||||
print_engine_status(env);
|
||||
test_fileops_2();
|
||||
print_engine_status(env);
|
||||
test_shutdown();
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue