2004-09-09 03:26:19 +02:00
|
|
|
/* Copyright (C) 2000-2003 MySQL AB
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2004-09-09 03:26:19 +02:00
|
|
|
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 Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2004-09-09 03:26:19 +02:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2004-09-09 03:26:19 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
2003-01-15 09:11:44 +01:00
|
|
|
#ifdef HAVE_REPLICATION
|
2002-12-16 14:33:29 +01:00
|
|
|
|
2000-11-11 22:50:39 +01:00
|
|
|
#ifndef SLAVE_H
|
|
|
|
#define SLAVE_H
|
|
|
|
|
2001-05-29 03:18:23 +02:00
|
|
|
#include "mysql.h"
|
2002-01-20 03:16:52 +01:00
|
|
|
#include "my_list.h"
|
2001-07-17 22:22:52 +02:00
|
|
|
#define SLAVE_NET_TIMEOUT 3600
|
2002-01-20 03:16:52 +01:00
|
|
|
#define MAX_SLAVE_ERRMSG 1024
|
2002-01-22 23:05:11 +01:00
|
|
|
#define MAX_SLAVE_ERROR 2000
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
|
|
|
|
MySQL Replication
|
|
|
|
|
|
|
|
Replication is implemented via two types of threads:
|
|
|
|
|
|
|
|
I/O Thread - One of these threads is started for each master server.
|
|
|
|
They maintain a connection to their master server, read log
|
|
|
|
events from the master as they arrive, and queues them into
|
|
|
|
a single, shared relay log file. A MASTER_INFO struct
|
|
|
|
represents each of these threads.
|
|
|
|
|
|
|
|
SQL Thread - One of these threads is started and reads from the relay log
|
|
|
|
file, executing each event. A RELAY_LOG_INFO struct
|
|
|
|
represents this thread.
|
|
|
|
|
|
|
|
Buffering in the relay log file makes it unnecessary to reread events from
|
|
|
|
a master server across a slave restart. It also decouples the slave from
|
|
|
|
the master where long-running updates and event logging are concerned--ie
|
|
|
|
it can continue to log new events while a slow query executes on the slave.
|
|
|
|
|
|
|
|
*****************************************************************************/
|
2001-07-17 22:22:52 +02:00
|
|
|
|
2003-08-25 16:20:21 +02:00
|
|
|
/*
|
|
|
|
MUTEXES in replication:
|
|
|
|
|
Fix for BUG#2921 "Replication problem on mutex lock in mySQL-4.0.18":
re-using unused LOCK_active_mi to serialize all administrative
commands related to replication:
START SLAVE, STOP SLAVE, RESET SLAVE, CHANGE MASTER, init_slave()
(replication autostart at server startup), end_slave() (replication
autostop at server shutdown), LOAD DATA FROM MASTER.
This protects us against a handful of deadlocks (like BUG#2921
when two START SLAVE, but when two STOP SLAVE too).
Removing unused variables.
sql/item_func.cc:
We don't need LOCK_active_mi just to MASTER_POS_WAIT().
sql/repl_failsafe.cc:
no need for macro
sql/set_var.cc:
no need for macro
sql/slave.cc:
Re-using unused LOCK_active_mi to serialize all administrative
commands related to replication:
START SLAVE, STOP SLAVE, RESET SLAVE, CHANGE MASTER, init_slave()
(replication autostart at server startup), end_slave() (replication
autostop at server shutdown), LOAD DATA FROM MASTER.
This protects us against a handful of deadlocks.
Removing unused variables.
sql/slave.h:
Re-using LOCK_active_mi to serialize administrative replication commands.
Macros unneeded. Removing unneeded variables.
sql/sql_parse.cc:
found unused variable.
Replacing macros.
sql/sql_show.cc:
replacing macros
2004-03-11 16:23:35 +01:00
|
|
|
LOCK_active_mi: [note: this was originally meant for multimaster, to switch
|
|
|
|
from a master to another, to protect active_mi] It is used to SERIALIZE ALL
|
|
|
|
administrative commands of replication: START SLAVE, STOP SLAVE, CHANGE
|
|
|
|
MASTER, RESET SLAVE, end_slave() (when mysqld stops) [init_slave() does not
|
|
|
|
need it it's called early]. Any of these commands holds the mutex from the
|
|
|
|
start till the end. This thus protects us against a handful of deadlocks
|
|
|
|
(consider start_slave_thread() which, when starting the I/O thread, releases
|
|
|
|
mi->run_lock, keeps rli->run_lock, and tries to re-acquire mi->run_lock).
|
|
|
|
|
|
|
|
Currently active_mi never moves (it's created at startup and deleted at
|
|
|
|
shutdown, and not changed: it always points to the same MASTER_INFO struct),
|
|
|
|
because we don't have multimaster. So for the moment, mi does not move, and
|
|
|
|
mi->rli does not either.
|
2003-08-25 16:20:21 +02:00
|
|
|
|
|
|
|
In MASTER_INFO: run_lock, data_lock
|
|
|
|
run_lock protects all information about the run state: slave_running, and the
|
|
|
|
existence of the I/O thread (to stop/start it, you need this mutex).
|
|
|
|
data_lock protects some moving members of the struct: counters (log name,
|
|
|
|
position) and relay log (MYSQL_LOG object).
|
|
|
|
|
|
|
|
In RELAY_LOG_INFO: run_lock, data_lock
|
|
|
|
see MASTER_INFO
|
|
|
|
|
Fix for BUG#2921 "Replication problem on mutex lock in mySQL-4.0.18":
re-using unused LOCK_active_mi to serialize all administrative
commands related to replication:
START SLAVE, STOP SLAVE, RESET SLAVE, CHANGE MASTER, init_slave()
(replication autostart at server startup), end_slave() (replication
autostop at server shutdown), LOAD DATA FROM MASTER.
This protects us against a handful of deadlocks (like BUG#2921
when two START SLAVE, but when two STOP SLAVE too).
Removing unused variables.
sql/item_func.cc:
We don't need LOCK_active_mi just to MASTER_POS_WAIT().
sql/repl_failsafe.cc:
no need for macro
sql/set_var.cc:
no need for macro
sql/slave.cc:
Re-using unused LOCK_active_mi to serialize all administrative
commands related to replication:
START SLAVE, STOP SLAVE, RESET SLAVE, CHANGE MASTER, init_slave()
(replication autostart at server startup), end_slave() (replication
autostop at server shutdown), LOAD DATA FROM MASTER.
This protects us against a handful of deadlocks.
Removing unused variables.
sql/slave.h:
Re-using LOCK_active_mi to serialize administrative replication commands.
Macros unneeded. Removing unneeded variables.
sql/sql_parse.cc:
found unused variable.
Replacing macros.
sql/sql_show.cc:
replacing macros
2004-03-11 16:23:35 +01:00
|
|
|
Order of acquisition: if you want to have LOCK_active_mi and a run_lock, you
|
|
|
|
must acquire LOCK_active_mi first.
|
|
|
|
|
2003-08-25 16:20:21 +02:00
|
|
|
In MYSQL_LOG: LOCK_log, LOCK_index of the binlog and the relay log
|
|
|
|
LOCK_log: when you write to it. LOCK_index: when you create/delete a binlog
|
|
|
|
(so that you have to update the .index file).
|
|
|
|
*/
|
|
|
|
|
2003-06-04 07:57:42 +02:00
|
|
|
extern ulong master_retry_count;
|
2002-01-22 23:05:11 +01:00
|
|
|
extern MY_BITMAP slave_error_mask;
|
|
|
|
extern bool use_slave_mask;
|
2001-08-03 23:57:53 +02:00
|
|
|
extern char* slave_load_tmpdir;
|
2002-01-20 03:16:52 +01:00
|
|
|
extern my_string master_info_file,relay_log_info_file;
|
|
|
|
extern my_string opt_relay_logname, opt_relaylog_index_name;
|
2002-08-22 15:50:58 +02:00
|
|
|
extern my_bool opt_skip_slave_start, opt_reckless_slave;
|
|
|
|
extern my_bool opt_log_slave_updates;
|
2002-08-23 14:14:01 +02:00
|
|
|
extern ulonglong relay_log_space_limit;
|
2002-01-20 03:16:52 +01:00
|
|
|
struct st_master_info;
|
|
|
|
|
A change of behaviour of Seconds_Behind_Master from SHOW SLAVE STATUS. It's going into 4.1
because old behaviour was somewhat nonsensical (kind of bug). Changes are that if repl threads are
down or disconnected the column will be NULL, and if master is idle the column will not grow indefinitely anymore.
sql/slave.cc:
mi->slave_running and rli->slave_running now uints (was needed only for mi but because of start_slave_thread() usage,
had to change both).
So mi->slave_running can now take 3 values: not running, running & not connected, running and connected.
The last value serves for calculation of Seconds_Behind_Master in SHOW SLAVE STATUS.
Changing this column's behaviour: if SQL or I/O thread is not running, or if I/O thread is not connected
(for example if it is reconnecting), it's NULL (to mean "unknown"). And if master is idle, the column will
not grow indefinitely like it used to (that was meaningless); this is fixed by forcing a value of 0
when the slave SQL thread has hit EOF of relay log (which has only a limited number of caveats explained
in comments in code).
sql/slave.h:
slave_running used to be bool but we need to distinguish, for the I/O slave thread, between
"running & connected" and "running & not connected" ("running" means the thread exists).
sql/sql_repl.cc:
we don't need anymore to set rli->last_master_timestamp to 0 (we used that to make Seconds_Behind_Master
be NULL) in RESET SLAVE and CHANGE MASTER, as these commands imply that slave threads are not running
and so Seconds_Behind_Master is already NULL because of that.
2004-12-16 18:12:22 +01:00
|
|
|
/*
|
|
|
|
3 possible values for MASTER_INFO::slave_running and
|
|
|
|
RELAY_LOG_INFO::slave_running.
|
|
|
|
The values 0,1,2 are very important: to keep the diff small, I didn't
|
|
|
|
substitute places where we use 0/1 with the newly defined symbols. So don't change
|
|
|
|
these values.
|
|
|
|
The same way, code is assuming that in RELAY_LOG_INFO we use only values
|
|
|
|
0/1.
|
|
|
|
I started with using an enum, but
|
|
|
|
enum_variable=1; is not legal so would have required many line changes.
|
|
|
|
*/
|
|
|
|
#define MYSQL_SLAVE_NOT_RUN 0
|
|
|
|
#define MYSQL_SLAVE_RUN_NOT_CONNECT 1
|
|
|
|
#define MYSQL_SLAVE_RUN_CONNECT 2
|
|
|
|
|
2004-03-17 09:30:40 +01:00
|
|
|
/****************************************************************************
|
2002-10-29 23:12:47 +01:00
|
|
|
|
|
|
|
Replication SQL Thread
|
|
|
|
|
|
|
|
st_relay_log_info contains:
|
|
|
|
- the current relay log
|
|
|
|
- the current relay log offset
|
|
|
|
- master log name
|
|
|
|
- master log sequence corresponding to the last update
|
|
|
|
- misc information specific to the SQL thread
|
2002-01-20 03:16:52 +01:00
|
|
|
|
|
|
|
st_relay_log_info is initialized from the slave.info file if such exists.
|
|
|
|
Otherwise, data members are intialized with defaults. The initialization is
|
|
|
|
done with init_relay_log_info() call.
|
|
|
|
|
|
|
|
The format of slave.info file:
|
|
|
|
|
|
|
|
relay_log_name
|
|
|
|
relay_log_pos
|
|
|
|
master_log_name
|
|
|
|
master_log_pos
|
|
|
|
|
|
|
|
To clean up, call end_relay_log_info()
|
2002-10-29 23:12:47 +01:00
|
|
|
|
|
|
|
*****************************************************************************/
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
typedef struct st_relay_log_info
|
|
|
|
{
|
2002-01-29 17:32:16 +01:00
|
|
|
/*** The following variables can only be read when protect by data lock ****/
|
2002-06-11 10:20:31 +02:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
info_fd - file descriptor of the info file. set only during
|
|
|
|
initialization or clean up - safe to read anytime
|
|
|
|
cur_log_fd - file descriptor of the current read relay log
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
File info_fd,cur_log_fd;
|
2002-01-29 17:32:16 +01:00
|
|
|
|
|
|
|
/*
|
2002-06-05 22:04:38 +02:00
|
|
|
Protected with internal locks.
|
|
|
|
Must get data_lock when resetting the logs.
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
|
|
|
MYSQL_LOG relay_log;
|
|
|
|
LOG_INFO linfo;
|
|
|
|
IO_CACHE cache_buf,*cur_log;
|
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* The following variables are safe to read any time */
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* IO_CACHE of the info file - set only during init or end */
|
2002-01-29 17:32:16 +01:00
|
|
|
IO_CACHE info_file;
|
2001-05-29 03:18:23 +02:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
When we restart slave thread we need to have access to the previously
|
|
|
|
created temporary tables. Modified only on init/end and by the SQL
|
|
|
|
thread, read only by SQL thread.
|
|
|
|
*/
|
2003-01-28 07:38:28 +01:00
|
|
|
TABLE *save_temporary_tables;
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
standard lock acquistion order to avoid deadlocks:
|
|
|
|
run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_t data_lock,run_lock;
|
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
start_cond is broadcast when SQL thread is started
|
|
|
|
stop_cond - when stopped
|
|
|
|
data_cond - when data protected by data_lock changes
|
|
|
|
*/
|
|
|
|
pthread_cond_t start_cond, stop_cond, data_cond;
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* parent master info structure */
|
2002-01-20 03:16:52 +01:00
|
|
|
struct st_master_info *mi;
|
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
Needed to deal properly with cur_log getting closed and re-opened with
|
|
|
|
a different log under our feet
|
2002-01-20 03:16:52 +01:00
|
|
|
*/
|
2002-06-05 22:04:38 +02:00
|
|
|
uint32 cur_log_old_open_count;
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
Replication: new code to not modify in-memory log positions until the COMMIT
is executed, even if the transaction spans on >=2 relay logs (bug #53).
New variable relay_log_purge =0|1
New test to verify bug #53
sql/log.cc:
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT.
sql/log_event.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/mysql_priv.h:
new option relay_log_purge (the user can now decide himself
if he wants his relay logs to be automatically purged or not,
we don't make unsafe guesses like before)
sql/mysqld.cc:
new option --innodb (replaces --skip-innodb).
Useful for the test suite : we have skip-innodb in mysql-test-run,
but we can ('-opt.info' file) choose to start the server with
InnoDB for this test only.
New option --bdb
sql/repl_failsafe.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/set_var.cc:
new variable relay_log_purge
sql/slave.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT
sql/slave.h:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/sql_class.h:
prototypes change
sql/sql_parse.cc:
removed thd argument (was not used in the function's body)
sql/sql_repl.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Turn relay_log_purge silently off when someone does CHANGE
MASTER TO RELAY_LOG_*
2003-04-24 15:29:25 +02:00
|
|
|
Let's call a group (of events) :
|
|
|
|
- a transaction
|
|
|
|
or
|
|
|
|
- an autocommiting query + its associated events (INSERT_ID,
|
|
|
|
TIMESTAMP...)
|
|
|
|
We need these rli coordinates :
|
|
|
|
- relay log name and position of the beginning of the group we currently are
|
|
|
|
executing. Needed to know where we have to restart when replication has
|
|
|
|
stopped in the middle of a group (which has been rolled back by the slave).
|
|
|
|
- relay log name and position just after the event we have just
|
|
|
|
executed. This event is part of the current group.
|
|
|
|
Formerly we only had the immediately above coordinates, plus a 'pending'
|
|
|
|
variable, but this dealt wrong with the case of a transaction starting on a
|
|
|
|
relay log and finishing (commiting) on another relay log. Case which can
|
|
|
|
happen when, for example, the relay log gets rotated because of
|
|
|
|
max_binlog_size.
|
|
|
|
*/
|
|
|
|
char group_relay_log_name[FN_REFLEN];
|
|
|
|
ulonglong group_relay_log_pos;
|
|
|
|
char event_relay_log_name[FN_REFLEN];
|
|
|
|
ulonglong event_relay_log_pos;
|
This will be pushed only after I fix the testsuite.
This is the main commit for Worklog tasks:
* A more dynamic binlog format which allows small changes (1064)
* Log session variables in Query_log_event (1063)
Below 5.0 means 5.0.0.
MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed),
SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think
of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this
works for queries, except LOAD DATA INFILE (for this it would have to wait
for Dmitri's push of WL#874, which in turns waits for the present push, so...
the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1,
5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1.
Apart from that, the new binlog format is designed so that it can tolerate
a little variation in the events (so that a 5.0.0 slave could replicate a
5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I
later add replication of charsets it should break nothing. And when I later
add a UID to every event, it should break nothing.
The main change brought by this patch is a new type of event, Format_description_log_event,
which describes some lengthes in other event types. This event is needed for
the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event,
we can later add more bytes to the header of every event without breaking compatibility.
Inside Query_log_event, we have some additional dynamic format, as every Query_log_event
can have a different number of status variables, stored as pairs (code, value); that's
how SQL_MODE and session variables and catalog are stored. Like this, we can later
add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows
if we want.
MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs.
Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs),
upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs);
so both can be "hot" upgrades.
Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0.
3.23 and 4.x can't be slaves of 5.0.
So downgrading from 5.0 to 4.x may be complicated.
Log_event::log_pos is now the position of the end of the event, which is
more useful than the position of the beginning. We take care about compatibility
with <5.0 (in which log_pos is the beginning).
I added a short test for replication of SQL_MODE and some other variables.
TODO:
- after committing this, merge the latest 5.0 into it
- fix all tests
- update the manual with upgrade notes.
client/Makefile.am:
mysqlbinlog.cc depends slightly on sql/mysql_priv.h
client/mysqlbinlog.cc:
Make mysqlbinlog able to read the new binlog format,
by seeking to the start and reading the first few events, to
detect the format of the binlog.
include/my_sys.h:
a correct tell() for SEQ_READ_APPEND caches.
mysys/mf_iocache2.c:
a correct tell() for SEQ_READ_APPEND caches
(my_b_tell() is not working for such caches).
sql/ha_innodb.cc:
we are getting rid of event lengthes here and there, which is good.
sql/log.cc:
Start events will have created==0 if generated by rotation (like in 3.23).
In 5.0 we always write a Format_description_log_event at the beginning of
every master's binary log and of every slave's relay log.
We also add Rotate and Stop to relay logs (like there already was in
master's binary logs).
When we rotate a relay log, we write the previous relay log's Start event
(the one which was sent from the master) to the beginning of the new log,
so that we don't need the previous relay log to understand the new one;
that's the purpose of MYSQL_LOG::description_event_for_queue.
Removed logging of SET FOREIGN_KEY_CHECKS, because we handle it as flags
in the Query event now.
sql/log_event.cc:
New event type: Format_description_log_event, to describe the log's format.
read_log_event() needs to be passed this event to be able to read 5.0 events.
Query_log_event has new members flags2 and sql_mode for replication of session
variables (except charsets which are WL#1062) and SQL_MODE.
flags2 is in fact a kind of copy of thd->options (&'d with a mask).
Now with this replication of FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS
and SQL_MODE work; with mysqlbinlog too.
sql/log_event.h:
Binlog version is changed to 4.
New classes (details in sql/log_event.cc).
Removing some useless #defines.
sql/mysql_priv.h:
Definition of SELECT_DISTINCT and others must be visible in client/mysqlbinlog.cc,
so adding #ifdefs.
sql/mysqld.cc:
update for prototype change
sql/slave.cc:
When the slave opens a relay log, it reads the first few events to know the format.
When slave I/O thread receives a Rotate from the master, it rotates its relay log
(to avoid mixed format in the relay log).
sql/slave.h:
in the slave we avoid lengthes and rely on absolute positions instead;
hence the introduction of future_group_master_log_pos and future_event_relay_log_pos
(explained in code).
sql/sql_class.cc:
catalog in THD
sql/sql_class.h:
catalog, and new members in MYSQL_LOG
sql/sql_repl.cc:
When the master starts sending binlog to slave, it must
first read the first few events to detect the binlog's format.
Same for SHOW BINLOG EVENTS.
2003-12-18 01:09:05 +01:00
|
|
|
ulonglong future_event_relay_log_pos;
|
|
|
|
|
Replication: new code to not modify in-memory log positions until the COMMIT
is executed, even if the transaction spans on >=2 relay logs (bug #53).
New variable relay_log_purge =0|1
New test to verify bug #53
sql/log.cc:
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT.
sql/log_event.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/mysql_priv.h:
new option relay_log_purge (the user can now decide himself
if he wants his relay logs to be automatically purged or not,
we don't make unsafe guesses like before)
sql/mysqld.cc:
new option --innodb (replaces --skip-innodb).
Useful for the test suite : we have skip-innodb in mysql-test-run,
but we can ('-opt.info' file) choose to start the server with
InnoDB for this test only.
New option --bdb
sql/repl_failsafe.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/set_var.cc:
new variable relay_log_purge
sql/slave.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT
sql/slave.h:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/sql_class.h:
prototypes change
sql/sql_parse.cc:
removed thd argument (was not used in the function's body)
sql/sql_repl.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Turn relay_log_purge silently off when someone does CHANGE
MASTER TO RELAY_LOG_*
2003-04-24 15:29:25 +02:00
|
|
|
/*
|
|
|
|
Original log name and position of the group we're currently executing
|
|
|
|
(whose coordinates are group_relay_log_name/pos in the relay log)
|
|
|
|
in the master's binlog. These concern the *group*, because in the master's
|
|
|
|
binlog the log_pos that comes with each event is the position of the
|
|
|
|
beginning of the group.
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
Replication: new code to not modify in-memory log positions until the COMMIT
is executed, even if the transaction spans on >=2 relay logs (bug #53).
New variable relay_log_purge =0|1
New test to verify bug #53
sql/log.cc:
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT.
sql/log_event.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/mysql_priv.h:
new option relay_log_purge (the user can now decide himself
if he wants his relay logs to be automatically purged or not,
we don't make unsafe guesses like before)
sql/mysqld.cc:
new option --innodb (replaces --skip-innodb).
Useful for the test suite : we have skip-innodb in mysql-test-run,
but we can ('-opt.info' file) choose to start the server with
InnoDB for this test only.
New option --bdb
sql/repl_failsafe.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/set_var.cc:
new variable relay_log_purge
sql/slave.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT
sql/slave.h:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/sql_class.h:
prototypes change
sql/sql_parse.cc:
removed thd argument (was not used in the function's body)
sql/sql_repl.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Turn relay_log_purge silently off when someone does CHANGE
MASTER TO RELAY_LOG_*
2003-04-24 15:29:25 +02:00
|
|
|
char group_master_log_name[FN_REFLEN];
|
|
|
|
volatile my_off_t group_master_log_pos;
|
2003-03-17 22:51:56 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Handling of the relay_log_space_limit optional constraint.
|
|
|
|
ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
|
2003-10-01 18:40:27 +02:00
|
|
|
threads, the SQL thread sets it to unblock the I/O thread and make it
|
2003-10-02 16:25:47 +02:00
|
|
|
temporarily forget about the constraint.
|
2003-03-17 22:51:56 +01:00
|
|
|
*/
|
2002-06-05 22:04:38 +02:00
|
|
|
ulonglong log_space_limit,log_space_total;
|
2003-03-17 22:51:56 +01:00
|
|
|
bool ignore_log_space_limit;
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
/*
|
2004-03-01 15:15:58 +01:00
|
|
|
When it commits, InnoDB internally stores the master log position it has
|
|
|
|
processed so far; the position to store is the one of the end of the
|
|
|
|
committing event (the COMMIT query event, or the event if in autocommit
|
|
|
|
mode).
|
2002-08-08 02:12:02 +02:00
|
|
|
*/
|
2004-03-01 15:15:58 +01:00
|
|
|
#if MYSQL_VERSION_ID < 40100
|
|
|
|
ulonglong future_master_log_pos;
|
|
|
|
#else
|
This will be pushed only after I fix the testsuite.
This is the main commit for Worklog tasks:
* A more dynamic binlog format which allows small changes (1064)
* Log session variables in Query_log_event (1063)
Below 5.0 means 5.0.0.
MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed),
SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think
of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this
works for queries, except LOAD DATA INFILE (for this it would have to wait
for Dmitri's push of WL#874, which in turns waits for the present push, so...
the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1,
5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1.
Apart from that, the new binlog format is designed so that it can tolerate
a little variation in the events (so that a 5.0.0 slave could replicate a
5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I
later add replication of charsets it should break nothing. And when I later
add a UID to every event, it should break nothing.
The main change brought by this patch is a new type of event, Format_description_log_event,
which describes some lengthes in other event types. This event is needed for
the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event,
we can later add more bytes to the header of every event without breaking compatibility.
Inside Query_log_event, we have some additional dynamic format, as every Query_log_event
can have a different number of status variables, stored as pairs (code, value); that's
how SQL_MODE and session variables and catalog are stored. Like this, we can later
add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows
if we want.
MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs.
Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs),
upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs);
so both can be "hot" upgrades.
Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0.
3.23 and 4.x can't be slaves of 5.0.
So downgrading from 5.0 to 4.x may be complicated.
Log_event::log_pos is now the position of the end of the event, which is
more useful than the position of the beginning. We take care about compatibility
with <5.0 (in which log_pos is the beginning).
I added a short test for replication of SQL_MODE and some other variables.
TODO:
- after committing this, merge the latest 5.0 into it
- fix all tests
- update the manual with upgrade notes.
client/Makefile.am:
mysqlbinlog.cc depends slightly on sql/mysql_priv.h
client/mysqlbinlog.cc:
Make mysqlbinlog able to read the new binlog format,
by seeking to the start and reading the first few events, to
detect the format of the binlog.
include/my_sys.h:
a correct tell() for SEQ_READ_APPEND caches.
mysys/mf_iocache2.c:
a correct tell() for SEQ_READ_APPEND caches
(my_b_tell() is not working for such caches).
sql/ha_innodb.cc:
we are getting rid of event lengthes here and there, which is good.
sql/log.cc:
Start events will have created==0 if generated by rotation (like in 3.23).
In 5.0 we always write a Format_description_log_event at the beginning of
every master's binary log and of every slave's relay log.
We also add Rotate and Stop to relay logs (like there already was in
master's binary logs).
When we rotate a relay log, we write the previous relay log's Start event
(the one which was sent from the master) to the beginning of the new log,
so that we don't need the previous relay log to understand the new one;
that's the purpose of MYSQL_LOG::description_event_for_queue.
Removed logging of SET FOREIGN_KEY_CHECKS, because we handle it as flags
in the Query event now.
sql/log_event.cc:
New event type: Format_description_log_event, to describe the log's format.
read_log_event() needs to be passed this event to be able to read 5.0 events.
Query_log_event has new members flags2 and sql_mode for replication of session
variables (except charsets which are WL#1062) and SQL_MODE.
flags2 is in fact a kind of copy of thd->options (&'d with a mask).
Now with this replication of FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS
and SQL_MODE work; with mysqlbinlog too.
sql/log_event.h:
Binlog version is changed to 4.
New classes (details in sql/log_event.cc).
Removing some useless #defines.
sql/mysql_priv.h:
Definition of SELECT_DISTINCT and others must be visible in client/mysqlbinlog.cc,
so adding #ifdefs.
sql/mysqld.cc:
update for prototype change
sql/slave.cc:
When the slave opens a relay log, it reads the first few events to know the format.
When slave I/O thread receives a Rotate from the master, it rotates its relay log
(to avoid mixed format in the relay log).
sql/slave.h:
in the slave we avoid lengthes and rely on absolute positions instead;
hence the introduction of future_group_master_log_pos and future_event_relay_log_pos
(explained in code).
sql/sql_class.cc:
catalog in THD
sql/sql_class.h:
catalog, and new members in MYSQL_LOG
sql/sql_repl.cc:
When the master starts sending binlog to slave, it must
first read the first few events to detect the binlog's format.
Same for SHOW BINLOG EVENTS.
2003-12-18 01:09:05 +01:00
|
|
|
ulonglong future_group_master_log_pos;
|
2004-03-01 15:15:58 +01:00
|
|
|
#endif
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2003-10-09 00:06:21 +02:00
|
|
|
time_t last_master_timestamp;
|
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
Needed for problems when slave stops and we want to restart it
|
|
|
|
skipping one or more events in the master log that have caused
|
|
|
|
errors, and have been manually applied by DBA already.
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
volatile uint32 slave_skip_counter;
|
2002-08-21 21:04:22 +02:00
|
|
|
volatile ulong abort_pos_wait; /* Incremented on change master */
|
2002-08-24 04:44:16 +02:00
|
|
|
volatile ulong slave_run_id; /* Incremented on slave start */
|
2002-06-05 22:04:38 +02:00
|
|
|
pthread_mutex_t log_space_lock;
|
|
|
|
pthread_cond_t log_space_cond;
|
|
|
|
THD * sql_thd;
|
|
|
|
int last_slave_errno;
|
2002-01-20 03:16:52 +01:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
int events_till_abort;
|
|
|
|
#endif
|
|
|
|
char last_slave_error[MAX_SLAVE_ERRMSG];
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* if not set, the value of other members of the structure are undefined */
|
2002-06-05 22:04:38 +02:00
|
|
|
bool inited;
|
A change of behaviour of Seconds_Behind_Master from SHOW SLAVE STATUS. It's going into 4.1
because old behaviour was somewhat nonsensical (kind of bug). Changes are that if repl threads are
down or disconnected the column will be NULL, and if master is idle the column will not grow indefinitely anymore.
sql/slave.cc:
mi->slave_running and rli->slave_running now uints (was needed only for mi but because of start_slave_thread() usage,
had to change both).
So mi->slave_running can now take 3 values: not running, running & not connected, running and connected.
The last value serves for calculation of Seconds_Behind_Master in SHOW SLAVE STATUS.
Changing this column's behaviour: if SQL or I/O thread is not running, or if I/O thread is not connected
(for example if it is reconnecting), it's NULL (to mean "unknown"). And if master is idle, the column will
not grow indefinitely like it used to (that was meaningless); this is fixed by forcing a value of 0
when the slave SQL thread has hit EOF of relay log (which has only a limited number of caveats explained
in comments in code).
sql/slave.h:
slave_running used to be bool but we need to distinguish, for the I/O slave thread, between
"running & connected" and "running & not connected" ("running" means the thread exists).
sql/sql_repl.cc:
we don't need anymore to set rli->last_master_timestamp to 0 (we used that to make Seconds_Behind_Master
be NULL) in RESET SLAVE and CHANGE MASTER, as these commands imply that slave threads are not running
and so Seconds_Behind_Master is already NULL because of that.
2004-12-16 18:12:22 +01:00
|
|
|
volatile bool abort_slave;
|
|
|
|
volatile uint slave_running;
|
2002-12-11 14:46:39 +01:00
|
|
|
|
2003-09-13 22:13:41 +02:00
|
|
|
/*
|
|
|
|
Condition and its parameters from START SLAVE UNTIL clause.
|
|
|
|
|
|
|
|
UNTIL condition is tested with is_until_satisfied() method that is
|
|
|
|
called by exec_relay_log_event(). is_until_satisfied() caches the result
|
|
|
|
of the comparison of log names because log names don't change very often;
|
|
|
|
this cache is invalidated by parts of code which change log names with
|
|
|
|
notify_*_log_name_updated() methods. (They need to be called only if SQL
|
|
|
|
thread is running).
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS} until_condition;
|
|
|
|
char until_log_name[FN_REFLEN];
|
|
|
|
ulonglong until_log_pos;
|
|
|
|
/* extension extracted from log_name and converted to int */
|
|
|
|
ulong until_log_name_extension;
|
|
|
|
/*
|
|
|
|
Cached result of comparison of until_log_name and current log name
|
|
|
|
-2 means unitialised, -1,0,1 are comarison results
|
|
|
|
*/
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
UNTIL_LOG_NAMES_CMP_UNKNOWN= -2, UNTIL_LOG_NAMES_CMP_LESS= -1,
|
|
|
|
UNTIL_LOG_NAMES_CMP_EQUAL= 0, UNTIL_LOG_NAMES_CMP_GREATER= 1
|
|
|
|
} until_log_names_cmp_result;
|
WL#1062 "log charset info into all Query_log_event":
we store 7 bytes (1 + 2*3) in every Query_log_event.
In the future if users want binlog optimized for small size and less safe,
we could add --binlog-no-charset (and binlog-no-sql-mode etc): charset info
is something by design optional (even if for now we don't offer possibility to disable it):
it's not a binlog format change.
We try to reduce the number of get_charset() calls in the slave SQL thread to a minimum
by caching the charset read from the previous event (which will often be equal to the one of the current event).
We don't use SET ONE_SHOT for charset-aware repl (we still do for timezones, will be fixed later).
No more errors if one changes the global value of charset vars on master or slave
(as we log charset info in all Query_log_event).
Not fixing Load_log_event as it will be rewritten soon by Dmitri.
Testing how mysqlbinlog behaves in rpl_charset.test.
mysqlbinlog needs to know where charset file is (to be able to convert a charset number found
in binlog (e.g. in User_var_log_event) to a charset name); mysql-test-run needs to pass
the correct value for this option to mysqlbinlog.
Many result udpates (adding charset info into every event shifts log_pos in SHOW BINLOG EVENTS).
Roughly the same job is to be done for timezones :)
client/mysqlbinlog.cc:
mysqlbinlog needs charsets knowledge, to be able to convert a charset
number found in binlog to a charset name (to be able to print things
like this:
SET @`a`:=_cp850 0x4DFC6C6C6572 COLLATE `cp850_general_ci`;
mysql-test/mysql-test-run.sh:
tell mysqlbinlog about charsets dir
mysql-test/r/ctype_ucs.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/drop_temp_table.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/insert_select.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/mix_innodb_myisam_binlog.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/mysqlbinlog.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/mysqlbinlog2.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
The log_pos shift is why the SET INSERT_ID=4 event changes position in the result.
mysql-test/r/rpl_charset.result:
Running mysqlbinlog to check how it behaves on charset stuff.
SET ONE_SHOT is now gone.
Repl of LOAD DATA INFILE is not yet charset-aware (will soon be, when WL#874 is pushed)
and, anyway result has a dependency on the temp filename (SQL-LOAD-*-[0-9] which is not constant).
No more errors if one changes global character sets.
mysql-test/r/rpl_error_ignored_table.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_flush_log_loop.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_flush_tables.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_loaddata.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_loaddata_rule_m.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_log.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_max_relay_size.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_relayrotate.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_replicate_do.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_rotate_logs.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_temporary.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_timezone.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_user_variables.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/user_var.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/t/rpl_charset.test:
Running mysqlbinlog to check how it behaves on charset stuff (so, need fixed timestamp).
SET ONE_SHOT is not printed to binlog anymore, so no need to test if ::exec_event() works ok.
Repl of LOAD DATA INFILE is not yet charset-aware (will soon be, when WL#874 is pushed)
and, anyway result has a dependency on the temp filename (SQL-LOAD-*-[0-9] which is not constant).
No more errors if one changes global character sets.
mysql-test/t/rpl_user_variables.test:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
sql/log.cc:
No more SET ONE_SHOT for charsets (remains for TZ until solved with Dmitri).
sql/log_event.cc:
We now log charset info in each Query_log_event in binlog. It's 2*3 = 6 bytes:
session character_set_client, session collation_connection, session collation_server.
Now we would need only one byte per variable, but Bar said 2 is safer for the future.
When slave or mysqlbinlog reads that info, it needs to get_charset() on these numbers (so, 3 get_charset() calls),
as most of the time the 6-byte charset info will be equal to the previous event's,
we cache the previous event's charset and if equal, no need to get_charset().
As "flags2", SQL_MODE, catalog, autoinc variables, charset info is not a permanent addition:
in the future we can add options to the master to not log any of these, old 5.0 should be able
to parse these.
A little bit of cleanup on autoinc stuff in replication.
Fixing a bug in Start_log_event_v3::exec_event() where we used rli->relay_log.description_event_for_exec->binlog_version
while we should use binlog_version (if it's a 3.23 master, that's all that counts; not the fact that the relay log is
in 5.0 format).
sql/log_event.h:
binlogging of charset info in each Query_log_event.
sql/mysql_priv.h:
comment
sql/set_var.cc:
checks to refuse change of global charset variables are removed: they were needed for 4.1->4.1
but not for 5.0.3->5.0.3.
Yes this opens a breach if one does 4.1->5.0.3, where the checks would still be needed. But these checks would need
reading relay_log.description_event_for_queue, which is currently an object used in many places by the I/O
thread and only it. So, currently we don't take mutexes for this object, and if we read the object in set_var.cc
(client thread) we need to add mutexes everywhere, but the replication code is already too broken with mutexes
now (no consistent use of mutexes); mutex usage in replication should be fixed but preferrably during/after
multimaster coding as it's going to shuffle mutexes already.
sql/set_var.h:
Since we don't forbid global change of charset vars for replication/binlogging,
don't need specific ::check() methods anymore
sql/slave.cc:
Some little debug info which has nothing to do with charsets.
Disabling master's charset check when slave I/O thread connects.
Functions for charset caching/invalidating in the slave SQL thread.
sql/slave.h:
Cached charset in the slave SQL thread.
2005-02-03 16:22:16 +01:00
|
|
|
|
|
|
|
char cached_charset[6];
|
"After Monty's review" changes to the fix for BUG#8325 "Deadlock in replication thread stops replication":
s/sleep/safe_sleep (thread safe); sleep 0/1/2/3/4/5/5/5 (get slave less late);
no message on error log (deadlock is too common sometimes), a global counter
instead (SHOW STATUS LIKE 'slave_retried_transactions').
Plus a fix for libmysql/Makefile.shared
libmysql/Makefile.shared:
When we "make clean" in libmysql/ we remove the symlinks there, so we
need to mark that they have to be recreated later: this is done by removing
../linked_libmysql_sources. If we don't do this, 'make' will fail after 'cd libmysql;make clean'.
This Makefile.shared is used by libmysql_r too.
No reason to remove linked_client_sources as we don't remove the links in client/.
mysql-test/r/rpl_deadlock.result:
result fix
mysql-test/t/rpl_deadlock.test:
small test addition
sql/mysqld.cc:
if active_mi could not be alloced, die. New SHOW STATUS LIKE "slave_retried_transactions".
sql/slave.cc:
If slave retries automatically a transaction, no message on error log
(too common situation); sleep 0 secs at first retry, then 1, 2, 3, 4,
5, 5, 5... Sleeping 0 is to get the least possible late, as deadlocks
are usually resolved at first try. New global counter rli->retried_trans
(for SHOW STATUS: total number of times the slave had to retry
any transaction). safe_sleep() is thread-safe, sleep() was not.
I change the rli->trans_retries counter to go from 0 to max instead
of the other way (better for new sleep()).
sql/slave.h:
new global counter rli->retried_trans
sql/sql_show.cc:
SHOW STATUS LIKE "slave_retried_transactions"; needs replication mutexes.
Can't be a simple SHOW_LONG, because active_mi is unset (not alloced yet)
when the static global status_vars is created (active_mi is set
in init_slave()).
sql/structs.h:
new SHOW_SLAVE_RETRIED_TRANS
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
2005-03-23 19:19:36 +01:00
|
|
|
/*
|
|
|
|
trans_retries varies between 0 to slave_transaction_retries and counts how
|
|
|
|
many times the slave has retried the present transaction; gets reset to 0
|
|
|
|
when the transaction finally succeeds. retried_trans is a cumulative
|
|
|
|
counter: how many times the slave has retried a transaction (any) since
|
|
|
|
slave started.
|
|
|
|
*/
|
|
|
|
ulong trans_retries, retried_trans;
|
2005-03-02 11:29:48 +01:00
|
|
|
|
2003-01-28 07:38:28 +01:00
|
|
|
st_relay_log_info();
|
|
|
|
~st_relay_log_info();
|
Replication: new code to not modify in-memory log positions until the COMMIT
is executed, even if the transaction spans on >=2 relay logs (bug #53).
New variable relay_log_purge =0|1
New test to verify bug #53
sql/log.cc:
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT.
sql/log_event.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/mysql_priv.h:
new option relay_log_purge (the user can now decide himself
if he wants his relay logs to be automatically purged or not,
we don't make unsafe guesses like before)
sql/mysqld.cc:
new option --innodb (replaces --skip-innodb).
Useful for the test suite : we have skip-innodb in mysql-test-run,
but we can ('-opt.info' file) choose to start the server with
InnoDB for this test only.
New option --bdb
sql/repl_failsafe.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/set_var.cc:
new variable relay_log_purge
sql/slave.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT
sql/slave.h:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/sql_class.h:
prototypes change
sql/sql_parse.cc:
removed thd argument (was not used in the function's body)
sql/sql_repl.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Turn relay_log_purge silently off when someone does CHANGE
MASTER TO RELAY_LOG_*
2003-04-24 15:29:25 +02:00
|
|
|
|
2003-09-13 22:13:41 +02:00
|
|
|
/*
|
|
|
|
Invalidate cached until_log_name and group_relay_log_name comparison
|
|
|
|
result. Should be called after any update of group_realy_log_name if
|
|
|
|
there chances that sql_thread is running.
|
|
|
|
*/
|
|
|
|
inline void notify_group_relay_log_name_update()
|
|
|
|
{
|
|
|
|
if (until_condition==UNTIL_RELAY_POS)
|
|
|
|
until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
The same as previous but for group_master_log_name.
|
|
|
|
*/
|
|
|
|
inline void notify_group_master_log_name_update()
|
|
|
|
{
|
|
|
|
if (until_condition==UNTIL_MASTER_POS)
|
|
|
|
until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2004-05-14 16:00:57 +02:00
|
|
|
inline void inc_event_relay_log_pos()
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2004-05-14 16:00:57 +02:00
|
|
|
event_relay_log_pos= future_event_relay_log_pos;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2004-05-14 16:00:57 +02:00
|
|
|
void inc_group_relay_log_pos(ulonglong log_pos,
|
|
|
|
bool skip_lock=0);
|
|
|
|
|
2003-01-25 14:07:51 +01:00
|
|
|
int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
|
|
|
|
longlong timeout);
|
2003-11-02 15:38:27 +01:00
|
|
|
void close_temporary_tables();
|
2003-09-13 22:13:41 +02:00
|
|
|
|
|
|
|
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
|
|
|
|
bool is_until_satisfied();
|
2003-12-26 11:32:02 +01:00
|
|
|
inline ulonglong until_pos()
|
|
|
|
{
|
|
|
|
return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
|
|
|
|
group_relay_log_pos);
|
|
|
|
}
|
WL#1062 "log charset info into all Query_log_event":
we store 7 bytes (1 + 2*3) in every Query_log_event.
In the future if users want binlog optimized for small size and less safe,
we could add --binlog-no-charset (and binlog-no-sql-mode etc): charset info
is something by design optional (even if for now we don't offer possibility to disable it):
it's not a binlog format change.
We try to reduce the number of get_charset() calls in the slave SQL thread to a minimum
by caching the charset read from the previous event (which will often be equal to the one of the current event).
We don't use SET ONE_SHOT for charset-aware repl (we still do for timezones, will be fixed later).
No more errors if one changes the global value of charset vars on master or slave
(as we log charset info in all Query_log_event).
Not fixing Load_log_event as it will be rewritten soon by Dmitri.
Testing how mysqlbinlog behaves in rpl_charset.test.
mysqlbinlog needs to know where charset file is (to be able to convert a charset number found
in binlog (e.g. in User_var_log_event) to a charset name); mysql-test-run needs to pass
the correct value for this option to mysqlbinlog.
Many result udpates (adding charset info into every event shifts log_pos in SHOW BINLOG EVENTS).
Roughly the same job is to be done for timezones :)
client/mysqlbinlog.cc:
mysqlbinlog needs charsets knowledge, to be able to convert a charset
number found in binlog to a charset name (to be able to print things
like this:
SET @`a`:=_cp850 0x4DFC6C6C6572 COLLATE `cp850_general_ci`;
mysql-test/mysql-test-run.sh:
tell mysqlbinlog about charsets dir
mysql-test/r/ctype_ucs.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/drop_temp_table.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/insert_select.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/mix_innodb_myisam_binlog.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/mysqlbinlog.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/mysqlbinlog2.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
The log_pos shift is why the SET INSERT_ID=4 event changes position in the result.
mysql-test/r/rpl_charset.result:
Running mysqlbinlog to check how it behaves on charset stuff.
SET ONE_SHOT is now gone.
Repl of LOAD DATA INFILE is not yet charset-aware (will soon be, when WL#874 is pushed)
and, anyway result has a dependency on the temp filename (SQL-LOAD-*-[0-9] which is not constant).
No more errors if one changes global character sets.
mysql-test/r/rpl_error_ignored_table.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_flush_log_loop.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_flush_tables.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_loaddata.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_loaddata_rule_m.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_log.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_max_relay_size.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_relayrotate.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_replicate_do.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_rotate_logs.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_temporary.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_timezone.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/rpl_user_variables.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/r/user_var.result:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
mysql-test/t/rpl_charset.test:
Running mysqlbinlog to check how it behaves on charset stuff (so, need fixed timestamp).
SET ONE_SHOT is not printed to binlog anymore, so no need to test if ::exec_event() works ok.
Repl of LOAD DATA INFILE is not yet charset-aware (will soon be, when WL#874 is pushed)
and, anyway result has a dependency on the temp filename (SQL-LOAD-*-[0-9] which is not constant).
No more errors if one changes global character sets.
mysql-test/t/rpl_user_variables.test:
different binlogging of charsets results in shifted log_pos and
one added SET @@CHARACTER_SET... per mysqlbinlog run.
sql/log.cc:
No more SET ONE_SHOT for charsets (remains for TZ until solved with Dmitri).
sql/log_event.cc:
We now log charset info in each Query_log_event in binlog. It's 2*3 = 6 bytes:
session character_set_client, session collation_connection, session collation_server.
Now we would need only one byte per variable, but Bar said 2 is safer for the future.
When slave or mysqlbinlog reads that info, it needs to get_charset() on these numbers (so, 3 get_charset() calls),
as most of the time the 6-byte charset info will be equal to the previous event's,
we cache the previous event's charset and if equal, no need to get_charset().
As "flags2", SQL_MODE, catalog, autoinc variables, charset info is not a permanent addition:
in the future we can add options to the master to not log any of these, old 5.0 should be able
to parse these.
A little bit of cleanup on autoinc stuff in replication.
Fixing a bug in Start_log_event_v3::exec_event() where we used rli->relay_log.description_event_for_exec->binlog_version
while we should use binlog_version (if it's a 3.23 master, that's all that counts; not the fact that the relay log is
in 5.0 format).
sql/log_event.h:
binlogging of charset info in each Query_log_event.
sql/mysql_priv.h:
comment
sql/set_var.cc:
checks to refuse change of global charset variables are removed: they were needed for 4.1->4.1
but not for 5.0.3->5.0.3.
Yes this opens a breach if one does 4.1->5.0.3, where the checks would still be needed. But these checks would need
reading relay_log.description_event_for_queue, which is currently an object used in many places by the I/O
thread and only it. So, currently we don't take mutexes for this object, and if we read the object in set_var.cc
(client thread) we need to add mutexes everywhere, but the replication code is already too broken with mutexes
now (no consistent use of mutexes); mutex usage in replication should be fixed but preferrably during/after
multimaster coding as it's going to shuffle mutexes already.
sql/set_var.h:
Since we don't forbid global change of charset vars for replication/binlogging,
don't need specific ::check() methods anymore
sql/slave.cc:
Some little debug info which has nothing to do with charsets.
Disabling master's charset check when slave I/O thread connects.
Functions for charset caching/invalidating in the slave SQL thread.
sql/slave.h:
Cached charset in the slave SQL thread.
2005-02-03 16:22:16 +01:00
|
|
|
/*
|
|
|
|
Last charset (6 bytes) seen by slave SQL thread is cached here; it helps
|
|
|
|
the thread save 3 get_charset() per Query_log_event if the charset is not
|
|
|
|
changing from event to event (common situation).
|
|
|
|
When the 6 bytes are equal to 0 is used to mean "cache is invalidated".
|
|
|
|
*/
|
|
|
|
void cached_charset_invalidate();
|
|
|
|
bool cached_charset_compare(char *charset);
|
2002-01-20 03:16:52 +01:00
|
|
|
} RELAY_LOG_INFO;
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
Log_event* next_event(RELAY_LOG_INFO* rli);
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
|
|
|
|
Replication IO Thread
|
|
|
|
|
|
|
|
st_master_info contains:
|
|
|
|
- information about how to connect to a master
|
|
|
|
- current master log name
|
|
|
|
- current master log offset
|
|
|
|
- misc control variables
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
st_master_info is initialized once from the master.info file if such
|
|
|
|
exists. Otherwise, data members corresponding to master.info fields
|
|
|
|
are initialized with defaults specified by master-* options. The
|
|
|
|
initialization is done through init_master_info() call.
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
The format of master.info file:
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
log_name
|
|
|
|
log_pos
|
|
|
|
master_host
|
|
|
|
master_user
|
|
|
|
master_pass
|
|
|
|
master_port
|
|
|
|
master_connect_retry
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
To write out the contents of master.info file to disk ( needed every
|
|
|
|
time we read and queue data from the master ), a call to
|
|
|
|
flush_master_info() is required.
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
To clean up, call end_master_info()
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
*****************************************************************************/
|
|
|
|
|
2000-11-11 22:50:39 +01:00
|
|
|
typedef struct st_master_info
|
|
|
|
{
|
2002-07-17 14:17:20 +02:00
|
|
|
/* the variables below are needed because we can change masters on the fly */
|
2002-01-20 03:16:52 +01:00
|
|
|
char master_log_name[FN_REFLEN];
|
2003-07-04 02:18:15 +02:00
|
|
|
char host[HOSTNAME_LENGTH+1];
|
|
|
|
char user[USERNAME_LENGTH+1];
|
|
|
|
char password[MAX_PASSWORD_LENGTH+1];
|
2003-09-01 13:16:20 +02:00
|
|
|
my_bool ssl; // enables use of SSL connection if true
|
|
|
|
char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN];
|
|
|
|
char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN];
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
my_off_t master_log_pos;
|
2002-08-08 02:12:02 +02:00
|
|
|
File fd; // we keep the file open, so we need to remember the file pointer
|
2000-11-25 03:49:13 +01:00
|
|
|
IO_CACHE file;
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_t data_lock,run_lock;
|
|
|
|
pthread_cond_t data_cond,start_cond,stop_cond;
|
2002-01-29 17:32:16 +01:00
|
|
|
THD *io_thd;
|
2002-02-07 23:29:46 +01:00
|
|
|
MYSQL* mysql;
|
2003-07-04 02:18:15 +02:00
|
|
|
uint32 file_id; /* for 3.23 load data infile */
|
2002-01-20 03:16:52 +01:00
|
|
|
RELAY_LOG_INFO rli;
|
2002-01-29 17:32:16 +01:00
|
|
|
uint port;
|
|
|
|
uint connect_retry;
|
2002-01-20 03:16:52 +01:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
int events_till_abort;
|
|
|
|
#endif
|
2002-01-29 17:32:16 +01:00
|
|
|
bool inited;
|
A change of behaviour of Seconds_Behind_Master from SHOW SLAVE STATUS. It's going into 4.1
because old behaviour was somewhat nonsensical (kind of bug). Changes are that if repl threads are
down or disconnected the column will be NULL, and if master is idle the column will not grow indefinitely anymore.
sql/slave.cc:
mi->slave_running and rli->slave_running now uints (was needed only for mi but because of start_slave_thread() usage,
had to change both).
So mi->slave_running can now take 3 values: not running, running & not connected, running and connected.
The last value serves for calculation of Seconds_Behind_Master in SHOW SLAVE STATUS.
Changing this column's behaviour: if SQL or I/O thread is not running, or if I/O thread is not connected
(for example if it is reconnecting), it's NULL (to mean "unknown"). And if master is idle, the column will
not grow indefinitely like it used to (that was meaningless); this is fixed by forcing a value of 0
when the slave SQL thread has hit EOF of relay log (which has only a limited number of caveats explained
in comments in code).
sql/slave.h:
slave_running used to be bool but we need to distinguish, for the I/O slave thread, between
"running & connected" and "running & not connected" ("running" means the thread exists).
sql/sql_repl.cc:
we don't need anymore to set rli->last_master_timestamp to 0 (we used that to make Seconds_Behind_Master
be NULL) in RESET SLAVE and CHANGE MASTER, as these commands imply that slave threads are not running
and so Seconds_Behind_Master is already NULL because of that.
2004-12-16 18:12:22 +01:00
|
|
|
volatile bool abort_slave;
|
|
|
|
volatile uint slave_running;
|
2002-08-24 04:44:16 +02:00
|
|
|
volatile ulong slave_run_id;
|
2005-02-01 15:36:48 +01:00
|
|
|
/*
|
2003-10-09 00:06:21 +02:00
|
|
|
The difference in seconds between the clock of the master and the clock of
|
|
|
|
the slave (second - first). It must be signed as it may be <0 or >0.
|
|
|
|
clock_diff_with_master is computed when the I/O thread starts; for this the
|
|
|
|
I/O thread does a SELECT UNIX_TIMESTAMP() on the master.
|
|
|
|
"how late the slave is compared to the master" is computed like this:
|
|
|
|
clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
|
|
|
|
|
|
|
|
*/
|
2005-02-01 15:36:48 +01:00
|
|
|
long clock_diff_with_master;
|
|
|
|
|
2002-08-24 04:44:16 +02:00
|
|
|
st_master_info()
|
This will be pushed only after I fix the testsuite.
This is the main commit for Worklog tasks:
* A more dynamic binlog format which allows small changes (1064)
* Log session variables in Query_log_event (1063)
Below 5.0 means 5.0.0.
MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed),
SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think
of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this
works for queries, except LOAD DATA INFILE (for this it would have to wait
for Dmitri's push of WL#874, which in turns waits for the present push, so...
the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1,
5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1.
Apart from that, the new binlog format is designed so that it can tolerate
a little variation in the events (so that a 5.0.0 slave could replicate a
5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I
later add replication of charsets it should break nothing. And when I later
add a UID to every event, it should break nothing.
The main change brought by this patch is a new type of event, Format_description_log_event,
which describes some lengthes in other event types. This event is needed for
the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event,
we can later add more bytes to the header of every event without breaking compatibility.
Inside Query_log_event, we have some additional dynamic format, as every Query_log_event
can have a different number of status variables, stored as pairs (code, value); that's
how SQL_MODE and session variables and catalog are stored. Like this, we can later
add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows
if we want.
MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs.
Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs),
upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs);
so both can be "hot" upgrades.
Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0.
3.23 and 4.x can't be slaves of 5.0.
So downgrading from 5.0 to 4.x may be complicated.
Log_event::log_pos is now the position of the end of the event, which is
more useful than the position of the beginning. We take care about compatibility
with <5.0 (in which log_pos is the beginning).
I added a short test for replication of SQL_MODE and some other variables.
TODO:
- after committing this, merge the latest 5.0 into it
- fix all tests
- update the manual with upgrade notes.
client/Makefile.am:
mysqlbinlog.cc depends slightly on sql/mysql_priv.h
client/mysqlbinlog.cc:
Make mysqlbinlog able to read the new binlog format,
by seeking to the start and reading the first few events, to
detect the format of the binlog.
include/my_sys.h:
a correct tell() for SEQ_READ_APPEND caches.
mysys/mf_iocache2.c:
a correct tell() for SEQ_READ_APPEND caches
(my_b_tell() is not working for such caches).
sql/ha_innodb.cc:
we are getting rid of event lengthes here and there, which is good.
sql/log.cc:
Start events will have created==0 if generated by rotation (like in 3.23).
In 5.0 we always write a Format_description_log_event at the beginning of
every master's binary log and of every slave's relay log.
We also add Rotate and Stop to relay logs (like there already was in
master's binary logs).
When we rotate a relay log, we write the previous relay log's Start event
(the one which was sent from the master) to the beginning of the new log,
so that we don't need the previous relay log to understand the new one;
that's the purpose of MYSQL_LOG::description_event_for_queue.
Removed logging of SET FOREIGN_KEY_CHECKS, because we handle it as flags
in the Query event now.
sql/log_event.cc:
New event type: Format_description_log_event, to describe the log's format.
read_log_event() needs to be passed this event to be able to read 5.0 events.
Query_log_event has new members flags2 and sql_mode for replication of session
variables (except charsets which are WL#1062) and SQL_MODE.
flags2 is in fact a kind of copy of thd->options (&'d with a mask).
Now with this replication of FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS
and SQL_MODE work; with mysqlbinlog too.
sql/log_event.h:
Binlog version is changed to 4.
New classes (details in sql/log_event.cc).
Removing some useless #defines.
sql/mysql_priv.h:
Definition of SELECT_DISTINCT and others must be visible in client/mysqlbinlog.cc,
so adding #ifdefs.
sql/mysqld.cc:
update for prototype change
sql/slave.cc:
When the slave opens a relay log, it reads the first few events to know the format.
When slave I/O thread receives a Rotate from the master, it rotates its relay log
(to avoid mixed format in the relay log).
sql/slave.h:
in the slave we avoid lengthes and rely on absolute positions instead;
hence the introduction of future_group_master_log_pos and future_event_relay_log_pos
(explained in code).
sql/sql_class.cc:
catalog in THD
sql/sql_class.h:
catalog, and new members in MYSQL_LOG
sql/sql_repl.cc:
When the master starts sending binlog to slave, it must
first read the first few events to detect the binlog's format.
Same for SHOW BINLOG EVENTS.
2003-12-18 01:09:05 +01:00
|
|
|
:ssl(0), fd(-1), io_thd(0), inited(0),
|
Fix for bug 254 :
we now make a distinction between if the master is < 3.23.57, 3.23 && >=57, and 4.x
(before the 2 3.23 were one). This is because in 3.23.57 we have a way to distinguish between
a Start_log_event written at server startup and one written at FLUSH LOGS, so we
have a way to know if the slave must drop old temp tables or not.
Change: mi->old_format was bool, now it's enum (to handle 3 cases). However, functions
which had 'bool old_format' as an argument have their prototypes unchanged, because
the old old_format == 0 now corresponds to the enum value BINLOG_FORMAT_CURRENT which
is equal to 0, so boolean tests are left untouched. The only case were we use mi->old_format
as an enum instead of casting it implicitly to a bool, is in Start_log_event::exec_event,
where we want to distinguish between the 3 possible enum values.
sql/log_event.cc:
Fix for bug 254 :
we now make a distinction between if the master is < 3.23.57, 3.23 && >=57, and 4.x
(before the 2 3.23 were one), to know if the slave must drop old temp tables or not.
sql/slave.cc:
Fix for bug 254 : mi->old_format is now enum.
An unrelated comment.
sql/slave.h:
fix for bug 254 : mi->old_format is now enum.
2003-06-06 16:41:28 +02:00
|
|
|
abort_slave(0),slave_running(0), slave_run_id(0)
|
2000-11-11 22:50:39 +01:00
|
|
|
{
|
|
|
|
host[0] = 0; user[0] = 0; password[0] = 0;
|
2003-09-01 13:16:20 +02:00
|
|
|
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
|
|
|
|
ssl_cipher[0]= 0; ssl_key[0]= 0;
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2003-08-11 21:44:43 +02:00
|
|
|
bzero((char*) &file, sizeof(file));
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
|
|
|
|
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
|
|
|
|
pthread_cond_init(&data_cond, NULL);
|
|
|
|
pthread_cond_init(&start_cond, NULL);
|
|
|
|
pthread_cond_init(&stop_cond, NULL);
|
2000-11-11 22:50:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~st_master_info()
|
|
|
|
{
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_destroy(&run_lock);
|
|
|
|
pthread_mutex_destroy(&data_lock);
|
|
|
|
pthread_cond_destroy(&data_cond);
|
|
|
|
pthread_cond_destroy(&start_cond);
|
|
|
|
pthread_cond_destroy(&stop_cond);
|
2000-11-11 22:50:39 +01:00
|
|
|
}
|
2001-01-17 13:47:33 +01:00
|
|
|
|
2000-11-11 22:50:39 +01:00
|
|
|
} MASTER_INFO;
|
|
|
|
|
2002-09-11 05:40:08 +02:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2000-11-11 22:50:39 +01:00
|
|
|
typedef struct st_table_rule_ent
|
|
|
|
{
|
|
|
|
char* db;
|
|
|
|
char* tbl_name;
|
|
|
|
uint key_len;
|
|
|
|
} TABLE_RULE_ENT;
|
|
|
|
|
|
|
|
#define TABLE_RULE_HASH_SIZE 16
|
2000-11-21 07:38:08 +01:00
|
|
|
#define TABLE_RULE_ARR_SIZE 16
|
2001-08-03 23:57:53 +02:00
|
|
|
#define MAX_SLAVE_ERRMSG 1024
|
|
|
|
|
Replication: new code to not modify in-memory log positions until the COMMIT
is executed, even if the transaction spans on >=2 relay logs (bug #53).
New variable relay_log_purge =0|1
New test to verify bug #53
sql/log.cc:
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT.
sql/log_event.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/mysql_priv.h:
new option relay_log_purge (the user can now decide himself
if he wants his relay logs to be automatically purged or not,
we don't make unsafe guesses like before)
sql/mysqld.cc:
new option --innodb (replaces --skip-innodb).
Useful for the test suite : we have skip-innodb in mysql-test-run,
but we can ('-opt.info' file) choose to start the server with
InnoDB for this test only.
New option --bdb
sql/repl_failsafe.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/set_var.cc:
new variable relay_log_purge
sql/slave.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT
sql/slave.h:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/sql_class.h:
prototypes change
sql/sql_parse.cc:
removed thd argument (was not used in the function's body)
sql/sql_repl.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Turn relay_log_purge silently off when someone does CHANGE
MASTER TO RELAY_LOG_*
2003-04-24 15:29:25 +02:00
|
|
|
#define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\
|
2002-01-20 03:16:52 +01:00
|
|
|
"FIRST")
|
|
|
|
#define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\
|
2001-08-03 23:57:53 +02:00
|
|
|
"FIRST")
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
/* masks for start/stop operations on io and sql slave threads */
|
|
|
|
#define SLAVE_IO 1
|
|
|
|
#define SLAVE_SQL 2
|
2002-01-29 17:32:16 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
If the following is set, if first gives an error, second will be
|
|
|
|
tried. Otherwise, if first fails, we fail.
|
|
|
|
*/
|
|
|
|
#define SLAVE_FORCE_ALL 4
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
int init_slave();
|
2002-04-30 15:40:46 +02:00
|
|
|
void init_slave_skip_errors(const char* arg);
|
2003-11-23 17:02:59 +01:00
|
|
|
bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache);
|
2002-08-08 02:12:02 +02:00
|
|
|
bool flush_relay_log_info(RELAY_LOG_INFO* rli);
|
2001-05-31 02:50:56 +02:00
|
|
|
int register_slave_on_master(MYSQL* mysql);
|
2002-01-20 03:16:52 +01:00
|
|
|
int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
|
|
|
|
bool skip_lock = 0);
|
|
|
|
int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex,
|
|
|
|
pthread_mutex_t* cond_lock,
|
|
|
|
pthread_cond_t* term_cond,
|
A change of behaviour of Seconds_Behind_Master from SHOW SLAVE STATUS. It's going into 4.1
because old behaviour was somewhat nonsensical (kind of bug). Changes are that if repl threads are
down or disconnected the column will be NULL, and if master is idle the column will not grow indefinitely anymore.
sql/slave.cc:
mi->slave_running and rli->slave_running now uints (was needed only for mi but because of start_slave_thread() usage,
had to change both).
So mi->slave_running can now take 3 values: not running, running & not connected, running and connected.
The last value serves for calculation of Seconds_Behind_Master in SHOW SLAVE STATUS.
Changing this column's behaviour: if SQL or I/O thread is not running, or if I/O thread is not connected
(for example if it is reconnecting), it's NULL (to mean "unknown"). And if master is idle, the column will
not grow indefinitely like it used to (that was meaningless); this is fixed by forcing a value of 0
when the slave SQL thread has hit EOF of relay log (which has only a limited number of caveats explained
in comments in code).
sql/slave.h:
slave_running used to be bool but we need to distinguish, for the I/O slave thread, between
"running & connected" and "running & not connected" ("running" means the thread exists).
sql/sql_repl.cc:
we don't need anymore to set rli->last_master_timestamp to 0 (we used that to make Seconds_Behind_Master
be NULL) in RESET SLAVE and CHANGE MASTER, as these commands imply that slave threads are not running
and so Seconds_Behind_Master is already NULL because of that.
2004-12-16 18:12:22 +01:00
|
|
|
volatile uint* slave_running);
|
2002-01-20 03:16:52 +01:00
|
|
|
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
|
|
|
|
MASTER_INFO* mi, const char* master_info_fname,
|
|
|
|
const char* slave_info_fname, int thread_mask);
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
cond_lock is usually same as start_lock. It is needed for the case when
|
|
|
|
start_lock is 0 which happens if start_slave_thread() is called already
|
|
|
|
inside the start_lock section, but at the same time we want a
|
|
|
|
pthread_cond_wait() on start_cond,start_lock
|
2002-01-20 03:16:52 +01:00
|
|
|
*/
|
|
|
|
int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
|
|
|
|
pthread_mutex_t *cond_lock,
|
|
|
|
pthread_cond_t* start_cond,
|
A change of behaviour of Seconds_Behind_Master from SHOW SLAVE STATUS. It's going into 4.1
because old behaviour was somewhat nonsensical (kind of bug). Changes are that if repl threads are
down or disconnected the column will be NULL, and if master is idle the column will not grow indefinitely anymore.
sql/slave.cc:
mi->slave_running and rli->slave_running now uints (was needed only for mi but because of start_slave_thread() usage,
had to change both).
So mi->slave_running can now take 3 values: not running, running & not connected, running and connected.
The last value serves for calculation of Seconds_Behind_Master in SHOW SLAVE STATUS.
Changing this column's behaviour: if SQL or I/O thread is not running, or if I/O thread is not connected
(for example if it is reconnecting), it's NULL (to mean "unknown"). And if master is idle, the column will
not grow indefinitely like it used to (that was meaningless); this is fixed by forcing a value of 0
when the slave SQL thread has hit EOF of relay log (which has only a limited number of caveats explained
in comments in code).
sql/slave.h:
slave_running used to be bool but we need to distinguish, for the I/O slave thread, between
"running & connected" and "running & not connected" ("running" means the thread exists).
sql/sql_repl.cc:
we don't need anymore to set rli->last_master_timestamp to 0 (we used that to make Seconds_Behind_Master
be NULL) in RESET SLAVE and CHANGE MASTER, as these commands imply that slave threads are not running
and so Seconds_Behind_Master is already NULL because of that.
2004-12-16 18:12:22 +01:00
|
|
|
volatile uint *slave_running,
|
2002-08-24 04:44:16 +02:00
|
|
|
volatile ulong *slave_run_id,
|
2003-03-01 23:59:27 +01:00
|
|
|
MASTER_INFO* mi,
|
|
|
|
bool high_priority);
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* If fd is -1, dump to NET */
|
2001-05-29 03:18:23 +02:00
|
|
|
int mysql_table_dump(THD* thd, const char* db,
|
|
|
|
const char* tbl_name, int fd = -1);
|
|
|
|
|
* Fix for BUG#1248: "LOAD DATA FROM MASTER drops the slave's db unexpectedly".
Now LOAD DATA FROM MASTER does not drop the database, instead it only tries to
create it, and drops/creates table-by-table.
* replicate_wild_ignore_table='db1.%' is now considered as "ignore the 'db1'
database as a whole", as it already works for CREATE DATABASE and DROP DATABASE.
mysql-test/r/rpl000009.result:
result update
mysql-test/t/rpl000009.test:
test that LOAD DATA FROM MASTER does not drop databases,
but rather table by table, thus preserving non-replicated tables.
Test that LOAD DATA FROM MASTER reports the error when a table could not
be dropped (system's "permission denied" for example).
Test that LOAD TABLE FROM MASTER reports the error when the table already exists.
sql/repl_failsafe.cc:
* replicate_wild_ignore_table='db1.%' is now considered as "ignore the 'db1'
database as a whole", as it already works for CREATE DATABASE and DROP DATABASE.
* If a db matches replicate_*_db rules, we don't drop/recreate it because this
could drop some tables in this db which could be slave-specific. Instead,
we do a CREATE DATABASE IF EXISTS, and we will drop each table which has
an equivalent on the master, table-by-table.
sql/slave.cc:
New argument to drop the table in create_table_from_dump()
(LOAD TABLE/DATA FROM MASTER are the only places where this function is used).
This is needed because LOAD DATA FROM MASTER does not drop the database anymore.
The behaviour when the table exists is unchanged: LOAD DATA silently replaces
the table, LOAD TABLE gives error.
sql/slave.h:
new argument to drop the table in fetch_master_table
sql/sql_parse.cc:
do not drop the table in LOAD TABLE FROM MASTER (this behaviour is already
true; but changes in LOAD DATA FROM MASTER made the argument needed).
2003-09-11 23:17:28 +02:00
|
|
|
/* retrieve table from master and copy to slave*/
|
2002-01-29 17:32:16 +01:00
|
|
|
int fetch_master_table(THD* thd, const char* db_name, const char* table_name,
|
* Fix for BUG#1248: "LOAD DATA FROM MASTER drops the slave's db unexpectedly".
Now LOAD DATA FROM MASTER does not drop the database, instead it only tries to
create it, and drops/creates table-by-table.
* replicate_wild_ignore_table='db1.%' is now considered as "ignore the 'db1'
database as a whole", as it already works for CREATE DATABASE and DROP DATABASE.
mysql-test/r/rpl000009.result:
result update
mysql-test/t/rpl000009.test:
test that LOAD DATA FROM MASTER does not drop databases,
but rather table by table, thus preserving non-replicated tables.
Test that LOAD DATA FROM MASTER reports the error when a table could not
be dropped (system's "permission denied" for example).
Test that LOAD TABLE FROM MASTER reports the error when the table already exists.
sql/repl_failsafe.cc:
* replicate_wild_ignore_table='db1.%' is now considered as "ignore the 'db1'
database as a whole", as it already works for CREATE DATABASE and DROP DATABASE.
* If a db matches replicate_*_db rules, we don't drop/recreate it because this
could drop some tables in this db which could be slave-specific. Instead,
we do a CREATE DATABASE IF EXISTS, and we will drop each table which has
an equivalent on the master, table-by-table.
sql/slave.cc:
New argument to drop the table in create_table_from_dump()
(LOAD TABLE/DATA FROM MASTER are the only places where this function is used).
This is needed because LOAD DATA FROM MASTER does not drop the database anymore.
The behaviour when the table exists is unchanged: LOAD DATA silently replaces
the table, LOAD TABLE gives error.
sql/slave.h:
new argument to drop the table in fetch_master_table
sql/sql_parse.cc:
do not drop the table in LOAD TABLE FROM MASTER (this behaviour is already
true; but changes in LOAD DATA FROM MASTER made the argument needed).
2003-09-11 23:17:28 +02:00
|
|
|
MASTER_INFO* mi, MYSQL* mysql, bool overwrite);
|
2001-05-29 03:18:23 +02:00
|
|
|
|
2003-07-23 15:46:46 +02:00
|
|
|
void table_rule_ent_hash_to_str(String* s, HASH* h);
|
|
|
|
void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a);
|
2004-10-20 03:04:37 +02:00
|
|
|
bool show_master_info(THD* thd, MASTER_INFO* mi);
|
|
|
|
bool show_binlog_info(THD* thd);
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* See if the query uses any tables that should not be replicated */
|
2004-12-03 15:18:25 +01:00
|
|
|
bool tables_ok(THD* thd, TABLE_LIST* tables);
|
2000-11-14 07:43:02 +01:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
Check to see if the database is ok to operate on with respect to the
|
|
|
|
do and ignore lists - used in replication
|
|
|
|
*/
|
2000-11-11 22:50:39 +01:00
|
|
|
int db_ok(const char* db, I_List<i_string> &do_list,
|
|
|
|
I_List<i_string> &ignore_list );
|
2003-01-25 14:07:51 +01:00
|
|
|
int db_ok_with_wild_table(const char *db);
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2000-11-14 07:43:02 +01:00
|
|
|
int add_table_rule(HASH* h, const char* table_spec);
|
2000-11-21 07:38:08 +01:00
|
|
|
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
|
2000-11-14 07:43:02 +01:00
|
|
|
void init_table_rule_hash(HASH* h, bool* h_inited);
|
2000-11-21 07:38:08 +01:00
|
|
|
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
|
2004-11-17 16:41:30 +01:00
|
|
|
const char *rewrite_db(const char* db, uint32 *new_db_len);
|
2004-10-19 22:27:19 +02:00
|
|
|
const char *print_slave_db_safe(const char *db);
|
2002-01-20 03:16:52 +01:00
|
|
|
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
|
2001-08-03 23:57:53 +02:00
|
|
|
void skip_load_data_infile(NET* net);
|
WL#1036 (print the db in slave error messages).
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.
sql/log_event.cc:
Print the default database when replication stops because of an error. Previously, we had:
"error "Duplicate entry 87987 for key 1", query 'insert into t values(87987)'", ie the db
was not mentioned, making it hard for cases where the same table name is used in
several databases.
Lengthened some error messages (for failing replication of LOAD DATA: mention the table
and the db).
Changes so that SHOW SLAVE STATUS reports as complete errors as the .err file.
sql/slave.cc:
Removed a useless declaration (the rewrite_db() function is already declared in slave.h).
Added missing ')' in error messages.
Tried to make error messages look nicer (previously we had
"do START SLAVE;, error_code=1062"
now we'll have
"do START SLAVE; . Error_code=1062".
This form has been discussed, I agree it's no panacea, but it's still more readable
like this. To be improved in the future :)
sql/slave.h:
declarations.
2003-07-24 22:25:36 +02:00
|
|
|
void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...);
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
void end_slave(); /* clean up */
|
2003-08-04 10:59:44 +02:00
|
|
|
void init_master_info_with_options(MASTER_INFO* mi);
|
2003-09-13 22:13:41 +02:00
|
|
|
void clear_until_condition(RELAY_LOG_INFO* rli);
|
A change of behaviour of Seconds_Behind_Master from SHOW SLAVE STATUS. It's going into 4.1
because old behaviour was somewhat nonsensical (kind of bug). Changes are that if repl threads are
down or disconnected the column will be NULL, and if master is idle the column will not grow indefinitely anymore.
sql/slave.cc:
mi->slave_running and rli->slave_running now uints (was needed only for mi but because of start_slave_thread() usage,
had to change both).
So mi->slave_running can now take 3 values: not running, running & not connected, running and connected.
The last value serves for calculation of Seconds_Behind_Master in SHOW SLAVE STATUS.
Changing this column's behaviour: if SQL or I/O thread is not running, or if I/O thread is not connected
(for example if it is reconnecting), it's NULL (to mean "unknown"). And if master is idle, the column will
not grow indefinitely like it used to (that was meaningless); this is fixed by forcing a value of 0
when the slave SQL thread has hit EOF of relay log (which has only a limited number of caveats explained
in comments in code).
sql/slave.h:
slave_running used to be bool but we need to distinguish, for the I/O slave thread, between
"running & connected" and "running & not connected" ("running" means the thread exists).
sql/sql_repl.cc:
we don't need anymore to set rli->last_master_timestamp to 0 (we used that to make Seconds_Behind_Master
be NULL) in RESET SLAVE and CHANGE MASTER, as these commands imply that slave threads are not running
and so Seconds_Behind_Master is already NULL because of that.
2004-12-16 18:12:22 +01:00
|
|
|
void clear_slave_error(RELAY_LOG_INFO* rli);
|
2002-01-20 03:16:52 +01:00
|
|
|
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
2002-08-08 02:12:02 +02:00
|
|
|
const char* slave_info_fname,
|
2004-11-25 09:26:45 +01:00
|
|
|
bool abort_if_no_master_info_file,
|
|
|
|
int thread_mask);
|
2000-12-09 22:28:51 +01:00
|
|
|
void end_master_info(MASTER_INFO* mi);
|
2002-01-20 03:16:52 +01:00
|
|
|
void end_relay_log_info(RELAY_LOG_INFO* rli);
|
|
|
|
void lock_slave_threads(MASTER_INFO* mi);
|
|
|
|
void unlock_slave_threads(MASTER_INFO* mi);
|
|
|
|
void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse);
|
|
|
|
int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
|
This will be pushed only after I fix the testsuite.
This is the main commit for Worklog tasks:
* A more dynamic binlog format which allows small changes (1064)
* Log session variables in Query_log_event (1063)
Below 5.0 means 5.0.0.
MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed),
SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think
of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this
works for queries, except LOAD DATA INFILE (for this it would have to wait
for Dmitri's push of WL#874, which in turns waits for the present push, so...
the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1,
5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1.
Apart from that, the new binlog format is designed so that it can tolerate
a little variation in the events (so that a 5.0.0 slave could replicate a
5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I
later add replication of charsets it should break nothing. And when I later
add a UID to every event, it should break nothing.
The main change brought by this patch is a new type of event, Format_description_log_event,
which describes some lengthes in other event types. This event is needed for
the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event,
we can later add more bytes to the header of every event without breaking compatibility.
Inside Query_log_event, we have some additional dynamic format, as every Query_log_event
can have a different number of status variables, stored as pairs (code, value); that's
how SQL_MODE and session variables and catalog are stored. Like this, we can later
add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows
if we want.
MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs.
Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs),
upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs);
so both can be "hot" upgrades.
Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0.
3.23 and 4.x can't be slaves of 5.0.
So downgrading from 5.0 to 4.x may be complicated.
Log_event::log_pos is now the position of the end of the event, which is
more useful than the position of the beginning. We take care about compatibility
with <5.0 (in which log_pos is the beginning).
I added a short test for replication of SQL_MODE and some other variables.
TODO:
- after committing this, merge the latest 5.0 into it
- fix all tests
- update the manual with upgrade notes.
client/Makefile.am:
mysqlbinlog.cc depends slightly on sql/mysql_priv.h
client/mysqlbinlog.cc:
Make mysqlbinlog able to read the new binlog format,
by seeking to the start and reading the first few events, to
detect the format of the binlog.
include/my_sys.h:
a correct tell() for SEQ_READ_APPEND caches.
mysys/mf_iocache2.c:
a correct tell() for SEQ_READ_APPEND caches
(my_b_tell() is not working for such caches).
sql/ha_innodb.cc:
we are getting rid of event lengthes here and there, which is good.
sql/log.cc:
Start events will have created==0 if generated by rotation (like in 3.23).
In 5.0 we always write a Format_description_log_event at the beginning of
every master's binary log and of every slave's relay log.
We also add Rotate and Stop to relay logs (like there already was in
master's binary logs).
When we rotate a relay log, we write the previous relay log's Start event
(the one which was sent from the master) to the beginning of the new log,
so that we don't need the previous relay log to understand the new one;
that's the purpose of MYSQL_LOG::description_event_for_queue.
Removed logging of SET FOREIGN_KEY_CHECKS, because we handle it as flags
in the Query event now.
sql/log_event.cc:
New event type: Format_description_log_event, to describe the log's format.
read_log_event() needs to be passed this event to be able to read 5.0 events.
Query_log_event has new members flags2 and sql_mode for replication of session
variables (except charsets which are WL#1062) and SQL_MODE.
flags2 is in fact a kind of copy of thd->options (&'d with a mask).
Now with this replication of FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS
and SQL_MODE work; with mysqlbinlog too.
sql/log_event.h:
Binlog version is changed to 4.
New classes (details in sql/log_event.cc).
Removing some useless #defines.
sql/mysql_priv.h:
Definition of SELECT_DISTINCT and others must be visible in client/mysqlbinlog.cc,
so adding #ifdefs.
sql/mysqld.cc:
update for prototype change
sql/slave.cc:
When the slave opens a relay log, it reads the first few events to know the format.
When slave I/O thread receives a Rotate from the master, it rotates its relay log
(to avoid mixed format in the relay log).
sql/slave.h:
in the slave we avoid lengthes and rely on absolute positions instead;
hence the introduction of future_group_master_log_pos and future_event_relay_log_pos
(explained in code).
sql/sql_class.cc:
catalog in THD
sql/sql_class.h:
catalog, and new members in MYSQL_LOG
sql/sql_repl.cc:
When the master starts sending binlog to slave, it must
first read the first few events to detect the binlog's format.
Same for SHOW BINLOG EVENTS.
2003-12-18 01:09:05 +01:00
|
|
|
bool need_data_lock, const char** errmsg,
|
|
|
|
bool look_for_description_event);
|
2001-01-24 17:15:34 +01:00
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
|
|
|
|
const char** errmsg);
|
This will be pushed only after I fix the testsuite.
This is the main commit for Worklog tasks:
* A more dynamic binlog format which allows small changes (1064)
* Log session variables in Query_log_event (1063)
Below 5.0 means 5.0.0.
MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed),
SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think
of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this
works for queries, except LOAD DATA INFILE (for this it would have to wait
for Dmitri's push of WL#874, which in turns waits for the present push, so...
the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1,
5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1.
Apart from that, the new binlog format is designed so that it can tolerate
a little variation in the events (so that a 5.0.0 slave could replicate a
5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I
later add replication of charsets it should break nothing. And when I later
add a UID to every event, it should break nothing.
The main change brought by this patch is a new type of event, Format_description_log_event,
which describes some lengthes in other event types. This event is needed for
the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event,
we can later add more bytes to the header of every event without breaking compatibility.
Inside Query_log_event, we have some additional dynamic format, as every Query_log_event
can have a different number of status variables, stored as pairs (code, value); that's
how SQL_MODE and session variables and catalog are stored. Like this, we can later
add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows
if we want.
MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs.
Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs),
upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs);
so both can be "hot" upgrades.
Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0.
3.23 and 4.x can't be slaves of 5.0.
So downgrading from 5.0 to 4.x may be complicated.
Log_event::log_pos is now the position of the end of the event, which is
more useful than the position of the beginning. We take care about compatibility
with <5.0 (in which log_pos is the beginning).
I added a short test for replication of SQL_MODE and some other variables.
TODO:
- after committing this, merge the latest 5.0 into it
- fix all tests
- update the manual with upgrade notes.
client/Makefile.am:
mysqlbinlog.cc depends slightly on sql/mysql_priv.h
client/mysqlbinlog.cc:
Make mysqlbinlog able to read the new binlog format,
by seeking to the start and reading the first few events, to
detect the format of the binlog.
include/my_sys.h:
a correct tell() for SEQ_READ_APPEND caches.
mysys/mf_iocache2.c:
a correct tell() for SEQ_READ_APPEND caches
(my_b_tell() is not working for such caches).
sql/ha_innodb.cc:
we are getting rid of event lengthes here and there, which is good.
sql/log.cc:
Start events will have created==0 if generated by rotation (like in 3.23).
In 5.0 we always write a Format_description_log_event at the beginning of
every master's binary log and of every slave's relay log.
We also add Rotate and Stop to relay logs (like there already was in
master's binary logs).
When we rotate a relay log, we write the previous relay log's Start event
(the one which was sent from the master) to the beginning of the new log,
so that we don't need the previous relay log to understand the new one;
that's the purpose of MYSQL_LOG::description_event_for_queue.
Removed logging of SET FOREIGN_KEY_CHECKS, because we handle it as flags
in the Query event now.
sql/log_event.cc:
New event type: Format_description_log_event, to describe the log's format.
read_log_event() needs to be passed this event to be able to read 5.0 events.
Query_log_event has new members flags2 and sql_mode for replication of session
variables (except charsets which are WL#1062) and SQL_MODE.
flags2 is in fact a kind of copy of thd->options (&'d with a mask).
Now with this replication of FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS
and SQL_MODE work; with mysqlbinlog too.
sql/log_event.h:
Binlog version is changed to 4.
New classes (details in sql/log_event.cc).
Removing some useless #defines.
sql/mysql_priv.h:
Definition of SELECT_DISTINCT and others must be visible in client/mysqlbinlog.cc,
so adding #ifdefs.
sql/mysqld.cc:
update for prototype change
sql/slave.cc:
When the slave opens a relay log, it reads the first few events to know the format.
When slave I/O thread receives a Rotate from the master, it rotates its relay log
(to avoid mixed format in the relay log).
sql/slave.h:
in the slave we avoid lengthes and rely on absolute positions instead;
hence the introduction of future_group_master_log_pos and future_event_relay_log_pos
(explained in code).
sql/sql_class.cc:
catalog in THD
sql/sql_class.h:
catalog, and new members in MYSQL_LOG
sql/sql_repl.cc:
When the master starts sending binlog to slave, it must
first read the first few events to detect the binlog's format.
Same for SHOW BINLOG EVENTS.
2003-12-18 01:09:05 +01:00
|
|
|
void set_slave_thread_options(THD* thd);
|
Last part of WL#1062: better replication of timezones: no more use
of SET ONE_SHOT; storing tz info directly in event (if this info is needed),
it's now allowed to have different global tz on master and slave.
client/mysqlbinlog.cc:
we need MAX_TIME_ZONE_NAME_LENGTH when processing log_event.h, and it's declared in mysql_priv.h
mysql-test/r/rpl_timezone.result:
result update
mysql-test/t/rpl_timezone-slave.opt:
Now that we can have different global value of timezone on master and slave, let's test it.
mysql-test/t/rpl_timezone.test:
Tests of the new replication of timezones: checking the output of mysqlbinlog,
replication of CONVERT_TZ().
sql/ha_innodb.cc:
No very fast shutdown on Netware (anyway it's disabled on all platforms,
but this is so that we don't forget to keep it disabled on Netware in the future).
sql/log.cc:
No more need to write SET ONE_SHOT to binlog for character set and timezone
(as we store this info directly nin the Query_log_event now).
sql/log_event.cc:
Exclude ::write() methods if MYSQL_CLIENT.
Storing timezone info in the Query_log_event in master. Re-reading it in slave.
Small code cleanups. I plan to not store the end 0 of catalog in binlog
events soon.
sql/log_event.h:
replication of time zones: a place for tz info in Query_log_event,
in LAST_EVENT_INFO. Plus if we are compiling a client, we don't need
the ::write() methods, so keeping them out (of mysqlbinlog.cc;
keeping them in, resulted in problem that mysqlbinlog does not know Timezone
structure).
sql/mysql_priv.h:
moving this define from tztime.h (tztime.h has things which are
too much for a client like mysqlbinlog).
sql/set_var.cc:
It's now allowed to change global value of charset or timezone even if using binlogging
or if being a slave.
Making CONVERT_TZ(,,@@session.time_zone) replicate.
sql/set_var.h:
these ::check()s are not needed anymore (changing global charset
or timezone is now allowed even if binlogging or slave)
sql/slave.cc:
No more need to check for same global timezone if master is 5.x
(ok, strictly speaking if it is > 5.0.3 but this is alpha).
sql/slave.h:
a function to wrap settings of charset to default.
sql/tztime.cc:
Adaptation of my_tz_find() to the case where it's not called from inside
a query (i.e. cannot join its tz tables to the query's ones): this variant
opens the tz tables itself, reads from them, and closes them. This is presently
only used by the slave SQL thread (when it sets the tz before executing a query).
sql/tztime.h:
declaration of new function, plus moving symbol to mysql_priv.h
for easier usage in mysqlbinlog (Dmitri, pardon me).
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
2005-03-22 00:26:12 +01:00
|
|
|
void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli);
|
2003-07-06 17:59:54 +02:00
|
|
|
void rotate_relay_log(MASTER_INFO* mi);
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-11-07 02:54:00 +01:00
|
|
|
extern "C" pthread_handler_decl(handle_slave_io,arg);
|
|
|
|
extern "C" pthread_handler_decl(handle_slave_sql,arg);
|
2002-01-20 03:16:52 +01:00
|
|
|
extern bool volatile abort_loop;
|
2002-07-17 14:17:20 +02:00
|
|
|
extern MASTER_INFO main_mi, *active_mi; /* active_mi for multi-master */
|
2002-01-20 03:16:52 +01:00
|
|
|
extern LIST master_list;
|
2000-11-11 22:50:39 +01:00
|
|
|
extern HASH replicate_do_table, replicate_ignore_table;
|
2000-11-14 07:43:02 +01:00
|
|
|
extern DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
|
|
|
|
extern bool do_table_inited, ignore_table_inited,
|
|
|
|
wild_do_table_inited, wild_ignore_table_inited;
|
2004-04-28 18:24:46 +02:00
|
|
|
extern bool table_rules_on, replicate_same_server_id;
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2000-12-02 18:11:50 +01:00
|
|
|
extern int disconnect_slave_event_count, abort_slave_event_count ;
|
2000-11-22 08:23:31 +01:00
|
|
|
|
2002-07-17 14:17:20 +02:00
|
|
|
/* the master variables are defaults read from my.cnf or command line */
|
2001-05-31 02:50:56 +02:00
|
|
|
extern uint master_port, master_connect_retry, report_port;
|
2000-11-11 22:50:39 +01:00
|
|
|
extern my_string master_user, master_password, master_host,
|
2002-01-29 17:32:16 +01:00
|
|
|
master_info_file, relay_log_info_file, report_user, report_host,
|
|
|
|
report_password;
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2003-09-01 13:16:20 +02:00
|
|
|
extern my_bool master_ssl;
|
|
|
|
extern my_string master_ssl_ca, master_ssl_capath, master_ssl_cert,
|
|
|
|
master_ssl_cipher, master_ssl_key;
|
|
|
|
|
2000-11-11 22:50:39 +01:00
|
|
|
extern I_List<i_string> replicate_do_db, replicate_ignore_db;
|
|
|
|
extern I_List<i_string_pair> replicate_rewrite_db;
|
|
|
|
extern I_List<THD> threads;
|
|
|
|
|
|
|
|
#endif
|
2002-12-16 14:33:29 +01:00
|
|
|
#else
|
|
|
|
#define SLAVE_IO 1
|
|
|
|
#define SLAVE_SQL 2
|
2003-01-15 09:11:44 +01:00
|
|
|
#endif /* HAVE_REPLICATION */
|