From 5fce14dad02be5b23a8718a9a94fb7de00a7bb1e Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 11 Jan 2018 23:55:13 +0200 Subject: [PATCH 01/10] Removed wrong DBUG_DUMP that accessed not initialized memory. --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index e723b62163a..7b8ec18cad6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8294,6 +8294,7 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length) @return New pointer into memory based on from + length of the data */ + const uchar *Field_blob::unpack(uchar *to, const uchar *from, const uchar *from_end, uint param_data) { @@ -8311,7 +8312,6 @@ const uchar *Field_blob::unpack(uchar *to, const uchar *from, DBUG_RETURN(0); store(reinterpret_cast(from) + master_packlength, length, field_charset); - DBUG_DUMP("record", to, table->s->reclength); DBUG_RETURN(from + master_packlength + length); } From 3dc3ab1a3048484910ca8acccaf76c71b080e533 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 11 Jan 2018 23:56:54 +0200 Subject: [PATCH 02/10] Added checking that row events ends with a proper end block Problems -------- The slave io thread did not conduct integrity check for a group of row-based events. Specifically it tolerates missed terminal block event that must be flagged with STMT_END. Failure to react on its loss can confuse the applier thread in various ways. Another potential issue was that there were no check of impossible second in row Gtid-log-event while the slave io thread is receiving to be skipped events after reconnect. Fixes ----- The slave io thread is made by this patch to track the rows event STMT_END status. Whenever at next event reading the IO thread finds out that a preceding Rows event did not actually had the flag, an explicit error is issued. Replication can be resumed after the source of failure is eliminated, see a provided test. Note that currently the row-based group integrity check excludes the compressed version 2 Rows events (which are not generated by MariaDB master). Its uncompressed counterpart is manually tested. The 2nd issue is covered to produce an error in case the io thread receives a successive Gtid_log_event while it is post-reconnect skipping. --- .../r/rpl_row_end_of_statement_loss.result | 42 ++++ .../rpl_row_end_of_statement_loss-master.opt | 2 + .../rpl/t/rpl_row_end_of_statement_loss.test | 66 ++++++ sql/rpl_mi.h | 21 ++ sql/slave.cc | 202 +++++++++++++++++- 5 files changed, 322 insertions(+), 11 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test diff --git a/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result b/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result new file mode 100644 index 00000000000..dc6a67b48d2 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result @@ -0,0 +1,42 @@ +include/master-slave.inc +[connection master] +connection slave; +call mtr.add_suppression("Slave IO thread did not receive an expected Rows-log end-of-statement"); +call mtr.add_suppression("Relay log write failure: could not queue event from master"); +SET @save_debug= @@global.debug; +SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss"; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_USE_GTID=SLAVE_POS; +connection master; +CREATE TABLE t (a INT, b text(8192));; +INSERT INTO t values (1, repeat('b', 8192)), (1, repeat('b', 8192)); +connection slave; +START SLAVE IO_THREAD; +include/wait_for_slave_io_error.inc [errno=1595] +SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss"; +include/start_slave.inc +connection master; +connection slave; +connection slave; +include/stop_slave.inc +connection master; +SET @save_log_bin_compress= @@GLOBAL.log_bin_compress; +SET @save_log_bin_compress_min_len= @@GLOBAL.log_bin_compress_min_len; +SET @@GLOBAL.log_bin_compress=ON; +SET @@GLOBAL.log_bin_compress_min_len=10; +INSERT INTO t values (2, repeat('b', 8192)), (2, repeat('b', 8192)); +connection slave; +SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss"; +START SLAVE IO_THREAD; +include/wait_for_slave_io_error.inc [errno=1595] +SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss"; +include/start_slave.inc +connection master; +connection slave; +connection master; +SET @@GLOBAL.log_bin_compress= @save_log_bin_compress; +SET @@GLOBAL.log_bin_compress_min_len= @save_log_bin_compress_min_len; +DROP TABLE t; +connection slave; +SET GLOBAL debug_dbug= @save_debug; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt new file mode 100644 index 00000000000..144bbca0730 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt @@ -0,0 +1,2 @@ +--binlog-row-event-max-size=8192 + diff --git a/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test new file mode 100644 index 00000000000..5b2d99f3bf1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test @@ -0,0 +1,66 @@ +--source include/have_debug.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +# Loss of STMT_END flagged event must error out the IO thread +--connection slave +call mtr.add_suppression("Slave IO thread did not receive an expected Rows-log end-of-statement"); +call mtr.add_suppression("Relay log write failure: could not queue event from master"); + +SET @save_debug= @@global.debug; +SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss"; +--source include/stop_slave.inc +--replace_result $MASTER_MYPORT MASTER_PORT +--eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, MASTER_USE_GTID=SLAVE_POS + +--connection master +--let $max_row_size=8192 +--eval CREATE TABLE t (a INT, b text($max_row_size)); +--eval INSERT INTO t values (1, repeat('b', $max_row_size)), (1, repeat('b', $max_row_size)) + +# Prove that the missed STMT_END marked rows-event causes the io thread stop. +--connection slave +START SLAVE IO_THREAD; +--let $slave_io_errno=1595 +--source include/wait_for_slave_io_error.inc +SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss"; +--source include/start_slave.inc + +--connection master +sync_slave_with_master; + +# Compressed version of the above +--connection slave +--source include/stop_slave.inc + +--connection master +SET @save_log_bin_compress= @@GLOBAL.log_bin_compress; +SET @save_log_bin_compress_min_len= @@GLOBAL.log_bin_compress_min_len; + +SET @@GLOBAL.log_bin_compress=ON; +SET @@GLOBAL.log_bin_compress_min_len=10; + +--eval INSERT INTO t values (2, repeat('b', $max_row_size)), (2, repeat('b', $max_row_size)) + +# Prove that the missed STMT_END marked rows-event causes the io thread stop. +--connection slave +SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event_loss"; +START SLAVE IO_THREAD; +--let $slave_io_errno=1595 +--source include/wait_for_slave_io_error.inc +SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event_loss"; +--source include/start_slave.inc + +--connection master +sync_slave_with_master; + +# cleanup + +--connection master +SET @@GLOBAL.log_bin_compress= @save_log_bin_compress; +SET @@GLOBAL.log_bin_compress_min_len= @save_log_bin_compress_min_len; +DROP TABLE t; +sync_slave_with_master; +SET GLOBAL debug_dbug= @save_debug; + +--source include/rpl_end.inc diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index ccc1be6e5ce..b304e45f86a 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -133,6 +133,19 @@ public: extern TYPELIB slave_parallel_mode_typelib; +typedef struct st_rows_event_tracker +{ + char binlog_file_name[FN_REFLEN]; + my_off_t first_seen; + my_off_t last_seen; + bool stmt_end_seen; + void update(const char* file_name, size_t pos, + const char* buf, + const Format_description_log_event *fdle); + void reset(); + bool check_and_report(const char* file_name, size_t pos); +} Rows_event_tracker; + /***************************************************************************** Replication IO Thread @@ -301,6 +314,14 @@ class Master_info : public Slave_reporting_capability uint64 gtid_reconnect_event_skip_count; /* gtid_event_seen is false until we receive first GTID event from master. */ bool gtid_event_seen; + /** + The struct holds some history of Rows- log-event reading/queuing + by the receiver thread. Its fields are updated per each such event + at time of queue_event(), and they are checked to detect + the Rows- event group integrity violation at time of first non-Rows- + event gets handled. + */ + Rows_event_tracker rows_event_tracker; bool in_start_all_slaves, in_stop_all_slaves; bool in_flush_all_relay_logs; uint users; /* Active user for object */ diff --git a/sql/slave.cc b/sql/slave.cc index c686553fdd5..e5c502c2de5 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3349,7 +3349,8 @@ static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings, we suppress prints to .err file as long as the reconnect happens without problems */ - *suppress_warnings= TRUE; + *suppress_warnings= + global_system_variables.log_warnings < 2 ? TRUE : FALSE; } else { @@ -4274,6 +4275,7 @@ pthread_handler_t handle_slave_io(void *arg) mi->abort_slave = 0; mysql_mutex_unlock(&mi->run_lock); mysql_cond_broadcast(&mi->start_cond); + mi->rows_event_tracker.reset(); DBUG_PRINT("master_info",("log_file_name: '%s' position: %llu", mi->master_log_name, mi->master_log_pos)); @@ -4356,6 +4358,10 @@ connected: */ mi->gtid_reconnect_event_skip_count= mi->events_queued_since_last_gtid; mi->gtid_event_seen= false; + /* + Reset stale state of the rows-event group tracker at reconnect. + */ + mi->rows_event_tracker.reset(); } #ifdef ENABLED_DEBUG_SYNC @@ -5752,7 +5758,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) char* new_buf = NULL; char new_buf_arr[4096]; bool is_malloc = false; - + bool is_rows_event= false; /* FD_q must have been prepared for the first R_a event inside get_master_version_and_clock() @@ -6186,11 +6192,11 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) got_gtid_event= true; if (mi->using_gtid == Master_info::USE_GTID_NO) goto default_action; - if (unlikely(!mi->gtid_event_seen)) + if (unlikely(mi->gtid_reconnect_event_skip_count)) { - mi->gtid_event_seen= true; - if (mi->gtid_reconnect_event_skip_count) + if (likely(!mi->gtid_event_seen)) { + mi->gtid_event_seen= true; /* If we are reconnecting, and we need to skip a partial event group already queued to the relay log before the reconnect, then we check @@ -6219,13 +6225,45 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) rpl_slave_state_tostring_helper(&error_msg, &event_gtid, &first); goto err; } + if (global_system_variables.log_warnings > 1) + { + bool first= true; + StringBuffer<1024> gtid_text; + rpl_slave_state_tostring_helper(>id_text, &mi->last_queued_gtid, + &first); + sql_print_information("Slave IO thread is reconnected to " + "receive Gtid_log_event %s. It is to skip %llu " + "already received events including the gtid one", + gtid_text.ptr(), + mi->events_queued_since_last_gtid); + } + goto default_action; + } + else + { + bool first; + StringBuffer<1024> gtid_text; + + gtid_text.append(STRING_WITH_LEN("Last received gtid: ")); + first= true; + rpl_slave_state_tostring_helper(>id_text, &mi->last_queued_gtid, + &first); + gtid_text.append(STRING_WITH_LEN(", currently received: ")); + first= true; + rpl_slave_state_tostring_helper(>id_text, &event_gtid, &first); + + error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; + sql_print_error("Slave IO thread has received a new Gtid_log_event " + "while skipping already logged events " + "after reconnect. %s. %llu remains to be skipped. " + "The number of originally read events was %llu", + gtid_text.ptr(), + mi->gtid_reconnect_event_skip_count, + mi->events_queued_since_last_gtid); + goto err; } } - - if (unlikely(mi->gtid_reconnect_event_skip_count)) - { - goto default_action; - } + mi->gtid_event_seen= true; /* We have successfully queued to relay log everything before this GTID, so @@ -6292,8 +6330,34 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) goto err; } } - buf = new_buf; is_compress_event = true; + buf = new_buf; + /* + As we are uncertain about compressed V2 rows events, we don't track + them + */ + if (LOG_EVENT_IS_ROW_V2((Log_event_type) buf[EVENT_TYPE_OFFSET])) + goto default_action; + /* fall through */ + case WRITE_ROWS_EVENT_V1: + case UPDATE_ROWS_EVENT_V1: + case DELETE_ROWS_EVENT_V1: + case WRITE_ROWS_EVENT: + case UPDATE_ROWS_EVENT: + case DELETE_ROWS_EVENT: + { + is_rows_event= true; + mi->rows_event_tracker.update(mi->master_log_name, + mi->master_log_pos, + buf, + mi->rli.relay_log. + description_event_for_queue); + + DBUG_EXECUTE_IF("simulate_stmt_end_rows_event_loss", + { + mi->rows_event_tracker.stmt_end_seen= false; + }); + } goto default_action; #ifndef DBUG_OFF @@ -6351,6 +6415,21 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) break; } + /* + Integrity of Rows- event group check. + A sequence of Rows- events must end with STMT_END_F flagged one. + Even when Heartbeat event interrupts Rows- events flow this must indicate a + malfunction e.g logging on the master. + */ + if (((uchar) buf[EVENT_TYPE_OFFSET] != HEARTBEAT_LOG_EVENT) && + !is_rows_event && + mi->rows_event_tracker.check_and_report(mi->master_log_name, + mi->master_log_pos)) + { + error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; + goto err; + } + /* If we filter events master-side (eg. @@skip_replication), we will see holes in the event positions from the master. If we see such a hole, adjust @@ -6519,6 +6598,21 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) The whole of the current event group is queued. So in case of reconnect we can start from after the current GTID. */ + if (mi->gtid_reconnect_event_skip_count) + { + bool first= true; + StringBuffer<1024> gtid_text; + + rpl_slave_state_tostring_helper(>id_text, &mi->last_queued_gtid, + &first); + sql_print_error("Slave IO thread received a terminal event from " + "group %s whose retrieval was interrupted " + "with reconnect. We still had %llu events to read. " + "The number of originally read events was %llu", + gtid_text.ptr(), + mi->gtid_reconnect_event_skip_count, + mi->events_queued_since_last_gtid); + } mi->gtid_current_pos.update(&mi->last_queued_gtid); mi->events_queued_since_last_gtid= 0; @@ -7518,6 +7612,92 @@ bool rpl_master_erroneous_autoinc(THD *thd) return FALSE; } + +static bool get_row_event_stmt_end(const char* buf, + const Format_description_log_event *fdle) +{ + uint8 const common_header_len= fdle->common_header_len; + Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET]; + + uint8 const post_header_len= fdle->post_header_len[event_type-1]; + const char *flag_start= buf + common_header_len; + /* + The term 4 below signifies that master is of 'an intermediate source', see + Rows_log_event::Rows_log_event. + */ + flag_start += RW_MAPID_OFFSET + (post_header_len == 6) ? 4 : RW_FLAGS_OFFSET; + + return (uint2korr(flag_start) & Rows_log_event::STMT_END_F) != 0; +} + + +/* + Reset log event tracking data. +*/ + +void Rows_event_tracker::reset() +{ + binlog_file_name[0]= 0; + first_seen= last_seen= 0; + stmt_end_seen= false; +} + + +/* + Update log event tracking data. + + The first- and last- seen event binlog position get memorized, as + well as the end-of-statement status of the last one. +*/ + +void Rows_event_tracker::update(const char* file_name, size_t pos, + const char* buf, + const Format_description_log_event *fdle) +{ + if (!first_seen) + { + first_seen= pos; + strmake(binlog_file_name, file_name, sizeof(binlog_file_name) - 1); + } + last_seen= pos; + DBUG_ASSERT(stmt_end_seen == 0); // We can only have one + stmt_end_seen= get_row_event_stmt_end(buf, fdle); +}; + + +/** + The function is called at next event reading + after a sequence of Rows- log-events. It checks the end-of-statement status + of the past sequence to report on any isssue. + In the positive case the tracker gets reset. + + @return true when the Rows- event group integrity found compromised, + false otherwise. +*/ +bool Rows_event_tracker::check_and_report(const char* file_name, + size_t pos) +{ + if (last_seen) + { + // there was at least one "block" event previously + if (!stmt_end_seen) + { + sql_print_error("Slave IO thread did not receive an expected " + "Rows-log end-of-statement for event starting " + "at log '%s' position %llu " + "whose last block was seen at log '%s' position %llu. " + "The end-of-statement should have been delivered " + "before the current one at log '%s' position %llu", + binlog_file_name, first_seen, + binlog_file_name, last_seen, file_name, pos); + return true; + } + reset(); + } + + return false; +} + /** @} (end of group Replication) */ From d32f5be307d5593bf36d243de275af88ff8ee92a Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 12 Jan 2018 15:11:56 +0300 Subject: [PATCH 03/10] MDEV-14372: Fix and enable rocksdb.information_schema test - Make Rdb_binlog_manager::unpack_value to not have a stack overrun when it is reading invalid data (which it currently does as we in MariaDB do not store binlog coordinates under BINLOG_INFO_INDEX_NUMBER, see comments in MDEV-14892 for details). - We may need to store these coordinates in the future, so instead of removing the call of this function, let's make it work properly for all possible inputs. --- .../rocksdb/r/information_schema.result | 30 +++++++++---------- .../rocksdb/mysql-test/rocksdb/t/disabled.def | 1 - .../rocksdb/t/information_schema-master.opt | 2 +- .../rocksdb/t/information_schema.test | 12 ++++++-- storage/rocksdb/rdb_datadic.cc | 27 ++++++++++++++++- storage/rocksdb/rdb_datadic.h | 5 +++- storage/rocksdb/rdb_i_s.cc | 1 - 7 files changed, 56 insertions(+), 22 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result index 291effa832c..717fb0b970c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result @@ -1,6 +1,20 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t3; +create table t1 (a int) engine=rocksdb; +drop table t1; +select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; +TYPE NAME VALUE +MAX_INDEX_ID MAX_INDEX_ID max_index_id +CF_FLAGS 0 default [0] +CF_FLAGS 1 __system__ [0] +DDL_DROP_INDEX_ONGOING cf_id:0,index_id:max_index_id +select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; +count(*) +4 +select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn'; +CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB; +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; TYPE NAME VALUE MAX_INDEX_ID MAX_INDEX_ID max_index_id @@ -9,20 +23,6 @@ CF_FLAGS 1 __system__ [0] select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; count(*) 3 -select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn'; -CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB; -INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); -select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; -TYPE NAME VALUE -BINLOG FILE master-bin.000001 -BINLOG POS 1066 -BINLOG GTID uuid:5 -MAX_INDEX_ID MAX_INDEX_ID max_index_id -CF_FLAGS 0 default [0] -CF_FLAGS 1 __system__ [0] -select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; -count(*) -6 set global rocksdb_force_flush_memtable_now = true; set global rocksdb_compact_cf='default'; select case when VALUE-@keysIn >= 3 then 'true' else 'false' end from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn'; @@ -66,7 +66,7 @@ SHOW GLOBAL VARIABLES LIKE 'ROCKSDB_PAUSE_BACKGROUND_WORK'; Variable_name Value rocksdb_pause_background_work ON DROP TABLE t3; -cf_id:0,index_id:267 +cf_id:0,index_id:264 SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0; SHOW GLOBAL VARIABLES LIKE 'ROCKSDB_PAUSE_BACKGROUND_WORK'; Variable_name Value diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index dc2e04b93d7..359d1d3e082 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -72,7 +72,6 @@ blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api tes ## Tests that fail for some other reason ## -information_schema : MariaRocks: requires GTIDs mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs rpl_row_triggers : MariaRocks: requires GTIDs diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt index 40b14167e17..86379847638 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt +++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema-master.opt @@ -1 +1 @@ ---binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log_slave_updates +--binlog_format=row --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test index c8d9b538529..8746e589046 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test @@ -9,6 +9,13 @@ DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t3; --enable_warnings +# MariaDB: the following is for handling the case where the tests +# is started on a totally empty datadir, where no MyRocks table has +# ever been created). In that case, there is no MAX_INDEX_ID. +# Create/drop a table so that we do have MAX_INDEX_ID. +create table t1 (a int) engine=rocksdb; +drop table t1; + --let $max_index_id = query_get_value(SELECT * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO where type = 'MAX_INDEX_ID', VALUE, 1) --replace_result $max_index_id max_index_id select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; @@ -19,9 +26,10 @@ select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB; INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); ---let $MASTER_UUID = query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1) +# No binlog coordinates in MariaDB: --let $MASTER_UUID = query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1) --let $max_index_id = query_get_value(SELECT * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO where type = 'MAX_INDEX_ID', VALUE, 1) ---replace_result $MASTER_UUID uuid $max_index_id max_index_id +# No binlog coordinates in MariaDB: --replace_result $MASTER_UUID uuid $max_index_id max_index_id +--replace_result $max_index_id max_index_id select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index f6f1406e80c..b2f5af705a3 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -4261,7 +4261,7 @@ bool Rdb_binlog_manager::read(char *const binlog_name, std::string value; rocksdb::Status status = m_dict->get_value(m_key_slice, &value); if (status.ok()) { - if (!unpack_value((const uchar *)value.c_str(), binlog_name, binlog_pos, + if (!unpack_value((const uchar *)value.c_str(), value.size(), binlog_name, binlog_pos, binlog_gtid)) ret = true; } @@ -4331,35 +4331,60 @@ Rdb_binlog_manager::pack_value(uchar *const buf, const char *const binlog_name, @return true on error */ bool Rdb_binlog_manager::unpack_value(const uchar *const value, + size_t value_size_arg, char *const binlog_name, my_off_t *const binlog_pos, char *const binlog_gtid) const { uint pack_len = 0; + intmax_t value_size= value_size_arg; DBUG_ASSERT(binlog_pos != nullptr); + if ((value_size -= Rdb_key_def::VERSION_SIZE) < 0) + return true; // read version const uint16_t version = rdb_netbuf_to_uint16(value); + pack_len += Rdb_key_def::VERSION_SIZE; if (version != Rdb_key_def::BINLOG_INFO_INDEX_NUMBER_VERSION) return true; + if ((value_size -= sizeof(uint16)) < 0) + return true; + // read binlog file name length const uint16_t binlog_name_len = rdb_netbuf_to_uint16(value + pack_len); pack_len += sizeof(uint16); + + if (binlog_name_len >= (FN_REFLEN+1)) + return true; + + if ((value_size -= binlog_name_len) < 0) + return true; + if (binlog_name_len) { // read and set binlog name memcpy(binlog_name, value + pack_len, binlog_name_len); binlog_name[binlog_name_len] = '\0'; pack_len += binlog_name_len; + if ((value_size -= sizeof(uint32)) < 0) + return true; // read and set binlog pos *binlog_pos = rdb_netbuf_to_uint32(value + pack_len); pack_len += sizeof(uint32); + if ((value_size -= sizeof(uint16)) < 0) + return true; // read gtid length const uint16_t binlog_gtid_len = rdb_netbuf_to_uint16(value + pack_len); pack_len += sizeof(uint16); + + if (binlog_gtid_len >= GTID_BUF_LEN) + return true; + if ((value_size -= binlog_gtid_len) < 0) + return true; + if (binlog_gtid && binlog_gtid_len > 0) { // read and set gtid memcpy(binlog_gtid, value + pack_len, binlog_gtid_len); diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h index 5796132de39..223f61edb43 100644 --- a/storage/rocksdb/rdb_datadic.h +++ b/storage/rocksdb/rdb_datadic.h @@ -46,6 +46,8 @@ class Rdb_field_packing; class Rdb_cf_manager; class Rdb_ddl_manager; +const uint32_t GTID_BUF_LEN = 60; + /* @brief Field packing context. @@ -1154,7 +1156,8 @@ private: rocksdb::Slice pack_value(uchar *const buf, const char *const binlog_name, const my_off_t &binlog_pos, const char *const binlog_gtid) const; - bool unpack_value(const uchar *const value, char *const binlog_name, + bool unpack_value(const uchar *const value, size_t value_size, + char *const binlog_name, my_off_t *const binlog_pos, char *const binlog_gtid) const; std::atomic m_slave_gtid_info_tbl; diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc index 424a9e6c1f4..f8ddcb00fb3 100644 --- a/storage/rocksdb/rdb_i_s.cc +++ b/storage/rocksdb/rdb_i_s.cc @@ -729,7 +729,6 @@ static int rdb_i_s_global_info_fill_table( DBUG_ASSERT(tables != nullptr); static const uint32_t INT_BUF_LEN = 21; - static const uint32_t GTID_BUF_LEN = 60; static const uint32_t CF_ID_INDEX_BUF_LEN = 60; int ret = 0; From c481fc9ca788a3ac1d61ed6336208c0e2c1cde78 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 12 Jan 2018 15:57:08 +0300 Subject: [PATCH 04/10] Change MyRocks maturity from Alpha to Beta --- storage/rocksdb/ha_rocksdb.h | 2 +- .../rocksdb/r/mariadb_port_fixes.result | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h index 82819bbf7b2..4432a4de8d1 100644 --- a/storage/rocksdb/ha_rocksdb.h +++ b/storage/rocksdb/ha_rocksdb.h @@ -1412,6 +1412,6 @@ private: Rdb_inplace_alter_ctx &operator=(const Rdb_inplace_alter_ctx &); }; -const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_ALPHA; +const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_BETA; } // namespace myrocks diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result index 9952314cd2c..021373be02a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result @@ -69,15 +69,15 @@ set global rocksdb_strict_collation_check=@tmp_rscc; # select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%'; plugin_name plugin_maturity -ROCKSDB Alpha -ROCKSDB_CFSTATS Alpha -ROCKSDB_DBSTATS Alpha -ROCKSDB_PERF_CONTEXT Alpha -ROCKSDB_PERF_CONTEXT_GLOBAL Alpha -ROCKSDB_CF_OPTIONS Alpha -ROCKSDB_COMPACTION_STATS Alpha -ROCKSDB_GLOBAL_INFO Alpha -ROCKSDB_DDL Alpha -ROCKSDB_INDEX_FILE_MAP Alpha -ROCKSDB_LOCKS Alpha -ROCKSDB_TRX Alpha +ROCKSDB Beta +ROCKSDB_CFSTATS Beta +ROCKSDB_DBSTATS Beta +ROCKSDB_PERF_CONTEXT Beta +ROCKSDB_PERF_CONTEXT_GLOBAL Beta +ROCKSDB_CF_OPTIONS Beta +ROCKSDB_COMPACTION_STATS Beta +ROCKSDB_GLOBAL_INFO Beta +ROCKSDB_DDL Beta +ROCKSDB_INDEX_FILE_MAP Beta +ROCKSDB_LOCKS Beta +ROCKSDB_TRX Beta From 028e2ddc549fb7573b11392c87b9e8faf1cbf38b Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Fri, 12 Jan 2018 19:16:36 +0530 Subject: [PATCH 05/10] Added a missing result file to the rocksdb_sys_vars result suite --- .../rocksdb_sys_vars/include/rocksdb_sys_var.inc | 1 + .../rocksdb_sys_vars/r/rocksdb_git_hash_basic.result | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc b/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc index 6ba93026674..db0abc57358 100644 --- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/include/rocksdb_sys_var.inc @@ -10,6 +10,7 @@ --eval SET @start_global_value = @@global.$sys_var if (!$suppress_default_value) { + --replace_regex /[a-f0-9]{40}/#/ SELECT @start_global_value; if ($session) { diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result new file mode 100644 index 00000000000..bbcfa1417eb --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_git_hash_basic.result @@ -0,0 +1,7 @@ +SET @start_global_value = @@global.ROCKSDB_GIT_HASH; +SELECT @start_global_value; +@start_global_value +# +"Trying to set variable @@global.ROCKSDB_GIT_HASH to 444. It should fail because it is readonly." +SET @@global.ROCKSDB_GIT_HASH = 444; +ERROR HY000: Variable 'rocksdb_git_hash' is a read only variable From 2da191791260d5ca3adcb6857404912d52926ee2 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 12 Jan 2018 16:04:29 +0000 Subject: [PATCH 06/10] Attempt to eliminate race conditions in rocksdb.information_schema --- storage/rocksdb/mysql-test/rocksdb/r/information_schema.result | 2 ++ storage/rocksdb/mysql-test/rocksdb/t/information_schema.test | 2 ++ 2 files changed, 4 insertions(+) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result index 717fb0b970c..6850d8dff16 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result @@ -1,6 +1,7 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t3; +SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=1; create table t1 (a int) engine=rocksdb; drop table t1; select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; @@ -12,6 +13,7 @@ DDL_DROP_INDEX_ONGOING cf_id:0,index_id:max_index_id select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; count(*) 4 +SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0; select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn'; CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB; INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test index 8746e589046..2ffc186dd8f 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test @@ -13,6 +13,7 @@ DROP TABLE IF EXISTS t3; # is started on a totally empty datadir, where no MyRocks table has # ever been created). In that case, there is no MAX_INDEX_ID. # Create/drop a table so that we do have MAX_INDEX_ID. +SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=1; create table t1 (a int) engine=rocksdb; drop table t1; @@ -20,6 +21,7 @@ drop table t1; --replace_result $max_index_id max_index_id select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; select count(*) from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO; +SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0; select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn'; From 4cafd8e66f77798168aecd9bb239f97d7cd1ee3b Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Sat, 13 Jan 2018 01:26:06 +0300 Subject: [PATCH 07/10] rocksdb.information_schema testcase is not stable --- storage/rocksdb/mysql-test/rocksdb/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index 359d1d3e082..c2ca6efe46c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -67,6 +67,7 @@ lock_wait_timeout_stats: MDEV-13404 compact_deletes: MDEV-12663 : rocksdb.compact_deletes times out and causes other tests to fail blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api test fails +information_schema: MDEV-14372: unstable testcase ## ## Tests that fail for some other reason @@ -75,4 +76,3 @@ blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api tes mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs rpl_row_triggers : MariaRocks: requires GTIDs - From 0a63b50c7a2dcab6fe99885cfcbd4a35d322c63a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 28 Nov 2017 16:34:31 +0400 Subject: [PATCH 08/10] Cleanup UT_LOW_PRIORITY_CPU/UT_RESUME_PRIORITY_CPU Server already has HMT_low/HMT_medium. --- config.h.cmake | 1 - configure.cmake | 11 ----------- include/my_cpu.h | 13 +++++++------ storage/innobase/include/ut0ut.h | 9 --------- storage/innobase/ut/ut0ut.cc | 5 +++-- 5 files changed, 10 insertions(+), 29 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index 51abd4b11d5..31a563037a0 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -191,7 +191,6 @@ #cmakedefine HAVE_PREAD 1 #cmakedefine HAVE_PAUSE_INSTRUCTION 1 #cmakedefine HAVE_FAKE_PAUSE_INSTRUCTION 1 -#cmakedefine HAVE_HMT_PRIORITY_INSTRUCTION 1 #cmakedefine HAVE_RDTSCLL 1 #cmakedefine HAVE_READ_REAL_TIME 1 #cmakedefine HAVE_PTHREAD_ATTR_CREATE 1 diff --git a/configure.cmake b/configure.cmake index ffcb9ba83b9..40aca55dc47 100644 --- a/configure.cmake +++ b/configure.cmake @@ -783,17 +783,6 @@ IF(NOT CMAKE_CROSSCOMPILING AND NOT MSVC) } " HAVE_FAKE_PAUSE_INSTRUCTION) ENDIF() - IF (NOT HAVE_PAUSE_INSTRUCTION) - CHECK_C_SOURCE_COMPILES(" - #include - int main() - { - __ppc_set_ppr_low(); - __ppc_set_ppr_med(); - return 0; - } - " HAVE_HMT_PRIORITY_INSTRUCTION) - ENDIF() ENDIF() CHECK_SYMBOL_EXISTS(tcgetattr "termios.h" HAVE_TCGETATTR 1) diff --git a/include/my_cpu.h b/include/my_cpu.h index 856a8e9b04a..f2e26fca70c 100644 --- a/include/my_cpu.h +++ b/include/my_cpu.h @@ -23,17 +23,18 @@ The defines are the same ones used by the linux kernel */ -#if defined(__powerpc__) +#ifdef _ARCH_PWR8 +#include /* Very low priority */ -#define HMT_very_low() asm volatile("or 31,31,31") +#define HMT_very_low() __ppc_set_ppr_very_low() /* Low priority */ -#define HMT_low() asm volatile("or 1,1,1") +#define HMT_low() __ppc_set_ppr_low() /* Medium low priority */ -#define HMT_medium_low() asm volatile("or 6,6,6") +#define HMT_medium_low() __ppc_set_ppr_med_low() /* Medium priority */ -#define HMT_medium() asm volatile("or 2,2,2") +#define HMT_medium() __ppc_set_ppr_med() /* Medium high priority */ -#define HMT_medium_high() asm volatile("or 5,5,5") +#define HMT_medium_high() __ppc_set_ppr_med_high() /* High priority */ #define HMT_high() asm volatile("or 3,3,3") #else diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 352f5cce83d..c91e24ad314 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -60,15 +60,6 @@ typedef time_t ib_time_t; # define UT_COMPILER_BARRIER() #endif -#if defined(HAVE_HMT_PRIORITY_INSTRUCTION) -# include -# define UT_LOW_PRIORITY_CPU() __ppc_set_ppr_low() -# define UT_RESUME_PRIORITY_CPU() __ppc_set_ppr_med() -#else -# define UT_LOW_PRIORITY_CPU() ((void)0) -# define UT_RESUME_PRIORITY_CPU() ((void)0) -#endif - /*********************************************************************//** Delays execution for at most max_wait_us microseconds or returns earlier if cond becomes true. diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 88c5c889c8d..25705cb0e2c 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -37,6 +37,7 @@ Created 5/11/1994 Heikki Tuuri #include "trx0trx.h" #include #include "log.h" +#include "my_cpu.h" #ifdef _WIN32 /*****************************************************************//** @@ -290,14 +291,14 @@ ut_delay( { ulint i; - UT_LOW_PRIORITY_CPU(); + HMT_low(); for (i = 0; i < delay * 50; i++) { MY_RELAX_CPU(); UT_COMPILER_BARRIER(); } - UT_RESUME_PRIORITY_CPU(); + HMT_medium(); } /*************************************************************//** From 09ef28abd7c3c80a80512bb4bba7f8e8f0194abe Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 13 Jan 2018 16:38:43 +0200 Subject: [PATCH 09/10] Fixed BUILD scripts - Removed extra set -x -v used for debugging - Fixed that that gcc version tests works for gcc 7 --- BUILD/FINISH.sh | 2 +- BUILD/check-cpu | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 1faf62a9b62..ea64183253d 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -14,7 +14,7 @@ # License along with this library; if not, write to the Free # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, # MA 02110-1301, USA -set -x -v + cflags="$c_warnings $extra_flags $EXTRA_FLAGS $EXTRA_CFLAGS" cxxflags="$cxx_warnings $base_cxxflags $extra_flags $EXTRA_FLAGS $EXTRA_CXXFLAGS" extra_configs="$extra_configs $local_infile_configs $EXTRA_CONFIGS" diff --git a/BUILD/check-cpu b/BUILD/check-cpu index ad8816dc421..c1c85cfd908 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -40,6 +40,12 @@ check_compiler_cpu_flags () { cc_major=$1 cc_minor=$2 cc_patch=$3 + if test -z "$cc_minor"; then + cc_minor="0"; + fi + if test -z "$cc_patch"; then + cc_minor="0"; + fi cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` fi From fc65577873967ecbba93b75260cc54275f5900d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 13 Jan 2018 18:04:03 +0200 Subject: [PATCH 10/10] MDEV-14887 On a 32-bit system, MariaDB 10.2 mishandles data file sizes exceeding 4GiB This is a regression that was introduced in MySQL 5.7.6 in https://github.com/mysql/mysql-server/commit/19855664de0245ff24e0753dc82723fc4e2fb7a5 fil_node_open_file(): Use proper 64-bit arithmetics for truncating size_bytes to a multiple of a file extent size. --- storage/innobase/fil/fil0fil.cc | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 3b496e3959f..86c0499eca4 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. +Copyright (c) 2014, 2018, MariaDB Corporation. 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 @@ -566,7 +566,6 @@ bool fil_node_open_file( fil_node_t* node) { - os_offset_t size_bytes; bool success; bool read_only_mode; fil_space_t* space = node->space; @@ -611,7 +610,7 @@ retry: return(false); } - size_bytes = os_file_get_size(node->handle); + os_offset_t size_bytes = os_file_get_size(node->handle); ut_a(size_bytes != (os_offset_t) -1); ut_a(space->purpose != FIL_TYPE_LOG); @@ -694,20 +693,17 @@ retry: space->free_len = free_len; if (first_time_open) { - ulint extent_size; - - extent_size = psize * FSP_EXTENT_SIZE; - - /* After apply-incremental, tablespaces are not extended - to a whole megabyte. Do not cut off valid data. */ - /* Truncate the size to a multiple of extent size. */ - if (size_bytes >= extent_size) { - size_bytes = ut_2pow_round(size_bytes, - extent_size); + ulint mask = psize * FSP_EXTENT_SIZE - 1; + + if (size_bytes <= mask) { + /* .ibd files start smaller than an + extent size. Do not truncate valid data. */ + } else { + size_bytes &= ~os_offset_t(mask); } - node->size = static_cast(size_bytes / psize); + node->size = ulint(size_bytes / psize); space->size += node->size; } }