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.
For application compatibility reasons MySQL converts "<autoincrement_column> IS NULL"
predicates to "<autoincrement_column> = LAST_INSERT_ID()" in the first SELECT following an
INSERT regardless of whether they're top level predicates or not. This causes wrong and
obscure results when these predicates are combined with others on the same columns. Fixed
by only doing the transformation on a single top-level predicate if a special SQL mode is
turned on (sql_auto_is_null).
Also made sql_auto_is_null off by default.
per-file comments:
mysql-test/r/func_isnull.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
test result updated
mysql-test/t/func_isnull.test
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
test case added
sql/mysqld.cc
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
sql_auto_is_null now is OFF by default.
sql/sql_select.cc
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
remove_eq_conds() split in two parts - one only checks the upper condition,
the req_remove_eq_conds() recursively checks all the condition tree.
mysql-test/extra/rpl_tests/rpl_insert_id.test
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
test fixed (set the sql_auto_is_null variable)
mysql-test/r/mysqlbinlog.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/r/mysqlbinlog2.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/r/odbc.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/r/query_cache.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/r/user_var-binlog.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/suite/rpl/r/rpl_insert_id.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/suite/rpl/r/rpl_sp.result
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
result updated
mysql-test/t/odbc.test
Bug#41371 Select returns 1 row with condition "col is not null and col is null"
test fixed (set the sql_auto_is_null variable)
The 'rpl_get_master_version_and_clock' test verifies if the slave I/O
thread tries to reconnect to master when it tries to get the values of
the UNIX_TIMESTAMP, SERVER_ID from master under network disconnection.
So the master server is restarted for making the transient network
disconnection. Restarting master server can bring two problems as following:
1. The time out error is encountered sporadically. The slave I/O thread tries
to reconnect master ten times, which is set in my.cnf. So in the test
framework sporadically the slave I/O thread really stoped when it can't
reconnect to master in the ten times successfully before the master starts,
then the time out error will be encountered while waiting for the slave to
start.
2. These warnings and errors are produced in server log file when
the slave I/O thread tries to get the values of the UNIX_TIMESTAMP,
SERVER_ID from master under the transient network disconnection.
To fix problem 1, increase the master retry count to sixty times,
so that the slave I/O thread has enough time to reconnect master
successfully.
To fix problem 2, suppress these warnings and errors by mtr suppression,
because they are expected.
mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt:
Added the *.opt file for increasing master retry count to
sixty times.
mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test:
Added mtr suppression for suppressing warnings and errors
in server log file.
binlog, replication aborts
In SBR or MBR, the schema name is not being written to the binlog
when executing a LOAD DATA statement. This becomes a problem when
the current database (lets call it db1) is different from the
table's schema (lets call it db2). For instance, take the
following statements:
use db1;
load data local infile 'infile.txt' into table db2.t
Should this statement be logged without t's schema (db2), when
replaying it, one can get db1.t populated instead of db2.t (if
db1.t exists). On the other hand, if there is no db1.t at all,
replication will stop.
We fix this by always logging the table (in load file) with fully
qualified name when its schema is different from the current
database or when no default database was selected.
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
Conflicts
=========
Text conflict in .bzr-mysql/default.conf
Text conflict in libmysqld/CMakeLists.txt
Text conflict in libmysqld/Makefile.am
Text conflict in mysql-test/collections/default.experimental
Text conflict in mysql-test/extra/rpl_tests/rpl_row_sp006.test
Text conflict in mysql-test/suite/binlog/r/binlog_tmp_table.result
Text conflict in mysql-test/suite/rpl/r/rpl_loaddata.result
Text conflict in mysql-test/suite/rpl/r/rpl_loaddata_fatal.result
Text conflict in mysql-test/suite/rpl/r/rpl_row_create_table.result
Text conflict in mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result
Text conflict in mysql-test/suite/rpl/r/rpl_stm_log.result
Text conflict in mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result
Text conflict in mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result
Text conflict in mysql-test/t/mysqlbinlog.test
Text conflict in sql/CMakeLists.txt
Text conflict in sql/Makefile.am
Text conflict in sql/log_event_old.cc
Text conflict in sql/rpl_rli.cc
Text conflict in sql/slave.cc
Text conflict in sql/sql_binlog.cc
Text conflict in sql/sql_lex.h
21 conflicts encountered.
NOTE
====
mysql-5.1-rpl-merge has been made a mirror of mysql-next-mr:
- "mysql-5.1-rpl-merge$ bzr pull ../mysql-next-mr"
This is the first cset (merge/...) committed after pulling
from mysql-next-mr.
Backporting BUG#43789 to mysql-5.1-bugteam
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.
Backporting BUG#38173 to mysql-5.1-bugteam
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.
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
A fix and a test case for Bug#34898 "mysql_info() reports 0 warnings
while mysql_warning_count() reports 1"
Review the patch by Chad Miller, implement review comments
(since Chad left) and push the patch.
This bug is actually not a bug. At least according to Monty.
See Bug#841 "wrong number of warnings" reported back in July 2003
and closed as "not a bug".
mysql_info() was printing the number of truncated columns, not
the number of warnings.
But since the message of mysql_info() was "Warnings: <number of truncated
columns>", people would expect to get the number
of warnings in it, not the number of truncated columns.
So a possible fix would be to change the message of mysql_info()
to say Rows changed: <n>, truncated: <m>.
Instead, put the number of warnings there. That is, remove the
feature that thd->cuted_fields (the number of truncated fields)
is exposed to the client. The number of truncated columns can be
calculated on the client, by analyzing SHOW WARNINGS output,
and in future we may remove thd->cuted_fields altogether.
So let's have one less thing to worry about.
client/mysqltest.cc:
Fix a bug in mysqltest program which used to return
a wrong number of affected rows in ps-protocol, and a wrong
mysql_info() information in both protocols in presence of warnings.
mysql-test/r/insert.result:
Update results (Bug#34898)
mysql-test/suite/rpl/r/rpl_udf.result:
Update to the changed output of mysqltest: mysql_info() is now printed
before warnings.
mysql-test/t/insert.test:
Add a test case for Bug#34898.
sql/sql_table.cc:
A fix for Bug#34898 - report statement warn count, not the
number of truncated values in mysql_info().
sql/sql_update.cc:
A fix for Bug#34898 - report statement warn count, not the
number of truncated values in mysql_info().
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.
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
Let
- T be a transactional table and N non-transactional table.
- B be begin, C commit and R rollback.
- N be a statement that accesses and changes only N-tables.
- T be a statement that accesses and changes only T-tables.
In RBR, changes to N-tables that happen early in a transaction are not immediately flushed
upon committing a statement. This behavior may, however, break consistency in the presence
of concurrency since changes done to N-tables become immediately visible to other
connections. To fix this problem, we do the following:
. B N N T C would log - B N C B N C B T C.
. B N N T R would log - B N C B N C B T R.
Note that we are not preserving history from the master as we are introducing a commit that
never happened. However, this seems to be more acceptable than the possibility of breaking
consistency in the presence of concurrency.
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.
The problem is that there is only one autoinc value associated with
the query when binlogging. If more than one autoinc values are used
in the query, the autoinc values after the first one can be inserted
wrongly on slave. So these autoinc values can become inconsistent on
master and slave.
The problem is resolved by marking all the statements that invoke
a trigger or call a function that updated autoinc fields as unsafe,
and will switch to row-format in Mixed mode. Actually, the statement
is safe if just one autoinc value is used in sub-statement, but it's
impossible to check how many autoinc values are used in sub-statement.)
mysql-test/suite/rpl/r/rpl_auto_increment_update_failure.result:
Test result for bug#45677
mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test:
Added test to verify the following two properties:
P1) insert/update in an autoinc column causes statement to
be logged in row format if binlog_format=mixed
P2) if binlog_format=mixed, and a trigger or function contains
two or more inserts/updates in a table that has an autoinc
column, then the slave should not go out of sync, even if
there are concurrent transactions.
sql/sql_base.cc:
Added function 'has_write_table_with_auto_increment' to check
if one (or more) write tables have auto_increment columns.
Removed function 'has_two_write_locked_tables_with_auto_increment',
because the function is included in function
'has_write_table_with_auto_increment'.