diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-09-19 12:43:02 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-09-19 12:43:02 +0300 |
commit | 22c322c649d5a15e3bb731d6751a0d80c8ec23b0 (patch) | |
tree | 11073f6169c237da226a977736d234c7c7b5c163 /storage | |
parent | 7d49aab32c3733f26cff8d83396a65bd120352e8 (diff) | |
parent | ec6042bda097fa53c43caf4a1acc32c5a77f6ed4 (diff) | |
download | mariadb-git-22c322c649d5a15e3bb731d6751a0d80c8ec23b0.tar.gz |
Merge branch '10.1' into 10.2
Diffstat (limited to 'storage')
-rw-r--r-- | storage/myisam/ha_myisam.cc | 15 | ||||
-rw-r--r-- | storage/tokudb/CMakeLists.txt | 2 | ||||
-rw-r--r-- | storage/tokudb/PerconaFT/buildheader/make_tdb.cc | 2 | ||||
-rw-r--r-- | storage/tokudb/PerconaFT/src/ydb-internal.h | 9 | ||||
-rw-r--r-- | storage/tokudb/PerconaFT/src/ydb_cursor.cc | 108 | ||||
-rw-r--r-- | storage/tokudb/ha_tokudb.cc | 8 | ||||
-rw-r--r-- | storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result | 315 | ||||
-rw-r--r-- | storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt | 2 | ||||
-rw-r--r-- | storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test | 14 | ||||
-rw-r--r-- | storage/tokudb/mysql-test/tokudb/r/dir_per_db.result | 10 | ||||
-rw-r--r-- | storage/tokudb/mysql-test/tokudb/t/dir_per_db.test | 17 | ||||
-rw-r--r-- | storage/xtradb/api/api0api.cc | 4 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 21 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.h | 6 | ||||
-rw-r--r-- | storage/xtradb/include/row0mysql.h | 2 | ||||
-rw-r--r-- | storage/xtradb/include/row0sel.h | 14 | ||||
-rw-r--r-- | storage/xtradb/include/univ.i | 2 | ||||
-rw-r--r-- | storage/xtradb/row/row0merge.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/row/row0sel.cc | 72 |
19 files changed, 210 insertions, 419 deletions
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 213b1dc9ec3..20bb672868d 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -2359,6 +2359,17 @@ ha_myisam::check_if_supported_inplace_alter(TABLE *new_table, } +static bool directories_differ(const char *d1, const char *d2) +{ + if (!d1 && !d2) + return false; + if (!d1 || !d2) + return true; + size_t l1= dirname_length(d1), l2= dirname_length(d2); + return l1 != l2 || strncmp(d1, d2, l1); +} + + bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info, uint table_changes) { @@ -2366,8 +2377,8 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info, if ((create_info->used_fields & HA_CREATE_USED_AUTO && create_info->auto_increment_value != stats.auto_increment_value) || - create_info->data_file_name != data_file_name || - create_info->index_file_name != index_file_name || + directories_differ(create_info->data_file_name, data_file_name) || + directories_differ(create_info->index_file_name, index_file_name) || table_changes == IS_EQUAL_NO || table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet return COMPATIBLE_DATA_NO; diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 90996725a45..73e4bf37a06 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(TOKUDB_VERSION 5.6.36-82.1) +SET(TOKUDB_VERSION 5.6.37-82.2) # PerconaFT only supports x86-64 and cmake-2.8.9+ IF(CMAKE_VERSION VERSION_LESS "2.8.9") MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB") diff --git a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc index 6f0b7c5f419..0fa876f2bd8 100644 --- a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc +++ b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc @@ -231,6 +231,8 @@ static void print_defines (void) { printf("#define DB_SET_RANGE_REVERSE 252\n"); // private tokudb //printf("#define DB_GET_BOTH_RANGE_REVERSE 251\n"); // private tokudb. No longer supported #2862. dodefine(DB_RMW); + + printf("#define DB_LOCKING_READ 0x80000000\n"); printf("#define DB_IS_RESETTING_OP 0x01000000\n"); // private tokudb printf("#define DB_PRELOCKED 0x00800000\n"); // private tokudb printf("#define DB_PRELOCKED_WRITE 0x00400000\n"); // private tokudb diff --git a/storage/tokudb/PerconaFT/src/ydb-internal.h b/storage/tokudb/PerconaFT/src/ydb-internal.h index a1eb43a67c5..db2041095f7 100644 --- a/storage/tokudb/PerconaFT/src/ydb-internal.h +++ b/storage/tokudb/PerconaFT/src/ydb-internal.h @@ -239,13 +239,16 @@ struct __toku_dbc_internal { struct simple_dbt skey_s,sval_s; struct simple_dbt *skey,*sval; - // if the rmw flag is asserted, cursor operations (like set) grab write locks instead of read locks + // if the rmw flag is asserted, cursor operations (like set) grab write + // locks instead of read locks // the rmw flag is set when the cursor is created with the DB_RMW flag set bool rmw; + bool locking_read; }; -static_assert(sizeof(__toku_dbc_internal) <= sizeof(((DBC *) nullptr)->_internal), - "__toku_dbc_internal doesn't fit in the internal portion of a DBC"); +static_assert( + sizeof(__toku_dbc_internal) <= sizeof(((DBC *)nullptr)->_internal), + "__toku_dbc_internal doesn't fit in the internal portion of a DBC"); static inline __toku_dbc_internal *dbc_struct_i(DBC *c) { union dbc_union { diff --git a/storage/tokudb/PerconaFT/src/ydb_cursor.cc b/storage/tokudb/PerconaFT/src/ydb_cursor.cc index 015e302f1c6..1f4f00b7423 100644 --- a/storage/tokudb/PerconaFT/src/ydb_cursor.cc +++ b/storage/tokudb/PerconaFT/src/ydb_cursor.cc @@ -110,12 +110,14 @@ c_get_wrapper_callback(DBT const *key, DBT const *val, void *extra) { return r; } -static inline uint32_t -get_cursor_prelocked_flags(uint32_t flags, DBC* dbc) { +static inline uint32_t get_cursor_prelocked_flags(uint32_t flags, DBC *dbc) { uint32_t lock_flags = flags & (DB_PRELOCKED | DB_PRELOCKED_WRITE); - //DB_READ_UNCOMMITTED and DB_READ_COMMITTED transactions 'own' all read locks for user-data dictionaries. - if (dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE) { + // DB_READ_UNCOMMITTED and DB_READ_COMMITTED transactions 'own' all read + // locks for user-data dictionaries. + if (dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE && + !(dbc_struct_i(dbc)->iso == TOKU_ISO_SNAPSHOT && + dbc_struct_i(dbc)->locking_read)) { lock_flags |= DB_PRELOCKED; } return lock_flags; @@ -671,37 +673,44 @@ int toku_c_close(DBC *c) { return 0; } -static int -c_set_bounds(DBC *dbc, const DBT *left_key, const DBT *right_key, bool pre_acquire, int out_of_range_error) { +static int c_set_bounds(DBC *dbc, + const DBT *left_key, + const DBT *right_key, + bool pre_acquire, + int out_of_range_error) { if (out_of_range_error != DB_NOTFOUND && - out_of_range_error != TOKUDB_OUT_OF_RANGE && - out_of_range_error != 0) { - return toku_ydb_do_error( - dbc->dbp->dbenv, - EINVAL, - "Invalid out_of_range_error [%d] for %s\n", - out_of_range_error, - __FUNCTION__ - ); - } - if (left_key == toku_dbt_negative_infinity() && right_key == toku_dbt_positive_infinity()) { + out_of_range_error != TOKUDB_OUT_OF_RANGE && out_of_range_error != 0) { + return toku_ydb_do_error(dbc->dbp->dbenv, + EINVAL, + "Invalid out_of_range_error [%d] for %s\n", + out_of_range_error, + __FUNCTION__); + } + if (left_key == toku_dbt_negative_infinity() && + right_key == toku_dbt_positive_infinity()) { out_of_range_error = 0; } DB *db = dbc->dbp; DB_TXN *txn = dbc_struct_i(dbc)->txn; HANDLE_PANICKED_DB(db); - toku_ft_cursor_set_range_lock(dbc_ftcursor(dbc), left_key, right_key, - (left_key == toku_dbt_negative_infinity()), - (right_key == toku_dbt_positive_infinity()), - out_of_range_error); + toku_ft_cursor_set_range_lock(dbc_ftcursor(dbc), + left_key, + right_key, + (left_key == toku_dbt_negative_infinity()), + (right_key == toku_dbt_positive_infinity()), + out_of_range_error); if (!db->i->lt || !txn || !pre_acquire) return 0; - //READ_UNCOMMITTED and READ_COMMITTED transactions do not need read locks. - if (!dbc_struct_i(dbc)->rmw && dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE) + // READ_UNCOMMITTED and READ_COMMITTED transactions do not need read locks. + if (!dbc_struct_i(dbc)->rmw && + dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE && + !(dbc_struct_i(dbc)->iso == TOKU_ISO_SNAPSHOT && + dbc_struct_i(dbc)->locking_read)) return 0; - toku::lock_request::type lock_type = dbc_struct_i(dbc)->rmw ? - toku::lock_request::type::WRITE : toku::lock_request::type::READ; + toku::lock_request::type lock_type = dbc_struct_i(dbc)->rmw + ? toku::lock_request::type::WRITE + : toku::lock_request::type::READ; int r = toku_db_get_range_lock(db, txn, left_key, right_key, lock_type); return r; } @@ -783,18 +792,20 @@ toku_c_get(DBC* c, DBT* key, DBT* val, uint32_t flag) { return r; } -int -toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_temporary_cursor) { +int toku_db_cursor_internal(DB *db, + DB_TXN *txn, + DBC *c, + uint32_t flags, + int is_temporary_cursor) { HANDLE_PANICKED_DB(db); HANDLE_DB_ILLEGAL_WORKING_PARENT_TXN(db, txn); - DB_ENV* env = db->dbenv; + DB_ENV *env = db->dbenv; - if (flags & ~(DB_SERIALIZABLE | DB_INHERIT_ISOLATION | DB_RMW | DBC_DISABLE_PREFETCHING)) { + if (flags & + ~(DB_SERIALIZABLE | DB_INHERIT_ISOLATION | DB_LOCKING_READ | DB_RMW | + DBC_DISABLE_PREFETCHING)) { return toku_ydb_do_error( - env, - EINVAL, - "Invalid flags set for toku_db_cursor\n" - ); + env, EINVAL, "Invalid flags set for toku_db_cursor\n"); } #define SCRS(name) c->name = name @@ -819,8 +830,8 @@ toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_te c->dbp = db; dbc_struct_i(c)->txn = txn; - dbc_struct_i(c)->skey_s = (struct simple_dbt){0,0}; - dbc_struct_i(c)->sval_s = (struct simple_dbt){0,0}; + dbc_struct_i(c)->skey_s = (struct simple_dbt){0, 0}; + dbc_struct_i(c)->sval_s = (struct simple_dbt){0, 0}; if (is_temporary_cursor) { dbc_struct_i(c)->skey = &db->i->skey; dbc_struct_i(c)->sval = &db->i->sval; @@ -831,28 +842,27 @@ toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_te if (flags & DB_SERIALIZABLE) { dbc_struct_i(c)->iso = TOKU_ISO_SERIALIZABLE; } else { - dbc_struct_i(c)->iso = txn ? db_txn_struct_i(txn)->iso : TOKU_ISO_SERIALIZABLE; + dbc_struct_i(c)->iso = + txn ? db_txn_struct_i(txn)->iso : TOKU_ISO_SERIALIZABLE; } dbc_struct_i(c)->rmw = (flags & DB_RMW) != 0; - enum cursor_read_type read_type = C_READ_ANY; // default, used in serializable and read uncommitted + dbc_struct_i(c)->locking_read = (flags & DB_LOCKING_READ) != 0; + enum cursor_read_type read_type = + C_READ_ANY; // default, used in serializable and read uncommitted if (txn) { if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED || - dbc_struct_i(c)->iso == TOKU_ISO_SNAPSHOT) - { + dbc_struct_i(c)->iso == TOKU_ISO_SNAPSHOT) { read_type = C_READ_SNAPSHOT; - } - else if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED_ALWAYS) { + } else if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED_ALWAYS) { read_type = C_READ_COMMITTED; } } - int r = toku_ft_cursor_create( - db->i->ft_handle, - dbc_ftcursor(c), - txn ? db_txn_struct_i(txn)->tokutxn : NULL, - read_type, - ((flags & DBC_DISABLE_PREFETCHING) != 0), - is_temporary_cursor != 0 - ); + int r = toku_ft_cursor_create(db->i->ft_handle, + dbc_ftcursor(c), + txn ? db_txn_struct_i(txn)->tokutxn : NULL, + read_type, + ((flags & DBC_DISABLE_PREFETCHING) != 0), + is_temporary_cursor != 0); if (r != 0) { invariant(r == TOKUDB_MVCC_DICTIONARY_TOO_NEW); } diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 2511bea8084..8168691dafa 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -7630,7 +7630,13 @@ static bool tokudb_check_db_dir_exist_from_table_name(const char *table_name) { memcpy(db_name, db_name_begin, db_name_size); db_name[db_name_size] = '\0'; - mysql_dir_exists = (check_db_dir_existence(db_name) == 0); + + // At this point, db_name contains the MySQL formatted database name. + // This is exactly the same format that would come into us through a + // CREATE TABLE. Some charaters (like ':' for example) might be expanded + // into hex (':' would papear as "@003a"). + // We need to check that the MySQL destination database directory exists. + mysql_dir_exists = (my_access(db_name, F_OK) == 0); return mysql_dir_exists; } diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result b/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result deleted file mode 100644 index 73c010c6eb7..00000000000 --- a/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result +++ /dev/null @@ -1,315 +0,0 @@ -include/master-slave.inc -[connection master] -connection slave; -include/stop_slave.inc -include/wait_for_slave_to_stop.inc -reset master; -reset slave; -start slave; -include/wait_for_slave_to_start.inc -connection slave; -set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; -set @@global.slave_ddl_exec_mode=STRICT; -connection master; -create table t1(n int not null auto_increment primary key)ENGINE=TokuDB; -insert into t1 values (NULL); -drop table t1; -create table t1 (word char(20) not null)ENGINE=TokuDB; -load data infile 'LOAD_FILE' into table t1 ignore 1 lines; -select count(*) from t1; -count(*) -69 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # insert into t1 values (NULL) -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # load data infile '../../std_data/words.dat' into table t1 ignore 1 lines -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # insert into t1 values (NULL) -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -flush logs; -create table t3 (a int)ENGINE=TokuDB; -connection master; -select * from t1 order by 1 asc; -word -Aarhus -Aaron -Aaron -Ababa -Ababa -aback -aback -abaft -abaft -abandon -abandon -abandoned -abandoned -abandoning -abandoning -abandonment -abandonment -abandons -abandons -abase -abased -abasement -abasements -abases -abash -abashed -abashes -abashing -abasing -abate -abated -abatement -abatements -abater -abates -abating -Abba -abbe -abbey -abbeys -abbot -abbots -Abbott -abbreviate -abbreviated -abbreviates -abbreviating -abbreviation -abbreviations -Abby -abdomen -abdomens -abdominal -abduct -abducted -abduction -abductions -abductor -abductors -abducts -Abe -abed -Abel -Abelian -Abelson -Aberdeen -Abernathy -aberrant -aberration -connection slave; -select * from t1 order by 1 asc; -word -Aarhus -Aaron -Aaron -Ababa -Ababa -aback -aback -abaft -abaft -abandon -abandon -abandoned -abandoned -abandoning -abandoning -abandonment -abandonment -abandons -abandons -abase -abased -abasement -abasements -abases -abash -abashed -abashes -abashing -abasing -abate -abated -abatement -abatements -abater -abates -abating -Abba -abbe -abbey -abbeys -abbot -abbots -Abbott -abbreviate -abbreviated -abbreviates -abbreviating -abbreviation -abbreviations -Abby -abdomen -abdomens -abdominal -abduct -abducted -abduction -abductions -abductor -abductors -abducts -Abe -abed -Abel -Abelian -Abelson -Aberdeen -Abernathy -aberrant -aberration -flush logs; -include/stop_slave.inc -include/start_slave.inc -connection master; -create table t2 (n int)ENGINE=TokuDB; -insert into t2 values (1); -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # insert into t1 values (NULL) -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # load data infile '../../std_data/words.dat' into table t1 ignore 1 lines -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Rotate # # master-bin.000002;pos=POS -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 # Binlog_checkpoint # # master-bin.000002 -master-bin.000002 # Gtid # # GTID #-#-# -master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB -master-bin.000002 # Gtid # # GTID #-#-# -master-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB -master-bin.000002 # Gtid # # BEGIN GTID #-#-# -master-bin.000002 # Annotate_rows # # insert into t2 values (1) -master-bin.000002 # Table_map # # table_id: # (test.t2) -master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000002 # Xid # # COMMIT /* XID */ -show binary logs; -Log_name File_size -master-bin.000001 # -master-bin.000002 # -connection slave; -show binary logs; -Log_name File_size -slave-bin.000001 # -slave-bin.000002 # -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000001 # Gtid # # GTID #-#-# -slave-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB -slave-bin.000001 # Gtid # # BEGIN GTID #-#-# -slave-bin.000001 # Annotate_rows # # insert into t1 values (NULL) -slave-bin.000001 # Table_map # # table_id: # (test.t1) -slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -slave-bin.000001 # Xid # # COMMIT /* XID */ -slave-bin.000001 # Gtid # # GTID #-#-# -slave-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ -slave-bin.000001 # Gtid # # GTID #-#-# -slave-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB -slave-bin.000001 # Gtid # # BEGIN GTID #-#-# -slave-bin.000001 # Annotate_rows # # load data infile '../../std_data/words.dat' into table t1 ignore 1 lines -slave-bin.000001 # Table_map # # table_id: # (test.t1) -slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -slave-bin.000001 # Xid # # COMMIT /* XID */ -slave-bin.000001 # Gtid # # GTID #-#-# -slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB -slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 -slave-bin.000002 # Gtid # # GTID #-#-# -slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB -slave-bin.000002 # Gtid # # BEGIN GTID #-#-# -slave-bin.000002 # Annotate_rows # # insert into t2 values (1) -slave-bin.000002 # Table_map # # table_id: # (test.t2) -slave-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F -slave-bin.000002 # Xid # # COMMIT /* XID */ -include/check_slave_is_running.inc -show binlog events in 'slave-bin.000005' from 4; -ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log -connection master; -DROP TABLE t1; -DROP TABLE t2; -DROP TABLE t3; -include/rpl_reset.inc -connection master; -create table t1(a int auto_increment primary key, b int); -insert into t1 values (NULL, 1); -set insert_id=5; -insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id()); -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; create table t1(a int auto_increment primary key, b int) -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # insert into t1 values (NULL, 1) -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT -master-bin.000001 # Gtid # # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows # # insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id()) -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT -select * from t1; -a b -1 1 -5 1 -6 1 -drop table t1; -connection slave; -set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; -connection master; -include/rpl_end.inc diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt b/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt deleted file mode 100644 index 773ec62bef2..00000000000 --- a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---skip-external-locking ---default-storage-engine=MyISAM diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test b/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test deleted file mode 100644 index 826eb5eab86..00000000000 --- a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test +++ /dev/null @@ -1,14 +0,0 @@ -################################### -# Wrapper for rpl_row_log.test # -# Added wrapper so that MyISAM & # -# Innodb and NDB could all use the# -# Same test. NDB produced a diff # -# bin-log # -################################### --- source include/have_binlog_format_row.inc --- source include/have_tokudb.inc --- source include/master-slave.inc -let $engine_type=TokuDB; --- source extra/rpl_tests/rpl_log.test - ---source include/rpl_end.inc diff --git a/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result b/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result index 371f97406c8..30d4e4244fd 100644 --- a/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result +++ b/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result @@ -1,3 +1,4 @@ +SET @orig_tokudb_dir_per_db=@@global.tokudb_dir_per_db; ######## # tokudb_dir_per_db = 1 ######## @@ -177,4 +178,11 @@ t1_status_id.tokudb DROP TABLE t2; ## Looking for *.tokudb files in data_dir ## Looking for *.tokudb files in data_dir/test -SET GLOBAL tokudb_dir_per_db=default; +CREATE DATABASE `a::a@@`; +CREATE TABLE `a::a@@`.`t1` (a INT) ENGINE=TOKUDB; +CREATE DATABASE `!@#$%^&*()`; +ALTER TABLE `a::a@@`.`t1` RENAME `!@#$%^&*()`.`t1`; +DROP TABLE `!@#$%^&*()`.`t1`; +DROP DATABASE `!@#$%^&*()`; +DROP DATABASE `a::a@@`; +SET GLOBAL tokudb_dir_per_db=@orig_tokudb_dir_per_db; diff --git a/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test b/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test index b638b706d87..64745cb049c 100644 --- a/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test +++ b/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test @@ -1,5 +1,7 @@ source include/have_tokudb.inc; +SET @orig_tokudb_dir_per_db=@@global.tokudb_dir_per_db; + --let $DB= test --let $DATADIR= `select @@datadir` --let $i= 2 @@ -73,4 +75,17 @@ while ($i) { --source dir_per_db_show_table_files.inc } -SET GLOBAL tokudb_dir_per_db=default; + +# test case for TDB-72 : Can not rename table in database with non alphanum +# characters in its name. +CREATE DATABASE `a::a@@`; +CREATE TABLE `a::a@@`.`t1` (a INT) ENGINE=TOKUDB; +CREATE DATABASE `!@#$%^&*()`; +ALTER TABLE `a::a@@`.`t1` RENAME `!@#$%^&*()`.`t1`; + +DROP TABLE `!@#$%^&*()`.`t1`; +DROP DATABASE `!@#$%^&*()`; +DROP DATABASE `a::a@@`; + +# cleanup +SET GLOBAL tokudb_dir_per_db=@orig_tokudb_dir_per_db; diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc index 2a46dd4b4c1..0aae482b9f5 100644 --- a/storage/xtradb/api/api0api.cc +++ b/storage/xtradb/api/api0api.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2008, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2008, 2017, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1988,6 +1988,7 @@ ib_cursor_read_row( page_format = static_cast<ib_bool_t>( dict_table_is_comp(tuple->index->table)); + rec = btr_pcur_get_rec(pcur); if (prebuilt->innodb_api_rec && @@ -2029,6 +2030,7 @@ ib_cursor_position( buf = static_cast<unsigned char*>(mem_alloc(UNIV_PAGE_SIZE)); + /* We want to position at one of the ends, row_search_for_mysql() uses the search_tuple fields to work out what to do. */ dtuple_set_n_fields(prebuilt->search_tuple, 0); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index a56dda417cc..d8c274dc65f 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -10561,6 +10561,27 @@ ha_innobase::ft_init_ext( } /*****************************************************************//** +Copy a cached MySQL row. +If requested, also avoids overwriting non-read columns. +@param[out] buf Row in MySQL format. +@param[in] cached_row Which row to copy. +@param[in] rec_len Record length. */ +void +ha_innobase::copy_cached_row( + uchar* buf, + const uchar* cached_row, + uint rec_len) +{ + if (prebuilt->keep_other_fields_on_keyread) { + row_sel_copy_cached_fields_for_mysql(buf, cached_row, + prebuilt); + } else { + memcpy(buf, cached_row, rec_len); + } +} + + +/*****************************************************************//** Set up search tuple for a query through FTS_DOC_ID_INDEX on supplied Doc ID. This is used by MySQL to retrieve the documents once the search result (Doc IDs) is available */ diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 426136e4d51..c5b0e723702 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -167,6 +167,10 @@ class ha_innobase: public handler int index_first(uchar * buf); int index_last(uchar * buf); + /* Copy a cached MySQL row. If requested, also avoids + overwriting non-read columns. */ + void copy_cached_row(uchar *to_rec, const uchar *from_rec, + uint rec_length); bool has_gap_locks() const { return true; } int rnd_init(bool scan); diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index a8503a5cfda..4326f1208e5 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under diff --git a/storage/xtradb/include/row0sel.h b/storage/xtradb/include/row0sel.h index fd5bc755a22..afeb216c2a2 100644 --- a/storage/xtradb/include/row0sel.h +++ b/storage/xtradb/include/row0sel.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -205,6 +205,18 @@ struct sel_buf_t{ when data != NULL */ }; +/** Copy used fields from cached row. +Copy cache record field by field, don't touch fields that +are not covered by current key. +@param[out] buf Where to copy the MySQL row. +@param[in] cached_rec What to copy (in MySQL row format). +@param[in] prebuilt prebuilt struct. */ +void +row_sel_copy_cached_fields_for_mysql( + byte* buf, + const byte* cached_rec, + row_prebuilt_t* prebuilt); + /** Query plan */ struct plan_t{ dict_table_t* table; /*!< table struct in the dictionary diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 739f6640eef..5886b078e4d 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -48,7 +48,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_BUGFIX 36 #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 82.1 +#define PERCONA_INNODB_VERSION 82.2 #endif /* Enable UNIV_LOG_ARCHIVE in XtraDB */ diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index d38f10ee7ba..9d299bf6288 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -1538,6 +1538,8 @@ row_merge_read_clustered_index( goto func_exit; } + mem_heap_empty(row_heap); + page_cur_move_to_next(cur); if (page_cur_is_after_last(cur)) { @@ -1970,8 +1972,6 @@ write_buffers: goto func_exit; } - mem_heap_empty(row_heap); - /* Increment innodb_onlineddl_pct_progress status variable */ read_rows++; if(read_rows % 1000 == 0) { diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc index 26fd7629a5d..d96d6d37844 100644 --- a/storage/xtradb/row/row0sel.cc +++ b/storage/xtradb/row/row0sel.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2015, 2017, MariaDB Corporation. @@ -2571,31 +2571,30 @@ row_sel_store_row_id_to_prebuilt( (dest,templ,src,len) #endif /* UNIV_DEBUG */ -/**************************************************************//** -Stores a non-SQL-NULL field in the MySQL format. The counterpart of this -function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */ +/** Stores a non-SQL-NULL field in the MySQL format. The counterpart of this +function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. +@param[in,out] dest buffer where to store; NOTE + that BLOBs are not in themselves stored + here: the caller must allocate and copy + the BLOB into buffer before, and pass + the pointer to the BLOB in 'data' +@param[in] templ MySQL column template. Its following fields + are referenced: type, is_unsigned, mysql_col_len, + mbminlen, mbmaxlen +@param[in] index InnoDB index +@param[in] field_no templ->rec_field_no or templ->clust_rec_field_no + or templ->icp_rec_field_no +@param[in] data data to store +@param[in] len length of the data +*/ static MY_ATTRIBUTE((nonnull)) void row_sel_field_store_in_mysql_format_func( -/*=====================================*/ - byte* dest, /*!< in/out: buffer where to store; NOTE - that BLOBs are not in themselves - stored here: the caller must allocate - and copy the BLOB into buffer before, - and pass the pointer to the BLOB in - 'data' */ + byte* dest, const mysql_row_templ_t* templ, - /*!< in: MySQL column template. - Its following fields are referenced: - type, is_unsigned, mysql_col_len, - mbminlen, mbmaxlen */ #ifdef UNIV_DEBUG const dict_index_t* index, - /*!< in: InnoDB index */ ulint field_no, - /*!< in: templ->rec_field_no or - templ->clust_rec_field_no or - templ->icp_rec_field_no */ #endif /* UNIV_DEBUG */ const byte* data, /*!< in: data to store */ ulint len) /*!< in: length of the data */ @@ -2748,7 +2747,7 @@ row_sel_field_store_in_mysql_format_func( #endif /* UNIV_DEBUG */ ut_ad(field->prefix_len ? field->prefix_len == len - : templ->mysql_col_len == len); + : (templ->mysql_col_len == len)); memcpy(dest, data, len); } } @@ -2772,8 +2771,6 @@ row_sel_field_store_in_mysql_format_func( @param[in] field_no templ->rec_field_no or templ->clust_rec_field_no or templ->icp_rec_field_no - or sec field no if clust_templ_for_sec - is TRUE @param[in] templ row template */ static MY_ATTRIBUTE((warn_unused_result)) @@ -2955,6 +2952,7 @@ row_sel_store_mysql_rec( = rec_clust ? templ->clust_rec_field_no : templ->rec_field_no; + /* We should never deliver column prefixes to MySQL, except for evaluating innobase_index_cond() and if the prefix index is longer than the actual row data. */ @@ -3353,6 +3351,36 @@ row_sel_copy_cached_field_for_mysql( ut_memcpy(buf, cache, len); } +/** Copy used fields from cached row. +Copy cache record field by field, don't touch fields that +are not covered by current key. +@param[out] buf Where to copy the MySQL row. +@param[in] cached_rec What to copy (in MySQL row format). +@param[in] prebuilt prebuilt struct. */ +void +row_sel_copy_cached_fields_for_mysql( + byte* buf, + const byte* cached_rec, + row_prebuilt_t* prebuilt) +{ + const mysql_row_templ_t*templ; + ulint i; + for (i = 0; i < prebuilt->n_template; i++) { + templ = prebuilt->mysql_template + i; + + row_sel_copy_cached_field_for_mysql( + buf, cached_rec, templ); + /* Copy NULL bit of the current field from cached_rec + to buf */ + if (templ->mysql_null_bit_mask) { + buf[templ->mysql_null_byte_offset] + ^= (buf[templ->mysql_null_byte_offset] + ^ cached_rec[templ->mysql_null_byte_offset]) + & (byte) templ->mysql_null_bit_mask; + } + } +} + /********************************************************************//** Pops a cached row for MySQL from the fetch cache. */ UNIV_INLINE |