We must not reset the charset in slave after each statement, otherwise the SET CHARACTER SET is cancelled immediately.
Instead, we write a SET CHARACTER SET DEFAULT to the master's binlog when needed (like we already do for SET FOREIGN_KEY_CHECKS);
such writing is not necessary in 4.1 (in 4.1 the bug does not exist, as the SET ONE_SHOT syntax is used).
I have written a test and it works, but I'm not pushing the test as it requires building with all charsets.
I have noticed differences between what is inserted in the master's table in 4.0 and 4.1, and alerted Bar.
processlist on slave":
we now report in SHOW PROCESSLIST that we are writing to the temp
files or loading the table. When we are writing to the tmp file:
| 3 | system user | | | Connect | 6 | Making temp file /tmp/SQL_LOAD-2-1-2.data |
and when we are actually loading the .data temp file into the table:
| 3 | system user | | test | Connect | 2 | | LOAD DATA INFILE '/tmp/SQL_LOAD-2-1-2.data' INTO TABLE `t` <...> |
Fix remaining cases of Bug #3596: fix possible races caused by an obsolete value of thd->query_length in SHOW PROCESSLIST and SHOW INNODB STATUS; this fix depends on the fact that thd->query is always set to NULL before setting it to point to a new query
in hard-coded replication messages, always put small-length info (error codes, explanation of the error) at the beginning,
so that it is not cut by truncation if the query is very long (which happens if the query goes first).
too big by 6 bytes. So I add code to substract 6 bytes if the master is 3.23.
This is not perfect (because it won't work if the slave I/O thread has not
noticed yet that the master is 3.23), but as long as the slave I/O thread
starts Exec_master_log_pos will be ok.
It must be merged to 4.1 but not to 5.0 (or it can be, because of #if MYSQL_VERSION_ID),
because 5.0 already works if the master is 3.23 (and in a more natural way:
in 5.0 we store the end_log_pos in the binlog and relay log).
I had to move functions from slave.h to slave.cc to satisfy gcc.
We introduce a new function mysql_test_parse_for_slave().
If the slave sees that the query got a really bad error on master
(killed e.g.), then it calls this function to know if this query
can be ignored because of replicate-*-table rules (do not worry
about replicate-*-db rules: they are checked so early that they have
no bug). If the answer is yes, it skips the query and continues. If
it's no, then it stops and say "fix your slave data manually" (like it
did before this change).
- the one about BUG#2921
- the one about relay log flushing
Both will be rewritten in a next changeset
(this one will not be pushed before the next changeset).
INSERT DELAYED works only for one-row inserts (in latest 4.0 versions
at least). So killing a delayed_insert thread does not spoil replication:
the rows which actually went into the table are exactly those listed
in the binlog. So when the delayed_insert thread is killed, don't log
it as 'killed', because it causes superfluous stops on the slave.
"(binlog, position) stored by InnoDB for a replication slave can be wrong".
This code contains conditional #if to distinguish between versions;
it should be merged into 4.1 and 5.0.
reset errors (in thd) before executing the event. Otherwise if an event is ignored
because of replicate-*-table rules (error ER_SLAVE_IGNORED_TABLE) this error code
may remain in thd->net and the next event may pick it.
"EE_ error codes (EE_DELETE, EE_WRITE) end up in the binlog, making slave stop".
The problem was that during execution of the command on the master, an error
can occur (for example, not space left on device, then mysqld waits and when
there is space it completes successfully: so finally it worked but the error
EE_WRITE remains in thd->net.last_errno and thd->net.last_error).
To know if finally the command succeeded, we test the 'error' variable in
every place, and if it shows no failure we reset thd->net.last_err* using
the function THD::clear_error() which is backported from 4.1.
A new test to see if now only real errors get to the binlog (note: the test
uses "rm").
Also a bit of memory free/alloc saving in log_event.cc (do not free the whole
mem_root after every query in the slave SQL thread: we can keep the initial
block of it; which will be freed when the thread terminates).
The constructor of Rotate_log_event used when we are rotating our binlog or
relay log, should not assume that there is a nonzero THD available.
For example, when we are reacting to SIGHUP, the THD is 0.
In fact we don't need to use the THD in this constructor;
we can do like for Stop_log_event, and use the minimal Log_event
constructor.
If we were allowed to put Unix-specific commands in the testsuite,
I'd add a test for this (<sigh>).
- when we don't have in_addr_t, use uint32.
- a forgotten initialization of slave_proxy_id in sql/log_event.cc (was not really "forgot", was
"we needn't init it there", but there was one case where we needed...).
- made slave_proxy_id always meaningful in THD and Log_event, so we can
rely more on it (no need to test if it's meaningful). THD::slave_proxy_id
is equal to THD::thread_id except for the slave SQL thread.
- clean up the slave's temporary table (i.e. free their memory) when slave
server shuts down.
"If 2 master threads with same-name temp table, slave makes bad binlog"
and (two birds with one stone) for
BUG#1240 "slave of slave breaks when STOP SLAVE was issud on parent slave
and temp tables".
Here is the design change:
in a slave running with --log-slave-updates, events are now logged with the
thread id they had on the master. So no more id conflicts between master threads,
but introduces id conflicts between one master thread and one normal
client thread connected to the slave. This is solved by storing the server id
in the temp table's name.
New test which requires mysql-test-run to be run with --manager,
otherwise it will be skipped.
Undoing a Monty's change (hum, a chill runs down my spine ;) which was
"Cleanup temporary tables when slave ends" in ChangeSet 1.1572.1.1.
query_alloc_block_size, query_prealloc_size, range_alloc_block_size,transaction_alloc_block_size and transaction_prealloc_size
Add more checks for "out of memory" detection in range optimization
Rotate_log_event::exec_event() believed that the relay log was corrupted. Fixed it
by moving the test for corruption to Start_log_event::exec_event().
Changed Rotate_log_event::exec_event() to not increment positions when the
event is seen in the middle of a transaction.
I did a separate commit in 4.1 (so this should not be merged to 4.0) because
code is a bit different in 4.1.
A test to see if the slave detects when the master died while writing a
transaction to the binlog (uses a forged truncated binlog I made).
Add quoting for use `database` for mysqlbinlog
Removed test ins0000001
Add support for --replace for exec in mysqltest
Don't refer to install dir in mysqlbinlog.result
Bug #1392 "On Win, slave leaves one temp file after successf. replicating LOAD DATA INFILE"
Windows-specific bug (we forgot to close a file before deleting it).
Patch written by me, tested by Miguel (thanks!) and it works.
when the SQL thread stops, set rli->inside_transaction to 0. This is needed if the user
later restarts replication from a completely different place where there are only autocommit
statements.
* Detect the case where the master died while flushing the binlog cache to the binlog
and stop with error. Cannot add a testcase for this in 4.0 (I tested it manually)
as the slave always runs with --skip-innodb.
fix for BUG#1113 "INSERT into non-trans table SELECT ; ROLLBACK" does not send warning"
and
fix for BUG#873 "In transaction, INSERT to non-trans table is written too early to binlog".
Now we don't always write the non-trans update immediately to the binlog;
if there is something in the binlog cache we write it to the binlog cache
(because the non-trans update could depend on a trans table which was modified
earlier in the transaction); then in case of ROLLBACK, we write the binlog
cache to the binlog, wrapped with BEGIN/ROLLBACK.
This guarantees that the slave does the same updates.
For ROLLBACK TO SAVEPOINT: when we execute a SAVEPOINT command we write it
to the binlog cache. At ROLLBACK TO SAVEPOINT, if some non-trans table was updated,
we write ROLLBACK TO SAVEPOINT to the binlog cache; when the transaction
terminates (COMMIT/ROLLBACK), the binlog cache will be flushed to the binlog
(because of the non-trans update) so we'll have SAVEPOINT and ROLLBACK TO
SAVEPOINT in the binlog.
Apart from this rare case of updates of mixed table types in transaction, the
usual way is still clear the binlog cache at ROLLBACK, or chop it at
ROLLBACK TO SAVEPOINT (meaning the SAVEPOINT command is also chopped, which
is fine).
Note that BUG#873 encompasses subbugs 1) and 2) of BUG#333 "3 binlogging bugs when doing INSERT with mixed InnoDB/MyISAM".
"LOAD DATA INFILE is badly filtered by binlog-*-db rules".
There will probably be a second final one to merge Dmitri's changes
to rpl_log.result and mine.
2 new tests:
rpl_loaddata_rule_m : test of logging of LOAD DATA INFILE when the master has binlog-*-db rules,
rpl_loaddata_rule_s : test of logging of LOAD DATA INFILE when the slave has binlog-*-db rules and --log-slave-updates.
log-slave-updates since this causes unexpected values in
Exec_master_log_pos in A->B->C replication setup, synchronization
problems in master_pos_wait()...
Still this brokes some functionality in sql/repl_failsafe.cc
(but this file is not used now)
the first 4 bytes of the relay log. Indeed comments in mysys/mf_iocache.c
say we must always use my_b_append for such a cache.
This *could* avoid a very rare assertion failure which is:
030524 19:32:38 Slave SQL thread initialized, starting replication in log 'FIRST' at position 0, relay log '/
users/gbichot/4.1.1/mysql-test/var/log/slave-relay-bin.000001' position: 4
030524 19:32:38 next log '/users/gbichot/4.1.1/mysql-test/var/log/slave-relay-bin.000002' is currently active
mysqld: mf_iocache.c:701: _my_b_seq_read: Assertion `pos_in_file == info->end_of_file' failed.
and which seemed to happen always when the SQL thread and/or the I/O thread
were at position 4 in a relay log.
I extended the task to cleaning error messages, making them look nicer,
and making the output of SHOW SLAVE STATUS (column Last_error) be as complete
as what's printed on the .err file;
previously we would have, for a failure of a replicated LOAD DATA INFILE:
- in the .err, 2 lines:
"duplicate entry 2708 for key 1"
"failed loading SQL_LOAD-5-2-2.info"
- and in SHOW SLAVE STATUS, only:
"failed loading SQL_LOAD-5-2-2.info".
Now SHOW SLAVE STATUS will contain the concatenation of the 2 messages.
BUG#797 "If query ignored on slave (replicate-ignore-table) the slave still checks if
the returned error (0) is the same as the one on the master, whereas it shouldn't
test this.
Plus a new test for BUG#797.