diff --git a/mysql-test/suite/tianmu/r/issue819.result b/mysql-test/suite/tianmu/r/issue819.result new file mode 100644 index 0000000000..e1628dc16e --- /dev/null +++ b/mysql-test/suite/tianmu/r/issue819.result @@ -0,0 +1,234 @@ +include/master-slave.inc +[connection master] +# +# Test the master-slave function of innodb +# +# connection master +use test; +create table ttt(id int primary key,name varchar(5))engine=innodb; +insert into ttt values(1,'AAA'); +delete from ttt where id=1; +insert into ttt values(1,'aaa'); +select * from ttt; +id name +1 aaa +# connection slave +include/sync_slave_sql_with_master.inc +select * from ttt; +id name +1 aaa +# connection master +drop table ttt; +include/sync_slave_sql_with_master.inc +# connection master +CREATE TABLE t1 (a int not null,b int not null)engine=innodb; +CREATE TABLE t2 (a int not null, b int not null, primary key (a,b))engine=innodb; +CREATE TABLE t3 (a int not null, b int not null, primary key (a,b))engine=innodb; +insert into t1 values (1,1),(2,1),(1,3); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(1,3); +delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +select * from t1; +a b +1 1 +2 1 +1 3 +select * from t2; +a b +3 3 +select * from t3; +a b +# connection slave +include/sync_slave_sql_with_master.inc +select * from t1; +a b +1 1 +2 1 +1 3 +select * from t2; +a b +3 3 +select * from t3; +a b +# connection master +drop table t1,t2,t3; +include/sync_slave_sql_with_master.inc +# connection master +CREATE TABLE t1 +( +place_id int (10) unsigned NOT NULL, +shows int(10) unsigned DEFAULT '0' NOT NULL, +ishows int(10) unsigned DEFAULT '0' NOT NULL, +ushows int(10) unsigned DEFAULT '0' NOT NULL, +clicks int(10) unsigned DEFAULT '0' NOT NULL, +iclicks int(10) unsigned DEFAULT '0' NOT NULL, +uclicks int(10) unsigned DEFAULT '0' NOT NULL, +ts timestamp, +PRIMARY KEY (place_id,ts) +)engine=innodb; +INSERT INTO t1 (place_id,shows,ishows,ushows,clicks,iclicks,uclicks,ts) +VALUES (1,0,0,0,0,0,0,20000928174434); +UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00"; +select place_id,shows from t1; +place_id shows +1 1 +# connection slave +include/sync_slave_sql_with_master.inc +select place_id,shows from t1; +place_id shows +1 1 +# connection master +drop table t1; +include/sync_slave_sql_with_master.inc +# +# Test the master-slave function of tianmu +# +# connection master +use test; +create table ttt(id int primary key,name varchar(5))engine=tianmu; +insert into ttt values(1,'AAA'); +update ttt set name='hhhh' where id=1; +select * from ttt; +id name +1 hhhh +# connection slave +include/sync_slave_sql_with_master.inc +select * from ttt; +id name +1 hhhh +# connection master +drop table ttt; +include/sync_slave_sql_with_master.inc +# connection master +create table t1(id int primary key,name varchar(5))engine=tianmu; +insert into t1 values(1,'AAA'); +delete from t1 where id=1; +insert into t1 values(1,'aaa'); +select * from t1; +id name +1 aaa +# connection slave +include/sync_slave_sql_with_master.inc +select * from t1; +id name +1 aaa +# connection master +drop table t1; +CREATE TABLE t1 (a int not null,b int not null)engine=tianmu; +CREATE TABLE t2 (a int not null, b int not null, primary key (a,b))engine=tianmu; +CREATE TABLE t3 (a int not null, b int not null, primary key (a,b))engine=tianmu; +insert into t1 values (1,1),(2,1),(1,3); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(1,3); +delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +select * from t1; +a b +1 1 +2 1 +1 3 +select * from t2; +a b +3 3 +select * from t3; +a b +# connection slave +include/sync_slave_sql_with_master.inc +select * from t1; +a b +1 1 +2 1 +1 3 +select * from t2; +a b +3 3 +select * from t3; +a b +# connection master +drop table t1,t2,t3; +include/sync_slave_sql_with_master.inc +# connection master +CREATE TABLE t1 +( +place_id int (10), +shows int(10), +ishows int(10), +ushows int(10), +clicks int(10), +iclicks int(10), +uclicks int(10), +ts timestamp, +PRIMARY KEY (place_id,ts) +)engine=tianmu; +INSERT INTO t1 (place_id,shows,ishows,ushows,clicks,iclicks,uclicks,ts) +VALUES (1,0,0,0,0,0,0,20000928174434); +UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00"; +select place_id,shows from t1; +place_id shows +1 1 +# connection slave +include/sync_slave_sql_with_master.inc +select place_id,shows from t1; +place_id shows +1 1 +# connection master +drop table t1; +create table t1 (s1 int); +create table t2 (s2 int); +insert into t1 values (1), (2); +insert into t2 values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +s1 s2 +1 2 +2 2 +1 3 +2 3 +1 2 +2 2 +1 3 +2 3 +# connection slave +include/sync_slave_sql_with_master.inc +select * from v1; +s1 s2 +1 2 +2 2 +1 3 +2 3 +1 2 +2 2 +1 3 +2 3 +# connection master +drop view v1; +drop tables t1, t2; +create table t1 (col1 int); +insert into t1 values (1); +create view v1 as select count(*) from t1; +insert into t1 values (null); +select * from v1; +count(*) +2 +# connection slave +include/sync_slave_sql_with_master.inc +select * from v1; +count(*) +2 +# connection master +drop view v1; +drop table t1; +create table t1 (a int); +create table t2 (a int); +create view v1 as select a from t1; +create view v2 as select a from t2 where a in (select a from v1); +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` from `v1`) latin1 latin1_swedish_ci +# connection slave +include/sync_slave_sql_with_master.inc +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` from `v1`) latin1 latin1_swedish_ci +# connection master +drop view v2, v1; +drop table t1, t2; diff --git a/mysql-test/suite/tianmu/t/issue819.test b/mysql-test/suite/tianmu/t/issue819.test new file mode 100644 index 0000000000..462bcea347 --- /dev/null +++ b/mysql-test/suite/tianmu/t/issue819.test @@ -0,0 +1,220 @@ +-- source include/have_tianmu.inc +--disable_warnings +-- source include/master-slave.inc +--enable_warnings +--echo # +--echo # Test the master-slave function of innodb +--echo # + +--echo # connection master +connection master; +use test; +create table ttt(id int primary key,name varchar(5))engine=innodb; +insert into ttt values(1,'AAA'); +delete from ttt where id=1; +insert into ttt values(1,'aaa'); +select * from ttt; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc + +select * from ttt; + +--echo # connection master +connection master; +drop table ttt; +--source include/sync_slave_sql_with_master.inc + +--echo # connection master +connection master; +CREATE TABLE t1 (a int not null,b int not null)engine=innodb; +CREATE TABLE t2 (a int not null, b int not null, primary key (a,b))engine=innodb; +CREATE TABLE t3 (a int not null, b int not null, primary key (a,b))engine=innodb; +insert into t1 values (1,1),(2,1),(1,3); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(1,3); +delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; + +select * from t1; +select * from t2; +select * from t3; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc + +select * from t1; +select * from t2; +select * from t3; + +--echo # connection master +connection master; +drop table t1,t2,t3; +--source include/sync_slave_sql_with_master.inc + +--echo # connection master +connection master; +CREATE TABLE t1 + ( + place_id int (10) unsigned NOT NULL, + shows int(10) unsigned DEFAULT '0' NOT NULL, + ishows int(10) unsigned DEFAULT '0' NOT NULL, + ushows int(10) unsigned DEFAULT '0' NOT NULL, + clicks int(10) unsigned DEFAULT '0' NOT NULL, + iclicks int(10) unsigned DEFAULT '0' NOT NULL, + uclicks int(10) unsigned DEFAULT '0' NOT NULL, + ts timestamp, + PRIMARY KEY (place_id,ts) + )engine=innodb; + +INSERT INTO t1 (place_id,shows,ishows,ushows,clicks,iclicks,uclicks,ts) +VALUES (1,0,0,0,0,0,0,20000928174434); +UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00"; +select place_id,shows from t1; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc +select place_id,shows from t1; + +--echo # connection master +connection master; +drop table t1; +--source include/sync_slave_sql_with_master.inc + +--echo # +--echo # Test the master-slave function of tianmu +--echo # + +--echo # connection master +connection master; +use test; +create table ttt(id int primary key,name varchar(5))engine=tianmu; +insert into ttt values(1,'AAA'); +update ttt set name='hhhh' where id=1; +select * from ttt; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc + +select * from ttt; + +--echo # connection master +connection master; +drop table ttt; +--source include/sync_slave_sql_with_master.inc + +--echo # connection master +connection master; +create table t1(id int primary key,name varchar(5))engine=tianmu; +insert into t1 values(1,'AAA'); +delete from t1 where id=1; +insert into t1 values(1,'aaa'); +select * from t1; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc +select * from t1; + +--echo # connection master +connection master; +drop table t1; + +CREATE TABLE t1 (a int not null,b int not null)engine=tianmu; +CREATE TABLE t2 (a int not null, b int not null, primary key (a,b))engine=tianmu; +CREATE TABLE t3 (a int not null, b int not null, primary key (a,b))engine=tianmu; +insert into t1 values (1,1),(2,1),(1,3); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(1,3); +delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; + +select * from t1; +select * from t2; +select * from t3; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc + +select * from t1; +select * from t2; +select * from t3; + +--echo # connection master +connection master; +drop table t1,t2,t3; +--source include/sync_slave_sql_with_master.inc + +--echo # connection master +connection master; +CREATE TABLE t1 + ( + place_id int (10), + shows int(10), + ishows int(10), + ushows int(10), + clicks int(10), + iclicks int(10), + uclicks int(10), + ts timestamp, + PRIMARY KEY (place_id,ts) + )engine=tianmu; + +INSERT INTO t1 (place_id,shows,ishows,ushows,clicks,iclicks,uclicks,ts) +VALUES (1,0,0,0,0,0,0,20000928174434); +UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00"; +select place_id,shows from t1; + +--echo # connection slave +--source include/sync_slave_sql_with_master.inc +select place_id,shows from t1; + +--echo # connection master +connection master; +drop table t1; + +# +# VIEW built over UNION +# +create table t1 (s1 int); +create table t2 (s2 int); +insert into t1 values (1), (2); +insert into t2 values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +--echo # connection slave +--source include/sync_slave_sql_with_master.inc +select * from v1; +--echo # connection master +connection master; +drop view v1; +drop tables t1, t2; + +# +# Aggregate functions in view list +# +create table t1 (col1 int); +insert into t1 values (1); +create view v1 as select count(*) from t1; +insert into t1 values (null); +select * from v1; +--echo # connection slave +--source include/sync_slave_sql_with_master.inc +select * from v1; +--echo # connection master +connection master; +drop view v1; +drop table t1; + +# +# Showing VIEW with VIEWs in subquery +# +create table t1 (a int); +create table t2 (a int); +create view v1 as select a from t1; +create view v2 as select a from t2 where a in (select a from v1); +show create view v2; +--echo # connection slave +--source include/sync_slave_sql_with_master.inc +show create view v2; +--echo # connection master +connection master; +drop view v2, v1; +drop table t1, t2; diff --git a/sql/log_event.cc b/sql/log_event.cc index ae187b2ce5..9ddb180f89 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -9681,6 +9681,19 @@ search_key_in_table(TABLE *table, MY_BITMAP *bi_cols, uint key_type) KEY *keyinfo; uint res= MAX_KEY; uint key; + /* + PK has bugs, not support + */ + bool check_if_tianmu_engine = table && table->s && + (table->s->db_type() ? (table->s->db_type()->db_type == DB_TYPE_TIANMU): false); + enum_sql_command sql_command = SQLCOM_END; + if(table->in_use && table->in_use->lex) sql_command = table->in_use->lex->sql_command; + if (check_if_tianmu_engine && ((sql_command == SQLCOM_DELETE) || + (sql_command == SQLCOM_DELETE_MULTI) || + (sql_command == SQLCOM_UPDATE) || + (sql_command == SQLCOM_UPDATE_MULTI))){ + DBUG_RETURN(res); + } if (key_type & PRI_KEY_FLAG && (table->s->primary_key < MAX_KEY)) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 35cbf379da..32e0dbf3ca 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -48,6 +48,8 @@ #include "partition_info.h" // partition_info #include "probes_mysql.h" // MYSQL_INSERT_START +#include "../storage/tianmu/system/configuration.h" + static bool check_view_insertability(THD *thd, TABLE_LIST *view, const TABLE_LIST *insert_table_ref); @@ -830,30 +832,30 @@ bool Sql_cmd_insert::mysql_insert(THD *thd,TABLE_LIST *table_list) if (error <= 0 || thd->get_transaction()->cannot_safely_rollback( Transaction_ctx::STMT)) { -//TIANMU UPGRADE BEGIN -#if defined(TIANMU) bool tianmu_engine = insert_table->s->db_type() ? insert_table->s->db_type()->db_type == DB_TYPE_TIANMU: false; - if (mysql_bin_log.is_open()&& !tianmu_engine) -#else - if (mysql_bin_log.is_open()) -#endif -//END + /* + In the delayed insert mode, tianmu will actively write data to the binlog cache, + but there is no non delayed insert. + You need to release the logic written to the binlog cache when the sql layer + is in the non delayed insert mode. + */ + if (mysql_bin_log.is_open()&& !(tianmu_engine && tianmu_sysvar_insert_delayed)) { int errcode= 0; - if (error <= 0) + if (error <= 0) { - /* - [Guilhem wrote] Temporary errors may have filled - thd->net.last_error/errno. For example if there has - been a disk full error when writing the row, and it was - MyISAM, then thd->net.last_error/errno will be set to - "disk full"... and the mysql_file_pwrite() will wait until free - space appears, and so when it finishes then the - write_row() was entirely successful - */ - /* todo: consider removing */ - thd->clear_error(); - } + /* + [Guilhem wrote] Temporary errors may have filled + thd->net.last_error/errno. For example if there has + been a disk full error when writing the row, and it was + MyISAM, then thd->net.last_error/errno will be set to + "disk full"... and the mysql_file_pwrite() will wait until free + space appears, and so when it finishes then the + write_row() was entirely successful + */ + /* todo: consider removing */ + thd->clear_error(); + } else errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); diff --git a/sql/sql_optimizer.cc b/sql/sql_optimizer.cc index ab11189e35..a9f9606fa4 100644 --- a/sql/sql_optimizer.cc +++ b/sql/sql_optimizer.cc @@ -5133,16 +5133,16 @@ bool JOIN::make_join_plan() The following codes can be deleted after subsequent support */ TABLE *const table= join_tab->table(); - bool tianmu_engine = table && table->s && - (table->s->db_type() ? table->s->db_type()->db_type == DB_TYPE_TIANMU: false); - enum_sql_command sqlCommand = SQLCOM_END; - if(thd->lex) sqlCommand = thd->lex->sql_command; - bool tianmuDeleteOrUpdate = (tianmu_engine && (sqlCommand == SQLCOM_DELETE || - sqlCommand == SQLCOM_DELETE_MULTI || - sqlCommand == SQLCOM_UPDATE || - sqlCommand == SQLCOM_UPDATE_MULTI)); - - if (!tianmuDeleteOrUpdate && update_ref_and_keys(thd, &keyuse_array, join_tab, tables, where_cond, + bool check_if_tianmu_engine = table && table->s && + (table->s->db_type() ? (table->s->db_type()->db_type == DB_TYPE_TIANMU): false); + enum_sql_command sql_command = SQLCOM_END; + if(thd->lex) sql_command = thd->lex->sql_command; + bool tianmu_delete_or_update = (check_if_tianmu_engine && ((sql_command == SQLCOM_DELETE) || + (sql_command == SQLCOM_DELETE_MULTI) || + (sql_command == SQLCOM_UPDATE) || + (sql_command == SQLCOM_UPDATE_MULTI))); + + if (!tianmu_delete_or_update && update_ref_and_keys(thd, &keyuse_array, join_tab, tables, where_cond, cond_equal, ~select_lex->outer_join, select_lex, &sargables)) DBUG_RETURN(true); diff --git a/storage/tianmu/handler/tianmu_handler.cpp b/storage/tianmu/handler/tianmu_handler.cpp index 951d7de3af..e173b7026b 100644 --- a/storage/tianmu/handler/tianmu_handler.cpp +++ b/storage/tianmu/handler/tianmu_handler.cpp @@ -170,7 +170,23 @@ namespace { std::vector GetAttrsUseIndicator(TABLE *table) { int col_id = 0; std::vector attr_uses; + enum_sql_command sql_command = SQLCOM_END; + if (table->in_use && table->in_use->lex) + sql_command = table->in_use->lex->sql_command; + bool tianmu_delete_or_update = (sql_command == SQLCOM_DELETE) || (sql_command == SQLCOM_DELETE_MULTI) || + (sql_command == SQLCOM_UPDATE) || (sql_command == SQLCOM_UPDATE_MULTI); + for (Field **field = table->field; *field; ++field, ++col_id) { + /* + The binlog in row format will record the information in each column of the currently modified row and generate a + change log, The information of each column in the current row is obtained from the engine layer, so when the + current statement is delete or update, you need to fill in data for each column. + Here, should set each column to be valid. + */ + if (tianmu_delete_or_update) { + attr_uses.push_back(true); + continue; + } if (bitmap_is_set(table->read_set, col_id) || bitmap_is_set(table->write_set, col_id)) attr_uses.push_back(true); else