Commit 460e7716 authored by Rich Prohaska's avatar Rich Prohaska

DB-397 remove table lock for tables with triggers in tokudb::start_stmt

parent 52030b59
set default_storage_engine='tokudb';
drop table if exists t1;
drop table if exists t1_audit;
create table t1 (
col1 int not null,
col2 int not null,
primary key (col1));
create table t1_audit (
col1 int not null,
action varchar(10) not null,
ts timestamp not null default now());
insert into t1 (col1,col2) values (0,0);
insert into t1_audit (col1,action) values (0,'DUMMY');
set local tokudb_prelock_empty=0;
create trigger t1_trigger before delete on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'BEFORE DELETE');
insert into t1 (col1,col2) values (1,1);
start transaction;
delete from t1 where col1 = 1;
select col1,col2 from t1;
col1 col2
0 0
select col1,action from t1_audit;
col1 action
0 DUMMY
1 BEFORE DEL
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
locks_dname locks_key_left locks_key_right
./test/t1_audit-main 0200000000000000 0200000000000000
./test/t1-main ff01000000 0101000000
./test/t1-main 0001000000 0001000000
commit;
drop trigger t1_trigger;
create trigger t1_trigger after delete on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'AFTER DELETE');
insert into t1 (col1,col2) values (2,2);
start transaction;
delete from t1 where col1 = 2;
select col1,col2 from t1;
col1 col2
0 0
select col1,action from t1_audit;
col1 action
0 DUMMY
1 BEFORE DEL
2 AFTER DELE
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
locks_dname locks_key_left locks_key_right
./test/t1_audit-main 0300000000000000 0300000000000000
./test/t1-main ff02000000 0102000000
./test/t1-main 0002000000 0002000000
commit;
drop trigger t1_trigger;
drop table t1;
drop table t1_audit;
set default_storage_engine='tokudb';
drop table if exists t1;
drop table if exists t1_audit;
create table t1 (
col1 int not null,
col2 int not null,
primary key (col1));
create table t1_audit (
col1 int not null,
action varchar(32) not null,
ts timestamp not null default now());
insert into t1 (col1,col2) values (0,0);
insert into t1_audit (col1,action) values (0,'DUMMY');
set local tokudb_prelock_empty=0;
create trigger t1_trigger before insert on t1
for each row
insert into t1_audit (col1, action) values (new.col1, 'BEFORE INSERT');
start transaction;
insert into t1 (col1, col2) values (1,1);
select col1,col2 from t1;
col1 col2
0 0
1 1
select col1,action from t1_audit;
col1 action
0 DUMMY
1 BEFORE INSERT
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
locks_dname locks_key_left locks_key_right
./test/t1_audit-main 0200000000000000 0200000000000000
./test/t1-main 0001000000 0001000000
commit;
drop trigger t1_trigger;
create trigger t1_trigger after insert on t1
for each row
insert into t1_audit (col1, action) values (new.col1, 'AFTER INSERT');
start transaction;
insert into t1 (col1, col2) values (2,2);
select col1,col2 from t1;
col1 col2
0 0
1 1
2 2
select col1,action from t1_audit;
col1 action
0 DUMMY
1 BEFORE INSERT
2 AFTER INSERT
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
locks_dname locks_key_left locks_key_right
./test/t1_audit-main 0300000000000000 0300000000000000
./test/t1-main 0002000000 0002000000
commit;
drop trigger t1_trigger;
drop table t1;
drop table t1_audit;
set default_storage_engine='tokudb';
drop table if exists t1, t1_audit;
create table t1 (
col1 int not null,
col2 int not null,
primary key (col1));
create table t1_audit (
col1 int not null,
action varchar(32) not null,
ts timestamp not null default now());
insert into t1 (col1,col2) values (0,0);
insert into t1_audit (col1,action) values (0,'DUMMY');
set local tokudb_prelock_empty=0;
create trigger t1_trigger before update on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'BEFORE UPDATE');
insert into t1 (col1,col2) values (1,1);
start transaction;
update t1 set col2=1000 where col1 = 1;
select col1,col2 from t1;
col1 col2
0 0
1 1000
select col1,action from t1_audit;
col1 action
0 DUMMY
1 BEFORE UPDATE
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
locks_dname locks_key_left locks_key_right
./test/t1_audit-main 0200000000000000 0200000000000000
./test/t1-main ff01000000 0101000000
./test/t1-main 0001000000 0001000000
commit;
drop trigger t1_trigger;
create trigger t1_trigger after update on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'AFTER UPDATE');
insert into t1 (col1,col2) values (2,2);
start transaction;
update t1 set col2=1001 where col1 = 2;
select col1,col2 from t1;
col1 col2
0 0
1 1000
2 1001
select col1,action from t1_audit;
col1 action
0 DUMMY
1 BEFORE UPDATE
2 AFTER UPDATE
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
locks_dname locks_key_left locks_key_right
./test/t1_audit-main 0300000000000000 0300000000000000
./test/t1-main ff02000000 0102000000
./test/t1-main 0002000000 0002000000
commit;
drop trigger t1_trigger;
drop table t1, t1_audit;
# check for any locking weirdness on DELETE triggers
source include/have_tokudb.inc;
set default_storage_engine='tokudb';
disable_warnings;
drop table if exists t1;
drop table if exists t1_audit;
enable_warnings;
create table t1 (
col1 int not null,
col2 int not null,
primary key (col1));
create table t1_audit (
col1 int not null,
action varchar(10) not null,
ts timestamp not null default now());
insert into t1 (col1,col2) values (0,0);
insert into t1_audit (col1,action) values (0,'DUMMY');
set local tokudb_prelock_empty=0;
create trigger t1_trigger before delete on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'BEFORE DELETE');
insert into t1 (col1,col2) values (1,1);
start transaction;
delete from t1 where col1 = 1;
select col1,col2 from t1;
select col1,action from t1_audit;
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
# note the locks on t1 and t1_audit
commit;
drop trigger t1_trigger;
create trigger t1_trigger after delete on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'AFTER DELETE');
insert into t1 (col1,col2) values (2,2);
start transaction;
delete from t1 where col1 = 2;
select col1,col2 from t1;
select col1,action from t1_audit;
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
# note the locks on t1 and t1_audit
commit;
drop trigger t1_trigger;
drop table t1;
drop table t1_audit;
\ No newline at end of file
# check for any locking weirdness on INSERT triggers
source include/have_tokudb.inc;
set default_storage_engine='tokudb';
disable_warnings;
drop table if exists t1;
drop table if exists t1_audit;
enable_warnings;
create table t1 (
col1 int not null,
col2 int not null,
primary key (col1));
create table t1_audit (
col1 int not null,
action varchar(32) not null,
ts timestamp not null default now());
insert into t1 (col1,col2) values (0,0);
insert into t1_audit (col1,action) values (0,'DUMMY');
set local tokudb_prelock_empty=0;
create trigger t1_trigger before insert on t1
for each row
insert into t1_audit (col1, action) values (new.col1, 'BEFORE INSERT');
start transaction;
insert into t1 (col1, col2) values (1,1);
select col1,col2 from t1;
select col1,action from t1_audit;
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
# note the locks on t1 and t1_audit
commit;
drop trigger t1_trigger;
create trigger t1_trigger after insert on t1
for each row
insert into t1_audit (col1, action) values (new.col1, 'AFTER INSERT');
start transaction;
insert into t1 (col1, col2) values (2,2);
select col1,col2 from t1;
select col1,action from t1_audit;
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
# note the locks on t1 and t1_audit
commit;
drop trigger t1_trigger;
drop table t1;
drop table t1_audit;
\ No newline at end of file
# check for any locking weirdness on UPDATE triggers
source include/have_tokudb.inc;
set default_storage_engine='tokudb';
disable_warnings;
drop table if exists t1, t1_audit;
enable_warnings;
create table t1 (
col1 int not null,
col2 int not null,
primary key (col1));
create table t1_audit (
col1 int not null,
action varchar(32) not null,
ts timestamp not null default now());
insert into t1 (col1,col2) values (0,0);
insert into t1_audit (col1,action) values (0,'DUMMY');
set local tokudb_prelock_empty=0;
# test before update trigger
create trigger t1_trigger before update on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'BEFORE UPDATE');
insert into t1 (col1,col2) values (1,1);
start transaction;
update t1 set col2=1000 where col1 = 1;
select col1,col2 from t1;
select col1,action from t1_audit;
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
# check locks on t1 and t1_audit
commit;
drop trigger t1_trigger;
# test after update trigger
create trigger t1_trigger after update on t1
for each row
insert into t1_audit (col1, action) values (old.col1, 'AFTER UPDATE');
insert into t1 (col1,col2) values (2,2);
start transaction;
update t1 set col2=1001 where col1 = 2;
select col1,col2 from t1;
select col1,action from t1_audit;
select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks;
# check locks on t1 and t1_audit
commit;
drop trigger t1_trigger;
# cleanup
drop table t1, t1_audit;
...@@ -6005,7 +6005,6 @@ int ha_tokudb::reset(void) { ...@@ -6005,7 +6005,6 @@ int ha_tokudb::reset(void) {
TOKUDB_HANDLER_DBUG_RETURN(0); TOKUDB_HANDLER_DBUG_RETURN(0);
} }
// //
// helper function that iterates through all DB's // helper function that iterates through all DB's
// and grabs a lock (either read or write, but not both) // and grabs a lock (either read or write, but not both)
...@@ -6017,6 +6016,7 @@ int ha_tokudb::reset(void) { ...@@ -6017,6 +6016,7 @@ int ha_tokudb::reset(void) {
// error otherwise // error otherwise
// //
int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) { int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) {
TOKUDB_HANDLER_DBUG_ENTER("%p %s", trans, lt == lock_read ? "r" : "w");
int error = ENOSYS; int error = ENOSYS;
if (!num_DBs_locked_in_bulk) { if (!num_DBs_locked_in_bulk) {
rw_rdlock(&share->num_DBs_lock); rw_rdlock(&share->num_DBs_lock);
...@@ -6048,10 +6048,9 @@ cleanup: ...@@ -6048,10 +6048,9 @@ cleanup:
if (!num_DBs_locked_in_bulk) { if (!num_DBs_locked_in_bulk) {
rw_unlock(&share->num_DBs_lock); rw_unlock(&share->num_DBs_lock);
} }
return error; TOKUDB_HANDLER_DBUG_RETURN(error);
} }
int ha_tokudb::create_txn(THD* thd, tokudb_trx_data* trx) { int ha_tokudb::create_txn(THD* thd, tokudb_trx_data* trx) {
int error; int error;
ulong tx_isolation = thd_tx_isolation(thd); ulong tx_isolation = thd_tx_isolation(thd);
...@@ -6228,7 +6227,6 @@ cleanup: ...@@ -6228,7 +6227,6 @@ cleanup:
TABLE LOCK is done. TABLE LOCK is done.
Under LOCK TABLES, each used tables will force a call to start_stmt. Under LOCK TABLES, each used tables will force a call to start_stmt.
*/ */
int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) { int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) {
TOKUDB_HANDLER_DBUG_ENTER("cmd %d lock %d %s", thd_sql_command(thd), lock_type, share->table_name); TOKUDB_HANDLER_DBUG_ENTER("cmd %d lock %d %s", thd_sql_command(thd), lock_type, share->table_name);
if (0) if (0)
...@@ -6257,27 +6255,6 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) { ...@@ -6257,27 +6255,6 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) {
TOKUDB_HANDLER_TRACE("trx->stmt %p already existed", trx->stmt); TOKUDB_HANDLER_TRACE("trx->stmt %p already existed", trx->stmt);
} }
} }
//
// we know we are in lock tables
// attempt to grab a table lock
// if fail, continue, do not return error
// This is because a failure ok, it simply means
// another active transaction has some locks.
// That other transaction modify this table
// until it is unlocked, therefore having acquire_table_lock
// potentially grab some locks but not all is ok.
//
if (lock.type <= TL_READ_NO_INSERT) {
acquire_table_lock(trx->sub_sp_level,lock_read);
}
else {
if (!(thd_sql_command(thd) == SQLCOM_CREATE_INDEX ||
thd_sql_command(thd) == SQLCOM_ALTER_TABLE ||
thd_sql_command(thd) == SQLCOM_DROP_INDEX ||
thd_sql_command(thd) == SQLCOM_TRUNCATE)) {
acquire_table_lock(trx->sub_sp_level,lock_write);
}
}
if (added_rows > deleted_rows) { if (added_rows > deleted_rows) {
share->rows_from_locked_table = added_rows - deleted_rows; share->rows_from_locked_table = added_rows - deleted_rows;
} }
......
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