Non-transactional updates that take place inside a transaction present problems
for logging because they are visible to other clients before the transaction
is committed, and they are not rolled back even if the transaction is rolled
back. It is not always possible to log correctly in statement format when both
transactional and non-transactional tables are used in the same transaction.
In the current patch, we ensure that such scenario is completely safe under the
ROW and MIXED modes.
CMakeLists.txt:
Add plugin/semisync subdirectory
mysql-test/mysql-test-run.pl:
Check for semisync dll for Windows
mysql-test/suite/rpl/r/rpl_semi_sync.result:
Update result file
mysql-test/suite/rpl/t/rpl_semi_sync.test:
Test semi-sync on Windows
plugin/semisync/semisync_master.cc:
Define gettimeofday for Windows
Before the patch, slaves only appear in the output of SHOW SLAVE HOSTS
when report-host option is set. If an expected slave does not appear in
the list, nobody knows whether the slave does not connect or has started
without the "report-host" option. The output also contains a strange
field "Rpl_recovery_rank" which has never been implemented and the manual
of MySQL5.4 declares that the field has been removed from MySQL5.4.
This patch is done with these,
According to the manual of MySQL5.4, "Rpl_recovery_rank" is removed.
Slaves will register themselves to master no matter if report_host option is set
or not. When slaves are registering themselves, their Server_ids, report_host
and other information are together sent to master. Sever_ids are never null
and is unique in one replication group. Slaves always can be identified with
different Server_ids no matter if report_host exists.
Post-push fix.
Problem: In a previous patch for BUG#39934, rpl_idempotency.test
was split in two tests. The mtr suppressions in the original test
did not make it into the new test. This caused pushbuild warnings.
Fix: copy the mtr suppressions from rpl_idempotency.test to
rpl_row_idempotency.test
mysql-test/suite/rpl/r/rpl_row_idempotency.result:
updated result file
mysql-test/suite/rpl/t/rpl_row_idempotency.test:
copied the warnings from rpl_idempotency.test to
rpl_row_idempotency.test
Post-push fix.
Problem: After the original bugfix, if a statement is unsafe,
binlog_format=mixed, and engine is statement-only, a warning was
generated and the statement executed. However, it is a fundamental
principle of binlogging that binlog_format=mixed should guarantee
correct logging, no compromise. So correct behavior is to generate
an error and don't execute the statement.
Fix: Generate error instead of warning.
Since issue_unsafe_warnings can only generate one error message,
this allows us to simplify the code a bit too:
decide_logging_format does not have to save the error code for
issue_unsafe_warnings
mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result:
updated result file
mysql-test/suite/binlog/r/binlog_stm_ps.result:
updated result file
mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result:
updated result file
mysql-test/suite/binlog/r/binlog_unsafe.result:
updated result file
mysql-test/suite/rpl/r/rpl_stm_found_rows.result:
updated result file
mysql-test/suite/rpl/r/rpl_stm_loadfile.result:
updated result file
mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result:
updated result file
mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test:
updated test:
- ER_BINLOG_UNSAFE_AND_STMT_ENGINE is now an error.
- added test for multiple types of unsafety
sql/share/errmsg.txt:
- Reformulated ER_BINLOG_UNSAFE_AND_STMT_ENGINE to reflect that it
is now an error, not a warning.
- Added "Reason for unsafeness" to ER_BINLOG_UNSAFE_STATEMENT and
ER_BINLOG_UNSAFE_AND_STMT_ENGINE.
sql/sql_class.cc:
In decide_logging_format:
- generate an error immediately in case 3, instead of scheduling a
warning to be generated later. also updated comments accordingly
- in case 7, there is only one unsafe warning error code now, so we
don't need to store it in binlog_unsafe_warning_flags
(see changes in sql_lex.h)
- fixed compilation warning in DBUG_PRINT
In issue_binlog_warning:
- moved array of error codes to sql_lex.h (so that they are
accessible also from decide_logging_format)
- simplified code after the first set of bits in
binlog_unsafe_warning_flags was removed
sql/sql_class.h:
- got rid of enum_binlog_stmt_warning. It's not needed anymore
since we only have one type of unsafe warning (one of them
turned into an error)
- updated comments accordingly
sql/sql_lex.cc:
added initialization of the array of error codes that has been
moved from THD::issue_unsafe_warnings to LEX.
sql/sql_lex.h:
Moved array of error codes from THD::issue_unsafe_warnings to LEX.
Remove functions that no longer needed
Fix warning suppressions
mysql-test/suite/rpl/t/rpl_semi_sync.test:
Fix warning suppressions
plugin/semisync/semisync_slave.cc:
Remove functions that no longer needed
plugin/semisync/semisync_slave.h:
Remove functions that no longer needed
Add an option to control whether the master should keep waiting
until timeout when it detected that there is no semi-sync slave
available.
The bool option 'rpl_semi_sync_master_wait_no_slave' is 1 by
defalt, and will keep waiting until timeout. When set to 0, the
master will switch to asynchronous replication immediately when
no semi-sync slave is available.
Semi-sync status were not reset by FLUSH STATUS, this was because
all semi-sync status variables are defined as SHOW_FUNC and FLUSH
STATUS could only reset SHOW_LONG type variables.
This problem is fixed by change all status variables that should
be reset by FLUSH STATUS from SHOW_FUNC to SHOW_LONG.
After the fix, the following status variables will be reset by
FLUSH STATUS:
Rpl_semi_sync_master_yes_tx
Rpl_semi_sync_master_no_tx
Note: normally, FLUSH STATUS itself will be written into binlog
and be replicated, so after FLUSH STATS, one of
Rpl_semi_sync_master_yes_tx
Rpl_semi_sync_master_no_tx
can be 1 dependent on the semi-sync status. So it's recommended
to use FLUSH NO_WRITE_TO_BINLOG STATUS to avoid this.
Semi-sync uses an extra connection from slave to master to send
replies, this is a normal client connection, and used a normal
SET query to set the reply information on master, which is visible
to user and may cause some confusion and complaining.
This problem is fixed by using the method of sending reply by
using the same connection that is used by master dump thread to
send binlog to slave. Since now the semi-sync plugins are integrated
with the server code, it is not a problem to use the internal net
interfaces to do this.
The master dump thread will mark the event requires a reply and
wait for the reply when the event just sent is the last event
of a transaction and semi-sync status is ON; And the slave will
send a reply to master when it received such an event that requires
a reply.
mysql-test/suite/rpl/r/rpl_stop_middle_group.result:
the new result file
mysql-test/suite/rpl/t/rpl_stop_middle_group.test:
renamed from rpl_row_stop_middle_update and added a regression test for bug#45940.
The issue appears when number of heartbeat events non-zero before start of test
block. But really we need to check that no new events has received during test block.
So I did following:
1. Replace absolute values by diff of values
2. Increase heartbeat period from 1.5 to 5 sec
CHANGE MASTER TO command required the value for RELAY_LOG_FILE to
be an absolute path, which was different from the requirement of
MASTER_LOG_FILE.
This patch fixed the problem by changing the value for RELAY_LOG_FILE
to be the basename of the log file as that for MASTER_LOG_FILE.
rpl_slave_skip fails randomly on PB2. This patch fixes the failure by
setting explicit wait for SQL thread to stop, instead of the
wait_for_slave_to_stop mysqltest command, after a start until command
is executed.
NOTE: Backporting the patch to next-mr.
The fix proposed in BUG#35542 and BUG#31665 introduces a performance issue
when fsyncing the master.info, relay.info and relay-log.bin* after #th events.
Although such solution has been proposed to reduce the probability of corrupted
files due to a slave-crash, the performance penalty introduced by it has
made the approach impractical for highly intensive workloads.
In a nutshell, the option --syn-relay-log proposed in BUG#35542 and BUG#31665
simultaneously fsyncs master.info, relay-log.info and relay-log.bin* and
this is the main source of performance issues.
This patch introduces new options that give more control to the user on
what should be fsynced and how often:
1) (--sync-master-info, integer) which syncs the master.info after #th event;
2) (--sync-relay-log, integer) which syncs the relay-log.bin* after #th
events.
3) (--sync-relay-log-info, integer) which syncs the relay.info after #th
transactions.
To provide both performance and increased reliability, we recommend the following
setup:
1) --sync-master-info = 0 eventually the operating system will fsync it;
2) --sync-relay-log = 0 eventually the operating system will fsync it;
3) --sync-relay-log-info = 1 fsyncs it after every transaction;
Notice, that the previous setup does not reduce the probability of
corrupted master.info and relay-log.bin*. To overcome the issue, this patch also
introduces a recovery mechanism that right after restart throws away relay-log.bin*
retrieved from a master and updates the master.info based on the relay.info:
4) (--relay-log-recovery, boolean) which enables a recovery mechanism that
throws away relay-log.bin* after a crash.
However, it can only recover the incorrect binlog file and position in master.info,
if other informations (host, port password, etc) are corrupted or incorrect,
then this recovery mechanism will fail to work.
vs not null
NOTE: Backporting the patch to next-mr.
The replication was generating corrupted data, warning messages on Valgrind
and aborting on debug mode while replicating a "null" to "not null" field.
Specifically the unpack_row routine, was considering the slave's table
definition and trying to retrieve a field value, where there was nothing to be
retrieved, ignoring the fact that the value was defined as "null" by the master.
To fix the problem, we proceed as follows:
1 - If it is not STRICT sql_mode, implicit default values are used, regardless
if it is multi-row or single-row statement.
2 - However, if it is STRICT mode, then a we do what follows:
2.1 If it is a transactional engine, we do a rollback on the first NULL that is
to be set into a NOT NULL column and return an error.
2.2 If it is a non-transactional engine and it is the first row to be inserted
with multi-row, we also return the error. Otherwise, we proceed with the
execution, use implicit default values and print out warning messages.
Unfortunately, the current patch cannot mimic the behavior showed by the master
for updates on multi-tables and multi-row inserts. This happens because such
statements are unfolded in different row events. For instance, considering the
following updates and strict mode:
(master)
create table t1 (a int);
create table t2 (a int not null);
insert into t1 values (1);
insert into t2 values (2);
update t1, t2 SET t1.a=10, t2.a=NULL;
t1 would have (10) and t2 would have (0) as this would be handled as a
multi-row update. On the other hand, if we had the following updates:
(master)
create table t1 (a int);
create table t2 (a int);
(slave)
create table t1 (a int);
create table t2 (a int not null);
(master)
insert into t1 values (1);
insert into t2 values (2);
update t1, t2 SET t1.a=10, t2.a=NULL;
On the master t1 would have (10) and t2 would have (NULL). On
the slave, t1 would have (10) but the update on t1 would fail.
NOTE: this is the backport to next-mr.
This patch addresses the bug reported by checking wether
host argument is an empty string or not. If empty, an error is
reported to the client, otherwise continue normally.
This commit is based on the originally proposed patch and adds
a test case as requested during review as well as refines comments,
and makes test case result file less verbose (compared to previous patch).
NOTE: this is the backport to next-mr.
When using replication, the slave will not log any slow query logs queries
replicated from the master, even if the option "--log-slow-slave-statements"
is set and these take more than "log_query_time" to execute.
In order to log slow queries in replicated thread one needs to set the
--log-slow-slave-statements, so that the SQL thread is initialized with the
correct switch. Although setting this flag correctly configures the slave
thread option to log slow queries, there is an issue with the condition that
is used to check whether to log the slow query or not. When replaying binlog
events the statement contains the SET TIMESTAMP clause which will force the
slow logging condition check to fail. Consequently, the slow query logging will
not take place.
This patch addresses this issue by removing the second condition from the
log_slow_statements as it prevents slow queries to be binlogged and seems
to be deprecated.
NOTE: Backporting the patch to next-mr.
The reason of the bug was incompatibile with the master side behaviour.
INSERT query on the master is allowed to insert into a table without specifying
values of DEFAULT-less fields if sql_mode is not strict.
Fixed with checking sql_mode by the sql thread to decide how to react.
Non-strict sql_mode should allow Write_rows event to complete.
todo: warnings can be shown via show slave status, still this is a
separate rather general issue how to show warnings for the slave threads.
files
NOTE: this is the backport to next-mr.
SHOW BINLOG EVENTS does not work with relay log files. If issuing
"SHOW BINLOG EVENTS IN 'relay-log.000001'" in a non-empty relay
log file (relay-log.000001), mysql reports empty set.
This patch addresses this issue by extending the SHOW command
with RELAYLOG. Events in relay log files can now be inspected by
issuing SHOW RELAYLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT
[offset,] row_count].
mysql-test/extra/rpl_tests/rpl_show_relaylog_events.inc:
Shared part of the test case.
mysql-test/include/show_binlog_events.inc:
Added options $binary_log_file, $binary_log_limit_row,
$binary_log_limit_offset so that show_binlog_events can take
same parameters as SHOW BINLOG EVENTS does.
mysql-test/include/show_relaylog_events.inc:
Clone of show_binlog_events for relaylog events.
mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test:
Test case for row based replication.
mysql-test/suite/rpl/t/rpl_stm_mix_show_relaylog_events.test:
Test case for statement and mixed mode replication.
sql/lex.h:
Added RELAYLOG symbol.
sql/mysqld.cc:
Added "show_relaylog_events" to status_vars.
sql/sp_head.cc:
Set SQLCOM_SHOW_RELAYLOG_EVENTS to return flags=
sp_head::MULTI_RESULTS; in sp_get_flags_for_command as
SQLCOM_SHOW_BINLOG_EVENTS does.
sql/sql_lex.h:
Added sql_command SQLCOM_SHOW_RELAYLOG_EVENTS to lex enum_sql_command.
sql/sql_parse.cc:
Added handling of SQLCOM_SHOW_RELAYLOG_EVENTS.
sql/sql_repl.cc:
mysql_show_binlog_events set to choose the log file to use based on
the command issued (SHOW BINLOG|RELAYLOG EVENTS).
sql/sql_yacc.yy:
Added RELAYLOG to the grammar.
If an EVENT is created without the DEFINER clause set explicitly or with it set
to CURRENT_USER, the master and slaves become inconsistent. This issue stems from
the fact that in both cases, the DEFINER is set to the CURRENT_USER of the current
thread. On the master, the CURRENT_USER is the mysqld's user, while on the slave,
the CURRENT_USER is empty for the SQL Thread which is responsible for executing
the statement.
To fix the problem, we do what follows. If the definer is not set explicitly,
a DEFINER clause is added when writing the query into binlog; if 'CURRENT_USER' is
used as the DEFINER, it is replaced with the value of the current user before
writing to binlog.
mysql-test/suite/rpl/r/rpl_create_if_not_exists.result:
Updated the result file after fixing bug#44331
mysql-test/suite/rpl/r/rpl_drop_if_exists.result:
Updated the result file after fixing bug#44331
mysql-test/suite/rpl/r/rpl_events.result:
Test result of Bug#44331
mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result:
Updated the result file after fixing bug#44331
mysql-test/suite/rpl/t/rpl_events.test:
Added test to verify if the definer is consistent between master and slave
when the event is created without the DEFINER clause set explicitly or the
DEFINER is set to CURRENT_USER
sql/events.cc:
The "create_query_string" function is added to create a new query string
for removing executable comments.
sql/sql_yacc.yy:
The remember_name token was added for recording the offset of EVENT_SYM.