summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2017-09-19 12:43:02 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2017-09-19 12:43:02 +0300
commit22c322c649d5a15e3bb731d6751a0d80c8ec23b0 (patch)
tree11073f6169c237da226a977736d234c7c7b5c163 /storage
parent7d49aab32c3733f26cff8d83396a65bd120352e8 (diff)
parentec6042bda097fa53c43caf4a1acc32c5a77f6ed4 (diff)
downloadmariadb-git-22c322c649d5a15e3bb731d6751a0d80c8ec23b0.tar.gz
Merge branch '10.1' into 10.2
Diffstat (limited to 'storage')
-rw-r--r--storage/myisam/ha_myisam.cc15
-rw-r--r--storage/tokudb/CMakeLists.txt2
-rw-r--r--storage/tokudb/PerconaFT/buildheader/make_tdb.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/ydb-internal.h9
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_cursor.cc108
-rw-r--r--storage/tokudb/ha_tokudb.cc8
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result315
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt2
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test14
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/dir_per_db.result10
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/dir_per_db.test17
-rw-r--r--storage/xtradb/api/api0api.cc4
-rw-r--r--storage/xtradb/handler/ha_innodb.cc21
-rw-r--r--storage/xtradb/handler/ha_innodb.h6
-rw-r--r--storage/xtradb/include/row0mysql.h2
-rw-r--r--storage/xtradb/include/row0sel.h14
-rw-r--r--storage/xtradb/include/univ.i2
-rw-r--r--storage/xtradb/row/row0merge.cc6
-rw-r--r--storage/xtradb/row/row0sel.cc72
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