mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge bb-10.2-ext into 10.3
This commit is contained in:
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
42
mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result
Normal file
42
mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result
Normal file
@ -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
|
@ -0,0 +1,2 @@
|
||||
--binlog-row-event-max-size=8192
|
||||
|
66
mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test
Normal file
66
mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test
Normal file
@ -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
|
@ -8448,6 +8448,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)
|
||||
{
|
||||
@ -8463,7 +8464,6 @@ const uchar *Field_blob::unpack(uchar *to, const uchar *from,
|
||||
if (from + master_packlength + length > from_end)
|
||||
DBUG_RETURN(0);
|
||||
set_ptr(length, const_cast<uchar*> (from) + master_packlength);
|
||||
DBUG_DUMP("record", to, table->s->reclength);
|
||||
DBUG_RETURN(from + master_packlength + length);
|
||||
}
|
||||
|
||||
|
21
sql/rpl_mi.h
21
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 */
|
||||
|
202
sql/slave.cc
202
sql/slave.cc
@ -3659,7 +3659,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
|
||||
{
|
||||
@ -4589,6 +4590,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));
|
||||
@ -4672,6 +4674,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
|
||||
@ -6077,7 +6083,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()
|
||||
@ -6511,11 +6517,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
|
||||
@ -6544,13 +6550,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
|
||||
@ -6617,8 +6655,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
|
||||
@ -6676,6 +6740,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
|
||||
@ -6845,6 +6924,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;
|
||||
|
||||
@ -7844,6 +7938,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)
|
||||
*/
|
||||
|
@ -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<ulint>(size_bytes / psize);
|
||||
node->size = ulint(size_bytes / psize);
|
||||
space->size += node->size;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,22 @@
|
||||
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;
|
||||
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
|
||||
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);
|
||||
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
|
||||
TYPE NAME VALUE
|
||||
MAX_INDEX_ID MAX_INDEX_ID max_index_id
|
||||
@ -9,20 +25,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 +68,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
|
||||
|
@ -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
|
||||
|
@ -69,11 +69,12 @@ compact_deletes: MDEV-12663 : rocksdb.compact_deletes times out and causes other
|
||||
blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api test fails
|
||||
unique_check: wrong error number
|
||||
autoinc_vars_thread: debug sync point wait timed out
|
||||
information_schema: MDEV-14372: unstable testcase
|
||||
|
||||
##
|
||||
## 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
|
||||
|
||||
|
@ -1 +1 @@
|
||||
--binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log_slave_updates
|
||||
--binlog_format=row --log_slave_updates
|
||||
|
@ -9,19 +9,29 @@ 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.
|
||||
SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=1;
|
||||
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;
|
||||
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';
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -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.
|
||||
@ -1158,7 +1160,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<Rdb_tbl_def *> m_slave_gtid_info_tbl;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user