2003-01-25 14:07:51 +01:00
|
|
|
/* Copyright (C) 2000-2003 MySQL AB
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2000-07-31 21:29:14 +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
|
2006-12-23 20:17:15 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2000-07-31 21:29:14 +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
|
|
|
|
2000-07-31 21:29:14 +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 */
|
|
|
|
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
@addtogroup Replication
|
|
|
|
@{
|
|
|
|
|
|
|
|
@file
|
|
|
|
|
|
|
|
@brief Code to run the io thread and the sql thread on the
|
|
|
|
replication slave.
|
|
|
|
*/
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
#include "mysql_priv.h"
|
2003-01-15 09:11:44 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
#include <mysql.h>
|
2000-12-12 03:34:56 +01:00
|
|
|
#include <myisam.h>
|
2000-11-11 22:50:39 +01:00
|
|
|
#include "slave.h"
|
2007-04-12 08:58:04 +02:00
|
|
|
#include "rpl_mi.h"
|
|
|
|
#include "rpl_rli.h"
|
2001-05-29 03:18:23 +02:00
|
|
|
#include "sql_repl.h"
|
2005-03-21 22:09:42 +01:00
|
|
|
#include "rpl_filter.h"
|
2001-10-11 21:54:06 +02:00
|
|
|
#include "repl_failsafe.h"
|
2000-07-31 21:29:14 +02:00
|
|
|
#include <thr_alarm.h>
|
2002-08-08 15:41:04 +02:00
|
|
|
#include <my_dir.h>
|
2003-05-31 12:15:46 +02:00
|
|
|
#include <sql_common.h>
|
2007-03-16 15:25:20 +01:00
|
|
|
#include <errmsg.h>
|
2009-07-16 08:56:43 +02:00
|
|
|
#include <mysqld_error.h>
|
2007-07-11 16:38:45 +02:00
|
|
|
#include <mysys_err.h>
|
2003-01-15 09:11:44 +01:00
|
|
|
|
2005-12-22 06:39:02 +01:00
|
|
|
#ifdef HAVE_REPLICATION
|
|
|
|
|
|
|
|
#include "rpl_tblmap.h"
|
|
|
|
|
BUG#22864 (Rollback following CREATE... SELECT discards 'CREATE TABLE'
from log):
When row-based logging is used, the CREATE-SELECT is written as two
parts: as a CREATE TABLE statement and as the rows for the table. For
both transactional and non-transactional tables, the CREATE TABLE
statement was written to the transaction cache, as were the rows, and
on statement end, the entire transaction cache was written to the binary
log if the table was non-transactional. For transactional tables, the
events were kept in the transaction cache until end of transaction (or
statement that were not part of a transaction).
For the case when AUTOCOMMIT=0 and we are creating a transactional table
using a create select, we would then keep the CREATE TABLE statement and
the rows for the CREATE-SELECT, while executing the following statements.
On a rollback, the transaction cache would then be cleared, which would
also remove the CREATE TABLE statement. Hence no table would be created
on the slave, while there is an empty table on the master.
This relates to BUG#22865 where the table being created exists on the
master, but not on the slave during insertion of rows into the newly
created table. This occurs since the CREATE TABLE statement were still
in the transaction cache until the statement finished executing, and
possibly longer if the table was transactional.
This patch changes the behaviour of the CREATE-SELECT statement by
adding an implicit commit at the end of the statement when creating
non-temporary tables. Hence, non-temporary tables will be written to the
binary log on completion, and in the even of AUTOCOMMIT=0, a new
transaction will be started. Temporary tables do not commit an ongoing
transaction: neither as a pre- not a post-commit.
The events for both transactional and non-transactional tables are
saved in the transaction cache, and written to the binary log at end
of the statement.
2006-12-21 09:29:02 +01:00
|
|
|
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
|
2006-10-31 12:23:14 +01:00
|
|
|
|
2005-03-23 19:19:36 +01:00
|
|
|
#define MAX_SLAVE_RETRY_PAUSE 5
|
2002-01-22 23:05:11 +01:00
|
|
|
bool use_slave_mask = 0;
|
|
|
|
MY_BITMAP slave_error_mask;
|
2008-11-22 00:22:21 +01:00
|
|
|
char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
|
2002-01-22 23:05:11 +01:00
|
|
|
|
2002-03-08 23:02:11 +01:00
|
|
|
typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
|
|
|
|
|
2001-08-03 23:57:53 +02:00
|
|
|
char* slave_load_tmpdir = 0;
|
2007-08-16 08:52:50 +02:00
|
|
|
Master_info *active_mi= 0;
|
2005-10-04 18:52:12 +02:00
|
|
|
my_bool replicate_same_server_id;
|
2002-08-23 14:14:01 +02:00
|
|
|
ulonglong relay_log_space_limit = 0;
|
2002-06-05 22:04:38 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
When slave thread exits, we need to remember the temporary tables so we
|
|
|
|
can re-use them on slave start.
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
TODO: move the vars below under Master_info
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
2001-01-24 17:15:34 +01:00
|
|
|
|
2000-12-02 18:11:50 +01:00
|
|
|
int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
|
2001-08-03 23:57:53 +02:00
|
|
|
int events_till_abort = -1;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2007-06-29 18:48:22 +02:00
|
|
|
enum enum_slave_reconnect_actions
|
|
|
|
{
|
|
|
|
SLAVE_RECON_ACT_REG= 0,
|
|
|
|
SLAVE_RECON_ACT_DUMP= 1,
|
|
|
|
SLAVE_RECON_ACT_EVENT= 2,
|
|
|
|
SLAVE_RECON_ACT_MAX
|
|
|
|
};
|
|
|
|
|
|
|
|
enum enum_slave_reconnect_messages
|
|
|
|
{
|
|
|
|
SLAVE_RECON_MSG_WAIT= 0,
|
|
|
|
SLAVE_RECON_MSG_KILLED_WAITING= 1,
|
|
|
|
SLAVE_RECON_MSG_AFTER= 2,
|
|
|
|
SLAVE_RECON_MSG_FAILED= 3,
|
|
|
|
SLAVE_RECON_MSG_COMMAND= 4,
|
|
|
|
SLAVE_RECON_MSG_KILLED_AFTER= 5,
|
|
|
|
SLAVE_RECON_MSG_MAX
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *reconnect_messages[SLAVE_RECON_ACT_MAX][SLAVE_RECON_MSG_MAX]=
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"Waiting to reconnect after a failed registration on master",
|
|
|
|
"Slave I/O thread killed while waitnig to reconnect after a failed \
|
|
|
|
registration on master",
|
|
|
|
"Reconnecting after a failed registration on master",
|
|
|
|
"failed registering on master, reconnecting to try again, \
|
|
|
|
log '%s' at postion %s",
|
|
|
|
"COM_REGISTER_SLAVE",
|
|
|
|
"Slave I/O thread killed during or after reconnect"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Waiting to reconnect after a failed binlog dump request",
|
|
|
|
"Slave I/O thread killed while retrying master dump",
|
|
|
|
"Reconnecting after a failed binlog dump request",
|
|
|
|
"failed dump request, reconnecting to try again, log '%s' at postion %s",
|
|
|
|
"COM_BINLOG_DUMP",
|
|
|
|
"Slave I/O thread killed during or after reconnect"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Waiting to reconnect after a failed master event read",
|
|
|
|
"Slave I/O thread killed while waiting to reconnect after a failed read",
|
|
|
|
"Reconnecting after a failed master event read",
|
|
|
|
"Slave I/O thread: Failed reading log event, reconnecting to retry, \
|
|
|
|
log '%s' at postion %s",
|
|
|
|
"",
|
|
|
|
"Slave I/O thread killed during or after a reconnect done to recover from \
|
|
|
|
failed read"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
|
2000-11-21 07:38:08 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
|
|
|
|
static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
|
2007-08-16 07:37:50 +02:00
|
|
|
static bool wait_for_relay_log_space(Relay_log_info* rli);
|
2007-08-16 08:52:50 +02:00
|
|
|
static inline bool io_slave_killed(THD* thd,Master_info* mi);
|
2007-08-16 07:37:50 +02:00
|
|
|
static inline bool sql_slave_killed(THD* thd,Relay_log_info* rli);
|
2002-01-20 03:16:52 +01:00
|
|
|
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
|
2009-04-06 13:42:33 +02:00
|
|
|
static void print_slave_skip_errors(void);
|
2007-08-16 08:52:50 +02:00
|
|
|
static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi);
|
|
|
|
static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
|
2006-07-07 09:27:55 +02:00
|
|
|
bool suppress_warnings);
|
2007-08-16 08:52:50 +02:00
|
|
|
static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
|
2006-07-07 09:27:55 +02:00
|
|
|
bool reconnect, bool suppress_warnings);
|
2002-03-08 23:02:11 +01:00
|
|
|
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
|
2006-07-07 09:27:55 +02:00
|
|
|
void* thread_killed_arg);
|
2001-05-29 03:18:23 +02:00
|
|
|
static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
|
2003-06-14 10:37:42 +02:00
|
|
|
static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
2006-07-07 09:27:55 +02:00
|
|
|
const char* table_name, bool overwrite);
|
2007-08-16 08:52:50 +02:00
|
|
|
static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
|
2007-08-16 07:37:50 +02:00
|
|
|
static Log_event* next_event(Relay_log_info* rli);
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
static int queue_event(Master_info* mi,const char* buf,ulong event_len);
|
2007-08-29 16:06:59 +02:00
|
|
|
static int terminate_slave_thread(THD *thd,
|
2009-04-28 13:46:07 +02:00
|
|
|
pthread_mutex_t *term_lock,
|
|
|
|
pthread_cond_t *term_cond,
|
2007-08-29 16:06:59 +02:00
|
|
|
volatile uint *slave_running,
|
|
|
|
bool skip_lock);
|
2007-11-22 17:22:54 +01:00
|
|
|
static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info);
|
2002-08-08 02:12:02 +02:00
|
|
|
|
|
|
|
/*
|
2003-02-04 20:52:14 +01:00
|
|
|
Find out which replications threads are running
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
SYNOPSIS
|
|
|
|
init_thread_mask()
|
2006-07-07 09:27:55 +02:00
|
|
|
mask Return value here
|
|
|
|
mi master_info for slave
|
|
|
|
inverse If set, returns which threads are not running
|
2003-02-04 20:52:14 +01:00
|
|
|
|
|
|
|
IMPLEMENTATION
|
|
|
|
Get a bit mask for which threads are running so that we can later restart
|
|
|
|
these threads.
|
|
|
|
|
|
|
|
RETURN
|
2006-07-07 09:27:55 +02:00
|
|
|
mask If inverse == 0, running threads
|
|
|
|
If inverse == 1, stopped threads
|
2002-08-08 02:12:02 +02:00
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
void init_thread_mask(int* mask,Master_info* mi,bool inverse)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
bool set_io = mi->slave_running, set_sql = mi->rli.slave_running;
|
|
|
|
register int tmp_mask=0;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("init_thread_mask");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (set_io)
|
|
|
|
tmp_mask |= SLAVE_IO;
|
|
|
|
if (set_sql)
|
|
|
|
tmp_mask |= SLAVE_SQL;
|
2002-08-21 21:04:22 +02:00
|
|
|
if (inverse)
|
|
|
|
tmp_mask^= (SLAVE_IO | SLAVE_SQL);
|
2002-01-20 03:16:52 +01:00
|
|
|
*mask = tmp_mask;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
lock_slave_threads()
|
2003-02-04 20:52:14 +01:00
|
|
|
*/
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
void lock_slave_threads(Master_info* mi)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("lock_slave_threads");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
//TODO: see if we can do this without dual mutex
|
|
|
|
pthread_mutex_lock(&mi->run_lock);
|
|
|
|
pthread_mutex_lock(&mi->rli.run_lock);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
unlock_slave_threads()
|
2003-02-04 20:52:14 +01:00
|
|
|
*/
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
void unlock_slave_threads(Master_info* mi)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("unlock_slave_threads");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
//TODO: see if we can do this without dual mutex
|
|
|
|
pthread_mutex_unlock(&mi->rli.run_lock);
|
|
|
|
pthread_mutex_unlock(&mi->run_lock);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/* Initialize slave structures */
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
int init_slave()
|
|
|
|
{
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_ENTER("init_slave");
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2004-03-11 16:23:35 +01:00
|
|
|
/*
|
|
|
|
This is called when mysqld starts. Before client connections are
|
|
|
|
accepted. However bootstrap may conflict with us if it does START SLAVE.
|
|
|
|
So it's safer to take the lock.
|
|
|
|
*/
|
|
|
|
pthread_mutex_lock(&LOCK_active_mi);
|
2002-08-08 02:12:02 +02:00
|
|
|
/*
|
|
|
|
TODO: re-write this to interate through the list of files
|
|
|
|
for multi-master
|
|
|
|
*/
|
2007-08-16 08:52:50 +02:00
|
|
|
active_mi= new Master_info;
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2009-04-06 13:42:33 +02:00
|
|
|
/*
|
|
|
|
If --slave-skip-errors=... was not used, the string value for the
|
|
|
|
system variable has not been set up yet. Do it now.
|
|
|
|
*/
|
|
|
|
if (!use_slave_mask)
|
|
|
|
{
|
|
|
|
print_slave_skip_errors();
|
|
|
|
}
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
/*
|
2002-08-08 02:12:02 +02:00
|
|
|
If master_host is not specified, try to read it from the master_info file.
|
|
|
|
If master_host is specified, create the master_info file if it doesn't
|
|
|
|
exists.
|
2002-01-20 03:16:52 +01:00
|
|
|
*/
|
2003-06-10 23:29:49 +02:00
|
|
|
if (!active_mi)
|
|
|
|
{
|
|
|
|
sql_print_error("Failed to allocate memory for the master info structure");
|
|
|
|
goto err;
|
|
|
|
}
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2003-06-23 19:05:54 +02:00
|
|
|
if (init_master_info(active_mi,master_info_file,relay_log_info_file,
|
2006-07-07 09:27:55 +02:00
|
|
|
!master_host, (SLAVE_IO | SLAVE_SQL)))
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2003-06-10 23:29:49 +02:00
|
|
|
sql_print_error("Failed to initialize the master info structure");
|
2003-01-28 07:38:28 +01:00
|
|
|
goto err;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
|
|
|
|
if (server_id && !master_host && active_mi->host[0])
|
|
|
|
master_host= active_mi->host;
|
|
|
|
|
2004-05-19 15:03:32 +02:00
|
|
|
/* If server id is not set, start_slave_thread() will say it */
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
if (master_host && !opt_skip_slave_start)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2002-08-08 02:12:02 +02:00
|
|
|
if (start_slave_threads(1 /* need mutex */,
|
2006-07-07 09:27:55 +02:00
|
|
|
0 /* no wait for start*/,
|
|
|
|
active_mi,
|
|
|
|
master_info_file,
|
|
|
|
relay_log_info_file,
|
|
|
|
SLAVE_IO | SLAVE_SQL))
|
2003-01-28 07:38:28 +01:00
|
|
|
{
|
2003-06-10 23:29:49 +02:00
|
|
|
sql_print_error("Failed to create slave threads");
|
2003-01-28 07:38:28 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2004-03-11 16:23:35 +01:00
|
|
|
pthread_mutex_unlock(&LOCK_active_mi);
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2003-01-28 07:38:28 +01:00
|
|
|
err:
|
2004-03-11 16:23:35 +01:00
|
|
|
pthread_mutex_unlock(&LOCK_active_mi);
|
2003-01-28 07:38:28 +01:00
|
|
|
DBUG_RETURN(1);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-06-08 20:02:01 +02:00
|
|
|
|
2008-11-22 00:22:21 +01:00
|
|
|
/**
|
|
|
|
Convert slave skip errors bitmap into a printable string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void print_slave_skip_errors(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
To be safe, we want 10 characters of room in the buffer for a number
|
|
|
|
plus terminators. Also, we need some space for constant strings.
|
|
|
|
10 characters must be sufficient for a number plus {',' | '...'}
|
|
|
|
plus a NUL terminator. That is a max 6 digit number.
|
|
|
|
*/
|
2008-11-27 11:50:28 +01:00
|
|
|
const size_t MIN_ROOM= 10;
|
2008-11-22 00:22:21 +01:00
|
|
|
DBUG_ENTER("print_slave_skip_errors");
|
|
|
|
DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
|
|
|
|
DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
|
|
|
|
|
|
|
|
if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
|
|
|
|
{
|
|
|
|
/* purecov: begin tested */
|
|
|
|
memcpy(slave_skip_error_names, STRING_WITH_LEN("OFF"));
|
|
|
|
/* purecov: end */
|
|
|
|
}
|
|
|
|
else if (bitmap_is_set_all(&slave_error_mask))
|
|
|
|
{
|
|
|
|
/* purecov: begin tested */
|
|
|
|
memcpy(slave_skip_error_names, STRING_WITH_LEN("ALL"));
|
|
|
|
/* purecov: end */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *buff= slave_skip_error_names;
|
|
|
|
char *bend= buff + sizeof(slave_skip_error_names);
|
|
|
|
int errnum;
|
|
|
|
|
2009-04-06 13:42:33 +02:00
|
|
|
for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++)
|
2008-11-22 00:22:21 +01:00
|
|
|
{
|
|
|
|
if (bitmap_is_set(&slave_error_mask, errnum))
|
|
|
|
{
|
|
|
|
if (buff + MIN_ROOM >= bend)
|
|
|
|
break; /* purecov: tested */
|
|
|
|
buff= int10_to_str(errnum, buff, 10);
|
|
|
|
*buff++= ',';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (buff != slave_skip_error_names)
|
|
|
|
buff--; // Remove last ','
|
|
|
|
if (errnum < MAX_SLAVE_ERROR)
|
|
|
|
{
|
|
|
|
/* Couldn't show all errors */
|
|
|
|
buff= strmov(buff, "..."); /* purecov: tested */
|
|
|
|
}
|
|
|
|
*buff=0;
|
|
|
|
}
|
|
|
|
DBUG_PRINT("init", ("error_names: '%s'", slave_skip_error_names));
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2004-09-15 21:10:31 +02:00
|
|
|
Init function to set up array for errors that should be skipped for slave
|
2002-04-30 15:40:46 +02:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
SYNOPSIS
|
|
|
|
init_slave_skip_errors()
|
2006-07-07 09:27:55 +02:00
|
|
|
arg List of errors numbers to skip, separated with ','
|
2003-02-04 20:52:14 +01:00
|
|
|
|
|
|
|
NOTES
|
|
|
|
Called from get_options() in mysqld.cc on start-up
|
|
|
|
*/
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-04-30 15:40:46 +02:00
|
|
|
void init_slave_skip_errors(const char* arg)
|
2002-01-22 23:05:11 +01:00
|
|
|
{
|
2002-04-30 15:40:46 +02:00
|
|
|
const char *p;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("init_slave_skip_errors");
|
|
|
|
|
2003-10-11 13:06:55 +02:00
|
|
|
if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
|
2002-01-22 23:05:11 +01:00
|
|
|
{
|
|
|
|
fprintf(stderr, "Badly out of memory, please check your system status\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
use_slave_mask = 1;
|
2002-03-12 18:37:58 +01:00
|
|
|
for (;my_isspace(system_charset_info,*arg);++arg)
|
2002-01-22 23:05:11 +01:00
|
|
|
/* empty */;
|
2003-04-01 11:17:28 +02:00
|
|
|
if (!my_strnncoll(system_charset_info,(uchar*)arg,4,(const uchar*)"all",4))
|
2002-01-22 23:05:11 +01:00
|
|
|
{
|
|
|
|
bitmap_set_all(&slave_error_mask);
|
2009-04-05 14:03:04 +02:00
|
|
|
print_slave_skip_errors();
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-22 23:05:11 +01:00
|
|
|
}
|
|
|
|
for (p= arg ; *p; )
|
|
|
|
{
|
|
|
|
long err_code;
|
|
|
|
if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
|
|
|
|
break;
|
|
|
|
if (err_code < MAX_SLAVE_ERROR)
|
|
|
|
bitmap_set_bit(&slave_error_mask,(uint)err_code);
|
2002-03-12 18:37:58 +01:00
|
|
|
while (!my_isdigit(system_charset_info,*p) && *p)
|
2002-01-22 23:05:11 +01:00
|
|
|
p++;
|
|
|
|
}
|
2008-11-22 00:22:21 +01:00
|
|
|
/* Convert slave skip errors bitmap into a printable string. */
|
|
|
|
print_slave_skip_errors();
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-22 23:05:11 +01:00
|
|
|
}
|
|
|
|
|
2009-05-23 01:29:41 +02:00
|
|
|
static void set_thd_in_use_temporary_tables(Relay_log_info *rli)
|
2009-05-23 01:15:21 +02:00
|
|
|
{
|
|
|
|
TABLE *table;
|
|
|
|
|
|
|
|
for (table= rli->save_temporary_tables ; table ; table= table->next)
|
|
|
|
table->in_use= rli->sql_thd;
|
|
|
|
}
|
2004-04-07 00:57:14 +02:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("terminate_slave_threads");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (!mi->inited)
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0); /* successfully do nothing */
|
2002-01-20 03:16:52 +01:00
|
|
|
int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
|
|
|
|
pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2009-04-28 13:46:07 +02:00
|
|
|
if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2003-01-07 15:53:10 +01:00
|
|
|
DBUG_PRINT("info",("Terminating IO thread"));
|
2002-01-20 03:16:52 +01:00
|
|
|
mi->abort_slave=1;
|
2009-04-28 13:46:07 +02:00
|
|
|
if ((error=terminate_slave_thread(mi->io_thd, io_lock,
|
2006-07-07 09:27:55 +02:00
|
|
|
&mi->stop_cond,
|
2007-08-29 16:06:59 +02:00
|
|
|
&mi->slave_running,
|
|
|
|
skip_lock)) &&
|
2006-07-07 09:27:55 +02:00
|
|
|
!force_all)
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2009-04-28 13:46:07 +02:00
|
|
|
if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2003-01-07 15:53:10 +01:00
|
|
|
DBUG_PRINT("info",("Terminating SQL thread"));
|
2002-01-20 03:16:52 +01:00
|
|
|
mi->rli.abort_slave=1;
|
2009-04-28 13:46:07 +02:00
|
|
|
if ((error=terminate_slave_thread(mi->rli.sql_thd, sql_lock,
|
2006-07-07 09:27:55 +02:00
|
|
|
&mi->rli.stop_cond,
|
2007-08-29 16:06:59 +02:00
|
|
|
&mi->rli.slave_running,
|
|
|
|
skip_lock)) &&
|
2006-07-07 09:27:55 +02:00
|
|
|
!force_all)
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2007-08-29 16:06:59 +02:00
|
|
|
/**
|
|
|
|
Wait for a slave thread to terminate.
|
|
|
|
|
|
|
|
This function is called after requesting the thread to terminate
|
|
|
|
(by setting @c abort_slave member of @c Relay_log_info or @c
|
|
|
|
Master_info structure to 1). Termination of the thread is
|
|
|
|
controlled with the the predicate <code>*slave_running</code>.
|
|
|
|
|
|
|
|
Function will acquire @c term_lock before waiting on the condition
|
|
|
|
unless @c skip_lock is true in which case the mutex should be owned
|
|
|
|
by the caller of this function and will remain acquired after
|
|
|
|
return from the function.
|
|
|
|
|
|
|
|
@param term_lock
|
|
|
|
Associated lock to use when waiting for @c term_cond
|
|
|
|
|
|
|
|
@param term_cond
|
|
|
|
Condition that is signalled when the thread has terminated
|
|
|
|
|
|
|
|
@param slave_running
|
|
|
|
Pointer to predicate to check for slave thread termination
|
|
|
|
|
|
|
|
@param skip_lock
|
|
|
|
If @c true the lock will not be acquired before waiting on
|
|
|
|
the condition. In this case, it is assumed that the calling
|
|
|
|
function acquires the lock before calling this function.
|
|
|
|
|
2009-04-30 15:17:46 +02:00
|
|
|
@retval 0 All OK ER_SLAVE_NOT_RUNNING otherwise.
|
2009-04-28 13:46:07 +02:00
|
|
|
|
2009-04-30 15:17:46 +02:00
|
|
|
@note If the executing thread has to acquire term_lock (skip_lock
|
|
|
|
is false), the negative running status does not represent
|
|
|
|
any issue therefore no error is reported.
|
2009-04-28 13:46:07 +02:00
|
|
|
|
2007-08-29 16:06:59 +02:00
|
|
|
*/
|
|
|
|
static int
|
|
|
|
terminate_slave_thread(THD *thd,
|
2009-04-30 15:17:46 +02:00
|
|
|
pthread_mutex_t *term_lock,
|
|
|
|
pthread_cond_t *term_cond,
|
2007-08-29 16:06:59 +02:00
|
|
|
volatile uint *slave_running,
|
|
|
|
bool skip_lock)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2005-02-03 16:22:16 +01:00
|
|
|
DBUG_ENTER("terminate_slave_thread");
|
2007-08-29 16:06:59 +02:00
|
|
|
if (!skip_lock)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
pthread_mutex_lock(term_lock);
|
2009-04-28 13:46:07 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
safe_mutex_assert_owner(term_lock);
|
|
|
|
}
|
2007-08-29 16:06:59 +02:00
|
|
|
if (!*slave_running)
|
|
|
|
{
|
|
|
|
if (!skip_lock)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2009-04-28 13:46:07 +02:00
|
|
|
/*
|
|
|
|
if run_lock (term_lock) is acquired locally then either
|
|
|
|
slave_running status is fine
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_unlock(term_lock);
|
2009-04-28 13:46:07 +02:00
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-02-03 16:22:16 +01:00
|
|
|
DBUG_RETURN(ER_SLAVE_NOT_RUNNING);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
DBUG_ASSERT(thd != 0);
|
2005-02-09 20:04:28 +01:00
|
|
|
THD_CHECK_SENTRY(thd);
|
2007-08-29 16:06:59 +02:00
|
|
|
|
2002-06-12 14:04:18 +02:00
|
|
|
/*
|
2005-02-09 20:04:28 +01:00
|
|
|
Is is critical to test if the slave is running. Otherwise, we might
|
2002-06-12 14:04:18 +02:00
|
|
|
be referening freed memory trying to kick it
|
2002-03-16 02:44:44 +01:00
|
|
|
*/
|
2003-03-12 00:40:06 +01:00
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
while (*slave_running) // Should always be true
|
2002-03-16 02:44:44 +01:00
|
|
|
{
|
2009-04-28 13:46:07 +02:00
|
|
|
int error;
|
2005-02-03 16:22:16 +01:00
|
|
|
DBUG_PRINT("loop", ("killing slave thread"));
|
2008-03-11 14:42:54 +01:00
|
|
|
|
2009-07-24 17:58:58 +02:00
|
|
|
pthread_mutex_lock(&thd->LOCK_thd_data);
|
2008-03-11 14:42:54 +01:00
|
|
|
#ifndef DONT_USE_THR_ALARM
|
|
|
|
/*
|
|
|
|
Error codes from pthread_kill are:
|
|
|
|
EINVAL: invalid signal number (can't happen)
|
|
|
|
ESRCH: thread already killed (can happen, should be ignored)
|
|
|
|
*/
|
|
|
|
IF_DBUG(int err= ) pthread_kill(thd->real_id, thr_client_alarm);
|
|
|
|
DBUG_ASSERT(err != EINVAL);
|
|
|
|
#endif
|
|
|
|
thd->awake(THD::NOT_KILLED);
|
2009-07-24 17:58:58 +02:00
|
|
|
pthread_mutex_unlock(&thd->LOCK_thd_data);
|
2008-03-11 14:42:54 +01:00
|
|
|
|
2002-06-12 14:04:18 +02:00
|
|
|
/*
|
|
|
|
There is a small chance that slave thread might miss the first
|
|
|
|
alarm. To protect againts it, resend the signal until it reacts
|
2002-01-20 03:16:52 +01:00
|
|
|
*/
|
|
|
|
struct timespec abstime;
|
2002-06-12 14:04:18 +02:00
|
|
|
set_timespec(abstime,2);
|
2007-08-29 16:06:59 +02:00
|
|
|
error= pthread_cond_timedwait(term_cond, term_lock, &abstime);
|
|
|
|
DBUG_ASSERT(error == ETIMEDOUT || error == 0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2007-08-29 16:06:59 +02:00
|
|
|
|
|
|
|
DBUG_ASSERT(*slave_running == 0);
|
|
|
|
|
|
|
|
if (!skip_lock)
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_unlock(term_lock);
|
2005-02-03 16:22:16 +01:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-08-24 04:44:16 +02:00
|
|
|
int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
|
2006-07-07 09:27:55 +02:00
|
|
|
pthread_mutex_t *cond_lock,
|
|
|
|
pthread_cond_t *start_cond,
|
|
|
|
volatile uint *slave_running,
|
|
|
|
volatile ulong *slave_run_id,
|
2007-08-16 08:52:50 +02:00
|
|
|
Master_info* mi,
|
2003-03-01 23:59:27 +01:00
|
|
|
bool high_priority)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
pthread_t th;
|
2002-08-24 04:44:16 +02:00
|
|
|
ulong start_id;
|
|
|
|
DBUG_ENTER("start_slave_thread");
|
|
|
|
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ASSERT(mi->inited);
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (start_lock)
|
|
|
|
pthread_mutex_lock(start_lock);
|
|
|
|
if (!server_id)
|
|
|
|
{
|
|
|
|
if (start_cond)
|
|
|
|
pthread_cond_broadcast(start_cond);
|
|
|
|
if (start_lock)
|
|
|
|
pthread_mutex_unlock(start_lock);
|
|
|
|
sql_print_error("Server id not set, will not start slave");
|
2002-08-24 04:44:16 +02:00
|
|
|
DBUG_RETURN(ER_BAD_SLAVE);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (*slave_running)
|
2002-08-08 02:12:02 +02:00
|
|
|
{
|
|
|
|
if (start_cond)
|
|
|
|
pthread_cond_broadcast(start_cond);
|
|
|
|
if (start_lock)
|
|
|
|
pthread_mutex_unlock(start_lock);
|
2002-08-24 04:44:16 +02:00
|
|
|
DBUG_RETURN(ER_SLAVE_MUST_STOP);
|
2002-08-08 02:12:02 +02:00
|
|
|
}
|
2002-08-24 04:44:16 +02:00
|
|
|
start_id= *slave_run_id;
|
|
|
|
DBUG_PRINT("info",("Creating new slave thread"));
|
2003-03-01 23:59:27 +01:00
|
|
|
if (high_priority)
|
|
|
|
my_pthread_attr_setprio(&connection_attrib,CONNECT_PRIOR);
|
2002-01-20 03:16:52 +01:00
|
|
|
if (pthread_create(&th, &connection_attrib, h_func, (void*)mi))
|
|
|
|
{
|
|
|
|
if (start_lock)
|
|
|
|
pthread_mutex_unlock(start_lock);
|
2002-08-24 04:44:16 +02:00
|
|
|
DBUG_RETURN(ER_SLAVE_THREAD);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2004-07-31 22:33:20 +02:00
|
|
|
if (start_cond && cond_lock) // caller has cond_lock
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
THD* thd = current_thd;
|
2002-08-24 04:44:16 +02:00
|
|
|
while (start_id == *slave_run_id)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2002-08-24 04:44:16 +02:00
|
|
|
DBUG_PRINT("sleep",("Waiting for slave thread to start"));
|
2002-01-20 03:16:52 +01:00
|
|
|
const char* old_msg = thd->enter_cond(start_cond,cond_lock,
|
2006-07-07 09:27:55 +02:00
|
|
|
"Waiting for slave thread to start");
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_cond_wait(start_cond,cond_lock);
|
|
|
|
thd->exit_cond(old_msg);
|
2004-07-31 22:33:20 +02:00
|
|
|
pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
|
2002-01-20 03:16:52 +01:00
|
|
|
if (thd->killed)
|
2006-07-07 09:27:55 +02:00
|
|
|
DBUG_RETURN(thd->killed_errno());
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (start_lock)
|
|
|
|
pthread_mutex_unlock(start_lock);
|
2002-08-24 04:44:16 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
start_slave_threads()
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
NOTES
|
|
|
|
SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
|
|
|
|
sense to do that for starting a slave--we always care if it actually
|
|
|
|
started the threads that were not previously running
|
2002-01-20 03:16:52 +01:00
|
|
|
*/
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
|
2007-08-16 08:52:50 +02:00
|
|
|
Master_info* mi, const char* master_info_fname,
|
2006-07-07 09:27:55 +02:00
|
|
|
const char* slave_info_fname, int thread_mask)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
pthread_mutex_t *lock_io=0,*lock_sql=0,*lock_cond_io=0,*lock_cond_sql=0;
|
|
|
|
pthread_cond_t* cond_io=0,*cond_sql=0;
|
|
|
|
int error=0;
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_ENTER("start_slave_threads");
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (need_slave_mutex)
|
|
|
|
{
|
|
|
|
lock_io = &mi->run_lock;
|
|
|
|
lock_sql = &mi->rli.run_lock;
|
|
|
|
}
|
|
|
|
if (wait_for_start)
|
|
|
|
{
|
|
|
|
cond_io = &mi->start_cond;
|
|
|
|
cond_sql = &mi->rli.start_cond;
|
|
|
|
lock_cond_io = &mi->run_lock;
|
|
|
|
lock_cond_sql = &mi->rli.run_lock;
|
|
|
|
}
|
2002-06-08 20:02:01 +02:00
|
|
|
|
|
|
|
if (thread_mask & SLAVE_IO)
|
|
|
|
error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
|
2006-07-07 09:27:55 +02:00
|
|
|
cond_io,
|
|
|
|
&mi->slave_running, &mi->slave_run_id,
|
|
|
|
mi, 1); //high priority, to read the most possible
|
2002-06-08 20:02:01 +02:00
|
|
|
if (!error && (thread_mask & SLAVE_SQL))
|
2002-08-21 21:04:22 +02:00
|
|
|
{
|
2002-06-08 20:02:01 +02:00
|
|
|
error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
|
2006-07-07 09:27:55 +02:00
|
|
|
cond_sql,
|
|
|
|
&mi->rli.slave_running, &mi->rli.slave_run_id,
|
|
|
|
mi, 0);
|
2002-08-21 21:04:22 +02:00
|
|
|
if (error)
|
2009-04-28 13:46:07 +02:00
|
|
|
terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex);
|
2002-08-21 21:04:22 +02:00
|
|
|
}
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2000-11-11 22:50:39 +01:00
|
|
|
|
2002-06-08 20:02:01 +02:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
#ifdef NOT_USED_YET
|
2007-08-16 08:52:50 +02:00
|
|
|
static int end_slave_on_walk(Master_info* mi, uchar* /*unused*/)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("end_slave_on_walk");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
end_master_info(mi);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-08-23 14:14:01 +02:00
|
|
|
#endif
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2009-06-23 11:10:04 +02:00
|
|
|
Release slave threads at time of executing shutdown.
|
2003-02-04 20:52:14 +01:00
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
end_slave()
|
|
|
|
*/
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2000-12-09 22:28:51 +01:00
|
|
|
void end_slave()
|
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("end_slave");
|
|
|
|
|
2004-03-11 16:23:35 +01:00
|
|
|
/*
|
|
|
|
This is called when the server terminates, in close_connections().
|
|
|
|
It terminates slave threads. However, some CHANGE MASTER etc may still be
|
|
|
|
running presently. If a START SLAVE was in progress, the mutex lock below
|
|
|
|
will make us wait until slave threads have started, and START SLAVE
|
|
|
|
returns, then we terminate them here.
|
|
|
|
*/
|
|
|
|
pthread_mutex_lock(&LOCK_active_mi);
|
2003-01-28 07:38:28 +01:00
|
|
|
if (active_mi)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
TODO: replace the line below with
|
|
|
|
list_walk(&master_list, (list_walk_action)end_slave_on_walk,0);
|
|
|
|
once multi-master code is ready.
|
|
|
|
*/
|
|
|
|
terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
|
2009-06-23 11:10:04 +02:00
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&LOCK_active_mi);
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Free all resources used by slave threads at time of executing shutdown.
|
|
|
|
The routine must be called after all possible users of @c active_mi
|
|
|
|
have left.
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
close_active_mi()
|
|
|
|
|
|
|
|
*/
|
|
|
|
void close_active_mi()
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&LOCK_active_mi);
|
|
|
|
if (active_mi)
|
|
|
|
{
|
2003-01-28 07:38:28 +01:00
|
|
|
end_master_info(active_mi);
|
|
|
|
delete active_mi;
|
|
|
|
active_mi= 0;
|
|
|
|
}
|
2004-03-11 16:23:35 +01:00
|
|
|
pthread_mutex_unlock(&LOCK_active_mi);
|
2000-12-09 22:28:51 +01:00
|
|
|
}
|
2000-11-21 07:38:08 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static bool io_slave_killed(THD* thd, Master_info* mi)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("io_slave_killed");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(mi->io_thd == thd);
|
2004-12-16 18:12:22 +01:00
|
|
|
DBUG_ASSERT(mi->slave_running); // tracking buffer overrun
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(mi->abort_slave || abort_loop || thd->killed);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 07:37:50 +02:00
|
|
|
static bool sql_slave_killed(THD* thd, Relay_log_info* rli)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("sql_slave_killed");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->sql_thd == thd);
|
|
|
|
DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
|
2005-12-22 06:39:02 +01:00
|
|
|
if (abort_loop || thd->killed || rli->abort_slave)
|
|
|
|
{
|
2009-03-26 09:25:06 +01:00
|
|
|
if (rli->abort_slave && rli->is_in_group() &&
|
|
|
|
thd->transaction.all.modified_non_trans_table)
|
|
|
|
DBUG_RETURN(0);
|
2005-12-22 06:39:02 +01:00
|
|
|
/*
|
|
|
|
If we are in an unsafe situation (stopping could corrupt replication),
|
|
|
|
we give one minute to the slave SQL thread of grace before really
|
|
|
|
terminating, in the hope that it will be able to read more events and
|
|
|
|
the unsafe situation will soon be left. Note that this one minute starts
|
|
|
|
from the last time anything happened in the slave SQL thread. So it's
|
|
|
|
really one minute of idleness, we don't timeout if the slave SQL thread
|
|
|
|
is actively working.
|
|
|
|
*/
|
2007-01-17 15:06:37 +01:00
|
|
|
if (rli->last_event_start_time == 0)
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2005-12-22 06:39:02 +01:00
|
|
|
DBUG_PRINT("info", ("Slave SQL thread is in an unsafe situation, giving "
|
|
|
|
"it some grace period"));
|
2007-01-17 15:06:37 +01:00
|
|
|
if (difftime(time(0), rli->last_event_start_time) > 60)
|
2005-12-22 06:39:02 +01:00
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
rli->report(ERROR_LEVEL, 0,
|
|
|
|
"SQL thread had to stop in an unsafe situation, in "
|
|
|
|
"the middle of applying updates to a "
|
|
|
|
"non-transactional table without any primary key. "
|
|
|
|
"There is a risk of duplicate updates when the slave "
|
|
|
|
"SQL thread is restarted. Please check your tables' "
|
|
|
|
"contents after restart.");
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2005-12-22 06:39:02 +01:00
|
|
|
}
|
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
skip_load_data_infile()
|
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
NOTES
|
|
|
|
This is used to tell a 3.23 master to break send_file()
|
|
|
|
*/
|
2002-10-02 12:33:08 +02:00
|
|
|
|
|
|
|
void skip_load_data_infile(NET *net)
|
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("skip_load_data_infile");
|
|
|
|
|
2002-10-02 12:33:08 +02:00
|
|
|
(void)net_request_file(net, "/dev/null");
|
2006-07-07 09:27:55 +02:00
|
|
|
(void)my_net_read(net); // discard response
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
(void)net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0); // ok
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-10-02 12:33:08 +02:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-10-02 12:33:08 +02:00
|
|
|
bool net_request_file(NET* net, const char* fname)
|
2000-10-03 01:59:12 +02:00
|
|
|
{
|
2002-10-02 12:33:08 +02:00
|
|
|
DBUG_ENTER("net_request_file");
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
DBUG_RETURN(net_write_command(net, 251, (uchar*) fname, strlen(fname),
|
|
|
|
(uchar*) "", 0));
|
2000-10-03 01:59:12 +02:00
|
|
|
}
|
|
|
|
|
2003-07-24 22:25:36 +02:00
|
|
|
/*
|
|
|
|
From other comments and tests in code, it looks like
|
2003-08-07 19:16:37 +02:00
|
|
|
sometimes Query_log_event and Load_log_event can have db == 0
|
2003-07-24 22:25:36 +02:00
|
|
|
(see rewrite_db() above for example)
|
|
|
|
(cases where this happens are unclear; it may be when the master is 3.23).
|
|
|
|
*/
|
2003-08-07 19:16:37 +02:00
|
|
|
|
|
|
|
const char *print_slave_db_safe(const char* db)
|
2003-07-24 22:25:36 +02:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("*print_slave_db_safe");
|
|
|
|
|
|
|
|
DBUG_RETURN((db ? db : ""));
|
2003-07-24 22:25:36 +02:00
|
|
|
}
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2006-10-31 12:23:14 +01:00
|
|
|
int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
|
2006-07-07 09:27:55 +02:00
|
|
|
const char *default_val)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2001-01-22 03:46:32 +01:00
|
|
|
uint length;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("init_strvar_from_file");
|
|
|
|
|
2001-01-22 03:46:32 +01:00
|
|
|
if ((length=my_b_gets(f,var, max_size)))
|
|
|
|
{
|
|
|
|
char* last_p = var + length -1;
|
|
|
|
if (*last_p == '\n')
|
|
|
|
*last_p = 0; // if we stopped on newline, kill it
|
|
|
|
else
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
If we truncated a line or stopped on last char, remove all chars
|
|
|
|
up to and including newline.
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
2001-01-22 03:46:32 +01:00
|
|
|
int c;
|
2009-06-09 18:11:21 +02:00
|
|
|
while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) ;
|
2000-12-15 04:17:18 +01:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
|
|
|
else if (default_val)
|
|
|
|
{
|
2001-10-02 21:21:14 +02:00
|
|
|
strmake(var, default_val, max_size-1);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2006-10-31 12:23:14 +01:00
|
|
|
int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
char buf[32];
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("init_intvar_from_file");
|
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
|
|
|
|
if (my_b_gets(f, buf, sizeof(buf)))
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
|
|
|
*var = atoi(buf);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2002-06-05 22:04:38 +02:00
|
|
|
else if (default_val)
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
|
|
|
*var = default_val;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2009-07-16 08:56:43 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Check if the error is caused by network.
|
|
|
|
@param[in] errorno Number of the error.
|
|
|
|
RETURNS:
|
|
|
|
TRUE network error
|
|
|
|
FALSE not network error
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool is_network_error(uint errorno)
|
|
|
|
{
|
|
|
|
if (errorno == CR_CONNECTION_ERROR ||
|
|
|
|
errorno == CR_CONN_HOST_ERROR ||
|
|
|
|
errorno == CR_SERVER_GONE_ERROR ||
|
|
|
|
errorno == CR_SERVER_LOST ||
|
|
|
|
errorno == ER_CON_COUNT_ERROR ||
|
|
|
|
errorno == ER_SERVER_SHUTDOWN)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/*
|
|
|
|
Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
|
|
|
|
relying on the binlog's version. This is not perfect: imagine an upgrade
|
|
|
|
of the master without waiting that all slaves are in sync with the master;
|
|
|
|
then a slave could be fooled about the binlog's format. This is what happens
|
|
|
|
when people upgrade a 3.23 master to 4.0 without doing RESET MASTER: 4.0
|
|
|
|
slaves are fooled. So we do this only to distinguish between 3.23 and more
|
|
|
|
recent masters (it's too late to change things for 3.23).
|
2006-07-07 09:27:55 +02:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
RETURNS
|
|
|
|
0 ok
|
|
|
|
1 error
|
2009-07-16 08:56:43 +02:00
|
|
|
2 transient network problem, the caller should try to reconnect
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
*/
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
|
2001-11-11 06:24:12 +01:00
|
|
|
{
|
2008-02-20 22:18:01 +01:00
|
|
|
char err_buff[MAX_SLAVE_ERRMSG];
|
2002-08-08 02:12:02 +02:00
|
|
|
const char* errmsg= 0;
|
2008-02-20 22:18:01 +01:00
|
|
|
int err_code= 0;
|
|
|
|
MYSQL_RES *master_res= 0;
|
|
|
|
MYSQL_ROW master_row;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("get_master_version_and_clock");
|
2003-12-19 22:40:23 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Free old description_event_for_queue (that is needed if we are in
|
|
|
|
a reconnection).
|
|
|
|
*/
|
|
|
|
delete mi->rli.relay_log.description_event_for_queue;
|
|
|
|
mi->rli.relay_log.description_event_for_queue= 0;
|
2006-07-07 09:27:55 +02:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
if (!my_isdigit(&my_charset_bin,*mysql->server_version))
|
2008-02-20 22:18:01 +01:00
|
|
|
{
|
2003-10-23 16:06:51 +02:00
|
|
|
errmsg = "Master reported unrecognized MySQL version";
|
2008-02-20 22:18:01 +01:00
|
|
|
err_code= ER_SLAVE_FATAL_ERROR;
|
|
|
|
sprintf(err_buff, ER(err_code), 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.
2003-12-18 01:09:05 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Note the following switch will bug when we have MySQL branch 30 ;)
|
|
|
|
*/
|
2006-07-07 09:27:55 +02:00
|
|
|
switch (*mysql->server_version)
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
{
|
|
|
|
case '0':
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
errmsg = "Master reported unrecognized MySQL version";
|
2008-02-20 22:18:01 +01:00
|
|
|
err_code= ER_SLAVE_FATAL_ERROR;
|
|
|
|
sprintf(err_buff, ER(err_code), 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.
2003-12-18 01:09:05 +01:00
|
|
|
break;
|
|
|
|
case '3':
|
|
|
|
mi->rli.relay_log.description_event_for_queue= new
|
2006-07-07 09:27:55 +02:00
|
|
|
Format_description_log_event(1, mysql->server_version);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
break;
|
|
|
|
case '4':
|
|
|
|
mi->rli.relay_log.description_event_for_queue= new
|
2006-07-07 09:27:55 +02:00
|
|
|
Format_description_log_event(3, mysql->server_version);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
break;
|
2006-07-07 09:27:55 +02:00
|
|
|
default:
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/*
|
|
|
|
Master is MySQL >=5.0. Give a default Format_desc event, so that we can
|
|
|
|
take the early steps (like tests for "is this a 3.23 master") which we
|
|
|
|
have to take before we receive the real master's Format_desc which will
|
|
|
|
override this one. Note that the Format_desc we create below is garbage
|
|
|
|
(it has the format of the *slave*); it's only good to help know if the
|
|
|
|
master is 3.23, 4.0, etc.
|
|
|
|
*/
|
|
|
|
mi->rli.relay_log.description_event_for_queue= new
|
2006-07-07 09:27:55 +02:00
|
|
|
Format_description_log_event(4, mysql->server_version);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
break;
|
|
|
|
}
|
2001-11-11 06:24:12 +01:00
|
|
|
}
|
2006-07-07 09:27:55 +02:00
|
|
|
|
|
|
|
/*
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
This does not mean that a 5.0 slave will be able to read a 6.0 master; but
|
|
|
|
as we don't know yet, we don't want to forbid this for now. If a 5.0 slave
|
|
|
|
can't read a 6.0 master, this will show up when the slave can't read some
|
|
|
|
events sent by the master, and there will be error messages.
|
|
|
|
*/
|
2006-07-07 09:27:55 +02:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
if (errmsg)
|
2008-02-20 22:18:01 +01:00
|
|
|
goto err;
|
2003-12-19 22:40:23 +01:00
|
|
|
|
|
|
|
/* as we are here, we tried to allocate the event */
|
|
|
|
if (!mi->rli.relay_log.description_event_for_queue)
|
|
|
|
{
|
2008-02-20 22:18:01 +01:00
|
|
|
errmsg= "default Format_description_log_event";
|
|
|
|
err_code= ER_SLAVE_CREATE_EVENT_FAILURE;
|
|
|
|
sprintf(err_buff, ER(err_code), errmsg);
|
|
|
|
goto err;
|
2003-12-19 22:40:23 +01:00
|
|
|
}
|
|
|
|
|
2004-06-03 23:17:18 +02:00
|
|
|
/*
|
|
|
|
Compare the master and slave's clock. Do not die if master's clock is
|
|
|
|
unavailable (very old master not supporting UNIX_TIMESTAMP()?).
|
|
|
|
*/
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2009-07-16 08:56:43 +02:00
|
|
|
DBUG_SYNC_POINT("debug_lock.before_get_UNIX_TIMESTAMP", 10);
|
|
|
|
master_res= NULL;
|
2005-11-20 19:47:07 +01:00
|
|
|
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
|
2004-06-03 23:17:18 +02:00
|
|
|
(master_res= mysql_store_result(mysql)) &&
|
|
|
|
(master_row= mysql_fetch_row(master_res)))
|
2003-10-09 00:06:21 +02:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->clock_diff_with_master=
|
2004-06-03 23:17:18 +02:00
|
|
|
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
|
2003-10-09 00:06:21 +02:00
|
|
|
}
|
2009-07-16 08:56:43 +02:00
|
|
|
else if (is_network_error(mysql_errno(mysql)))
|
|
|
|
{
|
|
|
|
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
|
|
|
"Get master clock failed with error: %s", mysql_error(mysql));
|
|
|
|
goto network_err;
|
|
|
|
}
|
|
|
|
else
|
2003-10-09 00:06:21 +02:00
|
|
|
{
|
2004-06-03 23:17:18 +02:00
|
|
|
mi->clock_diff_with_master= 0; /* The "most sensible" value */
|
2007-04-17 13:41:16 +02:00
|
|
|
sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, "
|
|
|
|
"do not trust column Seconds_Behind_Master of SHOW "
|
|
|
|
"SLAVE STATUS. Error: %s (%d)",
|
|
|
|
mysql_error(mysql), mysql_errno(mysql));
|
2004-06-03 23:17:18 +02:00
|
|
|
}
|
|
|
|
if (master_res)
|
2009-07-16 08:56:43 +02:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
mysql_free_result(master_res);
|
2009-07-16 08:56:43 +02:00
|
|
|
master_res= NULL;
|
|
|
|
}
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2004-06-03 23:17:18 +02:00
|
|
|
/*
|
|
|
|
Check that the master's server id and ours are different. Because if they
|
|
|
|
are equal (which can result from a simple copy of master's datadir to slave,
|
|
|
|
thus copying some my.cnf), replication will work but all events will be
|
|
|
|
skipped.
|
|
|
|
Do not die if SHOW VARIABLES LIKE 'SERVER_ID' fails on master (very old
|
|
|
|
master?).
|
|
|
|
Note: we could have put a @@SERVER_ID in the previous SELECT
|
|
|
|
UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
|
|
|
|
*/
|
2009-07-16 08:56:43 +02:00
|
|
|
DBUG_SYNC_POINT("debug_lock.before_get_SERVER_ID", 10);
|
|
|
|
master_res= NULL;
|
|
|
|
master_row= NULL;
|
2005-11-20 19:47:07 +01:00
|
|
|
if (!mysql_real_query(mysql,
|
|
|
|
STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_ID'")) &&
|
2009-07-16 08:56:43 +02:00
|
|
|
(master_res= mysql_store_result(mysql)) &&
|
|
|
|
(master_row= mysql_fetch_row(master_res)))
|
2004-06-03 23:17:18 +02:00
|
|
|
{
|
2009-07-16 08:56:43 +02:00
|
|
|
if ((::server_id == strtoul(master_row[1], 0, 10)) &&
|
2007-03-22 08:32:41 +01:00
|
|
|
!mi->rli.replicate_same_server_id)
|
2008-02-20 22:18:01 +01:00
|
|
|
{
|
2004-06-03 23:17:18 +02:00
|
|
|
errmsg= "The slave I/O thread stops because master and slave have equal \
|
|
|
|
MySQL server ids; these ids must be different for replication to work (or \
|
|
|
|
the --replicate-same-server-id option must be used on slave but this does \
|
|
|
|
not always make sense; please check the manual before using it).";
|
2008-02-20 22:18:01 +01:00
|
|
|
err_code= ER_SLAVE_FATAL_ERROR;
|
|
|
|
sprintf(err_buff, ER(err_code), errmsg);
|
2009-07-16 08:56:43 +02:00
|
|
|
goto err;
|
2008-02-20 22:18:01 +01:00
|
|
|
}
|
2009-07-16 08:56:43 +02:00
|
|
|
}
|
|
|
|
else if (mysql_errno(mysql))
|
|
|
|
{
|
|
|
|
if (is_network_error(mysql_errno(mysql)))
|
|
|
|
{
|
|
|
|
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
|
|
|
"Get master SERVER_ID failed with error: %s", mysql_error(mysql));
|
|
|
|
goto network_err;
|
|
|
|
}
|
|
|
|
/* Fatal error */
|
|
|
|
errmsg= "The slave I/O thread stops because a fatal error is encountered \
|
|
|
|
when it try to get the value of SERVER_ID variable from master.";
|
|
|
|
err_code= mysql_errno(mysql);
|
|
|
|
sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else if (!master_row && master_res)
|
|
|
|
{
|
|
|
|
mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
|
|
|
|
"Unknown system variable 'SERVER_ID' on master, \
|
|
|
|
maybe it is a *VERY OLD MASTER*.");
|
|
|
|
}
|
|
|
|
if (master_res)
|
|
|
|
{
|
2004-06-03 23:17:18 +02:00
|
|
|
mysql_free_result(master_res);
|
2009-07-16 08:56:43 +02:00
|
|
|
master_res= NULL;
|
2003-10-09 00:06:21 +02:00
|
|
|
}
|
|
|
|
|
2004-06-03 23:17:18 +02:00
|
|
|
/*
|
|
|
|
Check that the master's global character_set_server and ours are the same.
|
|
|
|
Not fatal if query fails (old master?).
|
2004-08-12 13:12:09 +02:00
|
|
|
Note that we don't check for equality of global character_set_client and
|
|
|
|
collation_connection (neither do we prevent their setting in
|
|
|
|
set_var.cc). That's because from what I (Guilhem) have tested, the global
|
|
|
|
values of these 2 are never used (new connections don't use them).
|
|
|
|
We don't test equality of global collation_database either as it's is
|
|
|
|
going to be deprecated (made read-only) in 4.1 very soon.
|
2005-02-03 16:22:16 +01:00
|
|
|
The test is only relevant if master < 5.0.3 (we'll test only if it's older
|
|
|
|
than the 5 branch; < 5.0.3 was alpha...), as >= 5.0.3 master stores
|
|
|
|
charset info in each binlog event.
|
|
|
|
We don't do it for 3.23 because masters <3.23.50 hang on
|
|
|
|
SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). So finally we
|
|
|
|
test only if master is 4.x.
|
2004-06-03 23:17:18 +02:00
|
|
|
*/
|
2005-02-03 16:22:16 +01:00
|
|
|
|
|
|
|
/* redundant with rest of code but safer against later additions */
|
|
|
|
if (*mysql->server_version == '3')
|
2005-01-17 21:26:14 +01:00
|
|
|
goto err;
|
2005-02-03 16:22:16 +01:00
|
|
|
|
2009-07-16 08:56:43 +02:00
|
|
|
if (*mysql->server_version == '4')
|
2003-10-09 00:06:21 +02:00
|
|
|
{
|
2009-07-16 08:56:43 +02:00
|
|
|
master_res= NULL;
|
|
|
|
if (!mysql_real_query(mysql,
|
|
|
|
STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) &&
|
|
|
|
(master_res= mysql_store_result(mysql)) &&
|
|
|
|
(master_row= mysql_fetch_row(master_res)))
|
2008-02-20 22:18:01 +01:00
|
|
|
{
|
2009-07-16 08:56:43 +02:00
|
|
|
if (strcmp(master_row[0], global_system_variables.collation_server->name))
|
|
|
|
{
|
|
|
|
errmsg= "The slave I/O thread stops because master and slave have \
|
2004-06-03 23:17:18 +02:00
|
|
|
different values for the COLLATION_SERVER global variable. The values must \
|
2009-07-16 08:56:43 +02:00
|
|
|
be equal for the Statement-format replication to work";
|
|
|
|
err_code= ER_SLAVE_FATAL_ERROR;
|
|
|
|
sprintf(err_buff, ER(err_code), errmsg);
|
|
|
|
goto err;
|
|
|
|
}
|
2008-02-20 22:18:01 +01:00
|
|
|
}
|
2009-07-16 08:56:43 +02:00
|
|
|
else if (is_network_error(mysql_errno(mysql)))
|
|
|
|
{
|
|
|
|
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
|
|
|
"Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql));
|
|
|
|
goto network_err;
|
|
|
|
}
|
|
|
|
else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
|
|
|
|
{
|
|
|
|
/* Fatal error */
|
|
|
|
errmsg= "The slave I/O thread stops because a fatal error is encountered \
|
|
|
|
when it try to get the value of COLLATION_SERVER global variable from master.";
|
|
|
|
err_code= mysql_errno(mysql);
|
|
|
|
sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
|
2008-02-20 22:18:01 +01:00
|
|
|
goto err;
|
2009-07-16 08:56:43 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
|
|
|
|
"Unknown system variable 'COLLATION_SERVER' on master, \
|
|
|
|
maybe it is a *VERY OLD MASTER*. *NOTE*: slave may experience \
|
|
|
|
inconsistency if replicated data deals with collation.");
|
|
|
|
|
|
|
|
if (master_res)
|
|
|
|
{
|
|
|
|
mysql_free_result(master_res);
|
|
|
|
master_res= NULL;
|
|
|
|
}
|
2003-10-09 00:06:21 +02:00
|
|
|
}
|
2004-06-03 23:17:18 +02:00
|
|
|
|
2004-06-18 08:11:31 +02:00
|
|
|
/*
|
|
|
|
Perform analogous check for time zone. Theoretically we also should
|
|
|
|
perform check here to verify that SYSTEM time zones are the same on
|
|
|
|
slave and master, but we can't rely on value of @@system_time_zone
|
|
|
|
variable (it is time zone abbreviation) since it determined at start
|
|
|
|
time and so could differ for slave and master even if they are really
|
|
|
|
in the same system time zone. So we are omiting this check and just
|
|
|
|
relying on documentation. Also according to Monty there are many users
|
2006-07-07 09:27:55 +02:00
|
|
|
who are using replication between servers in various time zones. Hence
|
|
|
|
such check will broke everything for them. (And now everything will
|
|
|
|
work for them because by default both their master and slave will have
|
2004-06-18 08:11:31 +02:00
|
|
|
'SYSTEM' time zone).
|
2005-03-22 00:26:12 +01:00
|
|
|
This check is only necessary for 4.x masters (and < 5.0.4 masters but
|
|
|
|
those were alpha).
|
2004-06-18 08:11:31 +02:00
|
|
|
*/
|
2009-07-16 08:56:43 +02:00
|
|
|
if (*mysql->server_version == '4')
|
2003-10-09 00:06:21 +02:00
|
|
|
{
|
2009-07-16 08:56:43 +02:00
|
|
|
master_res= NULL;
|
|
|
|
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
|
|
|
|
(master_res= mysql_store_result(mysql)) &&
|
|
|
|
(master_row= mysql_fetch_row(master_res)))
|
2008-02-20 22:18:01 +01:00
|
|
|
{
|
2009-07-16 08:56:43 +02:00
|
|
|
if (strcmp(master_row[0],
|
|
|
|
global_system_variables.time_zone->get_name()->ptr()))
|
|
|
|
{
|
|
|
|
errmsg= "The slave I/O thread stops because master and slave have \
|
2004-06-18 08:11:31 +02:00
|
|
|
different values for the TIME_ZONE global variable. The values must \
|
2009-07-16 08:56:43 +02:00
|
|
|
be equal for the Statement-format replication to work";
|
|
|
|
err_code= ER_SLAVE_FATAL_ERROR;
|
|
|
|
sprintf(err_buff, ER(err_code), errmsg);
|
|
|
|
goto err;
|
|
|
|
}
|
2008-02-20 22:18:01 +01:00
|
|
|
}
|
2009-07-16 08:56:43 +02:00
|
|
|
else if (is_network_error(mysql_errno(mysql)))
|
|
|
|
{
|
|
|
|
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
|
|
|
"Get master TIME_ZONE failed with error: %s", mysql_error(mysql));
|
|
|
|
goto network_err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Fatal error */
|
|
|
|
errmsg= "The slave I/O thread stops because a fatal error is encountered \
|
|
|
|
when it try to get the value of TIME_ZONE global variable from master.";
|
|
|
|
err_code= mysql_errno(mysql);
|
|
|
|
sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
|
2008-02-20 22:18:01 +01:00
|
|
|
goto err;
|
2009-07-16 08:56:43 +02:00
|
|
|
}
|
|
|
|
if (master_res)
|
|
|
|
{
|
|
|
|
mysql_free_result(master_res);
|
|
|
|
master_res= NULL;
|
|
|
|
}
|
2003-10-09 00:06:21 +02:00
|
|
|
}
|
|
|
|
|
2005-01-17 21:26:14 +01:00
|
|
|
err:
|
2001-11-11 06:24:12 +01:00
|
|
|
if (errmsg)
|
|
|
|
{
|
2009-07-16 08:56:43 +02:00
|
|
|
if (master_res)
|
|
|
|
mysql_free_result(master_res);
|
2008-02-20 22:18:01 +01:00
|
|
|
DBUG_ASSERT(err_code != 0);
|
2009-09-23 15:21:29 +02:00
|
|
|
mi->report(ERROR_LEVEL, err_code, "%s", err_buff);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-11-11 06:24:12 +01:00
|
|
|
}
|
2004-06-03 23:17:18 +02:00
|
|
|
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2009-07-16 08:56:43 +02:00
|
|
|
|
|
|
|
network_err:
|
|
|
|
if (master_res)
|
|
|
|
mysql_free_result(master_res);
|
|
|
|
DBUG_RETURN(2);
|
2001-11-11 06:24:12 +01:00
|
|
|
}
|
|
|
|
|
2003-09-11 23:17:28 +02:00
|
|
|
/*
|
|
|
|
Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD
|
|
|
|
DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it
|
|
|
|
from the dump. Honours replication inclusion/exclusion rules.
|
2004-09-07 14:57:54 +02:00
|
|
|
db must be non-zero (guarded by assertion).
|
2003-09-11 23:17:28 +02:00
|
|
|
|
|
|
|
RETURN VALUES
|
|
|
|
0 success
|
|
|
|
1 error
|
|
|
|
*/
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-06-14 10:37:42 +02:00
|
|
|
static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
2006-07-07 09:27:55 +02:00
|
|
|
const char* table_name, bool overwrite)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2003-06-14 10:37:42 +02:00
|
|
|
ulong packet_len;
|
2004-09-07 14:57:54 +02:00
|
|
|
char *query, *save_db;
|
|
|
|
uint32 save_db_length;
|
2001-06-01 23:03:16 +02:00
|
|
|
Vio* save_vio;
|
|
|
|
HA_CHECK_OPT check_opt;
|
2000-07-31 21:29:14 +02:00
|
|
|
TABLE_LIST tables;
|
2001-06-01 23:03:16 +02:00
|
|
|
int error= 1;
|
|
|
|
handler *file;
|
2006-11-30 02:40:42 +01:00
|
|
|
ulonglong save_options;
|
2003-06-14 10:37:42 +02:00
|
|
|
NET *net= &mysql->net;
|
2007-04-26 05:38:12 +02:00
|
|
|
const char *found_semicolon= NULL;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("create_table_from_dump");
|
2003-10-08 11:01:58 +02:00
|
|
|
|
2003-06-14 10:37:42 +02:00
|
|
|
packet_len= my_net_read(net); // read create table statement
|
2001-06-01 23:03:16 +02:00
|
|
|
if (packet_len == packet_error)
|
|
|
|
{
|
2004-11-12 13:34:00 +01:00
|
|
|
my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0));
|
2003-10-08 11:01:58 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-06-01 23:03:16 +02:00
|
|
|
}
|
|
|
|
if (net->read_pos[0] == 255) // error from master
|
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
char *err_msg;
|
2003-06-14 10:37:42 +02:00
|
|
|
err_msg= (char*) net->read_pos + ((mysql->server_capabilities &
|
2006-07-07 09:27:55 +02:00
|
|
|
CLIENT_PROTOCOL_41) ?
|
|
|
|
3+SQLSTATE_LENGTH+1 : 3);
|
2004-11-13 18:35:51 +01:00
|
|
|
my_error(ER_MASTER, MYF(0), err_msg);
|
2003-10-08 11:01:58 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-06-01 23:03:16 +02:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
thd->command = COM_TABLE_DUMP;
|
2003-06-14 10:37:42 +02:00
|
|
|
if (!(query = thd->strmake((char*) net->read_pos, packet_len)))
|
2001-06-01 23:03:16 +02:00
|
|
|
{
|
|
|
|
sql_print_error("create_table_from_dump: out of memory");
|
2004-11-12 13:34:00 +01:00
|
|
|
my_message(ER_GET_ERRNO, "Out of memory", MYF(0));
|
2003-10-08 11:01:58 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-06-01 23:03:16 +02:00
|
|
|
}
|
2009-07-24 17:58:58 +02:00
|
|
|
thd->set_query(query, packet_len);
|
2007-10-19 23:20:38 +02:00
|
|
|
thd->is_slave_error = 0;
|
2003-06-14 10:37:42 +02:00
|
|
|
|
2003-10-08 11:01:58 +02:00
|
|
|
bzero((char*) &tables,sizeof(tables));
|
|
|
|
tables.db = (char*)db;
|
2005-01-06 12:00:13 +01:00
|
|
|
tables.alias= tables.table_name= (char*)table_name;
|
2004-04-07 12:25:24 +02:00
|
|
|
|
2003-10-08 11:01:58 +02:00
|
|
|
/* Drop the table if 'overwrite' is true */
|
2007-12-12 16:21:01 +01:00
|
|
|
if (overwrite)
|
2003-10-08 11:01:58 +02:00
|
|
|
{
|
2007-12-12 16:21:01 +01:00
|
|
|
if (mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
|
|
|
|
{
|
|
|
|
sql_print_error("create_table_from_dump: failed to drop the table");
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Clear the OK result of mysql_rm_table(). */
|
|
|
|
thd->main_da.reset_diagnostics_area();
|
|
|
|
}
|
2003-10-08 11:01:58 +02:00
|
|
|
}
|
|
|
|
|
2003-09-11 23:17:28 +02:00
|
|
|
/* Create the table. We do not want to log the "create table" statement */
|
2001-11-18 01:23:46 +01:00
|
|
|
save_options = thd->options;
|
2007-02-22 16:03:08 +01:00
|
|
|
thd->options &= ~ (OPTION_BIN_LOG);
|
|
|
|
thd_proc_info(thd, "Creating table from master dump");
|
2001-01-22 03:46:32 +01:00
|
|
|
// save old db in case we are creating in a different database
|
2003-09-11 23:17:28 +02:00
|
|
|
save_db = thd->db;
|
2004-09-07 14:57:54 +02:00
|
|
|
save_db_length= thd->db_length;
|
2001-05-29 03:18:23 +02:00
|
|
|
thd->db = (char*)db;
|
2005-02-25 15:53:22 +01:00
|
|
|
DBUG_ASSERT(thd->db != 0);
|
2004-09-07 14:57:54 +02:00
|
|
|
thd->db_length= strlen(thd->db);
|
2007-04-26 05:38:12 +02:00
|
|
|
mysql_parse(thd, thd->query, packet_len, &found_semicolon); // run create table
|
2006-07-07 09:27:55 +02:00
|
|
|
thd->db = save_db; // leave things the way the were before
|
2004-09-07 14:57:54 +02:00
|
|
|
thd->db_length= save_db_length;
|
2001-11-18 01:23:46 +01:00
|
|
|
thd->options = save_options;
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2007-10-19 23:20:38 +02:00
|
|
|
if (thd->is_slave_error)
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err; // mysql_parse took care of the error send
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Opening master dump table");
|
2007-12-12 16:21:01 +01:00
|
|
|
thd->main_da.reset_diagnostics_area(); /* cleanup from CREATE_TABLE */
|
Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE
corrupts a MERGE table
Bug 26867 - LOCK TABLES + REPAIR + merge table result in
memory/cpu hogging
Bug 26377 - Deadlock with MERGE and FLUSH TABLE
Bug 25038 - Waiting TRUNCATE
Bug 25700 - merge base tables get corrupted by
optimize/analyze/repair table
Bug 30275 - Merge tables: flush tables or unlock tables
causes server to crash
Bug 19627 - temporary merge table locking
Bug 27660 - Falcon: merge table possible
Bug 30273 - merge tables: Can't lock file (errno: 155)
The problems were:
Bug 26379 - Combination of FLUSH TABLE and REPAIR TABLE
corrupts a MERGE table
1. A thread trying to lock a MERGE table performs busy waiting while
REPAIR TABLE or a similar table administration task is ongoing on
one or more of its MyISAM tables.
2. A thread trying to lock a MERGE table performs busy waiting until all
threads that did REPAIR TABLE or similar table administration tasks
on one or more of its MyISAM tables in LOCK TABLES segments do UNLOCK
TABLES. The difference against problem #1 is that the busy waiting
takes place *after* the administration task. It is terminated by
UNLOCK TABLES only.
3. Two FLUSH TABLES within a LOCK TABLES segment can invalidate the
lock. This does *not* require a MERGE table. The first FLUSH TABLES
can be replaced by any statement that requires other threads to
reopen the table. In 5.0 and 5.1 a single FLUSH TABLES can provoke
the problem.
Bug 26867 - LOCK TABLES + REPAIR + merge table result in
memory/cpu hogging
Trying DML on a MERGE table, which has a child locked and
repaired by another thread, made an infinite loop in the server.
Bug 26377 - Deadlock with MERGE and FLUSH TABLE
Locking a MERGE table and its children in parent-child order
and flushing the child deadlocked the server.
Bug 25038 - Waiting TRUNCATE
Truncating a MERGE child, while the MERGE table was in use,
let the truncate fail instead of waiting for the table to
become free.
Bug 25700 - merge base tables get corrupted by
optimize/analyze/repair table
Repairing a child of an open MERGE table corrupted the child.
It was necessary to FLUSH the child first.
Bug 30275 - Merge tables: flush tables or unlock tables
causes server to crash
Flushing and optimizing locked MERGE children crashed the server.
Bug 19627 - temporary merge table locking
Use of a temporary MERGE table with non-temporary children
could corrupt the children.
Temporary tables are never locked. So we do now prohibit
non-temporary chidlren of a temporary MERGE table.
Bug 27660 - Falcon: merge table possible
It was possible to create a MERGE table with non-MyISAM children.
Bug 30273 - merge tables: Can't lock file (errno: 155)
This was a Windows-only bug. Table administration statements
sometimes failed with "Can't lock file (errno: 155)".
These bugs are fixed by a new implementation of MERGE table open.
When opening a MERGE table in open_tables() we do now add the
child tables to the list of tables to be opened by open_tables()
(the "query_list"). The children are not opened in the handler at
this stage.
After opening the parent, open_tables() opens each child from the
now extended query_list. When the last child is opened, we remove
the children from the query_list again and attach the children to
the parent. This behaves similar to the old open. However it does
not open the MyISAM tables directly, but grabs them from the already
open children.
When closing a MERGE table in close_thread_table() we detach the
children only. Closing of the children is done implicitly because
they are in thd->open_tables.
For more detail see the comment at the top of ha_myisammrg.cc.
Changed from open_ltable() to open_and_lock_tables() in all places
that can be relevant for MERGE tables. The latter can handle tables
added to the list on the fly. When open_ltable() was used in a loop
over a list of tables, the list must be temporarily terminated
after every table for open_and_lock_tables().
table_list->required_type is set to FRMTYPE_TABLE to avoid open of
special tables. Handling of derived tables is suppressed.
These details are handled by the new function
open_n_lock_single_table(), which has nearly the same signature as
open_ltable() and can replace it in most cases.
In reopen_tables() some of the tables open by a thread can be
closed and reopened. When a MERGE child is affected, the parent
must be closed and reopened too. Closing of the parent is forced
before the first child is closed. Reopen happens in the order of
thd->open_tables. MERGE parents do not attach their children
automatically at open. This is done after all tables are reopened.
So all children are open when attaching them.
Special lock handling like mysql_lock_abort() or mysql_lock_remove()
needs to be suppressed for MERGE children or forwarded to the parent.
This depends on the situation. In loops over all open tables one
suppresses child lock handling. When a single table is touched,
forwarding is done.
Behavioral changes:
===================
This patch changes the behavior of temporary MERGE tables.
Temporary MERGE must have temporary children.
The old behavior was wrong. A temporary table is not locked. Hence
even non-temporary children were not locked. See
Bug 19627 - temporary merge table locking.
You cannot change the union list of a non-temporary MERGE table
when LOCK TABLES is in effect. The following does *not* work:
CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...;
LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE;
ALTER TABLE m1 ... UNION=(t1,t2) ...;
However, you can do this with a temporary MERGE table.
You cannot create a MERGE table with CREATE ... SELECT, neither
as a temporary MERGE table, nor as a non-temporary MERGE table.
CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;
Gives error message: table is not BASE TABLE.
2007-11-15 20:25:43 +01:00
|
|
|
/*
|
|
|
|
Note: If this function starts to fail for MERGE tables,
|
|
|
|
change the next two lines to these:
|
|
|
|
tables.table= NULL; // was set by mysql_rm_table()
|
|
|
|
if (!open_n_lock_single_table(thd, &tables, TL_WRITE))
|
|
|
|
*/
|
2003-09-11 23:17:28 +02:00
|
|
|
tables.lock_type = TL_WRITE;
|
WL#3984 (Revise locking of mysql.general_log and mysql.slow_log)
Bug#25422 (Hang with log tables)
Bug 17876 (Truncating mysql.slow_log in a SP after using cursor locks the
thread)
Bug 23044 (Warnings on flush of a log table)
Bug 29129 (Resetting general_log while the GLOBAL READ LOCK is set causes
a deadlock)
Prior to this fix, the server would hang when performing concurrent
ALTER TABLE or TRUNCATE TABLE statements against the LOG TABLES,
which are mysql.general_log and mysql.slow_log.
The root cause traces to the following code:
in sql_base.cc, open_table()
if (table->in_use != thd)
{
/* wait_for_condition will unlock LOCK_open for us */
wait_for_condition(thd, &LOCK_open, &COND_refresh);
}
The problem with this code is that the current implementation of the
LOGGER creates 'fake' THD objects, like
- Log_to_csv_event_handler::general_log_thd
- Log_to_csv_event_handler::slow_log_thd
which are not associated to a real thread running in the server,
so that waiting for these non-existing threads to release table locks
cause the dead lock.
In general, the design of Log_to_csv_event_handler does not fit into the
general architecture of the server, so that the concept of general_log_thd
and slow_log_thd has to be abandoned:
- this implementation does not work with table locking
- it will not work with commands like SHOW PROCESSLIST
- having the log tables always opened does not integrate well with DDL
operations / FLUSH TABLES / SET GLOBAL READ_ONLY
With this patch, the fundamental design of the LOGGER has been changed to:
- always open and close a log table when writing a log
- remove totally the usage of fake THD objects
- clarify how locking of log tables is implemented in general.
See WL#3984 for details related to the new locking design.
Additional changes (misc bugs exposed and fixed):
1)
mysqldump which would ignore some tables in dump_all_tables_in_db(),
but forget to ignore the same in dump_all_views_in_db().
2)
mysqldump would also issue an empty "LOCK TABLE" command when all the tables
to lock are to be ignored (numrows == 0), instead of not issuing the query.
3)
Internal errors handlers could intercept errors but not warnings
(see sql_error.cc).
4)
Implementing a nested call to open tables, for the performance schema tables,
exposed an existing bug in remove_table_from_cache(), which would perform:
in_use->some_tables_deleted=1;
against another thread, without any consideration about thread locking.
This call inside remove_table_from_cache() was not required anyway,
since calling mysql_lock_abort() takes care of aborting -- cleanly -- threads
that might hold a lock on a table.
This line (in_use->some_tables_deleted=1) has been removed.
2007-07-27 08:31:06 +02:00
|
|
|
if (!open_ltable(thd, &tables, TL_WRITE, 0))
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
|
|
|
sql_print_error("create_table_from_dump: could not open created table");
|
2001-06-01 23:03:16 +02:00
|
|
|
goto err;
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2001-06-01 23:03:16 +02:00
|
|
|
file = tables.table->file;
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Reading master dump table data");
|
2003-09-11 23:17:28 +02:00
|
|
|
/* Copy the data file */
|
2001-01-22 03:46:32 +01:00
|
|
|
if (file->net_read_dump(net))
|
|
|
|
{
|
2004-11-12 13:34:00 +01:00
|
|
|
my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0));
|
2003-09-11 23:17:28 +02:00
|
|
|
sql_print_error("create_table_from_dump: failed in\
|
2000-07-31 21:29:14 +02:00
|
|
|
handler::net_read_dump()");
|
2001-06-01 23:03:16 +02:00
|
|
|
goto err;
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
check_opt.init();
|
2002-03-13 18:20:17 +01:00
|
|
|
check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Rebuilding the index on master dump table");
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
|
|
|
We do not want repair() to spam us with messages
|
|
|
|
just send them to the error log, and report the failure in case of
|
|
|
|
problems.
|
|
|
|
*/
|
2001-06-01 23:03:16 +02:00
|
|
|
save_vio = thd->net.vio;
|
2001-01-22 03:46:32 +01:00
|
|
|
thd->net.vio = 0;
|
2003-09-11 23:17:28 +02:00
|
|
|
/* Rebuild the index file from the copied data file (with REPAIR) */
|
2006-02-17 07:52:32 +01:00
|
|
|
error=file->ha_repair(thd,&check_opt) != 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
thd->net.vio = save_vio;
|
2001-06-01 23:03:16 +02:00
|
|
|
if (error)
|
2005-11-23 21:45:02 +01:00
|
|
|
my_error(ER_INDEX_REBUILD, MYF(0), tables.table->s->table_name.str);
|
2001-06-01 23:03:16 +02:00
|
|
|
|
|
|
|
err:
|
2000-07-31 21:29:14 +02:00
|
|
|
close_thread_tables(thd);
|
2006-07-07 09:27:55 +02:00
|
|
|
DBUG_RETURN(error);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-08-21 21:04:22 +02:00
|
|
|
int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
|
2007-08-16 08:52:50 +02:00
|
|
|
Master_info *mi, MYSQL *mysql, bool overwrite)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-08-21 21:04:22 +02:00
|
|
|
int error= 1;
|
|
|
|
const char *errmsg=0;
|
|
|
|
bool called_connected= (mysql != NULL);
|
|
|
|
DBUG_ENTER("fetch_master_table");
|
|
|
|
DBUG_PRINT("enter", ("db_name: '%s' table_name: '%s'",
|
2006-07-07 09:27:55 +02:00
|
|
|
db_name,table_name));
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2001-06-01 23:51:23 +02:00
|
|
|
if (!called_connected)
|
2006-07-07 09:27:55 +02:00
|
|
|
{
|
2003-05-02 18:07:41 +02:00
|
|
|
if (!(mysql = mysql_init(NULL)))
|
2002-08-21 21:04:22 +02:00
|
|
|
{
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2001-06-01 23:51:23 +02:00
|
|
|
if (connect_to_master(thd, mysql, mi))
|
2001-05-29 03:18:23 +02:00
|
|
|
{
|
2004-11-13 18:35:51 +01:00
|
|
|
my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql));
|
2006-06-20 20:46:45 +02:00
|
|
|
/*
|
|
|
|
We need to clear the active VIO since, theoretically, somebody
|
|
|
|
might issue an awake() on this thread. If we are then in the
|
|
|
|
middle of closing and destroying the VIO inside the
|
|
|
|
mysql_close(), we will have a problem.
|
|
|
|
*/
|
|
|
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
|
|
|
thd->clear_active_vio();
|
|
|
|
#endif
|
2003-05-02 18:07:41 +02:00
|
|
|
mysql_close(mysql);
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-05-29 03:18:23 +02:00
|
|
|
}
|
2002-08-21 21:04:22 +02:00
|
|
|
if (thd->killed)
|
|
|
|
goto err;
|
2001-05-29 03:18:23 +02:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2001-06-02 01:53:52 +02:00
|
|
|
if (request_table_dump(mysql, db_name, table_name))
|
2001-06-01 23:03:16 +02:00
|
|
|
{
|
2002-08-21 21:04:22 +02:00
|
|
|
error= ER_UNKNOWN_ERROR;
|
|
|
|
errmsg= "Failed on table dump request";
|
2001-06-01 23:03:16 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2003-10-07 14:42:26 +02:00
|
|
|
if (create_table_from_dump(thd, mysql, db_name,
|
2006-07-07 09:27:55 +02:00
|
|
|
table_name, overwrite))
|
2003-10-07 14:42:26 +02:00
|
|
|
goto err; // create_table_from_dump have sent the error already
|
2000-07-31 21:29:14 +02:00
|
|
|
error = 0;
|
2002-08-21 21:04:22 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
err:
|
2002-08-21 21:04:22 +02:00
|
|
|
if (!called_connected)
|
2003-05-02 18:07:41 +02:00
|
|
|
mysql_close(mysql);
|
2004-05-28 12:59:29 +02:00
|
|
|
if (errmsg && thd->vio_ok())
|
2004-10-20 03:04:37 +02:00
|
|
|
my_message(error, errmsg, MYF(0));
|
2006-07-07 09:27:55 +02:00
|
|
|
DBUG_RETURN(test(error)); // Return 1 on error
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2003-09-01 13:16:20 +02:00
|
|
|
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2007-08-16 07:37:50 +02:00
|
|
|
static bool wait_for_relay_log_space(Relay_log_info* rli)
|
2002-04-02 06:46:23 +02:00
|
|
|
{
|
2002-06-02 16:04:16 +02:00
|
|
|
bool slave_killed=0;
|
2007-08-16 08:52:50 +02:00
|
|
|
Master_info* mi = rli->mi;
|
2003-08-11 21:44:43 +02:00
|
|
|
const char *save_proc_info;
|
2002-04-02 06:46:23 +02:00
|
|
|
THD* thd = mi->io_thd;
|
|
|
|
DBUG_ENTER("wait_for_relay_log_space");
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-04-02 06:46:23 +02:00
|
|
|
pthread_mutex_lock(&rli->log_space_lock);
|
2003-08-11 21:44:43 +02:00
|
|
|
save_proc_info= thd->enter_cond(&rli->log_space_cond,
|
2006-07-07 09:27:55 +02:00
|
|
|
&rli->log_space_lock,
|
|
|
|
"\
|
2003-11-21 19:35:33 +01:00
|
|
|
Waiting for the slave SQL thread to free enough relay log space");
|
2002-04-02 06:46:23 +02:00
|
|
|
while (rli->log_space_limit < rli->log_space_total &&
|
2006-07-07 09:27:55 +02:00
|
|
|
!(slave_killed=io_slave_killed(thd,mi)) &&
|
2003-03-17 22:51:56 +01:00
|
|
|
!rli->ignore_log_space_limit)
|
2002-04-02 06:46:23 +02:00
|
|
|
pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
|
2003-06-15 12:01:51 +02:00
|
|
|
thd->exit_cond(save_proc_info);
|
2002-04-02 06:46:23 +02:00
|
|
|
DBUG_RETURN(slave_killed);
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2005-10-12 13:29:55 +02:00
|
|
|
/*
|
|
|
|
Builds a Rotate from the ignored events' info and writes it to relay log.
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2005-10-12 13:29:55 +02:00
|
|
|
SYNOPSIS
|
|
|
|
write_ignored_events_info_to_relay_log()
|
|
|
|
thd pointer to I/O thread's thd
|
|
|
|
mi
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Slave I/O thread, going to die, must leave a durable trace of the
|
|
|
|
ignored events' end position for the use of the slave SQL thread, by
|
|
|
|
calling this function. Only that thread can call it (see assertion).
|
|
|
|
*/
|
2007-08-16 08:52:50 +02:00
|
|
|
static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
|
2005-10-12 13:29:55 +02:00
|
|
|
{
|
2007-08-16 07:37:50 +02:00
|
|
|
Relay_log_info *rli= &mi->rli;
|
2005-10-12 13:29:55 +02:00
|
|
|
pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("write_ignored_events_info_to_relay_log");
|
|
|
|
|
2005-10-12 13:29:55 +02:00
|
|
|
DBUG_ASSERT(thd == mi->io_thd);
|
|
|
|
pthread_mutex_lock(log_lock);
|
|
|
|
if (rli->ign_master_log_name_end[0])
|
2002-06-05 22:04:38 +02:00
|
|
|
{
|
2005-10-12 13:29:55 +02:00
|
|
|
DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
|
2005-12-22 06:39:02 +01:00
|
|
|
Rotate_log_event *ev= new Rotate_log_event(rli->ign_master_log_name_end,
|
2005-10-12 13:29:55 +02:00
|
|
|
0, rli->ign_master_log_pos_end,
|
|
|
|
Rotate_log_event::DUP_NAME);
|
|
|
|
rli->ign_master_log_name_end[0]= 0;
|
|
|
|
/* can unlock before writing as slave SQL thd will soon see our Rotate */
|
|
|
|
pthread_mutex_unlock(log_lock);
|
|
|
|
if (likely((bool)ev))
|
|
|
|
{
|
|
|
|
ev->server_id= 0; // don't be ignored by slave SQL thread
|
|
|
|
if (unlikely(rli->relay_log.append(ev)))
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
|
|
|
|
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
|
|
|
|
"failed to write a Rotate event"
|
|
|
|
" to the relay log, SHOW SLAVE STATUS may be"
|
|
|
|
" inaccurate");
|
2005-10-12 13:29:55 +02:00
|
|
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
2006-01-03 17:54:54 +01:00
|
|
|
if (flush_master_info(mi, 1))
|
|
|
|
sql_print_error("Failed to flush master info file");
|
2005-10-12 13:29:55 +02:00
|
|
|
delete ev;
|
|
|
|
}
|
|
|
|
else
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE,
|
|
|
|
ER(ER_SLAVE_CREATE_EVENT_FAILURE),
|
|
|
|
"Rotate_event (out of memory?),"
|
|
|
|
" SHOW SLAVE STATUS may be inaccurate");
|
2002-06-05 22:04:38 +02:00
|
|
|
}
|
2005-10-12 13:29:55 +02:00
|
|
|
else
|
|
|
|
pthread_mutex_unlock(log_lock);
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
int register_slave_on_master(MYSQL* mysql, Master_info *mi,
|
2007-06-29 18:48:22 +02:00
|
|
|
bool *suppress_warnings)
|
2001-05-31 02:50:56 +02:00
|
|
|
{
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
uchar buf[1024], *pos= buf;
|
2002-12-11 08:17:51 +01:00
|
|
|
uint report_host_len, report_user_len=0, report_password_len=0;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("register_slave_on_master");
|
2001-05-31 02:50:56 +02:00
|
|
|
|
2007-06-29 18:48:22 +02:00
|
|
|
*suppress_warnings= FALSE;
|
2002-01-20 03:16:52 +01:00
|
|
|
if (!report_host)
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-12-11 08:17:51 +01:00
|
|
|
report_host_len= strlen(report_host);
|
2002-01-20 03:16:52 +01:00
|
|
|
if (report_user)
|
2002-12-11 08:17:51 +01:00
|
|
|
report_user_len= strlen(report_user);
|
2002-06-05 22:04:38 +02:00
|
|
|
if (report_password)
|
2002-12-11 08:17:51 +01:00
|
|
|
report_password_len= strlen(report_password);
|
|
|
|
/* 30 is a good safety margin */
|
|
|
|
if (report_host_len + report_user_len + report_password_len + 30 >
|
|
|
|
sizeof(buf))
|
2006-07-07 09:27:55 +02:00
|
|
|
DBUG_RETURN(0); // safety
|
2002-12-11 08:17:51 +01:00
|
|
|
|
|
|
|
int4store(pos, server_id); pos+= 4;
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
pos= net_store_data(pos, (uchar*) report_host, report_host_len);
|
|
|
|
pos= net_store_data(pos, (uchar*) report_user, report_user_len);
|
|
|
|
pos= net_store_data(pos, (uchar*) report_password, report_password_len);
|
2002-12-11 08:17:51 +01:00
|
|
|
int2store(pos, (uint16) report_port); pos+= 2;
|
2006-07-07 09:27:55 +02:00
|
|
|
int4store(pos, rpl_recovery_rank); pos+= 4;
|
2002-12-11 08:17:51 +01:00
|
|
|
/* The master will fill in master_id */
|
2006-07-07 09:27:55 +02:00
|
|
|
int4store(pos, 0); pos+= 4;
|
2002-12-11 08:17:51 +01:00
|
|
|
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0))
|
2001-05-31 02:50:56 +02:00
|
|
|
{
|
2007-06-29 18:48:22 +02:00
|
|
|
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
|
|
|
|
{
|
|
|
|
*suppress_warnings= TRUE; // Suppress reconnect warning
|
|
|
|
}
|
2007-11-22 17:22:54 +01:00
|
|
|
else if (!check_io_slave_killed(mi->io_thd, mi, NULL))
|
2007-06-29 18:48:22 +02:00
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
|
|
|
|
mysql_errno(mysql));
|
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
|
|
|
|
ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf);
|
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-05-31 02:50:56 +02:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2001-05-31 02:50:56 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2009-01-09 13:49:24 +01:00
|
|
|
/**
|
|
|
|
Execute a SHOW SLAVE STATUS statement.
|
|
|
|
|
|
|
|
@param thd Pointer to THD object for the client thread executing the
|
|
|
|
statement.
|
|
|
|
|
|
|
|
@param mi Pointer to Master_info object for the IO thread.
|
|
|
|
|
|
|
|
@retval FALSE success
|
|
|
|
@retval TRUE failure
|
|
|
|
*/
|
2007-08-16 08:52:50 +02:00
|
|
|
bool show_master_info(THD* thd, Master_info* mi)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-01-20 03:16:52 +01:00
|
|
|
// TODO: fix this for multi-master
|
2000-07-31 21:29:14 +02:00
|
|
|
List<Item> field_list;
|
2002-12-11 08:17:51 +01:00
|
|
|
Protocol *protocol= thd->protocol;
|
|
|
|
DBUG_ENTER("show_master_info");
|
|
|
|
|
2003-10-09 00:06:21 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Slave_IO_State",
|
2006-07-07 09:27:55 +02:00
|
|
|
14));
|
2000-07-31 21:29:14 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_Host",
|
2006-07-07 09:27:55 +02:00
|
|
|
sizeof(mi->host)));
|
2000-07-31 21:29:14 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_User",
|
2006-07-07 09:27:55 +02:00
|
|
|
sizeof(mi->user)));
|
2002-12-11 08:17:51 +01:00
|
|
|
field_list.push_back(new Item_return_int("Master_Port", 7,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONG));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_return_int("Connect_Retry", 10,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONG));
|
2002-01-20 03:16:52 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Master_Log_File",
|
2006-07-07 09:27:55 +02:00
|
|
|
FN_REFLEN));
|
2002-12-11 08:17:51 +01:00
|
|
|
field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONGLONG));
|
2002-01-20 03:16:52 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Relay_Log_File",
|
2006-07-07 09:27:55 +02:00
|
|
|
FN_REFLEN));
|
2002-12-11 08:17:51 +01:00
|
|
|
field_list.push_back(new Item_return_int("Relay_Log_Pos", 10,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONGLONG));
|
2002-01-20 03:16:52 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
|
2006-07-07 09:27:55 +02:00
|
|
|
FN_REFLEN));
|
2002-01-20 03:16:52 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
|
|
|
|
field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20));
|
|
|
|
field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", 20));
|
|
|
|
field_list.push_back(new Item_empty_string("Replicate_Do_Table", 20));
|
|
|
|
field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", 23));
|
|
|
|
field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", 24));
|
|
|
|
field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table",
|
2006-07-07 09:27:55 +02:00
|
|
|
28));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_return_int("Last_Errno", 4, MYSQL_TYPE_LONG));
|
|
|
|
field_list.push_back(new Item_empty_string("Last_Error", 20));
|
|
|
|
field_list.push_back(new Item_return_int("Skip_Counter", 10,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONG));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONGLONG));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_return_int("Relay_Log_Space", 10,
|
2006-07-07 09:27:55 +02:00
|
|
|
MYSQL_TYPE_LONGLONG));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Until_Condition", 6));
|
2003-09-13 22:13:41 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
|
2006-07-07 09:27:55 +02:00
|
|
|
field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
|
2003-09-13 22:13:41 +02:00
|
|
|
MYSQL_TYPE_LONGLONG));
|
2003-09-01 13:16:20 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_Allowed", 7));
|
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_CA_File",
|
|
|
|
sizeof(mi->ssl_ca)));
|
2006-07-07 09:27:55 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_CA_Path",
|
2003-09-01 13:16:20 +02:00
|
|
|
sizeof(mi->ssl_capath)));
|
2006-07-07 09:27:55 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_Cert",
|
2003-09-01 13:16:20 +02:00
|
|
|
sizeof(mi->ssl_cert)));
|
2006-07-07 09:27:55 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_Cipher",
|
2003-09-01 13:16:20 +02:00
|
|
|
sizeof(mi->ssl_cipher)));
|
2006-07-07 09:27:55 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_Key",
|
2003-09-01 13:16:20 +02:00
|
|
|
sizeof(mi->ssl_key)));
|
2003-11-20 20:07:25 +01:00
|
|
|
field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10,
|
2003-10-09 00:06:21 +02:00
|
|
|
MYSQL_TYPE_LONGLONG));
|
2007-03-29 15:09:57 +02:00
|
|
|
field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert",
|
|
|
|
3));
|
2007-06-09 07:19:37 +02:00
|
|
|
field_list.push_back(new Item_return_int("Last_IO_Errno", 4, MYSQL_TYPE_LONG));
|
|
|
|
field_list.push_back(new Item_empty_string("Last_IO_Error", 20));
|
|
|
|
field_list.push_back(new Item_return_int("Last_SQL_Errno", 4, MYSQL_TYPE_LONG));
|
|
|
|
field_list.push_back(new Item_empty_string("Last_SQL_Error", 20));
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2004-08-03 12:32:21 +02:00
|
|
|
if (protocol->send_fields(&field_list,
|
|
|
|
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2002-08-18 15:04:26 +02:00
|
|
|
if (mi->host[0])
|
|
|
|
{
|
2003-06-17 23:19:38 +02:00
|
|
|
DBUG_PRINT("info",("host is set: '%s'", mi->host));
|
2002-08-18 15:04:26 +02:00
|
|
|
String *packet= &thd->packet;
|
2002-12-11 08:17:51 +01:00
|
|
|
protocol->prepare_for_resend();
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2004-12-16 18:12:22 +01:00
|
|
|
/*
|
2008-02-05 16:36:26 +01:00
|
|
|
slave_running can be accessed without run_lock but not other
|
|
|
|
non-volotile members like mi->io_thd, which is guarded by the mutex.
|
2004-12-16 18:12:22 +01:00
|
|
|
*/
|
2008-02-05 16:36:26 +01:00
|
|
|
pthread_mutex_lock(&mi->run_lock);
|
|
|
|
protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
|
|
|
|
pthread_mutex_unlock(&mi->run_lock);
|
|
|
|
|
2002-08-18 15:04:26 +02:00
|
|
|
pthread_mutex_lock(&mi->data_lock);
|
|
|
|
pthread_mutex_lock(&mi->rli.data_lock);
|
2009-06-16 17:04:30 +02:00
|
|
|
pthread_mutex_lock(&mi->err_lock);
|
|
|
|
pthread_mutex_lock(&mi->rli.err_lock);
|
2003-03-18 08:34:19 +01:00
|
|
|
protocol->store(mi->host, &my_charset_bin);
|
|
|
|
protocol->store(mi->user, &my_charset_bin);
|
2002-12-11 08:17:51 +01:00
|
|
|
protocol->store((uint32) mi->port);
|
|
|
|
protocol->store((uint32) mi->connect_retry);
|
2003-03-18 08:34:19 +01:00
|
|
|
protocol->store(mi->master_log_name, &my_charset_bin);
|
2002-12-11 08:17:51 +01:00
|
|
|
protocol->store((ulonglong) mi->master_log_pos);
|
2003-04-24 15:29:25 +02:00
|
|
|
protocol->store(mi->rli.group_relay_log_name +
|
2006-07-07 09:27:55 +02:00
|
|
|
dirname_length(mi->rli.group_relay_log_name),
|
|
|
|
&my_charset_bin);
|
2003-04-24 15:29:25 +02:00
|
|
|
protocol->store((ulonglong) mi->rli.group_relay_log_pos);
|
|
|
|
protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
|
2005-08-08 23:13:49 +02:00
|
|
|
protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
|
|
|
|
"Yes" : "No", &my_charset_bin);
|
2003-03-18 08:34:19 +01:00
|
|
|
protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin);
|
2005-03-08 21:12:35 +01:00
|
|
|
protocol->store(rpl_filter->get_do_db());
|
|
|
|
protocol->store(rpl_filter->get_ignore_db());
|
|
|
|
|
2003-07-23 15:46:46 +02:00
|
|
|
char buf[256];
|
|
|
|
String tmp(buf, sizeof(buf), &my_charset_bin);
|
2005-03-08 21:12:35 +01:00
|
|
|
rpl_filter->get_do_table(&tmp);
|
2003-07-23 15:46:46 +02:00
|
|
|
protocol->store(&tmp);
|
2005-03-08 21:12:35 +01:00
|
|
|
rpl_filter->get_ignore_table(&tmp);
|
2003-07-23 15:46:46 +02:00
|
|
|
protocol->store(&tmp);
|
2005-03-08 21:12:35 +01:00
|
|
|
rpl_filter->get_wild_do_table(&tmp);
|
2003-07-23 15:46:46 +02:00
|
|
|
protocol->store(&tmp);
|
2005-03-08 21:12:35 +01:00
|
|
|
rpl_filter->get_wild_ignore_table(&tmp);
|
2003-07-23 15:46:46 +02:00
|
|
|
protocol->store(&tmp);
|
|
|
|
|
2007-06-11 22:15:39 +02:00
|
|
|
protocol->store(mi->rli.last_error().number);
|
|
|
|
protocol->store(mi->rli.last_error().message, &my_charset_bin);
|
2002-12-11 08:17:51 +01:00
|
|
|
protocol->store((uint32) mi->rli.slave_skip_counter);
|
2003-04-24 15:29:25 +02:00
|
|
|
protocol->store((ulonglong) mi->rli.group_master_log_pos);
|
2002-12-11 08:17:51 +01:00
|
|
|
protocol->store((ulonglong) mi->rli.log_space_total);
|
2003-09-13 22:13:41 +02:00
|
|
|
|
|
|
|
protocol->store(
|
2007-08-16 07:37:50 +02:00
|
|
|
mi->rli.until_condition==Relay_log_info::UNTIL_NONE ? "None":
|
|
|
|
( mi->rli.until_condition==Relay_log_info::UNTIL_MASTER_POS? "Master":
|
2003-09-13 22:13:41 +02:00
|
|
|
"Relay"), &my_charset_bin);
|
|
|
|
protocol->store(mi->rli.until_log_name, &my_charset_bin);
|
|
|
|
protocol->store((ulonglong) mi->rli.until_log_pos);
|
2006-07-07 09:27:55 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_OPENSSL
|
2003-09-01 13:16:20 +02:00
|
|
|
protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
|
|
|
|
#else
|
|
|
|
protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
|
|
|
|
#endif
|
|
|
|
protocol->store(mi->ssl_ca, &my_charset_bin);
|
|
|
|
protocol->store(mi->ssl_capath, &my_charset_bin);
|
|
|
|
protocol->store(mi->ssl_cert, &my_charset_bin);
|
|
|
|
protocol->store(mi->ssl_cipher, &my_charset_bin);
|
|
|
|
protocol->store(mi->ssl_key, &my_charset_bin);
|
2003-10-09 00:06:21 +02:00
|
|
|
|
2004-12-16 18:12:22 +01:00
|
|
|
/*
|
|
|
|
Seconds_Behind_Master: if SQL thread is running and I/O thread is
|
|
|
|
connected, we can compute it otherwise show NULL (i.e. unknown).
|
|
|
|
*/
|
|
|
|
if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) &&
|
|
|
|
mi->rli.slave_running)
|
2004-03-02 22:38:14 +01:00
|
|
|
{
|
2007-04-13 14:56:24 +02:00
|
|
|
long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp)
|
2007-01-27 02:46:45 +01:00
|
|
|
- mi->clock_diff_with_master);
|
2004-03-02 22:38:14 +01:00
|
|
|
/*
|
2007-01-27 02:46:45 +01:00
|
|
|
Apparently on some systems time_diff can be <0. Here are possible
|
|
|
|
reasons related to MySQL:
|
2004-03-02 23:03:52 +01:00
|
|
|
- the master is itself a slave of another master whose time is ahead.
|
|
|
|
- somebody used an explicit SET TIMESTAMP on the master.
|
|
|
|
Possible reason related to granularity-to-second of time functions
|
|
|
|
(nothing to do with MySQL), which can explain a value of -1:
|
|
|
|
assume the master's and slave's time are perfectly synchronized, and
|
|
|
|
that at slave's connection time, when the master's timestamp is read,
|
|
|
|
it is at the very end of second 1, and (a very short time later) when
|
|
|
|
the slave's timestamp is read it is at the very beginning of second
|
|
|
|
2. Then the recorded value for master is 1 and the recorded value for
|
|
|
|
slave is 2. At SHOW SLAVE STATUS time, assume that the difference
|
|
|
|
between timestamp of slave and rli->last_master_timestamp is 0
|
|
|
|
(i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.
|
2004-12-16 18:12:22 +01:00
|
|
|
This confuses users, so we don't go below 0: hence the max().
|
|
|
|
|
|
|
|
last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
|
|
|
|
special marker to say "consider we have caught up".
|
2004-03-02 22:38:14 +01:00
|
|
|
*/
|
2007-01-27 02:46:45 +01:00
|
|
|
protocol->store((longlong)(mi->rli.last_master_timestamp ?
|
|
|
|
max(0, time_diff) : 0));
|
2004-03-02 22:38:14 +01:00
|
|
|
}
|
2003-10-09 00:06:21 +02:00
|
|
|
else
|
2007-03-29 15:09:57 +02:00
|
|
|
{
|
2003-10-09 00:06:21 +02:00
|
|
|
protocol->store_null();
|
2007-03-29 15:09:57 +02:00
|
|
|
}
|
|
|
|
protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin);
|
2003-10-09 00:06:21 +02:00
|
|
|
|
2007-06-09 07:19:37 +02:00
|
|
|
// Last_IO_Errno
|
2007-06-11 22:15:39 +02:00
|
|
|
protocol->store(mi->last_error().number);
|
2007-06-09 07:19:37 +02:00
|
|
|
// Last_IO_Error
|
2007-06-11 22:15:39 +02:00
|
|
|
protocol->store(mi->last_error().message, &my_charset_bin);
|
2007-06-09 07:19:37 +02:00
|
|
|
// Last_SQL_Errno
|
2007-06-11 22:15:39 +02:00
|
|
|
protocol->store(mi->rli.last_error().number);
|
2007-06-09 07:19:37 +02:00
|
|
|
// Last_SQL_Error
|
2007-06-11 22:15:39 +02:00
|
|
|
protocol->store(mi->rli.last_error().message, &my_charset_bin);
|
2007-06-09 07:19:37 +02:00
|
|
|
|
2009-06-16 17:04:30 +02:00
|
|
|
pthread_mutex_unlock(&mi->rli.err_lock);
|
|
|
|
pthread_mutex_unlock(&mi->err_lock);
|
2002-08-18 15:04:26 +02:00
|
|
|
pthread_mutex_unlock(&mi->rli.data_lock);
|
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
2006-01-03 17:54:54 +01:00
|
|
|
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length()))
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2002-08-18 15:04:26 +02:00
|
|
|
}
|
2008-02-19 13:58:08 +01:00
|
|
|
my_eof(thd);
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(FALSE);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2001-01-17 13:47:33 +01:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
void set_slave_thread_options(THD* thd)
|
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("set_slave_thread_options");
|
2006-11-03 12:27:37 +01:00
|
|
|
/*
|
|
|
|
It's nonsense to constrain the slave threads with max_join_size; if a
|
|
|
|
query succeeded on master, we HAVE to execute it. So set
|
|
|
|
OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
|
|
|
|
(and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
|
|
|
|
SELECT examining more than 4 billion rows would still fail (yes, because
|
|
|
|
when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
|
|
|
|
only for client threads.
|
|
|
|
*/
|
|
|
|
ulonglong options= thd->options | OPTION_BIG_SELECTS;
|
|
|
|
if (opt_log_slave_updates)
|
|
|
|
options|= OPTION_BIN_LOG;
|
|
|
|
else
|
|
|
|
options&= ~OPTION_BIN_LOG;
|
|
|
|
thd->options= options;
|
2005-02-07 14:15:48 +01:00
|
|
|
thd->variables.completion_type= 0;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
}
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 07:37:50 +02:00
|
|
|
void set_slave_thread_default_charset(THD* thd, Relay_log_info const *rli)
|
2005-03-22 00:26:12 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("set_slave_thread_default_charset");
|
|
|
|
|
2005-03-22 00:26:12 +01:00
|
|
|
thd->variables.character_set_client=
|
|
|
|
global_system_variables.character_set_client;
|
|
|
|
thd->variables.collation_connection=
|
|
|
|
global_system_variables.collation_connection;
|
|
|
|
thd->variables.collation_server=
|
|
|
|
global_system_variables.collation_server;
|
|
|
|
thd->update_charset();
|
2006-11-10 15:10:41 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
We use a const cast here since the conceptual (and externally
|
|
|
|
visible) behavior of the function is to set the default charset of
|
|
|
|
the thread. That the cache has to be invalidated is a secondary
|
|
|
|
effect.
|
|
|
|
*/
|
2007-08-16 07:37:50 +02:00
|
|
|
const_cast<Relay_log_info*>(rli)->cached_charset_invalidate();
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2005-03-22 00:26:12 +01:00
|
|
|
}
|
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
init_slave_thread()
|
2003-02-04 20:52:14 +01:00
|
|
|
*/
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("init_slave_thread");
|
2008-02-13 13:09:41 +01:00
|
|
|
#if !defined(DBUG_OFF)
|
|
|
|
int simulate_error= 0;
|
|
|
|
#endif
|
2003-12-04 22:42:18 +01:00
|
|
|
thd->system_thread = (thd_type == SLAVE_THD_SQL) ?
|
2006-07-07 09:27:55 +02:00
|
|
|
SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
|
2005-09-15 21:29:07 +02:00
|
|
|
thd->security_ctx->skip_grants();
|
2000-07-31 21:29:14 +02:00
|
|
|
my_net_init(&thd->net, 0);
|
2006-11-12 19:01:58 +01:00
|
|
|
/*
|
|
|
|
Adding MAX_LOG_EVENT_HEADER_LEN to the max_allowed_packet on all
|
|
|
|
slave threads, since a replication event can become this much larger
|
|
|
|
than the corresponding packet (query) sent from client to master.
|
|
|
|
*/
|
2006-09-11 23:19:05 +02:00
|
|
|
thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet
|
2006-11-12 19:01:58 +01:00
|
|
|
+ MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
|
2000-11-14 07:43:02 +01:00
|
|
|
thd->slave_thread = 1;
|
2007-07-30 10:33:50 +02:00
|
|
|
thd->enable_slow_log= opt_log_slow_slave_statements;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
set_slave_thread_options(thd);
|
2000-07-31 21:29:14 +02:00
|
|
|
thd->client_capabilities = CLIENT_LOCAL_FILES;
|
|
|
|
pthread_mutex_lock(&LOCK_thread_count);
|
2007-02-23 12:13:55 +01:00
|
|
|
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
2000-07-31 21:29:14 +02:00
|
|
|
pthread_mutex_unlock(&LOCK_thread_count);
|
|
|
|
|
2008-02-13 13:09:41 +01:00
|
|
|
DBUG_EXECUTE_IF("simulate_io_slave_error_on_init",
|
|
|
|
simulate_error|= (1 << SLAVE_THD_IO););
|
|
|
|
DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init",
|
|
|
|
simulate_error|= (1 << SLAVE_THD_SQL););
|
|
|
|
#if !defined(DBUG_OFF)
|
|
|
|
if (init_thr_lock() || thd->store_globals() || simulate_error & (1<< thd_type))
|
|
|
|
#else
|
2002-03-30 20:36:05 +01:00
|
|
|
if (init_thr_lock() || thd->store_globals())
|
2008-02-13 13:09:41 +01:00
|
|
|
#endif
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2003-03-10 11:00:19 +01:00
|
|
|
thd->cleanup();
|
2000-07-31 21:29:14 +02:00
|
|
|
DBUG_RETURN(-1);
|
|
|
|
}
|
2007-11-05 16:25:40 +01:00
|
|
|
lex_start(thd);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (thd_type == SLAVE_THD_SQL)
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Waiting for the next event in relay log");
|
2002-01-20 03:16:52 +01:00
|
|
|
else
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Waiting for master update");
|
2000-07-31 21:29:14 +02:00
|
|
|
thd->version=refresh_version;
|
|
|
|
thd->set_time();
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-03-08 23:02:11 +01:00
|
|
|
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
|
2006-07-07 09:27:55 +02:00
|
|
|
void* thread_killed_arg)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-08-21 21:04:22 +02:00
|
|
|
int nap_time;
|
2000-07-31 21:29:14 +02:00
|
|
|
thr_alarm_t alarmed;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("safe_sleep");
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
thr_alarm_init(&alarmed);
|
2007-07-30 10:33:50 +02:00
|
|
|
time_t start_time= my_time(0);
|
2000-07-31 21:29:14 +02:00
|
|
|
time_t end_time= start_time+sec;
|
|
|
|
|
2002-08-21 21:04:22 +02:00
|
|
|
while ((nap_time= (int) (end_time - start_time)) > 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-08-21 21:04:22 +02:00
|
|
|
ALARM alarm_buff;
|
2001-01-22 03:46:32 +01:00
|
|
|
/*
|
2002-08-08 02:12:02 +02:00
|
|
|
The only reason we are asking for alarm is so that
|
2001-01-22 03:46:32 +01:00
|
|
|
we will be woken up in case of murder, so if we do not get killed,
|
|
|
|
set the alarm so it goes off after we wake up naturally
|
|
|
|
*/
|
2002-08-21 21:04:22 +02:00
|
|
|
thr_alarm(&alarmed, 2 * nap_time, &alarm_buff);
|
2000-07-31 21:29:14 +02:00
|
|
|
sleep(nap_time);
|
2002-08-21 21:04:22 +02:00
|
|
|
thr_end_alarm(&alarmed);
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-03-08 23:02:11 +01:00
|
|
|
if ((*thread_killed)(thd,thread_killed_arg))
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2007-07-30 10:33:50 +02:00
|
|
|
start_time= my_time(0);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-08-21 21:04:22 +02:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int request_dump(MYSQL* mysql, Master_info* mi,
|
2006-07-07 09:27:55 +02:00
|
|
|
bool *suppress_warnings)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
uchar buf[FN_REFLEN + 10];
|
2000-07-31 21:29:14 +02:00
|
|
|
int len;
|
|
|
|
int binlog_flags = 0; // for now
|
2002-01-20 03:16:52 +01:00
|
|
|
char* logname = mi->master_log_name;
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_ENTER("request_dump");
|
2007-06-29 18:48:22 +02:00
|
|
|
|
|
|
|
*suppress_warnings= FALSE;
|
2002-08-21 21:04:22 +02:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
// TODO if big log files: Change next to int8store()
|
2004-11-10 17:07:39 +01:00
|
|
|
int4store(buf, (ulong) mi->master_log_pos);
|
2000-07-31 21:29:14 +02:00
|
|
|
int2store(buf + 4, binlog_flags);
|
2000-09-30 01:20:26 +02:00
|
|
|
int4store(buf + 6, server_id);
|
2000-08-21 23:18:32 +02:00
|
|
|
len = (uint) strlen(logname);
|
2000-09-30 01:20:26 +02:00
|
|
|
memcpy(buf + 10, logname,len);
|
2003-05-02 18:07:41 +02:00
|
|
|
if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
|
|
|
Something went wrong, so we will just reconnect and retry later
|
|
|
|
in the future, we should do a better error analysis, but for
|
|
|
|
now we just fill up the error log :-)
|
|
|
|
*/
|
2003-05-02 18:07:41 +02:00
|
|
|
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
|
2007-06-29 18:48:22 +02:00
|
|
|
*suppress_warnings= TRUE; // Suppress reconnect warning
|
2002-07-23 17:31:22 +02:00
|
|
|
else
|
2002-08-21 21:04:22 +02:00
|
|
|
sql_print_error("Error on COM_BINLOG_DUMP: %d %s, will retry in %d secs",
|
2006-07-07 09:27:55 +02:00
|
|
|
mysql_errno(mysql), mysql_error(mysql),
|
|
|
|
master_connect_retry);
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_RETURN(0);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2001-05-29 03:18:23 +02:00
|
|
|
static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
uchar buf[1024], *p = buf;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("request_table_dump");
|
|
|
|
|
2000-08-21 23:18:32 +02:00
|
|
|
uint table_len = (uint) strlen(table);
|
|
|
|
uint db_len = (uint) strlen(db);
|
2002-06-05 22:04:38 +02:00
|
|
|
if (table_len + db_len > sizeof(buf) - 2)
|
2002-07-23 17:31:22 +02:00
|
|
|
{
|
|
|
|
sql_print_error("request_table_dump: Buffer overrun");
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2006-07-07 09:27:55 +02:00
|
|
|
}
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
*p++ = db_len;
|
|
|
|
memcpy(p, db, db_len);
|
|
|
|
p += db_len;
|
|
|
|
*p++ = table_len;
|
|
|
|
memcpy(p, table, table_len);
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2003-05-02 18:07:41 +02:00
|
|
|
if (simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
|
|
|
sql_print_error("request_table_dump: Error sending the table dump \
|
2000-07-31 21:29:14 +02:00
|
|
|
command");
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-07-23 17:31:22 +02:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
Read one event from the master
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-07-23 17:31:22 +02:00
|
|
|
SYNOPSIS
|
|
|
|
read_event()
|
2006-07-07 09:27:55 +02:00
|
|
|
mysql MySQL connection
|
|
|
|
mi Master connection information
|
|
|
|
suppress_warnings TRUE when a normal net read timeout has caused us to
|
|
|
|
try a reconnect. We do not want to print anything to
|
|
|
|
the error log in this case because this a anormal
|
|
|
|
event in an idle server.
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-07-23 17:31:22 +02:00
|
|
|
RETURN VALUES
|
2006-07-07 09:27:55 +02:00
|
|
|
'packet_error' Error
|
|
|
|
number Length of packet
|
2002-07-23 17:31:22 +02:00
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-08-08 02:12:02 +02:00
|
|
|
ulong len;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("read_event");
|
2001-01-22 03:46:32 +01:00
|
|
|
|
2007-06-29 18:48:22 +02:00
|
|
|
*suppress_warnings= FALSE;
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
|
|
|
my_real_read() will time us out
|
|
|
|
We check if we were told to die, and if not, try reading again
|
|
|
|
*/
|
2000-11-22 08:23:31 +01:00
|
|
|
#ifndef DBUG_OFF
|
2005-12-22 06:39:02 +01:00
|
|
|
if (disconnect_slave_event_count && !(mi->events_till_disconnect--))
|
2006-07-07 09:27:55 +02:00
|
|
|
DBUG_RETURN(packet_error);
|
2000-11-22 08:23:31 +01:00
|
|
|
#endif
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2006-07-24 12:56:53 +02:00
|
|
|
len = cli_safe_read(mysql);
|
2001-10-13 17:28:35 +02:00
|
|
|
if (len == packet_error || (long) len < 1)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2003-05-02 18:07:41 +02:00
|
|
|
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
|
2002-07-23 17:31:22 +02:00
|
|
|
{
|
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
We are trying a normal reconnect after a read timeout;
|
|
|
|
we suppress prints to .err file as long as the reconnect
|
|
|
|
happens without problems
|
2002-07-23 17:31:22 +02:00
|
|
|
*/
|
|
|
|
*suppress_warnings= TRUE;
|
|
|
|
}
|
|
|
|
else
|
2005-02-09 20:04:28 +01:00
|
|
|
sql_print_error("Error reading packet from server: %s ( server_errno=%d)",
|
2006-07-07 09:27:55 +02:00
|
|
|
mysql_error(mysql), mysql_errno(mysql));
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(packet_error);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2003-08-27 21:30:50 +02:00
|
|
|
/* Check if eof packet */
|
|
|
|
if (len < 8 && mysql->net.read_pos[0] == 254)
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
2004-09-15 21:10:31 +02:00
|
|
|
sql_print_information("Slave: received end packet from server, apparent "
|
|
|
|
"master shutdown: %s",
|
2006-07-07 09:27:55 +02:00
|
|
|
mysql_error(mysql));
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(packet_error);
|
2001-01-22 03:46:32 +01:00
|
|
|
}
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2006-11-27 00:47:38 +01:00
|
|
|
DBUG_PRINT("exit", ("len: %lu net->read_pos[4]: %d",
|
2006-07-07 09:27:55 +02:00
|
|
|
len, mysql->net.read_pos[4]));
|
|
|
|
DBUG_RETURN(len - 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2006-01-12 19:51:02 +01:00
|
|
|
/*
|
|
|
|
Check if the current error is of temporary nature of not.
|
|
|
|
Some errors are temporary in nature, such as
|
|
|
|
ER_LOCK_DEADLOCK and ER_LOCK_WAIT_TIMEOUT. Ndb also signals
|
|
|
|
that the error is temporary by pushing a warning with the error code
|
|
|
|
ER_GET_TEMPORARY_ERRMSG, if the originating error is temporary.
|
|
|
|
*/
|
|
|
|
static int has_temporary_error(THD *thd)
|
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("has_temporary_error");
|
|
|
|
|
2007-10-20 20:16:12 +02:00
|
|
|
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
|
2007-12-12 16:21:01 +01:00
|
|
|
if (thd->main_da.is_error())
|
|
|
|
{
|
|
|
|
thd->clear_error();
|
|
|
|
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
|
|
|
});
|
|
|
|
|
|
|
|
/*
|
|
|
|
If there is no message in THD, we can't say if it's a temporary
|
|
|
|
error or not. This is currently the case for Incident_log_event,
|
|
|
|
which sets no message. Return FALSE.
|
|
|
|
*/
|
|
|
|
if (!thd->is_error())
|
|
|
|
DBUG_RETURN(0);
|
2006-01-12 19:51:02 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Temporary error codes:
|
|
|
|
currently, InnoDB deadlock detected by InnoDB or lock
|
|
|
|
wait timeout (innodb_lock_wait_timeout exceeded
|
|
|
|
*/
|
2007-12-12 16:21:01 +01:00
|
|
|
if (thd->main_da.sql_errno() == ER_LOCK_DEADLOCK ||
|
|
|
|
thd->main_da.sql_errno() == ER_LOCK_WAIT_TIMEOUT)
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2006-01-12 19:51:02 +01:00
|
|
|
|
|
|
|
#ifdef HAVE_NDB_BINLOG
|
|
|
|
/*
|
|
|
|
currently temporary error set in ndbcluster
|
|
|
|
*/
|
|
|
|
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
|
|
|
|
MYSQL_ERROR *err;
|
|
|
|
while ((err= it++))
|
|
|
|
{
|
2006-02-14 22:36:11 +01:00
|
|
|
DBUG_PRINT("info", ("has warning %d %s", err->code, err->msg));
|
2006-01-12 19:51:02 +01:00
|
|
|
switch (err->code)
|
|
|
|
{
|
|
|
|
case ER_GET_TEMPORARY_ERRMSG:
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2006-01-12 19:51:02 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2006-01-12 19:51:02 +01:00
|
|
|
}
|
2005-02-03 16:22:16 +01:00
|
|
|
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
Applies the given event and advances the relay log position.
|
|
|
|
|
|
|
|
In essence, this function does:
|
|
|
|
|
|
|
|
@code
|
|
|
|
ev->apply_event(rli);
|
|
|
|
ev->update_pos(rli);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
But it also does some maintainance, such as skipping events if
|
|
|
|
needed and reporting errors.
|
|
|
|
|
|
|
|
If the @c skip flag is set, then it is tested whether the event
|
|
|
|
should be skipped, by looking at the slave_skip_counter and the
|
|
|
|
server id. The skip flag should be set when calling this from a
|
|
|
|
replication thread but not set when executing an explicit BINLOG
|
|
|
|
statement.
|
|
|
|
|
|
|
|
@retval 0 OK.
|
|
|
|
|
|
|
|
@retval 1 Error calling ev->apply_event().
|
|
|
|
|
|
|
|
@retval 2 No error calling ev->apply_event(), but error calling
|
|
|
|
ev->update_pos().
|
|
|
|
*/
|
2009-10-14 03:39:05 +02:00
|
|
|
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
{
|
|
|
|
int exec_res= 0;
|
|
|
|
|
|
|
|
DBUG_ENTER("apply_event_and_update_pos");
|
|
|
|
|
|
|
|
DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
|
|
|
|
ev->get_type_str(), ev->get_type_code(),
|
|
|
|
ev->server_id));
|
|
|
|
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
|
|
|
|
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
|
|
|
|
FLAGSTR(thd->options, OPTION_BEGIN),
|
|
|
|
rli->last_event_start_time));
|
|
|
|
|
|
|
|
/*
|
|
|
|
Execute the event to change the database and update the binary
|
|
|
|
log coordinates, but first we set some data that is needed for
|
|
|
|
the thread.
|
|
|
|
|
|
|
|
The event will be executed unless it is supposed to be skipped.
|
|
|
|
|
|
|
|
Queries originating from this server must be skipped. Low-level
|
|
|
|
events (Format_description_log_event, Rotate_log_event,
|
|
|
|
Stop_log_event) from this server must also be skipped. But for
|
|
|
|
those we don't want to modify 'group_master_log_pos', because
|
|
|
|
these events did not exist on the master.
|
|
|
|
Format_description_log_event is not completely skipped.
|
|
|
|
|
|
|
|
Skip queries specified by the user in 'slave_skip_counter'. We
|
|
|
|
can't however skip events that has something to do with the log
|
|
|
|
files themselves.
|
|
|
|
|
|
|
|
Filtering on own server id is extremely important, to ignore
|
|
|
|
execution of events created by the creation/rotation of the relay
|
|
|
|
log (remember that now the relay log starts with its Format_desc,
|
|
|
|
has a Rotate etc).
|
|
|
|
*/
|
|
|
|
|
|
|
|
thd->server_id = ev->server_id; // use the original server id for logging
|
|
|
|
thd->set_time(); // time the query
|
|
|
|
thd->lex->current_select= 0;
|
|
|
|
if (!ev->when)
|
|
|
|
ev->when= my_time(0);
|
|
|
|
ev->thd = thd; // because up to this point, ev->thd == 0
|
|
|
|
|
2009-10-14 03:39:05 +02:00
|
|
|
int reason= ev->shall_skip(rli);
|
|
|
|
if (reason == Log_event::EVENT_SKIP_COUNT)
|
|
|
|
--rli->slave_skip_counter;
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
|
|
|
if (reason == Log_event::EVENT_SKIP_NOT)
|
|
|
|
exec_res= ev->apply_event(rli);
|
|
|
|
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
#ifndef DBUG_OFF
|
2009-10-14 03:39:05 +02:00
|
|
|
/*
|
|
|
|
This only prints information to the debug trace.
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
|
2009-10-14 03:39:05 +02:00
|
|
|
TODO: Print an informational message to the error log?
|
|
|
|
*/
|
|
|
|
static const char *const explain[] = {
|
|
|
|
// EVENT_SKIP_NOT,
|
|
|
|
"not skipped",
|
|
|
|
// EVENT_SKIP_IGNORE,
|
|
|
|
"skipped because event should be ignored",
|
|
|
|
// EVENT_SKIP_COUNT
|
|
|
|
"skipped because event skip counter was non-zero"
|
|
|
|
};
|
|
|
|
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
|
|
|
|
thd->options & OPTION_BEGIN ? 1 : 0,
|
|
|
|
rli->get_flag(Relay_log_info::IN_STMT)));
|
|
|
|
DBUG_PRINT("skip_event", ("%s event was %s",
|
|
|
|
ev->get_type_str(), explain[reason]));
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
DBUG_PRINT("info", ("apply_event error = %d", exec_res));
|
|
|
|
if (exec_res == 0)
|
|
|
|
{
|
|
|
|
int error= ev->update_pos(rli);
|
2008-02-06 14:44:47 +01:00
|
|
|
#ifdef HAVE_purify
|
|
|
|
if (!rli->is_fake)
|
|
|
|
#endif
|
|
|
|
{
|
2008-02-07 08:41:32 +01:00
|
|
|
#ifndef DBUG_OFF
|
2008-02-06 14:44:47 +01:00
|
|
|
char buf[22];
|
2008-02-07 08:41:32 +01:00
|
|
|
#endif
|
2008-02-06 14:44:47 +01:00
|
|
|
DBUG_PRINT("info", ("update_pos error = %d", error));
|
|
|
|
DBUG_PRINT("info", ("group %s %s",
|
|
|
|
llstr(rli->group_relay_log_pos, buf),
|
|
|
|
rli->group_relay_log_name));
|
|
|
|
DBUG_PRINT("info", ("event %s %s",
|
|
|
|
llstr(rli->event_relay_log_pos, buf),
|
|
|
|
rli->event_relay_log_name));
|
|
|
|
}
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
/*
|
|
|
|
The update should not fail, so print an error message and
|
|
|
|
return an error code.
|
|
|
|
|
|
|
|
TODO: Replace this with a decent error message when merged
|
|
|
|
with BUG#24954 (which adds several new error message).
|
|
|
|
*/
|
|
|
|
if (error)
|
|
|
|
{
|
2008-02-06 14:44:47 +01:00
|
|
|
char buf[22];
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
|
|
|
|
"It was not possible to update the positions"
|
|
|
|
" of the relay log information: the slave may"
|
|
|
|
" be in an inconsistent state."
|
|
|
|
" Stopped in %s position %s",
|
|
|
|
rli->group_relay_log_name,
|
|
|
|
llstr(rli->group_relay_log_pos, buf));
|
|
|
|
DBUG_RETURN(2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DBUG_RETURN(exec_res ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Top-level function for executing the next event from the relay log.
|
|
|
|
|
|
|
|
This function reads the event from the relay log, executes it, and
|
|
|
|
advances the relay log position. It also handles errors, etc.
|
|
|
|
|
|
|
|
This function may fail to apply the event for the following reasons:
|
|
|
|
|
|
|
|
- The position specfied by the UNTIL condition of the START SLAVE
|
|
|
|
command is reached.
|
|
|
|
|
|
|
|
- It was not possible to read the event from the log.
|
|
|
|
|
|
|
|
- The slave is killed.
|
|
|
|
|
|
|
|
- An error occurred when applying the event, and the event has been
|
|
|
|
tried slave_trans_retries times. If the event has been retried
|
|
|
|
fewer times, 0 is returned.
|
|
|
|
|
|
|
|
- init_master_info or init_relay_log_pos failed. (These are called
|
2009-01-09 13:49:24 +01:00
|
|
|
if a failure occurs when applying the event.)
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
|
|
|
|
- An error occurred when updating the binlog position.
|
|
|
|
|
|
|
|
@retval 0 The event was applied.
|
|
|
|
|
|
|
|
@retval 1 The event was not applied.
|
|
|
|
*/
|
2007-08-16 07:37:50 +02:00
|
|
|
static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("exec_relay_log_event");
|
|
|
|
|
2003-09-13 22:13:41 +02:00
|
|
|
/*
|
|
|
|
We acquire this mutex since we need it for all operations except
|
2005-02-17 13:52:16 +01:00
|
|
|
event execution. But we will release it in places where we will
|
2003-09-13 22:13:41 +02:00
|
|
|
wait for something for example inside of next_event().
|
|
|
|
*/
|
|
|
|
pthread_mutex_lock(&rli->data_lock);
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
Log_event * ev = next_event(rli);
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->sql_thd==thd);
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2002-03-08 23:02:11 +01:00
|
|
|
if (sql_slave_killed(thd,rli))
|
2003-05-25 23:09:46 +02:00
|
|
|
{
|
2003-09-13 22:13:41 +02:00
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
2003-07-01 12:29:55 +02:00
|
|
|
delete ev;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2003-05-25 23:09:46 +02:00
|
|
|
}
|
2000-09-28 23:58:16 +02:00
|
|
|
if (ev)
|
|
|
|
{
|
2001-08-03 23:57:53 +02:00
|
|
|
int exec_res;
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2008-02-22 16:07:07 +01:00
|
|
|
/*
|
|
|
|
This tests if the position of the beginning of the current event
|
|
|
|
hits the UNTIL barrier.
|
|
|
|
*/
|
2008-02-27 18:46:06 +01:00
|
|
|
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
|
2008-02-27 14:43:54 +01:00
|
|
|
rli->is_until_satisfied((rli->is_in_group() || !ev->log_pos) ?
|
2008-02-22 16:07:07 +01:00
|
|
|
rli->group_master_log_pos :
|
|
|
|
ev->log_pos - ev->data_written))
|
|
|
|
{
|
|
|
|
char buf[22];
|
|
|
|
sql_print_information("Slave SQL thread stopped because it reached its"
|
|
|
|
" UNTIL position %s", llstr(rli->until_pos(), buf));
|
|
|
|
/*
|
|
|
|
Setting abort_slave flag because we do not want additional message about
|
|
|
|
error in query execution to be printed.
|
|
|
|
*/
|
|
|
|
rli->abort_slave= 1;
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
|
|
|
delete ev;
|
2008-02-27 14:43:54 +01:00
|
|
|
DBUG_RETURN(1);
|
2005-02-17 13:52:16 +01:00
|
|
|
}
|
2009-10-14 03:39:05 +02:00
|
|
|
exec_res= apply_event_and_update_pos(ev, thd, rli);
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2007-01-17 15:06:37 +01:00
|
|
|
/*
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
Format_description_log_event should not be deleted because it will be
|
|
|
|
used to read info about the relay log's format; it will be deleted when
|
|
|
|
the SQL thread does not need it, i.e. when this thread terminates.
|
2007-01-17 15:06:37 +01:00
|
|
|
*/
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
|
2007-03-22 08:32:41 +01:00
|
|
|
{
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
DBUG_PRINT("info", ("Deleting the event after it has been executed"));
|
|
|
|
delete ev;
|
2007-03-22 08:32:41 +01:00
|
|
|
}
|
|
|
|
|
2005-02-17 13:52:16 +01:00
|
|
|
/*
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
update_log_pos failed: this should not happen, so we don't
|
|
|
|
retry.
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
*/
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
if (exec_res == 2)
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
2005-03-02 11:29:48 +01:00
|
|
|
if (slave_trans_retries)
|
|
|
|
{
|
2007-10-20 20:16:12 +02:00
|
|
|
int temp_err;
|
|
|
|
if (exec_res && (temp_err= has_temporary_error(thd)))
|
2005-03-02 11:29:48 +01:00
|
|
|
{
|
|
|
|
const char *errmsg;
|
|
|
|
/*
|
|
|
|
We were in a transaction which has been rolled back because of a
|
2006-01-12 19:51:02 +01:00
|
|
|
temporary error;
|
|
|
|
let's seek back to BEGIN log event and retry it all again.
|
2006-10-30 12:07:36 +01:00
|
|
|
Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
|
2006-10-11 09:16:37 +02:00
|
|
|
there is no rollback since 5.0.13 (ref: manual).
|
2005-03-02 11:29:48 +01:00
|
|
|
We have to not only seek but also
|
|
|
|
a) init_master_info(), to seek back to hot relay log's start for later
|
|
|
|
(for when we will come back to this hot log after re-processing the
|
|
|
|
possibly existing old logs where BEGIN is: check_binlog_magic() will
|
|
|
|
then need the cache to be at position 0 (see comments at beginning of
|
|
|
|
init_master_info()).
|
|
|
|
b) init_relay_log_pos(), because the BEGIN may be an older relay log.
|
|
|
|
*/
|
2005-03-23 19:19:36 +01:00
|
|
|
if (rli->trans_retries < slave_trans_retries)
|
2005-03-02 11:29:48 +01:00
|
|
|
{
|
|
|
|
if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
|
|
|
|
sql_print_error("Failed to initialize the master info structure");
|
|
|
|
else if (init_relay_log_pos(rli,
|
|
|
|
rli->group_relay_log_name,
|
|
|
|
rli->group_relay_log_pos,
|
2005-03-02 16:37:54 +01:00
|
|
|
1, &errmsg, 1))
|
2005-03-02 11:29:48 +01:00
|
|
|
sql_print_error("Error initializing relay log position: %s",
|
|
|
|
errmsg);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
exec_res= 0;
|
2006-03-07 13:29:53 +01:00
|
|
|
end_trans(thd, ROLLBACK);
|
2006-07-07 09:27:55 +02:00
|
|
|
/* chance for concurrent connection to get more locks */
|
2005-03-23 19:19:36 +01:00
|
|
|
safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
|
2006-07-07 09:27:55 +02:00
|
|
|
(CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
|
2005-03-23 19:19:36 +01:00
|
|
|
pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
|
2006-07-07 09:27:55 +02:00
|
|
|
rli->trans_retries++;
|
2005-03-23 19:19:36 +01:00
|
|
|
rli->retried_trans++;
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
|
|
|
DBUG_PRINT("info", ("Slave retries transaction "
|
|
|
|
"rli->trans_retries: %lu", rli->trans_retries));
|
2006-07-07 09:27:55 +02:00
|
|
|
}
|
2005-03-02 11:29:48 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
sql_print_error("Slave SQL thread retried transaction %lu time(s) "
|
|
|
|
"in vain, giving up. Consider raising the value of "
|
|
|
|
"the slave_transaction_retries variable.",
|
|
|
|
slave_trans_retries);
|
|
|
|
}
|
2009-06-09 18:44:26 +02:00
|
|
|
else if ((exec_res && !temp_err) ||
|
2007-10-20 20:16:12 +02:00
|
|
|
(opt_using_transactions &&
|
|
|
|
rli->group_relay_log_pos == rli->event_relay_log_pos))
|
2006-03-07 13:29:53 +01:00
|
|
|
{
|
|
|
|
/*
|
2007-10-20 20:16:12 +02:00
|
|
|
Only reset the retry counter if the entire group succeeded
|
|
|
|
or failed with a non-transient error. On a successful
|
|
|
|
event, the execution will proceed as usual; in the case of a
|
2006-03-07 13:29:53 +01:00
|
|
|
non-transient error, the slave will stop with an error.
|
|
|
|
*/
|
|
|
|
rli->trans_retries= 0; // restart from fresh
|
2007-10-30 12:49:42 +01:00
|
|
|
DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
|
2007-10-20 20:16:12 +02:00
|
|
|
rli->trans_retries));
|
2006-03-07 13:29:53 +01:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
}
|
|
|
|
DBUG_RETURN(exec_res);
|
2000-09-28 23:58:16 +02:00
|
|
|
}
|
2006-05-30 18:21:03 +02:00
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
2007-06-09 07:19:37 +02:00
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE,
|
|
|
|
ER(ER_SLAVE_RELAY_LOG_READ_FAILURE), "\
|
2003-06-02 17:30:47 +02:00
|
|
|
Could not parse relay log event entry. The possible reasons are: the master's \
|
|
|
|
binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
|
|
|
|
binary log), the slave's relay log is corrupted (you can check this by running \
|
|
|
|
'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
|
|
|
|
or slave's MySQL code. If you want to check the master's binary log or slave's \
|
|
|
|
relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
|
|
|
|
on this slave.\
|
2001-02-21 03:39:48 +01:00
|
|
|
");
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
|
2007-06-29 18:48:22 +02:00
|
|
|
{
|
|
|
|
if (io_slave_killed(thd, mi))
|
|
|
|
{
|
2007-11-22 17:22:54 +01:00
|
|
|
if (info && global_system_variables.log_warnings)
|
2009-09-23 15:21:29 +02:00
|
|
|
sql_print_information("%s", info);
|
2007-06-29 18:48:22 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@brief Try to reconnect slave IO thread.
|
|
|
|
|
|
|
|
@details Terminates current connection to master, sleeps for
|
|
|
|
@c mi->connect_retry msecs and initiates new connection with
|
|
|
|
@c safe_reconnect(). Variable pointed by @c retry_count is increased -
|
|
|
|
if it exceeds @c master_retry_count then connection is not re-established
|
|
|
|
and function signals error.
|
|
|
|
Unless @c suppres_warnings is TRUE, a warning is put in the server error log
|
|
|
|
when reconnecting. The warning message and messages used to report errors
|
|
|
|
are taken from @c messages array. In case @c master_retry_count is exceeded,
|
|
|
|
no messages are added to the log.
|
|
|
|
|
|
|
|
@param[in] thd Thread context.
|
|
|
|
@param[in] mysql MySQL connection.
|
|
|
|
@param[in] mi Master connection information.
|
|
|
|
@param[in,out] retry_count Number of attempts to reconnect.
|
|
|
|
@param[in] suppress_warnings TRUE when a normal net read timeout
|
|
|
|
has caused to reconnecting.
|
|
|
|
@param[in] messages Messages to print/log, see
|
|
|
|
reconnect_messages[] array.
|
|
|
|
|
|
|
|
@retval 0 OK.
|
|
|
|
@retval 1 There was an error.
|
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi,
|
2007-06-29 18:48:22 +02:00
|
|
|
uint *retry_count, bool suppress_warnings,
|
|
|
|
const char *messages[SLAVE_RECON_MSG_MAX])
|
|
|
|
{
|
|
|
|
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
|
|
|
|
thd->proc_info= messages[SLAVE_RECON_MSG_WAIT];
|
|
|
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
|
|
|
thd->clear_active_vio();
|
|
|
|
#endif
|
|
|
|
end_server(mysql);
|
|
|
|
if ((*retry_count)++)
|
|
|
|
{
|
|
|
|
if (*retry_count > master_retry_count)
|
|
|
|
return 1; // Don't retry forever
|
|
|
|
safe_sleep(thd, mi->connect_retry, (CHECK_KILLED_FUNC) io_slave_killed,
|
|
|
|
(void *) mi);
|
|
|
|
}
|
|
|
|
if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING]))
|
|
|
|
return 1;
|
|
|
|
thd->proc_info = messages[SLAVE_RECON_MSG_AFTER];
|
|
|
|
if (!suppress_warnings)
|
|
|
|
{
|
|
|
|
char buf[256], llbuff[22];
|
|
|
|
my_snprintf(buf, sizeof(buf), messages[SLAVE_RECON_MSG_FAILED],
|
|
|
|
IO_RPL_LOG_NAME, llstr(mi->master_log_pos, llbuff));
|
|
|
|
/*
|
|
|
|
Raise a warining during registering on master/requesting dump.
|
|
|
|
Log a message reading event.
|
|
|
|
*/
|
|
|
|
if (messages[SLAVE_RECON_MSG_COMMAND][0])
|
|
|
|
{
|
|
|
|
mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
|
|
|
|
ER(ER_SLAVE_MASTER_COM_FAILURE),
|
|
|
|
messages[SLAVE_RECON_MSG_COMMAND], buf);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-09-23 15:21:29 +02:00
|
|
|
sql_print_information("%s", buf);
|
2007-06-29 18:48:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (safe_reconnect(thd, mysql, mi, 1) || io_slave_killed(thd, mi))
|
|
|
|
{
|
|
|
|
if (global_system_variables.log_warnings)
|
2009-09-23 15:21:29 +02:00
|
|
|
sql_print_information("%s", messages[SLAVE_RECON_MSG_KILLED_AFTER]);
|
2007-06-29 18:48:22 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-09 13:49:24 +01:00
|
|
|
/**
|
|
|
|
Slave IO thread entry point.
|
|
|
|
|
|
|
|
@param arg Pointer to Master_info struct that holds information for
|
|
|
|
the IO thread.
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2009-01-09 13:49:24 +01:00
|
|
|
@return Always 0.
|
|
|
|
*/
|
2005-10-08 16:39:55 +02:00
|
|
|
pthread_handler_t handle_slave_io(void *arg)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-08-24 04:44:16 +02:00
|
|
|
THD *thd; // needs to be first for thread_stack
|
|
|
|
MYSQL *mysql;
|
2007-08-16 08:52:50 +02:00
|
|
|
Master_info *mi = (Master_info*)arg;
|
2007-08-16 07:37:50 +02:00
|
|
|
Relay_log_info *rli= &mi->rli;
|
2002-08-24 04:44:16 +02:00
|
|
|
char llbuff[22];
|
|
|
|
uint retry_count;
|
2007-06-29 18:48:22 +02:00
|
|
|
bool suppress_warnings;
|
2009-07-16 08:56:43 +02:00
|
|
|
int ret;
|
2007-06-29 18:48:22 +02:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
|
|
|
|
#endif
|
2002-08-24 04:44:16 +02:00
|
|
|
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
|
|
|
|
my_thread_init();
|
2003-03-10 11:00:19 +01:00
|
|
|
DBUG_ENTER("handle_slave_io");
|
2002-08-24 04:44:16 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(mi->inited);
|
2002-08-24 04:44:16 +02:00
|
|
|
mysql= NULL ;
|
|
|
|
retry_count= 0;
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_lock(&mi->run_lock);
|
2002-08-24 04:44:16 +02:00
|
|
|
/* Inform waiting threads that slave has started */
|
|
|
|
mi->slave_run_id++;
|
|
|
|
|
2005-02-17 13:52:16 +01:00
|
|
|
#ifndef DBUG_OFF
|
2005-12-22 06:39:02 +01:00
|
|
|
mi->events_till_disconnect = disconnect_slave_event_count;
|
2005-02-17 13:52:16 +01:00
|
|
|
#endif
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
thd= new THD; // note that contructor of THD uses DBUG_ !
|
2002-03-30 20:36:05 +01:00
|
|
|
THD_CHECK_SENTRY(thd);
|
2008-02-13 13:09:41 +01:00
|
|
|
mi->io_thd = thd;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
pthread_detach_this_thread();
|
2005-11-23 19:18:10 +01:00
|
|
|
thd->thread_stack= (char*) &thd; // remember where our stack is
|
2009-06-03 16:14:18 +02:00
|
|
|
mi->clear_error();
|
2002-01-20 03:16:52 +01:00
|
|
|
if (init_slave_thread(thd, SLAVE_THD_IO))
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
|
|
|
pthread_cond_broadcast(&mi->start_cond);
|
|
|
|
pthread_mutex_unlock(&mi->run_lock);
|
|
|
|
sql_print_error("Failed during slave I/O thread initialization");
|
|
|
|
goto err;
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
pthread_mutex_lock(&LOCK_thread_count);
|
2000-07-31 21:29:14 +02:00
|
|
|
threads.append(thd);
|
2002-08-08 02:12:02 +02:00
|
|
|
pthread_mutex_unlock(&LOCK_thread_count);
|
2002-01-20 03:16:52 +01:00
|
|
|
mi->slave_running = 1;
|
|
|
|
mi->abort_slave = 0;
|
|
|
|
pthread_mutex_unlock(&mi->run_lock);
|
2002-08-08 02:12:02 +02:00
|
|
|
pthread_cond_broadcast(&mi->start_cond);
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->master_log_name,
|
|
|
|
llstr(mi->master_log_pos,llbuff)));
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2003-05-02 18:07:41 +02:00
|
|
|
if (!(mi->mysql = mysql = mysql_init(NULL)))
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
|
|
|
|
ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()");
|
2001-01-22 03:46:32 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Connecting to master");
|
2000-12-02 18:11:50 +01:00
|
|
|
// we can get killed during safe_connect
|
2002-01-20 03:16:52 +01:00
|
|
|
if (!safe_connect(thd, mysql, mi))
|
2006-09-11 23:19:05 +02:00
|
|
|
{
|
2006-11-27 00:47:38 +01:00
|
|
|
sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
|
|
|
|
"replication started in log '%s' at position %s",
|
|
|
|
mi->user, mi->host, mi->port,
|
2006-09-11 23:19:05 +02:00
|
|
|
IO_RPL_LOG_NAME,
|
|
|
|
llstr(mi->master_log_pos,llbuff));
|
2006-11-12 19:01:58 +01:00
|
|
|
/*
|
|
|
|
Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O
|
|
|
|
thread, since a replication event can become this much larger than
|
|
|
|
the corresponding packet (query) sent from client to master.
|
|
|
|
*/
|
2006-09-11 23:19:05 +02:00
|
|
|
mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER;
|
|
|
|
}
|
2000-12-02 18:11:50 +01:00
|
|
|
else
|
2001-03-07 22:50:44 +01:00
|
|
|
{
|
2004-09-15 21:10:31 +02:00
|
|
|
sql_print_information("Slave I/O thread killed while connecting to master");
|
2001-03-07 22:50:44 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2001-05-31 02:50:56 +02:00
|
|
|
|
2001-06-29 02:22:29 +02:00
|
|
|
connected:
|
2001-06-29 03:48:49 +02:00
|
|
|
|
2004-12-16 18:12:22 +01:00
|
|
|
// TODO: the assignment below should be under mutex (5.0)
|
|
|
|
mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
|
2001-08-03 23:57:53 +02:00
|
|
|
thd->slave_net = &mysql->net;
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Checking master version");
|
2009-07-16 08:56:43 +02:00
|
|
|
ret= get_master_version_and_clock(mysql, mi);
|
|
|
|
if (ret == 1)
|
|
|
|
/* Fatal error */
|
2001-11-11 06:24:12 +01:00
|
|
|
goto err;
|
2009-07-16 08:56:43 +02:00
|
|
|
|
|
|
|
if (ret == 2)
|
|
|
|
{
|
|
|
|
if (check_io_slave_killed(mi->io_thd, mi, "Slave I/O thread killed"
|
|
|
|
"while calling get_master_version_and_clock(...)"))
|
|
|
|
goto err;
|
|
|
|
suppress_warnings= FALSE;
|
|
|
|
/* Try to reconnect because the error was caused by a transient network problem */
|
|
|
|
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_REG]))
|
|
|
|
goto err;
|
|
|
|
goto connected;
|
|
|
|
}
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
|
|
|
|
if (mi->rli.relay_log.description_event_for_queue->binlog_version > 1)
|
2001-11-11 06:24:12 +01:00
|
|
|
{
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
Register ourselves with the master.
|
|
|
|
*/
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Registering slave on master");
|
2007-06-29 18:48:22 +02:00
|
|
|
if (register_slave_on_master(mysql, mi, &suppress_warnings))
|
2007-05-31 10:17:16 +02:00
|
|
|
{
|
2007-11-22 17:22:54 +01:00
|
|
|
if (!check_io_slave_killed(thd, mi, "Slave I/O thread killed "
|
|
|
|
"while registering slave on master"))
|
|
|
|
{
|
|
|
|
sql_print_error("Slave I/O thread couldn't register on master");
|
|
|
|
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_REG]))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else
|
2007-06-29 18:48:22 +02:00
|
|
|
goto err;
|
|
|
|
goto connected;
|
2007-05-31 10:17:16 +02:00
|
|
|
}
|
2007-06-29 18:48:22 +02:00
|
|
|
DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_REG",
|
|
|
|
if (!retry_count_reg)
|
|
|
|
{
|
|
|
|
retry_count_reg++;
|
|
|
|
sql_print_information("Forcing to reconnect slave I/O thread");
|
|
|
|
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_REG]))
|
|
|
|
goto err;
|
|
|
|
goto connected;
|
|
|
|
});
|
2001-11-11 06:24:12 +01:00
|
|
|
}
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2002-08-21 21:04:22 +02:00
|
|
|
DBUG_PRINT("info",("Starting reading binary log from master"));
|
2002-03-08 23:02:11 +01:00
|
|
|
while (!io_slave_killed(thd,mi))
|
2001-01-22 03:46:32 +01:00
|
|
|
{
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Requesting binlog dump");
|
2002-07-23 17:31:22 +02:00
|
|
|
if (request_dump(mysql, mi, &suppress_warnings))
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
|
|
|
sql_print_error("Failed on request_dump()");
|
2007-06-29 18:48:22 +02:00
|
|
|
if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
|
|
|
|
requesting master dump") ||
|
|
|
|
try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_DUMP]))
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
2002-01-29 17:32:16 +01:00
|
|
|
goto connected;
|
|
|
|
}
|
2007-06-29 18:48:22 +02:00
|
|
|
DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP",
|
|
|
|
if (!retry_count_dump)
|
|
|
|
{
|
|
|
|
retry_count_dump++;
|
|
|
|
sql_print_information("Forcing to reconnect slave I/O thread");
|
|
|
|
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_DUMP]))
|
|
|
|
goto err;
|
|
|
|
goto connected;
|
|
|
|
});
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2009-06-03 16:14:18 +02:00
|
|
|
DBUG_ASSERT(mi->last_error().number == 0);
|
2002-03-08 23:02:11 +01:00
|
|
|
while (!io_slave_killed(thd,mi))
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
2006-12-14 23:51:37 +01:00
|
|
|
ulong event_len;
|
2005-02-17 13:52:16 +01:00
|
|
|
/*
|
2003-08-25 14:13:58 +02:00
|
|
|
We say "waiting" because read_event() will wait if there's nothing to
|
2005-02-09 20:04:28 +01:00
|
|
|
read. But if there's something to read, it will not wait. The
|
|
|
|
important thing is to not confuse users by saying "reading" whereas
|
|
|
|
we're in fact receiving nothing.
|
2003-08-25 14:13:58 +02:00
|
|
|
*/
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Waiting for master to send event");
|
2006-12-14 23:51:37 +01:00
|
|
|
event_len= read_event(mysql, mi, &suppress_warnings);
|
2007-06-29 18:48:22 +02:00
|
|
|
if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
|
|
|
|
reading event"))
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
2007-06-29 18:48:22 +02:00
|
|
|
DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
|
|
|
|
if (!retry_count_event)
|
|
|
|
{
|
|
|
|
retry_count_event++;
|
|
|
|
sql_print_information("Forcing to reconnect slave I/O thread");
|
|
|
|
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_EVENT]))
|
|
|
|
goto err;
|
|
|
|
goto connected;
|
|
|
|
});
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
if (event_len == packet_error)
|
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
uint mysql_error_number= mysql_errno(mysql);
|
2007-07-11 16:38:45 +02:00
|
|
|
switch (mysql_error_number) {
|
|
|
|
case CR_NET_PACKET_TOO_LARGE:
|
2006-07-07 09:27:55 +02:00
|
|
|
sql_print_error("\
|
2002-08-08 02:12:02 +02:00
|
|
|
Log entry on master is longer than max_allowed_packet (%ld) on \
|
|
|
|
slave. If the entry is correct, restart the server with a higher value of \
|
|
|
|
max_allowed_packet",
|
2006-07-07 09:27:55 +02:00
|
|
|
thd->variables.max_allowed_packet);
|
2009-09-18 10:20:29 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
|
2009-09-23 15:21:29 +02:00
|
|
|
"%s", ER(ER_NET_PACKET_TOO_LARGE));
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
2007-07-11 16:38:45 +02:00
|
|
|
case ER_MASTER_FATAL_ERROR_READING_BINLOG:
|
2009-09-18 10:20:29 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
|
|
|
|
ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
|
|
|
|
mysql_error_number, mysql_error(mysql));
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
2009-09-18 10:20:29 +02:00
|
|
|
case ER_OUT_OF_RESOURCES:
|
2007-07-11 16:38:45 +02:00
|
|
|
sql_print_error("\
|
|
|
|
Stopping slave I/O thread due to out-of-memory error from master");
|
2009-09-18 10:20:29 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
|
2009-09-23 15:21:29 +02:00
|
|
|
"%s", ER(ER_OUT_OF_RESOURCES));
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2007-06-29 18:48:22 +02:00
|
|
|
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
|
|
|
|
reconnect_messages[SLAVE_RECON_ACT_EVENT]))
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
|
|
|
goto connected;
|
2002-06-05 22:04:38 +02:00
|
|
|
} // if (event_len == packet_error)
|
2005-02-17 13:52:16 +01:00
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
retry_count=0; // ok event, reset retry counter
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Queueing master event to the relay log");
|
2002-01-29 17:32:16 +01:00
|
|
|
if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
|
2006-07-07 09:27:55 +02:00
|
|
|
event_len))
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
|
|
|
|
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
|
|
|
|
"could not queue event from master");
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
2002-01-29 17:32:16 +01:00
|
|
|
}
|
2006-01-03 17:54:54 +01:00
|
|
|
if (flush_master_info(mi, 1))
|
|
|
|
{
|
|
|
|
sql_print_error("Failed to flush master info file");
|
|
|
|
goto err;
|
|
|
|
}
|
2003-05-25 23:09:46 +02:00
|
|
|
/*
|
|
|
|
See if the relay logs take too much space.
|
|
|
|
We don't lock mi->rli.log_space_lock here; this dirty read saves time
|
|
|
|
and does not introduce any problem:
|
|
|
|
- if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
|
|
|
|
the clean value is 0), then we are reading only one more event as we
|
|
|
|
should, and we'll block only at the next event. No big deal.
|
|
|
|
- if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
|
|
|
|
the clean value is 1), then we are going into wait_for_relay_log_space()
|
|
|
|
for no reason, but this function will do a clean read, notice the clean
|
|
|
|
value and exit immediately.
|
|
|
|
*/
|
2003-06-16 15:49:54 +02:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
{
|
|
|
|
char llbuf1[22], llbuf2[22];
|
|
|
|
DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
|
|
|
|
ignore_log_space_limit=%d",
|
2005-10-12 13:29:55 +02:00
|
|
|
llstr(rli->log_space_limit,llbuf1),
|
|
|
|
llstr(rli->log_space_total,llbuf2),
|
2006-07-07 09:27:55 +02:00
|
|
|
(int) rli->ignore_log_space_limit));
|
2003-06-16 15:49:54 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-10-12 13:29:55 +02:00
|
|
|
if (rli->log_space_limit && rli->log_space_limit <
|
2006-07-07 09:27:55 +02:00
|
|
|
rli->log_space_total &&
|
2005-10-12 13:29:55 +02:00
|
|
|
!rli->ignore_log_space_limit)
|
2006-07-07 09:27:55 +02:00
|
|
|
if (wait_for_relay_log_space(rli))
|
|
|
|
{
|
|
|
|
sql_print_error("Slave I/O thread aborted while waiting for relay \
|
2002-04-02 06:46:23 +02:00
|
|
|
log space");
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2001-04-20 14:18:46 +02:00
|
|
|
// error = 0;
|
2002-01-29 17:32:16 +01:00
|
|
|
err:
|
2002-01-20 03:16:52 +01:00
|
|
|
// print the current replication position
|
2004-09-15 21:10:31 +02:00
|
|
|
sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
|
2006-07-07 09:27:55 +02:00
|
|
|
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
|
2009-07-24 17:58:58 +02:00
|
|
|
thd->set_query(NULL, 0);
|
A fix and a test case for
Bug#19022 "Memory bug when switching db during trigger execution"
Bug#17199 "Problem when view calls function from another database."
Bug#18444 "Fully qualified stored function names don't work correctly in
SELECT statements"
Documentation note: this patch introduces a change in behaviour of prepared
statements.
This patch adds a few new invariants with regard to how THD::db should
be used. These invariants should be preserved in future:
- one should never refer to THD::db by pointer and always make a deep copy
(strmake, strdup)
- one should never compare two databases by pointer, but use strncmp or
my_strncasecmp
- TABLE_LIST object table->db should be always initialized in the parser or
by creator of the object.
For prepared statements it means that if the current database is changed
after a statement is prepared, the database that was current at prepare
remains active. This also means that you can not prepare a statement that
implicitly refers to the current database if the latter is not set.
This is not documented, and therefore needs documentation. This is NOT a
change in behavior for almost all SQL statements except:
- ALTER TABLE t1 RENAME t2
- OPTIMIZE TABLE t1
- ANALYZE TABLE t1
- TRUNCATE TABLE t1 --
until this patch t1 or t2 could be evaluated at the first execution of
prepared statement.
CURRENT_DATABASE() still works OK and is evaluated at every execution
of prepared statement.
Note, that in stored routines this is not an issue as the default
database is the database of the stored procedure and "use" statement
is prohibited in stored routines.
This patch makes obsolete the use of check_db_used (it was never used in the
old code too) and all other places that check for table->db and assign it
from THD::db if it's NULL, except the parser.
How this patch was created: THD::{db,db_length} were replaced with a
LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were
manually checked and:
- if the place uses thd->db by pointer, it was fixed to make a deep copy
- if a place compared two db pointers, it was fixed to compare them by value
(via strcmp/my_strcasecmp, whatever was approproate)
Then this intermediate patch was used to write a smaller patch that does the
same thing but without a rename.
TODO in 5.1:
- remove check_db_used
- deploy THD::set_db in mysql_change_db
See also comments to individual files.
2006-06-26 22:47:52 +02:00
|
|
|
thd->reset_db(NULL, 0);
|
2002-02-07 23:29:46 +01:00
|
|
|
if (mysql)
|
|
|
|
{
|
2006-06-20 20:46:45 +02:00
|
|
|
/*
|
|
|
|
Here we need to clear the active VIO before closing the
|
|
|
|
connection with the master. The reason is that THD::awake()
|
|
|
|
might be called from terminate_slave_thread() because somebody
|
|
|
|
issued a STOP SLAVE. If that happends, the close_active_vio()
|
|
|
|
can be called in the middle of closing the VIO associated with
|
|
|
|
the 'mysql' object, causing a crash.
|
|
|
|
*/
|
|
|
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
|
|
|
thd->clear_active_vio();
|
|
|
|
#endif
|
2003-05-02 18:07:41 +02:00
|
|
|
mysql_close(mysql);
|
2002-02-07 23:29:46 +01:00
|
|
|
mi->mysql=0;
|
|
|
|
}
|
2005-10-12 13:29:55 +02:00
|
|
|
write_ignored_events_info_to_relay_log(thd, mi);
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Waiting for slave mutex on exit");
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_lock(&mi->run_lock);
|
2005-10-03 18:34:42 +02:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/* Forget the relay log's format */
|
|
|
|
delete mi->rli.relay_log.description_event_for_queue;
|
|
|
|
mi->rli.relay_log.description_event_for_queue= 0;
|
2007-08-16 08:52:50 +02:00
|
|
|
// TODO: make rpl_status part of Master_info
|
2001-10-11 21:54:06 +02:00
|
|
|
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(thd->net.buff != 0);
|
2002-02-07 23:29:46 +01:00
|
|
|
net_end(&thd->net); // destructor will not free it, because net.vio is 0
|
2007-11-01 21:52:56 +01:00
|
|
|
close_thread_tables(thd);
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_lock(&LOCK_thread_count);
|
2002-03-30 20:36:05 +01:00
|
|
|
THD_CHECK_SENTRY(thd);
|
2000-07-31 21:29:14 +02:00
|
|
|
delete thd;
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_unlock(&LOCK_thread_count);
|
2006-07-25 12:30:18 +02:00
|
|
|
mi->abort_slave= 0;
|
|
|
|
mi->slave_running= 0;
|
|
|
|
mi->io_thd= 0;
|
2007-02-03 20:14:16 +01:00
|
|
|
/*
|
|
|
|
Note: the order of the two following calls (first broadcast, then unlock)
|
|
|
|
is important. Otherwise a killer_thread can execute between the calls and
|
|
|
|
delete the mi structure leading to a crash! (see BUG#25306 for details)
|
|
|
|
*/
|
2006-07-07 18:31:00 +02:00
|
|
|
pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
|
2009-04-28 13:46:07 +02:00
|
|
|
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
|
2007-02-03 20:14:16 +01:00
|
|
|
pthread_mutex_unlock(&mi->run_lock);
|
2009-09-23 15:10:23 +02:00
|
|
|
|
|
|
|
DBUG_LEAVE; // Must match DBUG_ENTER()
|
2006-07-07 18:31:00 +02:00
|
|
|
my_thread_end();
|
2000-07-31 21:29:14 +02:00
|
|
|
pthread_exit(0);
|
2009-09-23 15:10:23 +02:00
|
|
|
return 0; // Avoid compiler warnings
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2009-03-18 11:31:17 +01:00
|
|
|
/*
|
|
|
|
Check the temporary directory used by commands like
|
|
|
|
LOAD DATA INFILE.
|
|
|
|
*/
|
|
|
|
static
|
2009-04-19 03:21:33 +02:00
|
|
|
int check_temp_dir(char* tmp_file)
|
2009-03-18 11:31:17 +01:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
MY_DIR *dirp;
|
2009-04-19 03:21:33 +02:00
|
|
|
char tmp_dir[FN_REFLEN];
|
|
|
|
size_t tmp_dir_size;
|
2009-03-18 11:31:17 +01:00
|
|
|
|
|
|
|
DBUG_ENTER("check_temp_dir");
|
|
|
|
|
2009-04-19 03:21:33 +02:00
|
|
|
/*
|
|
|
|
Get the directory from the temporary file.
|
|
|
|
*/
|
|
|
|
dirname_part(tmp_dir, tmp_file, &tmp_dir_size);
|
|
|
|
|
2009-03-18 11:31:17 +01:00
|
|
|
/*
|
|
|
|
Check if the directory exists.
|
|
|
|
*/
|
|
|
|
if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
my_dirend(dirp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
Check permissions to create a file.
|
|
|
|
*/
|
|
|
|
if ((fd= my_create(tmp_file, CREATE_MODE,
|
|
|
|
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
|
|
|
|
MYF(MY_WME))) < 0)
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
Clean up.
|
|
|
|
*/
|
|
|
|
my_close(fd, MYF(0));
|
|
|
|
my_delete(tmp_file, MYF(0));
|
|
|
|
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2009-01-09 13:49:24 +01:00
|
|
|
/**
|
|
|
|
Slave SQL thread entry point.
|
|
|
|
|
|
|
|
@param arg Pointer to Relay_log_info object that holds information
|
|
|
|
for the SQL thread.
|
2001-01-22 03:46:32 +01:00
|
|
|
|
2009-01-09 13:49:24 +01:00
|
|
|
@return Always 0.
|
|
|
|
*/
|
2005-10-08 16:39:55 +02:00
|
|
|
pthread_handler_t handle_slave_sql(void *arg)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
THD *thd; /* needs to be first for thread_stack */
|
2002-01-20 03:16:52 +01:00
|
|
|
char llbuff[22],llbuff1[22];
|
2006-05-30 18:21:03 +02:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
Relay_log_info* rli = &((Master_info*)arg)->rli;
|
2002-08-24 04:44:16 +02:00
|
|
|
const char *errmsg;
|
|
|
|
|
|
|
|
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
|
|
|
|
my_thread_init();
|
2003-03-10 11:00:19 +01:00
|
|
|
DBUG_ENTER("handle_slave_sql");
|
2002-08-24 04:44:16 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->inited);
|
|
|
|
pthread_mutex_lock(&rli->run_lock);
|
|
|
|
DBUG_ASSERT(!rli->slave_running);
|
2002-08-24 04:44:16 +02:00
|
|
|
errmsg= 0;
|
2006-07-07 09:27:55 +02:00
|
|
|
#ifndef DBUG_OFF
|
2002-01-20 03:16:52 +01:00
|
|
|
rli->events_till_abort = abort_slave_event_count;
|
2006-07-07 09:27:55 +02:00
|
|
|
#endif
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2002-08-24 04:44:16 +02:00
|
|
|
thd = new THD; // note that contructor of THD uses DBUG_ !
|
2003-03-19 20:23:13 +01:00
|
|
|
thd->thread_stack = (char*)&thd; // remember where our stack is
|
2008-02-13 13:09:41 +01:00
|
|
|
rli->sql_thd= thd;
|
2003-03-19 20:23:13 +01:00
|
|
|
|
2002-08-24 04:44:16 +02:00
|
|
|
/* Inform waiting threads that slave has started */
|
|
|
|
rli->slave_run_id++;
|
2008-02-13 13:09:41 +01:00
|
|
|
rli->slave_running = 1;
|
2002-08-24 04:44:16 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_detach_this_thread();
|
|
|
|
if (init_slave_thread(thd, SLAVE_THD_SQL))
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
TODO: this is currently broken - slave start and change master
|
|
|
|
will be stuck if we fail here
|
|
|
|
*/
|
|
|
|
pthread_cond_broadcast(&rli->start_cond);
|
|
|
|
pthread_mutex_unlock(&rli->run_lock);
|
2009-02-11 12:56:25 +01:00
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
|
|
|
|
"Failed during slave thread initialization");
|
2002-01-29 17:32:16 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2003-03-19 20:23:13 +01:00
|
|
|
thd->init_for_queries();
|
2002-01-20 03:16:52 +01:00
|
|
|
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
|
2009-05-23 01:15:21 +02:00
|
|
|
set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
|
2002-08-08 02:12:02 +02:00
|
|
|
pthread_mutex_lock(&LOCK_thread_count);
|
2002-01-20 03:16:52 +01:00
|
|
|
threads.append(thd);
|
2002-08-08 02:12:02 +02:00
|
|
|
pthread_mutex_unlock(&LOCK_thread_count);
|
2004-12-16 18:12:22 +01:00
|
|
|
/*
|
|
|
|
We are going to set slave_running to 1. Assuming slave I/O thread is
|
|
|
|
alive and connected, this is going to make Seconds_Behind_Master be 0
|
|
|
|
i.e. "caught up". Even if we're just at start of thread. Well it's ok, at
|
|
|
|
the moment we start we can think we are caught up, and the next second we
|
|
|
|
start receiving data so we realize we are not caught up and
|
|
|
|
Seconds_Behind_Master grows. No big deal.
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
rli->abort_slave = 0;
|
|
|
|
pthread_mutex_unlock(&rli->run_lock);
|
2002-08-08 02:12:02 +02:00
|
|
|
pthread_cond_broadcast(&rli->start_cond);
|
2003-03-17 22:51:56 +01:00
|
|
|
|
2003-08-04 10:59:44 +02:00
|
|
|
/*
|
|
|
|
Reset errors for a clean start (otherwise, if the master is idle, the SQL
|
|
|
|
thread may execute no Query_log_event, so the error will remain even
|
2003-10-09 00:06:21 +02:00
|
|
|
though there's no problem anymore). Do not reset the master timestamp
|
2003-11-22 02:21:40 +01:00
|
|
|
(imagine the slave has caught everything, the STOP SLAVE and START SLAVE:
|
|
|
|
as we are not sure that we are going to receive a query, we want to
|
|
|
|
remember the last master timestamp (to say how many seconds behind we are
|
|
|
|
now.
|
2003-10-09 00:06:21 +02:00
|
|
|
But the master timestamp is reset by RESET SLAVE & CHANGE MASTER.
|
2003-08-04 10:59:44 +02:00
|
|
|
*/
|
2007-06-09 07:19:37 +02:00
|
|
|
rli->clear_error();
|
2003-03-17 22:51:56 +01:00
|
|
|
|
|
|
|
//tell the I/O thread to take relay_log_space_limit into account from now on
|
2003-05-25 23:09:46 +02:00
|
|
|
pthread_mutex_lock(&rli->log_space_lock);
|
2003-03-17 22:51:56 +01:00
|
|
|
rli->ignore_log_space_limit= 0;
|
2003-05-25 23:09:46 +02:00
|
|
|
pthread_mutex_unlock(&rli->log_space_lock);
|
2005-03-23 19:19:36 +01:00
|
|
|
rli->trans_retries= 0; // start from "no error"
|
2007-10-30 12:49:42 +01:00
|
|
|
DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
|
2003-03-17 22:51:56 +01:00
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
if (init_relay_log_pos(rli,
|
2006-07-07 09:27:55 +02:00
|
|
|
rli->group_relay_log_name,
|
|
|
|
rli->group_relay_log_pos,
|
|
|
|
1 /*need data lock*/, &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.
2003-12-18 01:09:05 +01:00
|
|
|
1 /*look for a description_event*/))
|
2009-02-11 12:56:25 +01:00
|
|
|
{
|
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
|
|
|
|
"Error initializing relay log position: %s", errmsg);
|
2002-01-20 03:16:52 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
THD_CHECK_SENTRY(thd);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
{
|
|
|
|
char llbuf1[22], llbuf2[22];
|
|
|
|
DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
|
2006-07-07 09:27:55 +02:00
|
|
|
llstr(my_b_tell(rli->cur_log),llbuf1),
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
llstr(rli->event_relay_log_pos,llbuf2)));
|
|
|
|
DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
|
|
|
|
/*
|
|
|
|
Wonder if this is correct. I (Guilhem) wonder if my_b_tell() returns the
|
|
|
|
correct position when it's called just after my_b_seek() (the questionable
|
|
|
|
stuff is those "seek is done on next read" comments in the my_b_seek()
|
|
|
|
source code).
|
|
|
|
The crude reality is that this assertion randomly fails whereas
|
|
|
|
replication seems to work fine. And there is no easy explanation why it
|
|
|
|
fails (as we my_b_seek(rli->event_relay_log_pos) at the very end of
|
|
|
|
init_relay_log_pos() called above). Maybe the assertion would be
|
|
|
|
meaningful if we held rli->data_lock between the my_b_seek() and the
|
|
|
|
DBUG_ASSERT().
|
|
|
|
*/
|
|
|
|
#ifdef SHOULD_BE_CHECKED
|
|
|
|
DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->event_relay_log_pos);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->sql_thd == thd);
|
2002-06-08 20:02:01 +02:00
|
|
|
|
|
|
|
DBUG_PRINT("master_info",("log_file_name: %s position: %s",
|
2006-07-07 09:27:55 +02:00
|
|
|
rli->group_master_log_name,
|
|
|
|
llstr(rli->group_master_log_pos,llbuff)));
|
2002-08-08 02:12:02 +02:00
|
|
|
if (global_system_variables.log_warnings)
|
2004-09-15 21:10:31 +02:00
|
|
|
sql_print_information("Slave SQL thread initialized, starting replication in \
|
2002-06-05 22:04:38 +02:00
|
|
|
log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
|
2006-07-07 09:27:55 +02:00
|
|
|
llstr(rli->group_master_log_pos,llbuff),rli->group_relay_log_name,
|
|
|
|
llstr(rli->group_relay_log_pos,llbuff1));
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2009-04-19 03:21:33 +02:00
|
|
|
if (check_temp_dir(rli->slave_patternload_file))
|
2009-03-18 11:31:17 +01:00
|
|
|
{
|
|
|
|
rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
|
|
|
|
"Unable to use slave's temporary directory %s - %s",
|
|
|
|
slave_load_tmpdir, thd->main_da.message());
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2003-07-18 11:11:01 +02:00
|
|
|
/* execute init_slave variable */
|
2004-03-20 15:56:20 +01:00
|
|
|
if (sys_init_slave.value_length)
|
2003-07-18 11:11:01 +02:00
|
|
|
{
|
2003-12-08 06:13:14 +01:00
|
|
|
execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave);
|
2007-10-19 23:20:38 +02:00
|
|
|
if (thd->is_slave_error)
|
2003-07-18 11:11:01 +02:00
|
|
|
{
|
2009-02-11 12:56:25 +01:00
|
|
|
rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
|
|
|
|
"Slave SQL thread aborted. Can't execute init_slave query");
|
2003-07-18 11:11:01 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-22 16:07:07 +01:00
|
|
|
/*
|
|
|
|
First check until condition - probably there is nothing to execute. We
|
|
|
|
do not want to wait for next event in this case.
|
|
|
|
*/
|
|
|
|
pthread_mutex_lock(&rli->data_lock);
|
2008-02-27 18:46:06 +01:00
|
|
|
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
|
2008-02-22 16:07:07 +01:00
|
|
|
rli->is_until_satisfied(rli->group_master_log_pos))
|
|
|
|
{
|
|
|
|
char buf[22];
|
|
|
|
sql_print_information("Slave SQL thread stopped because it reached its"
|
|
|
|
" UNTIL position %s", llstr(rli->until_pos(), buf));
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
/* Read queries from the IO/THREAD until this thread is killed */
|
|
|
|
|
2002-03-08 23:02:11 +01:00
|
|
|
while (!sql_slave_killed(thd,rli))
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Reading event from the relay log");
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->sql_thd == thd);
|
2002-03-30 20:36:05 +01:00
|
|
|
THD_CHECK_SENTRY(thd);
|
2002-01-20 03:16:52 +01:00
|
|
|
if (exec_relay_log_event(thd,rli))
|
|
|
|
{
|
2007-01-17 15:06:37 +01:00
|
|
|
DBUG_PRINT("info", ("exec_relay_log_event() failed"));
|
2002-01-20 03:16:52 +01:00
|
|
|
// do not scare the user if SQL thread was simply killed or stopped
|
2002-03-08 23:02:11 +01:00
|
|
|
if (!sql_slave_killed(thd,rli))
|
2006-01-12 19:51:02 +01:00
|
|
|
{
|
|
|
|
/*
|
2007-01-17 15:06:37 +01:00
|
|
|
retrieve as much info as possible from the thd and, error
|
|
|
|
codes and warnings and print this to the error log as to
|
|
|
|
allow the user to locate the error
|
2006-01-12 19:51:02 +01:00
|
|
|
*/
|
2007-06-11 22:15:39 +02:00
|
|
|
uint32 const last_errno= rli->last_error().number;
|
2007-06-09 07:19:37 +02:00
|
|
|
|
2007-12-12 16:21:01 +01:00
|
|
|
if (thd->is_error())
|
2006-01-12 19:51:02 +01:00
|
|
|
{
|
2007-12-12 16:21:01 +01:00
|
|
|
char const *const errmsg= thd->main_da.message();
|
|
|
|
|
|
|
|
DBUG_PRINT("info",
|
|
|
|
("thd->main_da.sql_errno()=%d; rli->last_error.number=%d",
|
|
|
|
thd->main_da.sql_errno(), last_errno));
|
2007-06-09 07:19:37 +02:00
|
|
|
if (last_errno == 0)
|
2006-01-12 19:51:02 +01:00
|
|
|
{
|
2009-02-11 12:56:25 +01:00
|
|
|
/*
|
|
|
|
This function is reporting an error which was not reported
|
|
|
|
while executing exec_relay_log_event().
|
|
|
|
*/
|
2009-09-23 15:21:29 +02:00
|
|
|
rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), "%s", errmsg);
|
2006-01-12 19:51:02 +01:00
|
|
|
}
|
2007-12-12 16:21:01 +01:00
|
|
|
else if (last_errno != thd->main_da.sql_errno())
|
2006-01-12 19:51:02 +01:00
|
|
|
{
|
2009-02-11 12:56:25 +01:00
|
|
|
/*
|
|
|
|
* An error was reported while executing exec_relay_log_event()
|
|
|
|
* however the error code differs from what is in the thread.
|
|
|
|
* This function prints out more information to help finding
|
|
|
|
* what caused the problem.
|
|
|
|
*/
|
2006-01-12 19:51:02 +01:00
|
|
|
sql_print_error("Slave (additional info): %s Error_code: %d",
|
2007-12-12 16:21:01 +01:00
|
|
|
errmsg, thd->main_da.sql_errno());
|
2006-01-12 19:51:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print any warnings issued */
|
|
|
|
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
|
|
|
|
MYSQL_ERROR *err;
|
2007-03-16 14:56:57 +01:00
|
|
|
/*
|
|
|
|
Added controlled slave thread cancel for replication
|
|
|
|
of user-defined variables.
|
|
|
|
*/
|
|
|
|
bool udf_error = false;
|
2006-01-12 19:51:02 +01:00
|
|
|
while ((err= it++))
|
2007-03-16 14:56:57 +01:00
|
|
|
{
|
|
|
|
if (err->code == ER_CANT_OPEN_LIBRARY)
|
|
|
|
udf_error = true;
|
2006-01-12 19:51:02 +01:00
|
|
|
sql_print_warning("Slave: %s Error_code: %d",err->msg, err->code);
|
2007-03-16 14:56:57 +01:00
|
|
|
}
|
|
|
|
if (udf_error)
|
|
|
|
sql_print_error("Error loading user-defined library, slave SQL "
|
|
|
|
"thread aborted. Install the missing library, and restart the "
|
|
|
|
"slave SQL thread with \"SLAVE START\". We stopped at log '%s' "
|
|
|
|
"position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos,
|
|
|
|
llbuff));
|
|
|
|
else
|
|
|
|
sql_print_error("\
|
2002-01-20 03:16:52 +01:00
|
|
|
Error running query, slave SQL thread aborted. Fix the problem, and restart \
|
2002-01-29 17:32:16 +01:00
|
|
|
the slave SQL thread with \"SLAVE START\". We stopped at log \
|
2004-09-08 10:45:50 +02:00
|
|
|
'%s' position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos, llbuff));
|
2006-01-12 19:51:02 +01:00
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
/* Thread stopped. Print the current replication position to the log */
|
2004-10-29 18:26:52 +02:00
|
|
|
sql_print_information("Slave SQL thread exiting, replication stopped in log "
|
2006-07-07 09:27:55 +02:00
|
|
|
"'%s' at position %s",
|
|
|
|
RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
|
2002-08-08 02:12:02 +02:00
|
|
|
|
|
|
|
err:
|
2005-12-22 06:39:02 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Some events set some playgrounds, which won't be cleared because thread
|
|
|
|
stops. Stopping of this thread may not be known to these events ("stop"
|
|
|
|
request is detected only by the present function, not by events), so we
|
|
|
|
must "proactively" clear playgrounds:
|
|
|
|
*/
|
|
|
|
rli->cleanup_context(thd, 1);
|
2003-12-19 22:40:23 +01:00
|
|
|
/*
|
|
|
|
Some extra safety, which should not been needed (normally, event deletion
|
|
|
|
should already have done these assignments (each event which sets these
|
|
|
|
variables is supposed to set them to 0 before terminating)).
|
|
|
|
*/
|
2009-07-24 17:58:58 +02:00
|
|
|
thd->catalog= 0;
|
|
|
|
thd->set_query(NULL, 0);
|
A fix and a test case for
Bug#19022 "Memory bug when switching db during trigger execution"
Bug#17199 "Problem when view calls function from another database."
Bug#18444 "Fully qualified stored function names don't work correctly in
SELECT statements"
Documentation note: this patch introduces a change in behaviour of prepared
statements.
This patch adds a few new invariants with regard to how THD::db should
be used. These invariants should be preserved in future:
- one should never refer to THD::db by pointer and always make a deep copy
(strmake, strdup)
- one should never compare two databases by pointer, but use strncmp or
my_strncasecmp
- TABLE_LIST object table->db should be always initialized in the parser or
by creator of the object.
For prepared statements it means that if the current database is changed
after a statement is prepared, the database that was current at prepare
remains active. This also means that you can not prepare a statement that
implicitly refers to the current database if the latter is not set.
This is not documented, and therefore needs documentation. This is NOT a
change in behavior for almost all SQL statements except:
- ALTER TABLE t1 RENAME t2
- OPTIMIZE TABLE t1
- ANALYZE TABLE t1
- TRUNCATE TABLE t1 --
until this patch t1 or t2 could be evaluated at the first execution of
prepared statement.
CURRENT_DATABASE() still works OK and is evaluated at every execution
of prepared statement.
Note, that in stored routines this is not an issue as the default
database is the database of the stored procedure and "use" statement
is prohibited in stored routines.
This patch makes obsolete the use of check_db_used (it was never used in the
old code too) and all other places that check for table->db and assign it
from THD::db if it's NULL, except the parser.
How this patch was created: THD::{db,db_length} were replaced with a
LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were
manually checked and:
- if the place uses thd->db by pointer, it was fixed to make a deep copy
- if a place compared two db pointers, it was fixed to compare them by value
(via strcmp/my_strcasecmp, whatever was approproate)
Then this intermediate patch was used to write a smaller patch that does the
same thing but without a rename.
TODO in 5.1:
- remove check_db_used
- deploy THD::set_db in mysql_change_db
See also comments to individual files.
2006-06-26 22:47:52 +02:00
|
|
|
thd->reset_db(NULL, 0);
|
2007-02-22 16:03:08 +01:00
|
|
|
thd_proc_info(thd, "Waiting for slave mutex on exit");
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_lock(&rli->run_lock);
|
2003-06-14 16:40:00 +02:00
|
|
|
/* We need data_lock, at least to wake up any waiting master_pos_wait() */
|
|
|
|
pthread_mutex_lock(&rli->data_lock);
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
|
2003-06-14 16:40:00 +02:00
|
|
|
/* When master_pos_wait() wakes up it will check this and terminate */
|
2006-07-07 09:27:55 +02:00
|
|
|
rli->slave_running= 0;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/* Forget the relay log's format */
|
|
|
|
delete rli->relay_log.description_event_for_exec;
|
|
|
|
rli->relay_log.description_event_for_exec= 0;
|
2003-06-14 16:40:00 +02:00
|
|
|
/* Wake up master_pos_wait() */
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
|
|
|
DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
|
|
|
|
pthread_cond_broadcast(&rli->data_cond);
|
2003-06-15 12:01:51 +02:00
|
|
|
rli->ignore_log_space_limit= 0; /* don't need any lock */
|
2005-02-03 16:22:16 +01:00
|
|
|
/* we die so won't remember charset - re-update them on next thread start */
|
|
|
|
rli->cached_charset_invalidate();
|
2002-01-20 03:16:52 +01:00
|
|
|
rli->save_temporary_tables = thd->temporary_tables;
|
2002-01-29 17:32:16 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
TODO: see if we can do this conditionally in next_event() instead
|
|
|
|
to avoid unneeded position re-init
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
thd->temporary_tables = 0; // remove tempation from destructor to close them
|
|
|
|
DBUG_ASSERT(thd->net.buff != 0);
|
|
|
|
net_end(&thd->net); // destructor will not free it, because we are weird
|
|
|
|
DBUG_ASSERT(rli->sql_thd == thd);
|
2002-03-30 20:36:05 +01:00
|
|
|
THD_CHECK_SENTRY(thd);
|
2002-08-08 02:12:02 +02:00
|
|
|
rli->sql_thd= 0;
|
2009-05-23 01:15:21 +02:00
|
|
|
set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_mutex_lock(&LOCK_thread_count);
|
2002-03-30 20:36:05 +01:00
|
|
|
THD_CHECK_SENTRY(thd);
|
2002-01-20 03:16:52 +01:00
|
|
|
delete thd;
|
|
|
|
pthread_mutex_unlock(&LOCK_thread_count);
|
2007-03-01 10:03:42 +01:00
|
|
|
/*
|
|
|
|
Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
|
|
|
|
is important. Otherwise a killer_thread can execute between the calls and
|
|
|
|
delete the mi structure leading to a crash! (see BUG#25306 for details)
|
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_cond_broadcast(&rli->stop_cond);
|
2009-04-28 13:46:07 +02:00
|
|
|
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
|
2007-02-03 20:14:16 +01:00
|
|
|
pthread_mutex_unlock(&rli->run_lock); // tell the world we are done
|
2009-09-23 15:10:23 +02:00
|
|
|
|
|
|
|
DBUG_LEAVE; // Must match DBUG_ENTER()
|
2003-02-04 20:52:14 +01:00
|
|
|
my_thread_end();
|
2002-01-20 03:16:52 +01:00
|
|
|
pthread_exit(0);
|
2009-09-23 15:10:23 +02:00
|
|
|
return 0; // Avoid compiler warnings
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2001-01-22 03:46:32 +01:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
process_io_create_file()
|
2003-02-04 20:52:14 +01:00
|
|
|
*/
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
|
2002-02-07 23:29:46 +01:00
|
|
|
{
|
|
|
|
int error = 1;
|
|
|
|
ulong num_bytes;
|
|
|
|
bool cev_not_written;
|
2002-10-02 12:33:08 +02:00
|
|
|
THD *thd = mi->io_thd;
|
|
|
|
NET *net = &mi->mysql->net;
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_ENTER("process_io_create_file");
|
2002-02-07 23:29:46 +01:00
|
|
|
|
|
|
|
if (unlikely(!cev->is_valid()))
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(1);
|
2005-03-08 21:12:35 +01:00
|
|
|
|
|
|
|
if (!rpl_filter->db_ok(cev->db))
|
2002-02-07 23:29:46 +01:00
|
|
|
{
|
|
|
|
skip_load_data_infile(net);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
|
|
|
DBUG_ASSERT(cev->inited_from_old);
|
|
|
|
thd->file_id = cev->file_id = mi->file_id++;
|
2002-02-09 21:58:53 +01:00
|
|
|
thd->server_id = cev->server_id;
|
2002-02-07 23:29:46 +01:00
|
|
|
cev_not_written = 1;
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-02-07 23:29:46 +01:00
|
|
|
if (unlikely(net_request_file(net,cev->fname)))
|
|
|
|
{
|
|
|
|
sql_print_error("Slave I/O: failed requesting download of '%s'",
|
2006-07-07 09:27:55 +02:00
|
|
|
cev->fname);
|
2002-02-07 23:29:46 +01:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2003-01-28 07:38:28 +01:00
|
|
|
/*
|
|
|
|
This dummy block is so we could instantiate Append_block_log_event
|
|
|
|
once and then modify it slightly instead of doing it multiple times
|
|
|
|
in the loop
|
2002-02-07 23:29:46 +01:00
|
|
|
*/
|
|
|
|
{
|
2003-08-21 10:24:37 +02:00
|
|
|
Append_block_log_event aev(thd,0,0,0,0);
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-02-07 23:29:46 +01:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (unlikely((num_bytes=my_net_read(net)) == packet_error))
|
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
sql_print_error("Network read error downloading '%s' from master",
|
|
|
|
cev->fname);
|
|
|
|
goto err;
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
|
|
|
if (unlikely(!num_bytes)) /* eof */
|
|
|
|
{
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
/* 3.23 master wants it */
|
|
|
|
net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0);
|
2004-02-11 00:06:46 +01:00
|
|
|
/*
|
|
|
|
If we wrote Create_file_log_event, then we need to write
|
|
|
|
Execute_load_log_event. If we did not write Create_file_log_event,
|
|
|
|
then this is an empty file and we can just do as if the LOAD DATA
|
|
|
|
INFILE had not existed, i.e. write nothing.
|
|
|
|
*/
|
|
|
|
if (unlikely(cev_not_written))
|
2006-07-07 09:27:55 +02:00
|
|
|
break;
|
|
|
|
Execute_load_log_event xev(thd,0,0);
|
|
|
|
xev.log_pos = cev->log_pos;
|
|
|
|
if (unlikely(mi->rli.relay_log.append(&xev)))
|
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
|
|
|
|
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
|
|
|
|
"error writing Exec_load event to relay log");
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
|
|
|
|
break;
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
|
|
|
if (unlikely(cev_not_written))
|
|
|
|
{
|
2008-01-30 16:03:00 +01:00
|
|
|
cev->block = net->read_pos;
|
2006-07-07 09:27:55 +02:00
|
|
|
cev->block_len = num_bytes;
|
|
|
|
if (unlikely(mi->rli.relay_log.append(cev)))
|
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
|
|
|
|
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
|
|
|
|
"error writing Create_file event to relay log");
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
cev_not_written=0;
|
|
|
|
mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-01-30 16:03:00 +01:00
|
|
|
aev.block = net->read_pos;
|
2006-07-07 09:27:55 +02:00
|
|
|
aev.block_len = num_bytes;
|
|
|
|
aev.log_pos = cev->log_pos;
|
|
|
|
if (unlikely(mi->rli.relay_log.append(&aev)))
|
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
|
|
|
|
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
|
|
|
|
"error writing Append_block event to relay log");
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error=0;
|
|
|
|
err:
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2002-09-11 05:40:08 +02:00
|
|
|
Start using a new binary log on the master
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
process_io_rotate()
|
2006-07-07 09:27:55 +02:00
|
|
|
mi master_info for the slave
|
|
|
|
rev The rotate log event read from the binary log
|
2002-09-11 05:40:08 +02:00
|
|
|
|
|
|
|
DESCRIPTION
|
2003-04-24 15:29:25 +02:00
|
|
|
Updates the master info with the place in the next binary
|
2002-09-11 05:40:08 +02:00
|
|
|
log where we should start reading.
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
Rotate the relay log to avoid mixed-format relay logs.
|
2002-09-11 05:40:08 +02:00
|
|
|
|
|
|
|
NOTES
|
|
|
|
We assume we already locked mi->data_lock
|
|
|
|
|
|
|
|
RETURN VALUES
|
2006-07-07 09:27:55 +02:00
|
|
|
0 ok
|
|
|
|
1 Log event is illegal
|
2002-06-05 22:04:38 +02:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
|
2002-01-25 06:49:47 +01:00
|
|
|
{
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_ENTER("process_io_rotate");
|
2002-09-11 05:40:08 +02:00
|
|
|
safe_mutex_assert_owner(&mi->data_lock);
|
2002-06-08 20:02:01 +02:00
|
|
|
|
2002-02-07 23:29:46 +01:00
|
|
|
if (unlikely(!rev->is_valid()))
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_RETURN(1);
|
2002-09-11 05:40:08 +02:00
|
|
|
|
2005-10-12 13:29:55 +02:00
|
|
|
/* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
|
2002-09-11 05:40:08 +02:00
|
|
|
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
|
|
|
|
mi->master_log_pos= rev->pos;
|
2006-11-20 21:42:06 +01:00
|
|
|
DBUG_PRINT("info", ("master_log_pos: '%s' %lu",
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->master_log_name, (ulong) mi->master_log_pos));
|
2002-01-25 06:49:47 +01:00
|
|
|
#ifndef DBUG_OFF
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
If we do not do this, we will be getting the first
|
|
|
|
rotate event forever, so we need to not disconnect after one.
|
|
|
|
*/
|
|
|
|
if (disconnect_slave_event_count)
|
2005-12-22 06:39:02 +01:00
|
|
|
mi->events_till_disconnect++;
|
2002-01-25 06:49:47 +01:00
|
|
|
#endif
|
2005-02-09 20:04:28 +01:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/*
|
|
|
|
If description_event_for_queue is format <4, there is conversion in the
|
|
|
|
relay log to the slave's format (4). And Rotate can mean upgrade or
|
|
|
|
nothing. If upgrade, it's to 5.0 or newer, so we will get a Format_desc, so
|
|
|
|
no need to reset description_event_for_queue now. And if it's nothing (same
|
|
|
|
master version as before), no need (still using the slave's format).
|
|
|
|
*/
|
|
|
|
if (mi->rli.relay_log.description_event_for_queue->binlog_version >= 4)
|
|
|
|
{
|
|
|
|
delete mi->rli.relay_log.description_event_for_queue;
|
|
|
|
/* start from format 3 (MySQL 4.0) again */
|
|
|
|
mi->rli.relay_log.description_event_for_queue= new
|
|
|
|
Format_description_log_event(3);
|
|
|
|
}
|
2004-07-26 19:42:59 +02:00
|
|
|
/*
|
|
|
|
Rotate the relay log makes binlog format detection easier (at next slave
|
|
|
|
start or mysqlbinlog)
|
|
|
|
*/
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
rotate_relay_log(mi); /* will take the right mutexes */
|
2002-06-08 20:02:01 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-25 06:49:47 +01:00
|
|
|
}
|
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
2005-02-09 20:04:28 +01:00
|
|
|
Reads a 3.23 event and converts it to the slave's format. This code was
|
|
|
|
copied from MySQL 4.0.
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
2007-08-16 08:52:50 +02:00
|
|
|
static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
|
2006-07-07 09:27:55 +02:00
|
|
|
ulong event_len)
|
2002-01-25 06:49:47 +01:00
|
|
|
{
|
2002-01-29 17:32:16 +01:00
|
|
|
const char *errmsg = 0;
|
2002-09-11 05:40:08 +02:00
|
|
|
ulong inc_pos;
|
|
|
|
bool ignore_event= 0;
|
|
|
|
char *tmp_buf = 0;
|
2007-08-16 07:37:50 +02:00
|
|
|
Relay_log_info *rli= &mi->rli;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
DBUG_ENTER("queue_binlog_ver_1_event");
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2002-09-11 05:40:08 +02:00
|
|
|
/*
|
|
|
|
If we get Load event, we need to pass a non-reusable buffer
|
|
|
|
to read_log_event, so we do a trick
|
2002-02-07 23:29:46 +01:00
|
|
|
*/
|
|
|
|
if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
|
|
|
|
{
|
|
|
|
if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
|
|
|
|
{
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
|
|
|
|
ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed");
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(1);
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
|
|
|
memcpy(tmp_buf,buf,event_len);
|
2004-04-08 22:12:22 +02:00
|
|
|
/*
|
|
|
|
Create_file constructor wants a 0 as last char of buffer, this 0 will
|
|
|
|
serve as the string-termination char for the file's name (which is at the
|
|
|
|
end of the buffer)
|
|
|
|
We must increment event_len, otherwise the event constructor will not see
|
|
|
|
this end 0, which leads to segfault.
|
|
|
|
*/
|
|
|
|
tmp_buf[event_len++]=0;
|
2004-04-30 10:42:12 +02:00
|
|
|
int4store(tmp_buf+EVENT_LEN_OFFSET, event_len);
|
2002-02-07 23:29:46 +01:00
|
|
|
buf = (const char*)tmp_buf;
|
|
|
|
}
|
2003-08-21 10:24:37 +02:00
|
|
|
/*
|
|
|
|
This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
|
|
|
|
send the loaded file, and write it to the relay log in the form of
|
|
|
|
Append_block/Exec_load (the SQL thread needs the data, as that thread is not
|
|
|
|
connected to the master).
|
|
|
|
*/
|
2002-01-29 17:32:16 +01:00
|
|
|
Log_event *ev = Log_event::read_log_event(buf,event_len, &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.
2003-12-18 01:09:05 +01:00
|
|
|
mi->rli.relay_log.description_event_for_queue);
|
2002-01-27 06:26:24 +01:00
|
|
|
if (unlikely(!ev))
|
2002-01-25 06:49:47 +01:00
|
|
|
{
|
|
|
|
sql_print_error("Read invalid event from master: '%s',\
|
2002-01-29 17:32:16 +01:00
|
|
|
master could be corrupt but a more likely cause of this is a bug",
|
2006-07-07 09:27:55 +02:00
|
|
|
errmsg);
|
2002-06-05 22:04:38 +02:00
|
|
|
my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
|
|
|
|
DBUG_RETURN(1);
|
2002-01-25 06:49:47 +01:00
|
|
|
}
|
2007-01-17 15:06:37 +01:00
|
|
|
|
2002-01-27 06:26:24 +01:00
|
|
|
pthread_mutex_lock(&mi->data_lock);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
ev->log_pos= mi->master_log_pos; /* 3.23 events don't contain log_pos */
|
2002-01-29 17:32:16 +01:00
|
|
|
switch (ev->get_type_code()) {
|
2002-09-11 05:40:08 +02:00
|
|
|
case STOP_EVENT:
|
2003-06-12 16:20:31 +02:00
|
|
|
ignore_event= 1;
|
2002-09-11 05:40:08 +02:00
|
|
|
inc_pos= event_len;
|
|
|
|
break;
|
2002-01-25 06:49:47 +01:00
|
|
|
case ROTATE_EVENT:
|
2002-01-27 06:26:24 +01:00
|
|
|
if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
|
2002-01-25 06:49:47 +01:00
|
|
|
{
|
|
|
|
delete ev;
|
2002-01-27 06:26:24 +01:00
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(1);
|
2002-01-25 06:49:47 +01:00
|
|
|
}
|
2002-09-11 05:40:08 +02:00
|
|
|
inc_pos= 0;
|
2002-01-27 06:26:24 +01:00
|
|
|
break;
|
2002-02-07 23:29:46 +01:00
|
|
|
case CREATE_FILE_EVENT:
|
2003-08-21 10:24:37 +02:00
|
|
|
/*
|
|
|
|
Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
|
|
|
|
queue_old_event() which is for 3.23 events which don't comprise
|
|
|
|
CREATE_FILE_EVENT. This is because read_log_event() above has just
|
|
|
|
transformed LOAD_EVENT into CREATE_FILE_EVENT.
|
|
|
|
*/
|
2002-02-07 23:29:46 +01:00
|
|
|
{
|
2002-09-11 05:40:08 +02:00
|
|
|
/* We come here when and only when tmp_buf != 0 */
|
2005-02-25 15:53:22 +01:00
|
|
|
DBUG_ASSERT(tmp_buf != 0);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
inc_pos=event_len;
|
|
|
|
ev->log_pos+= inc_pos;
|
2002-02-07 23:29:46 +01:00
|
|
|
int error = process_io_create_file(mi,(Create_file_log_event*)ev);
|
2002-01-27 06:26:24 +01:00
|
|
|
delete ev;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
mi->master_log_pos += inc_pos;
|
2006-11-20 21:42:06 +01:00
|
|
|
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
|
2002-01-27 06:26:24 +01:00
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
2002-02-07 23:29:46 +01:00
|
|
|
my_free((char*)tmp_buf, MYF(0));
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-02-07 23:29:46 +01:00
|
|
|
}
|
2002-01-25 06:49:47 +01:00
|
|
|
default:
|
2002-09-11 05:40:08 +02:00
|
|
|
inc_pos= event_len;
|
2002-01-25 06:49:47 +01:00
|
|
|
break;
|
|
|
|
}
|
2002-09-11 05:40:08 +02:00
|
|
|
if (likely(!ignore_event))
|
2002-01-25 06:49:47 +01:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
if (ev->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.
2003-12-18 01:09:05 +01:00
|
|
|
Don't do it for fake Rotate events (see comment in
|
|
|
|
Log_event::Log_event(const char* buf...) in log_event.cc).
|
|
|
|
*/
|
|
|
|
ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */
|
2002-09-11 05:40:08 +02:00
|
|
|
if (unlikely(rli->relay_log.append(ev)))
|
2002-01-27 06:26:24 +01:00
|
|
|
{
|
|
|
|
delete ev;
|
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(1);
|
2002-01-27 06:26:24 +01:00
|
|
|
}
|
2002-09-11 05:40:08 +02:00
|
|
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
2002-01-25 06:49:47 +01:00
|
|
|
}
|
|
|
|
delete ev;
|
2002-09-11 05:40:08 +02:00
|
|
|
mi->master_log_pos+= inc_pos;
|
2006-11-20 21:42:06 +01:00
|
|
|
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
|
2002-01-29 21:50:09 +01:00
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-25 06:49:47 +01:00
|
|
|
}
|
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/*
|
|
|
|
Reads a 4.0 event and converts it to the slave's format. This code was copied
|
|
|
|
from queue_binlog_ver_1_event(), with some affordable simplifications.
|
|
|
|
*/
|
2007-08-16 08:52:50 +02:00
|
|
|
static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
|
2006-07-07 09:27:55 +02:00
|
|
|
ulong event_len)
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
{
|
|
|
|
const char *errmsg = 0;
|
|
|
|
ulong inc_pos;
|
|
|
|
char *tmp_buf = 0;
|
2007-08-16 07:37:50 +02:00
|
|
|
Relay_log_info *rli= &mi->rli;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
DBUG_ENTER("queue_binlog_ver_3_event");
|
|
|
|
|
|
|
|
/* read_log_event() will adjust log_pos to be end_log_pos */
|
|
|
|
Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
|
|
|
|
mi->rli.relay_log.description_event_for_queue);
|
|
|
|
if (unlikely(!ev))
|
|
|
|
{
|
|
|
|
sql_print_error("Read invalid event from master: '%s',\
|
|
|
|
master could be corrupt but a more likely cause of this is a bug",
|
2006-07-07 09:27:55 +02:00
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
pthread_mutex_lock(&mi->data_lock);
|
|
|
|
switch (ev->get_type_code()) {
|
|
|
|
case STOP_EVENT:
|
|
|
|
goto err;
|
|
|
|
case ROTATE_EVENT:
|
|
|
|
if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
|
|
|
|
{
|
|
|
|
delete ev;
|
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
inc_pos= 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
inc_pos= event_len;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (unlikely(rli->relay_log.append(ev)))
|
|
|
|
{
|
|
|
|
delete ev;
|
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
|
|
|
delete ev;
|
|
|
|
mi->master_log_pos+= inc_pos;
|
|
|
|
err:
|
2006-11-20 21:42:06 +01:00
|
|
|
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_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.
2003-12-18 01:09:05 +01:00
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
queue_old_event()
|
|
|
|
|
|
|
|
Writes a 3.23 or 4.0 event to the relay log, after converting it to the 5.0
|
|
|
|
(exactly, slave's) format. To do the conversion, we create a 5.0 event from
|
|
|
|
the 3.23/4.0 bytes, then write this event to the relay log.
|
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
TODO:
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
Test this code before release - it has to be tested on a separate
|
|
|
|
setup with 3.23 master or 4.0 master
|
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int queue_old_event(Master_info *mi, const char *buf,
|
2006-07-07 09:27:55 +02:00
|
|
|
ulong event_len)
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("queue_old_event");
|
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
switch (mi->rli.relay_log.description_event_for_queue->binlog_version)
|
|
|
|
{
|
|
|
|
case 1:
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
case 3:
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
default: /* unsupported format; eg version 2 */
|
|
|
|
DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->rli.relay_log.description_event_for_queue->binlog_version));
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(1);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
}
|
|
|
|
}
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
queue_event()
|
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
If the event is 3.23/4.0, passes it to queue_old_event() which will convert
|
|
|
|
it. Otherwise, writes a 5.0 (or newer) event to the relay log. Then there is
|
|
|
|
no format conversion, it's pure read/write of bytes.
|
|
|
|
So a 5.0.0 slave's relay log can contain events in the slave's format or in
|
|
|
|
any >=5.0.0 format.
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
|
|
|
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
static int queue_event(Master_info* mi,const char* buf, ulong event_len)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2002-09-11 05:40:08 +02:00
|
|
|
int error= 0;
|
|
|
|
ulong inc_pos;
|
2007-08-16 07:37:50 +02:00
|
|
|
Relay_log_info *rli= &mi->rli;
|
2005-10-12 13:29:55 +02:00
|
|
|
pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_ENTER("queue_event");
|
|
|
|
|
2006-12-15 05:21:15 +01:00
|
|
|
LINT_INIT(inc_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.
2003-12-18 01:09:05 +01:00
|
|
|
if (mi->rli.relay_log.description_event_for_queue->binlog_version<4 &&
|
|
|
|
buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(queue_old_event(mi,buf,event_len));
|
2002-01-27 06:26:24 +01:00
|
|
|
|
2006-03-29 13:27:36 +02:00
|
|
|
LINT_INIT(inc_pos);
|
2002-01-27 06:26:24 +01:00
|
|
|
pthread_mutex_lock(&mi->data_lock);
|
2002-09-11 05:40:08 +02:00
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
switch (buf[EVENT_TYPE_OFFSET]) {
|
2002-01-27 06:26:24 +01:00
|
|
|
case STOP_EVENT:
|
2003-06-12 16:20:31 +02:00
|
|
|
/*
|
|
|
|
We needn't write this event to the relay log. Indeed, it just indicates a
|
2003-10-08 11:01:58 +02:00
|
|
|
master server shutdown. The only thing this does is cleaning. But
|
|
|
|
cleaning is already done on a per-master-thread basis (as the master
|
|
|
|
server is shutting down cleanly, it has written all DROP TEMPORARY TABLE
|
2005-03-02 16:37:54 +01:00
|
|
|
prepared statements' deletion are TODO only when we binlog prep stmts).
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2003-10-08 11:01:58 +02:00
|
|
|
We don't even increment mi->master_log_pos, because we may be just after
|
|
|
|
a Rotate event. Btw, in a few milliseconds we are going to have a Start
|
|
|
|
event from the next binlog (unless the master is presently running
|
|
|
|
without --log-bin).
|
2003-06-12 16:20:31 +02:00
|
|
|
*/
|
|
|
|
goto err;
|
2002-01-20 03:16:52 +01:00
|
|
|
case ROTATE_EVENT:
|
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
Rotate_log_event rev(buf,event_len,mi->rli.relay_log.description_event_for_queue);
|
2002-01-27 06:26:24 +01:00
|
|
|
if (unlikely(process_io_rotate(mi,&rev)))
|
2002-09-11 05:40:08 +02:00
|
|
|
{
|
2003-06-12 16:20:31 +02:00
|
|
|
error= 1;
|
|
|
|
goto err;
|
2002-09-11 05:40:08 +02:00
|
|
|
}
|
2003-06-12 16:20:31 +02:00
|
|
|
/*
|
|
|
|
Now the I/O thread has just changed its mi->master_log_name, so
|
|
|
|
incrementing mi->master_log_pos is nonsense.
|
|
|
|
*/
|
2002-09-11 05:40:08 +02:00
|
|
|
inc_pos= 0;
|
2002-01-20 03:16:52 +01:00
|
|
|
break;
|
|
|
|
}
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
case FORMAT_DESCRIPTION_EVENT:
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Create an event, and save it (when we rotate the relay log, we will have
|
|
|
|
to write this event again).
|
|
|
|
*/
|
|
|
|
/*
|
2005-02-09 20:04:28 +01:00
|
|
|
We are the only thread which reads/writes description_event_for_queue.
|
|
|
|
The relay_log struct does not move (though some members of it can
|
|
|
|
change), so we needn't any lock (no rli->data_lock, no log lock).
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
*/
|
2003-12-19 22:40:23 +01:00
|
|
|
Format_description_log_event* tmp;
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
const char* errmsg;
|
2003-12-19 22:40:23 +01:00
|
|
|
if (!(tmp= (Format_description_log_event*)
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
Log_event::read_log_event(buf, event_len, &errmsg,
|
2003-12-19 22:40:23 +01:00
|
|
|
mi->rli.relay_log.description_event_for_queue)))
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
{
|
|
|
|
error= 2;
|
|
|
|
goto err;
|
|
|
|
}
|
2003-12-19 22:40:23 +01:00
|
|
|
delete mi->rli.relay_log.description_event_for_queue;
|
|
|
|
mi->rli.relay_log.description_event_for_queue= tmp;
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
Though this does some conversion to the slave's format, this will
|
2006-07-07 09:27:55 +02:00
|
|
|
preserve the master's binlog format version, and number of event types.
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
*/
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
If the event was not requested by the slave (the slave did not ask for
|
2006-07-07 09:27:55 +02:00
|
|
|
it), i.e. has end_log_pos=0, we do not increment mi->master_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.
2003-12-18 01:09:05 +01:00
|
|
|
*/
|
|
|
|
inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
|
|
|
|
DBUG_PRINT("info",("binlog format is now %d",
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->rli.relay_log.description_event_for_queue->binlog_version));
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
2002-01-20 03:16:52 +01:00
|
|
|
default:
|
2002-09-11 05:40:08 +02:00
|
|
|
inc_pos= event_len;
|
2002-01-20 03:16:52 +01:00
|
|
|
break;
|
|
|
|
}
|
2003-06-12 16:20:31 +02:00
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
|
|
|
If this event is originating from this server, don't queue it.
|
2003-06-12 16:20:31 +02:00
|
|
|
We don't check this for 3.23 events because it's simpler like this; 3.23
|
2003-10-08 11:01:58 +02:00
|
|
|
will be filtered anyway by the SQL slave thread which also tests the
|
|
|
|
server id (we must also keep this test in the SQL thread, in case somebody
|
2003-06-12 16:20:31 +02:00
|
|
|
upgrades a 4.0 slave which has a not-filtered relay log).
|
|
|
|
|
|
|
|
ANY event coming from ourselves can be ignored: it is obvious for queries;
|
|
|
|
for STOP_EVENT/ROTATE_EVENT/START_EVENT: these cannot come from ourselves
|
|
|
|
(--log-slave-updates would not log that) unless this slave is also its
|
|
|
|
direct master (an unsupported, useless setup!).
|
|
|
|
*/
|
|
|
|
|
2005-10-12 13:29:55 +02:00
|
|
|
pthread_mutex_lock(log_lock);
|
|
|
|
|
2004-05-05 22:01:41 +02:00
|
|
|
if ((uint4korr(buf + SERVER_ID_OFFSET) == ::server_id) &&
|
2007-03-22 08:32:41 +01:00
|
|
|
!mi->rli.replicate_same_server_id)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2003-06-12 16:20:31 +02:00
|
|
|
/*
|
|
|
|
Do not write it to the relay log.
|
2005-10-12 13:29:55 +02:00
|
|
|
a) We still want to increment mi->master_log_pos, so that we won't
|
|
|
|
re-read this event from the master if the slave IO thread is now
|
|
|
|
stopped/restarted (more efficient if the events we are ignoring are big
|
|
|
|
LOAD DATA INFILE).
|
|
|
|
b) We want to record that we are skipping events, for the information of
|
|
|
|
the slave SQL thread, otherwise that thread may let
|
|
|
|
rli->group_relay_log_pos stay too small if the last binlog's event is
|
|
|
|
ignored.
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
But events which were generated by this slave and which do not exist in
|
|
|
|
the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
|
|
|
|
mi->master_log_pos.
|
2003-06-12 16:20:31 +02:00
|
|
|
*/
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
if (buf[EVENT_TYPE_OFFSET]!=FORMAT_DESCRIPTION_EVENT &&
|
|
|
|
buf[EVENT_TYPE_OFFSET]!=ROTATE_EVENT &&
|
|
|
|
buf[EVENT_TYPE_OFFSET]!=STOP_EVENT)
|
2005-10-13 00:29:23 +02:00
|
|
|
{
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
mi->master_log_pos+= inc_pos;
|
2005-10-13 00:29:23 +02:00
|
|
|
memcpy(rli->ign_master_log_name_end, mi->master_log_name, FN_REFLEN);
|
|
|
|
DBUG_ASSERT(rli->ign_master_log_name_end[0]);
|
|
|
|
rli->ign_master_log_pos_end= mi->master_log_pos;
|
|
|
|
}
|
2005-10-12 13:29:55 +02:00
|
|
|
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
|
2006-11-22 13:11:36 +01:00
|
|
|
DBUG_PRINT("info", ("master_log_pos: %lu, event originating from the same server, ignored",
|
2006-11-20 21:42:06 +01:00
|
|
|
(ulong) mi->master_log_pos));
|
2006-07-07 09:27:55 +02:00
|
|
|
}
|
2004-04-05 12:56:05 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* write the event to the relay log */
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
|
2003-06-12 16:20:31 +02:00
|
|
|
{
|
|
|
|
mi->master_log_pos+= inc_pos;
|
2006-11-20 21:42:06 +01:00
|
|
|
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
|
2003-06-12 16:20:31 +02:00
|
|
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
|
|
|
}
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
else
|
2005-10-12 21:58:02 +02:00
|
|
|
error= 3;
|
2005-10-12 13:29:55 +02:00
|
|
|
rli->ign_master_log_name_end[0]= 0; // last event is not ignored
|
2004-04-05 12:56:05 +02:00
|
|
|
}
|
2005-10-12 13:29:55 +02:00
|
|
|
pthread_mutex_unlock(log_lock);
|
2003-06-12 16:20:31 +02:00
|
|
|
|
|
|
|
|
|
|
|
err:
|
2002-01-27 06:26:24 +01:00
|
|
|
pthread_mutex_unlock(&mi->data_lock);
|
2006-12-15 05:21:15 +01:00
|
|
|
DBUG_PRINT("info", ("error: %d", error));
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 07:37:50 +02:00
|
|
|
void end_relay_log_info(Relay_log_info* rli)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2002-08-08 02:12:02 +02:00
|
|
|
DBUG_ENTER("end_relay_log_info");
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
if (!rli->inited)
|
2002-08-08 02:12:02 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-20 03:16:52 +01:00
|
|
|
if (rli->info_fd >= 0)
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
|
|
|
end_io_cache(&rli->info_file);
|
2002-08-08 02:12:02 +02:00
|
|
|
(void) my_close(rli->info_fd, MYF(MY_WME));
|
2002-01-29 17:32:16 +01:00
|
|
|
rli->info_fd = -1;
|
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
if (rli->cur_log_fd >= 0)
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
|
|
|
end_io_cache(&rli->cache_buf);
|
|
|
|
(void)my_close(rli->cur_log_fd, MYF(MY_WME));
|
|
|
|
rli->cur_log_fd = -1;
|
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
rli->inited = 0;
|
2003-07-14 13:59:26 +02:00
|
|
|
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
2003-10-31 23:20:23 +01:00
|
|
|
/*
|
|
|
|
Delete the slave's temporary tables from memory.
|
|
|
|
In the future there will be other actions than this, to ensure persistance
|
|
|
|
of slave's temp tables after shutdown.
|
|
|
|
*/
|
|
|
|
rli->close_temporary_tables();
|
2002-08-08 02:12:02 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
Bug#46013: rpl_extraColmaster_myisam fails on pb2
Bug#45243: crash on win in sql thread clear_tables_to_lock() -> free()
Bug#45242: crash on win in mysql_close() -> free()
Bug#45238: rpl_slave_skip, rpl_change_master failed (lost connection) for STOP SLAVE
Bug#46030: rpl_truncate_3innodb causes server crash on windows
Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2
When killing a user session on the server, it's necessary to
interrupt (notify) the thread associated with the session that
the connection is being killed so that the thread is woken up
if waiting for I/O. On a few platforms (Mac, Windows and HP-UX)
where the SIGNAL_WITH_VIO_CLOSE flag is defined, this interruption
procedure is to asynchronously close the underlying socket of
the connection.
In order to enable this schema, each connection serving thread
registers its VIO (I/O interface) so that other threads can
access it and close the connection. But only the owner thread of
the VIO might delete it as to guarantee that other threads won't
see freed memory (the thread unregisters the VIO before deleting
it). A side note: closing the socket introduces a harmless race
that might cause a thread attempt to read from a closed socket,
but this is deemed acceptable.
The problem is that this infrastructure was meant to only be used
by server threads, but the slave I/O thread was registering the
VIO of a mysql handle (a client API structure that represents a
connection to another server instance) as a active connection of
the thread. But under some circumstances such as network failures,
the client API might destroy the VIO associated with a handle at
will, yet the VIO wouldn't be properly unregistered. This could
lead to accesses to freed data if a thread attempted to kill a
slave I/O thread whose connection was already broken.
There was a attempt to work around this by checking whether
the socket was being interrupted, but this hack didn't work as
intended due to the aforementioned race -- attempting to read
from the socket would yield a "bad file descriptor" error.
The solution is to add a hook to the client API that is called
from the client code before the VIO of a handle is deleted.
This hook allows the slave I/O thread to detach the active vio
so it does not point to freed memory.
2009-08-13 22:07:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Hook to detach the active VIO before closing a connection handle.
|
|
|
|
|
|
|
|
The client API might close the connection (and associated data)
|
|
|
|
in case it encounters a unrecoverable (network) error. This hook
|
|
|
|
is called from the client code before the VIO handle is deleted
|
|
|
|
allows the thread to detach the active vio so it does not point
|
|
|
|
to freed memory.
|
|
|
|
|
|
|
|
Other calls to THD::clear_active_vio throughout this module are
|
|
|
|
redundant due to the hook but are left in place for illustrative
|
|
|
|
purposes.
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern "C" void slave_io_thread_detach_vio()
|
|
|
|
{
|
|
|
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
|
|
|
THD *thd= current_thd;
|
2009-09-30 23:38:02 +02:00
|
|
|
if (thd && thd->slave_thread)
|
Bug#46013: rpl_extraColmaster_myisam fails on pb2
Bug#45243: crash on win in sql thread clear_tables_to_lock() -> free()
Bug#45242: crash on win in mysql_close() -> free()
Bug#45238: rpl_slave_skip, rpl_change_master failed (lost connection) for STOP SLAVE
Bug#46030: rpl_truncate_3innodb causes server crash on windows
Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2
When killing a user session on the server, it's necessary to
interrupt (notify) the thread associated with the session that
the connection is being killed so that the thread is woken up
if waiting for I/O. On a few platforms (Mac, Windows and HP-UX)
where the SIGNAL_WITH_VIO_CLOSE flag is defined, this interruption
procedure is to asynchronously close the underlying socket of
the connection.
In order to enable this schema, each connection serving thread
registers its VIO (I/O interface) so that other threads can
access it and close the connection. But only the owner thread of
the VIO might delete it as to guarantee that other threads won't
see freed memory (the thread unregisters the VIO before deleting
it). A side note: closing the socket introduces a harmless race
that might cause a thread attempt to read from a closed socket,
but this is deemed acceptable.
The problem is that this infrastructure was meant to only be used
by server threads, but the slave I/O thread was registering the
VIO of a mysql handle (a client API structure that represents a
connection to another server instance) as a active connection of
the thread. But under some circumstances such as network failures,
the client API might destroy the VIO associated with a handle at
will, yet the VIO wouldn't be properly unregistered. This could
lead to accesses to freed data if a thread attempted to kill a
slave I/O thread whose connection was already broken.
There was a attempt to work around this by checking whether
the socket was being interrupted, but this hack didn't work as
intended due to the aforementioned race -- attempting to read
from the socket would yield a "bad file descriptor" error.
The solution is to add a hook to the client API that is called
from the client code before the VIO of a handle is deleted.
This hook allows the slave I/O thread to detach the active vio
so it does not point to freed memory.
2009-08-13 22:07:20 +02:00
|
|
|
thd->clear_active_vio();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
/*
|
|
|
|
Try to connect until successful or slave killed
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
SYNPOSIS
|
|
|
|
safe_connect()
|
2006-07-07 09:27:55 +02:00
|
|
|
thd Thread handler for slave
|
|
|
|
mysql MySQL connection handle
|
|
|
|
mi Replication handle
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
RETURN
|
2006-07-07 09:27:55 +02:00
|
|
|
0 ok
|
|
|
|
# Error
|
2003-02-04 20:52:14 +01:00
|
|
|
*/
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("safe_connect");
|
|
|
|
|
|
|
|
DBUG_RETURN(connect_to_master(thd, mysql, mi, 0, 0));
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2001-10-03 15:27:20 +02:00
|
|
|
/*
|
2003-02-04 20:52:14 +01:00
|
|
|
SYNPOSIS
|
|
|
|
connect_to_master()
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
IMPLEMENTATION
|
|
|
|
Try to connect until successful or slave killed or we have retried
|
|
|
|
master_retry_count times
|
2001-10-03 15:27:20 +02:00
|
|
|
*/
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
|
2006-07-07 09:27:55 +02:00
|
|
|
bool reconnect, bool suppress_warnings)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2000-12-02 18:11:50 +01:00
|
|
|
int slave_was_killed;
|
2006-07-07 09:27:55 +02:00
|
|
|
int last_errno= -2; // impossible error
|
2001-10-03 15:27:20 +02:00
|
|
|
ulong err_count=0;
|
2001-03-07 22:50:44 +01:00
|
|
|
char llbuff[22];
|
2002-08-08 02:12:02 +02:00
|
|
|
DBUG_ENTER("connect_to_master");
|
2001-03-07 22:50:44 +01:00
|
|
|
|
2000-11-22 08:23:31 +01:00
|
|
|
#ifndef DBUG_OFF
|
2005-12-22 06:39:02 +01:00
|
|
|
mi->events_till_disconnect = disconnect_slave_event_count;
|
2000-11-22 08:23:31 +01:00
|
|
|
#endif
|
2003-06-14 10:37:42 +02:00
|
|
|
ulong client_flag= CLIENT_REMEMBER_OPTIONS;
|
2002-08-08 02:12:02 +02:00
|
|
|
if (opt_slave_compressed_protocol)
|
2006-07-07 09:27:55 +02:00
|
|
|
client_flag=CLIENT_COMPRESS; /* We will use compression */
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2003-06-14 10:37:42 +02:00
|
|
|
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
|
|
|
|
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2003-09-01 13:16:20 +02:00
|
|
|
#ifdef HAVE_OPENSSL
|
|
|
|
if (mi->ssl)
|
2007-03-29 15:09:57 +02:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
mysql_ssl_set(mysql,
|
2003-09-01 13:16:20 +02:00
|
|
|
mi->ssl_key[0]?mi->ssl_key:0,
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->ssl_cert[0]?mi->ssl_cert:0,
|
2003-09-01 13:16:20 +02:00
|
|
|
mi->ssl_ca[0]?mi->ssl_ca:0,
|
|
|
|
mi->ssl_capath[0]?mi->ssl_capath:0,
|
|
|
|
mi->ssl_cipher[0]?mi->ssl_cipher:0);
|
2007-03-29 15:09:57 +02:00
|
|
|
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
|
|
|
&mi->ssl_verify_server_cert);
|
|
|
|
}
|
2003-09-01 13:16:20 +02:00
|
|
|
#endif
|
|
|
|
|
2003-06-14 10:37:42 +02:00
|
|
|
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
|
|
|
|
/* This one is not strictly needed but we have it here for completeness */
|
|
|
|
mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
|
|
|
|
|
2002-03-08 23:02:11 +01:00
|
|
|
while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
|
2006-07-07 09:27:55 +02:00
|
|
|
(reconnect ? mysql_reconnect(mysql) != 0 :
|
|
|
|
mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
|
|
|
|
mi->port, 0, client_flag) == 0))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2001-10-03 15:27:20 +02:00
|
|
|
/* Don't repeat last error */
|
2003-05-02 18:07:41 +02:00
|
|
|
if ((int)mysql_errno(mysql) != last_errno)
|
2001-10-03 15:27:20 +02:00
|
|
|
{
|
2003-05-02 18:07:41 +02:00
|
|
|
last_errno=mysql_errno(mysql);
|
2002-07-23 17:31:22 +02:00
|
|
|
suppress_warnings= 0;
|
2007-06-09 07:19:37 +02:00
|
|
|
mi->report(ERROR_LEVEL, last_errno,
|
|
|
|
"error %s to master '%s@%s:%d'"
|
|
|
|
" - retry-time: %d retries: %lu",
|
|
|
|
(reconnect ? "reconnecting" : "connecting"),
|
|
|
|
mi->user, mi->host, mi->port,
|
|
|
|
mi->connect_retry, master_retry_count);
|
2001-10-03 15:27:20 +02:00
|
|
|
}
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
By default we try forever. The reason is that failure will trigger
|
|
|
|
master election, so if the user did not set master_retry_count we
|
2002-08-08 02:12:02 +02:00
|
|
|
do not want to have election triggered on the first failure to
|
2002-01-29 17:32:16 +01:00
|
|
|
connect
|
2001-10-11 21:54:06 +02:00
|
|
|
*/
|
2002-08-08 02:12:02 +02:00
|
|
|
if (++err_count == master_retry_count)
|
2001-10-03 15:27:20 +02:00
|
|
|
{
|
|
|
|
slave_was_killed=1;
|
2001-10-23 21:28:03 +02:00
|
|
|
if (reconnect)
|
|
|
|
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER);
|
2001-10-03 15:27:20 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
|
2006-07-07 09:27:55 +02:00
|
|
|
(void*)mi);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2000-12-02 18:11:50 +01:00
|
|
|
|
2001-10-03 15:27:20 +02:00
|
|
|
if (!slave_was_killed)
|
|
|
|
{
|
2009-06-03 16:14:18 +02:00
|
|
|
mi->clear_error(); // clear possible left over reconnect error
|
2001-10-23 21:28:03 +02:00
|
|
|
if (reconnect)
|
2006-07-07 09:27:55 +02:00
|
|
|
{
|
2002-08-08 02:12:02 +02:00
|
|
|
if (!suppress_warnings && global_system_variables.log_warnings)
|
2006-07-07 09:27:55 +02:00
|
|
|
sql_print_information("Slave: connected to master '%s@%s:%d',\
|
2002-01-20 03:16:52 +01:00
|
|
|
replication resumed in log '%s' at position %s", mi->user,
|
2006-07-07 09:27:55 +02:00
|
|
|
mi->host, mi->port,
|
|
|
|
IO_RPL_LOG_NAME,
|
|
|
|
llstr(mi->master_log_pos,llbuff));
|
2002-07-23 17:31:22 +02:00
|
|
|
}
|
2001-10-23 21:28:03 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE);
|
2006-01-19 03:56:06 +01:00
|
|
|
general_log_print(thd, COM_CONNECT_OUT, "%s@%s:%d",
|
|
|
|
mi->user, mi->host, mi->port);
|
2001-10-23 21:28:03 +02:00
|
|
|
}
|
2001-03-14 07:07:12 +01:00
|
|
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
2001-10-03 15:27:20 +02:00
|
|
|
thd->set_active_vio(mysql->net.vio);
|
2006-07-07 09:27:55 +02:00
|
|
|
#endif
|
2001-10-03 15:27:20 +02:00
|
|
|
}
|
2004-12-09 14:44:10 +01:00
|
|
|
mysql->reconnect= 1;
|
2002-08-08 02:12:02 +02:00
|
|
|
DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
|
|
|
|
DBUG_RETURN(slave_was_killed);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2001-10-23 21:28:03 +02:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
safe_reconnect()
|
2002-01-29 17:32:16 +01:00
|
|
|
|
2003-02-04 20:52:14 +01:00
|
|
|
IMPLEMENTATION
|
|
|
|
Try to connect until successful or slave killed or we have retried
|
|
|
|
master_retry_count times
|
2001-10-23 21:28:03 +02:00
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
|
2006-07-07 09:27:55 +02:00
|
|
|
bool suppress_warnings)
|
2001-10-23 21:28:03 +02:00
|
|
|
{
|
2003-06-24 11:10:35 +02:00
|
|
|
DBUG_ENTER("safe_reconnect");
|
|
|
|
DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings));
|
2001-10-23 21:28:03 +02:00
|
|
|
}
|
|
|
|
|
2002-07-23 17:31:22 +02:00
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
/*
|
|
|
|
Store the file and position where the execute-slave thread are in the
|
|
|
|
relay log.
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
flush_relay_log_info()
|
2006-07-07 09:27:55 +02:00
|
|
|
rli Relay log information
|
2002-08-08 02:12:02 +02:00
|
|
|
|
|
|
|
NOTES
|
|
|
|
- As this is only called by the slave thread, we don't need to
|
|
|
|
have a lock on this.
|
|
|
|
- If there is an active transaction, then we don't update the position
|
|
|
|
in the relay log. This is to ensure that we re-execute statements
|
|
|
|
if we die in the middle of an transaction that was rolled back.
|
|
|
|
- As a transaction never spans binary logs, we don't have to handle the
|
|
|
|
case where we do a relay-log-rotation in the middle of the transaction.
|
|
|
|
If this would not be the case, we would have to ensure that we
|
|
|
|
don't delete the relay log file where the transaction started when
|
|
|
|
we switch to a new relay log file.
|
|
|
|
|
|
|
|
TODO
|
|
|
|
- Change the log file information to a binary format to avoid calling
|
|
|
|
longlong2str.
|
|
|
|
|
|
|
|
RETURN VALUES
|
2006-07-07 09:27:55 +02:00
|
|
|
0 ok
|
|
|
|
1 write error
|
2002-08-08 02:12:02 +02:00
|
|
|
*/
|
|
|
|
|
2007-08-16 07:37:50 +02:00
|
|
|
bool flush_relay_log_info(Relay_log_info* rli)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2002-08-08 02:12:02 +02:00
|
|
|
bool error=0;
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("flush_relay_log_info");
|
2005-12-22 06:39:02 +01:00
|
|
|
|
|
|
|
if (unlikely(rli->no_storage))
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(0);
|
2005-12-22 06:39:02 +01:00
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
IO_CACHE *file = &rli->info_file;
|
|
|
|
char buff[FN_REFLEN*2+22*2+4], *pos;
|
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
my_b_seek(file, 0L);
|
2003-04-24 15:29:25 +02:00
|
|
|
pos=strmov(buff, rli->group_relay_log_name);
|
2002-08-08 02:12:02 +02:00
|
|
|
*pos++='\n';
|
2003-04-24 15:29:25 +02:00
|
|
|
pos=longlong2str(rli->group_relay_log_pos, pos, 10);
|
2002-08-08 02:12:02 +02:00
|
|
|
*pos++='\n';
|
2003-04-24 15:29:25 +02:00
|
|
|
pos=strmov(pos, rli->group_master_log_name);
|
2002-08-08 02:12:02 +02:00
|
|
|
*pos++='\n';
|
2003-04-24 15:29:25 +02:00
|
|
|
pos=longlong2str(rli->group_master_log_pos, pos, 10);
|
2002-08-08 02:12:02 +02:00
|
|
|
*pos='\n';
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
if (my_b_write(file, (uchar*) buff, (size_t) (pos-buff)+1))
|
2002-08-08 02:12:02 +02:00
|
|
|
error=1;
|
|
|
|
if (flush_io_cache(file))
|
|
|
|
error=1;
|
2005-12-22 06:39:02 +01:00
|
|
|
|
2004-03-10 16:30:47 +01:00
|
|
|
/* Flushing the relay log is done by the slave I/O thread */
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_RETURN(error);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-10-29 23:12:47 +01:00
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2002-10-29 23:12:47 +01:00
|
|
|
Called when we notice that the current "hot" log got rotated under our feet.
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
|
|
|
|
2007-08-16 07:37:50 +02:00
|
|
|
static IO_CACHE *reopen_relay_log(Relay_log_info *rli, const char **errmsg)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-05-30 18:21:03 +02:00
|
|
|
DBUG_ENTER("reopen_relay_log");
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
|
|
|
|
DBUG_ASSERT(rli->cur_log_fd == -1);
|
2002-06-05 22:04:38 +02:00
|
|
|
|
|
|
|
IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
|
2003-04-24 15:29:25 +02:00
|
|
|
if ((rli->cur_log_fd=open_binlog(cur_log,rli->event_relay_log_name,
|
2006-07-07 09:27:55 +02:00
|
|
|
errmsg)) <0)
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-12-11 14:46:39 +01:00
|
|
|
/*
|
|
|
|
We want to start exactly where we was before:
|
2006-07-07 09:27:55 +02:00
|
|
|
relay_log_pos Current log pos
|
|
|
|
pending Number of bytes already processed from the event
|
2002-12-11 14:46:39 +01:00
|
|
|
*/
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
|
2003-04-24 15:29:25 +02:00
|
|
|
my_b_seek(cur_log,rli->event_relay_log_pos);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(cur_log);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2009-01-09 13:49:24 +01:00
|
|
|
/**
|
|
|
|
Reads next event from the relay log. Should be called from the
|
|
|
|
slave IO thread.
|
|
|
|
|
|
|
|
@param rli Relay_log_info structure for the slave IO thread.
|
|
|
|
|
|
|
|
@return The event read, or NULL on error. If an error occurs, the
|
|
|
|
error is reported through the sql_print_information() or
|
|
|
|
sql_print_error() functions.
|
|
|
|
*/
|
2007-08-16 07:37:50 +02:00
|
|
|
static Log_event* next_event(Relay_log_info* rli)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
Log_event* ev;
|
|
|
|
IO_CACHE* cur_log = rli->cur_log;
|
2006-05-30 18:21:03 +02:00
|
|
|
pthread_mutex_t *log_lock = rli->relay_log.get_log_lock();
|
2002-01-20 03:16:52 +01:00
|
|
|
const char* errmsg=0;
|
|
|
|
THD* thd = rli->sql_thd;
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_ENTER("next_event");
|
2006-05-30 18:21:03 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
DBUG_ASSERT(thd != 0);
|
|
|
|
|
2005-12-22 06:39:02 +01:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
if (abort_slave_event_count && !rli->events_till_abort--)
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
#endif
|
|
|
|
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
|
|
|
For most operations we need to protect rli members with data_lock,
|
2003-09-13 22:13:41 +02:00
|
|
|
so we assume calling function acquired this mutex for us and we will
|
|
|
|
hold it for the most of the loop below However, we will release it
|
|
|
|
whenever it is worth the hassle, and in the cases when we go into a
|
|
|
|
pthread_cond_wait() with the non-data_lock mutex
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
2003-09-13 22:13:41 +02:00
|
|
|
safe_mutex_assert_owner(&rli->data_lock);
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2002-08-23 14:14:01 +02:00
|
|
|
while (!sql_slave_killed(thd,rli))
|
2002-01-29 17:32:16 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
We can have two kinds of log reading:
|
2002-06-05 22:04:38 +02:00
|
|
|
hot_log:
|
|
|
|
rli->cur_log points at the IO_CACHE of relay_log, which
|
|
|
|
is actively being updated by the I/O thread. We need to be careful
|
|
|
|
in this case and make sure that we are not looking at a stale log that
|
|
|
|
has already been rotated. If it has been, we reopen the log.
|
|
|
|
|
|
|
|
The other case is much simpler:
|
|
|
|
We just have a read only log that nobody else will be updating.
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
bool hot_log;
|
|
|
|
if ((hot_log = (cur_log != &rli->cache_buf)))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
|
|
|
|
pthread_mutex_lock(log_lock);
|
2002-01-29 17:32:16 +01:00
|
|
|
|
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
Reading xxx_file_id is safe because the log will only
|
|
|
|
be rotated when we hold relay_log.LOCK_log
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
2002-06-05 22:04:38 +02:00
|
|
|
if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count)
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
// The master has switched to a new log file; Reopen the old log file
|
|
|
|
cur_log=reopen_relay_log(rli, &errmsg);
|
|
|
|
pthread_mutex_unlock(log_lock);
|
|
|
|
if (!cur_log) // No more log files
|
|
|
|
goto err;
|
|
|
|
hot_log=0; // Using old binary log
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
}
|
2006-12-18 14:38:59 +01:00
|
|
|
/*
|
|
|
|
As there is no guarantee that the relay is open (for example, an I/O
|
|
|
|
error during a write by the slave I/O thread may have closed it), we
|
|
|
|
have to test it.
|
|
|
|
*/
|
|
|
|
if (!my_b_inited(cur_log))
|
|
|
|
goto err;
|
2003-07-03 01:08:36 +02:00
|
|
|
#ifndef DBUG_OFF
|
|
|
|
{
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/* This is an assertion which sometimes fails, let's try to track it */
|
2003-07-03 01:08:36 +02:00
|
|
|
char llbuf1[22], llbuf2[22];
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
|
2005-02-01 15:36:48 +01:00
|
|
|
llstr(my_b_tell(cur_log),llbuf1),
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
llstr(rli->event_relay_log_pos,llbuf2)));
|
|
|
|
DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
|
|
|
|
DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos);
|
2003-07-03 01:08:36 +02:00
|
|
|
}
|
|
|
|
#endif
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
|
|
|
Relay log is always in new format - if the master is 3.23, the
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
I/O thread will convert the format for us.
|
2004-09-15 21:10:31 +02:00
|
|
|
A problem: the description event may be in a previous relay log. So if
|
|
|
|
the slave has been shutdown meanwhile, we would have to look in old relay
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
logs, which may even have been deleted. So we need to write this
|
|
|
|
description event at the beginning of the relay log.
|
2004-09-15 21:10:31 +02:00
|
|
|
When the relay log is created when the I/O thread starts, easy: the
|
|
|
|
master will send the description event and we will queue it.
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
But if the relay log is created by new_file(): then the solution is:
|
2006-05-05 08:45:58 +02:00
|
|
|
MYSQL_BIN_LOG::open() will write the buffered description event.
|
2002-02-07 23:29:46 +01:00
|
|
|
*/
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
if ((ev=Log_event::read_log_event(cur_log,0,
|
|
|
|
rli->relay_log.description_event_for_exec)))
|
2005-02-01 15:36:48 +01:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
|
|
|
DBUG_ASSERT(thd==rli->sql_thd);
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/*
|
|
|
|
read it while we have a lock, to avoid a mutex lock in
|
|
|
|
inc_event_relay_log_pos()
|
|
|
|
*/
|
|
|
|
rli->future_event_relay_log_pos= my_b_tell(cur_log);
|
2002-01-20 03:16:52 +01:00
|
|
|
if (hot_log)
|
2006-07-07 09:27:55 +02:00
|
|
|
pthread_mutex_unlock(log_lock);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(ev);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
DBUG_ASSERT(thd==rli->sql_thd);
|
2006-07-07 09:27:55 +02:00
|
|
|
if (opt_reckless_slave) // For mysql-test
|
2002-04-16 01:09:30 +02:00
|
|
|
cur_log->error = 0;
|
2002-06-05 22:04:38 +02:00
|
|
|
if (cur_log->error < 0)
|
2002-04-16 01:09:30 +02:00
|
|
|
{
|
|
|
|
errmsg = "slave SQL thread aborted because of I/O error";
|
2002-06-05 22:04:38 +02:00
|
|
|
if (hot_log)
|
2006-07-07 09:27:55 +02:00
|
|
|
pthread_mutex_unlock(log_lock);
|
2002-04-16 01:09:30 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
if (!cur_log->error) /* EOF */
|
|
|
|
{
|
2002-01-29 17:32:16 +01:00
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
On a hot log, EOF means that there are no more updates to
|
|
|
|
process and we must block until I/O thread adds some and
|
|
|
|
signals us to continue
|
2002-01-29 17:32:16 +01:00
|
|
|
*/
|
2002-01-20 03:16:52 +01:00
|
|
|
if (hot_log)
|
|
|
|
{
|
2004-12-16 22:38:42 +01:00
|
|
|
/*
|
|
|
|
We say in Seconds_Behind_Master that we have "caught up". Note that
|
|
|
|
for example if network link is broken but I/O slave thread hasn't
|
|
|
|
noticed it (slave_net_timeout not elapsed), then we'll say "caught
|
|
|
|
up" whereas we're not really caught up. Fixing that would require
|
|
|
|
internally cutting timeout in smaller pieces in network read, no
|
|
|
|
thanks. Another example: SQL has caught up on I/O, now I/O has read
|
|
|
|
a new event and is queuing it; the false "0" will exist until SQL
|
|
|
|
finishes executing the new event; it will be look abnormal only if
|
|
|
|
the events have old timestamps (then you get "many", 0, "many").
|
2007-10-04 17:46:31 +02:00
|
|
|
|
|
|
|
Transient phases like this can be fixed with implemeting
|
|
|
|
Heartbeat event which provides the slave the status of the
|
|
|
|
master at time the master does not have any new update to send.
|
|
|
|
Seconds_Behind_Master would be zero only when master has no
|
|
|
|
more updates in binlog for slave. The heartbeat can be sent
|
|
|
|
in a (small) fraction of slave_net_timeout. Until it's done
|
|
|
|
rli->last_master_timestamp is temporarely (for time of
|
|
|
|
waiting for the following event) reset whenever EOF is
|
|
|
|
reached.
|
2004-12-16 22:38:42 +01:00
|
|
|
*/
|
2007-04-17 08:39:38 +02:00
|
|
|
time_t save_timestamp= rli->last_master_timestamp;
|
2004-12-16 22:38:42 +01:00
|
|
|
rli->last_master_timestamp= 0;
|
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
DBUG_ASSERT(rli->relay_log.get_open_count() ==
|
2005-10-13 18:24:01 +02:00
|
|
|
rli->cur_log_old_open_count);
|
2005-10-12 13:29:55 +02:00
|
|
|
|
|
|
|
if (rli->ign_master_log_name_end[0])
|
|
|
|
{
|
|
|
|
/* We generate and return a Rotate, to make our positions advance */
|
|
|
|
DBUG_PRINT("info",("seeing an ignored end segment"));
|
2005-12-22 06:39:02 +01:00
|
|
|
ev= new Rotate_log_event(rli->ign_master_log_name_end,
|
2005-10-12 13:29:55 +02:00
|
|
|
0, rli->ign_master_log_pos_end,
|
2005-10-13 00:29:23 +02:00
|
|
|
Rotate_log_event::DUP_NAME);
|
2005-10-12 13:29:55 +02:00
|
|
|
rli->ign_master_log_name_end[0]= 0;
|
2005-10-13 18:24:01 +02:00
|
|
|
pthread_mutex_unlock(log_lock);
|
2005-10-12 13:29:55 +02:00
|
|
|
if (unlikely(!ev))
|
|
|
|
{
|
|
|
|
errmsg= "Slave SQL thread failed to create a Rotate event "
|
|
|
|
"(out of memory?), SHOW SLAVE STATUS may be inaccurate";
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
ev->server_id= 0; // don't be ignored by slave SQL thread
|
|
|
|
DBUG_RETURN(ev);
|
|
|
|
}
|
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
|
|
|
We can, and should release data_lock while we are waiting for
|
|
|
|
update. If we do not, show slave status will block
|
|
|
|
*/
|
|
|
|
pthread_mutex_unlock(&rli->data_lock);
|
2003-03-17 22:51:56 +01:00
|
|
|
|
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
Possible deadlock :
|
2003-03-17 22:51:56 +01:00
|
|
|
- the I/O thread has reached log_space_limit
|
|
|
|
- the SQL thread has read all relay logs, but cannot purge for some
|
|
|
|
reason:
|
|
|
|
* it has already purged all logs except the current one
|
|
|
|
* there are other logs than the current one but they're involved in
|
|
|
|
a transaction that finishes in the current one (or is not finished)
|
|
|
|
Solution :
|
|
|
|
Wake up the possibly waiting I/O thread, and set a boolean asking
|
|
|
|
the I/O thread to temporarily ignore the log_space_limit
|
|
|
|
constraint, because we do not want the I/O thread to block because of
|
|
|
|
space (it's ok if it blocks for any other reason (e.g. because the
|
2006-07-07 09:27:55 +02:00
|
|
|
master does not send anything). Then the I/O thread stops waiting
|
2003-03-17 22:51:56 +01:00
|
|
|
and reads more events.
|
|
|
|
The SQL thread decides when the I/O thread should take log_space_limit
|
2006-07-07 09:27:55 +02:00
|
|
|
into account again : ignore_log_space_limit is reset to 0
|
2003-03-17 22:51:56 +01:00
|
|
|
in purge_first_log (when the SQL thread purges the just-read relay
|
|
|
|
log), and also when the SQL thread starts. We should also reset
|
|
|
|
ignore_log_space_limit to 0 when the user does RESET SLAVE, but in
|
|
|
|
fact, no need as RESET SLAVE requires that the slave
|
2003-06-15 12:01:51 +02:00
|
|
|
be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
|
|
|
|
it stops.
|
2003-03-17 22:51:56 +01:00
|
|
|
*/
|
|
|
|
pthread_mutex_lock(&rli->log_space_lock);
|
|
|
|
// prevent the I/O thread from blocking next times
|
2006-07-07 09:27:55 +02:00
|
|
|
rli->ignore_log_space_limit= 1;
|
2003-05-25 23:09:46 +02:00
|
|
|
/*
|
2007-08-16 07:37:50 +02:00
|
|
|
If the I/O thread is blocked, unblock it. Ok to broadcast
|
|
|
|
after unlock, because the mutex is only destroyed in
|
|
|
|
~Relay_log_info(), i.e. when rli is destroyed, and rli will
|
|
|
|
not be destroyed before we exit the present function.
|
2003-05-25 23:09:46 +02:00
|
|
|
*/
|
2003-03-17 22:51:56 +01:00
|
|
|
pthread_mutex_unlock(&rli->log_space_lock);
|
2003-04-24 15:29:25 +02:00
|
|
|
pthread_cond_broadcast(&rli->log_space_cond);
|
2003-03-17 22:51:56 +01:00
|
|
|
// Note that wait_for_update unlocks lock_log !
|
2003-08-25 14:13:58 +02:00
|
|
|
rli->relay_log.wait_for_update(rli->sql_thd, 1);
|
2003-03-17 22:51:56 +01:00
|
|
|
// re-acquire data lock since we released it earlier
|
|
|
|
pthread_mutex_lock(&rli->data_lock);
|
2004-12-16 18:12:22 +01:00
|
|
|
rli->last_master_timestamp= save_timestamp;
|
2006-07-07 09:27:55 +02:00
|
|
|
continue;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
If the log was not hot, we need to move to the next log in
|
|
|
|
sequence. The next log could be hot or cold, we deal with both
|
|
|
|
cases separately after doing some common initialization
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
|
|
|
end_io_cache(cur_log);
|
|
|
|
DBUG_ASSERT(rli->cur_log_fd >= 0);
|
|
|
|
my_close(rli->cur_log_fd, MYF(MY_WME));
|
|
|
|
rli->cur_log_fd = -1;
|
2006-07-07 09:27:55 +02:00
|
|
|
|
2003-04-24 15:29:25 +02:00
|
|
|
if (relay_log_purge)
|
2002-06-05 22:04:38 +02:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
2003-04-24 15:29:25 +02:00
|
|
|
purge_first_log will properly set up relay log coordinates in rli.
|
|
|
|
If the group's coordinates are equal to the event's coordinates
|
|
|
|
(i.e. the relay log was not rotated in the middle of a group),
|
|
|
|
we can purge this relay log too.
|
|
|
|
We do ulonglong and string comparisons, this may be slow but
|
|
|
|
- purging the last relay log is nice (it can save 1GB of disk), so we
|
|
|
|
like to detect the case where we can do it, and given this,
|
|
|
|
- I see no better detection method
|
|
|
|
- purge_first_log is not called that often
|
|
|
|
*/
|
2006-07-07 09:27:55 +02:00
|
|
|
if (rli->relay_log.purge_first_log
|
2003-04-24 15:29:25 +02:00
|
|
|
(rli,
|
|
|
|
rli->group_relay_log_pos == rli->event_relay_log_pos
|
|
|
|
&& !strcmp(rli->group_relay_log_name,rli->event_relay_log_name)))
|
2006-07-07 09:27:55 +02:00
|
|
|
{
|
|
|
|
errmsg = "Error purging processed logs";
|
|
|
|
goto err;
|
|
|
|
}
|
2002-06-05 22:04:38 +02:00
|
|
|
}
|
2002-01-20 03:16:52 +01:00
|
|
|
else
|
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
|
|
|
If hot_log is set, then we already have a lock on
|
|
|
|
LOCK_log. If not, we have to get the lock.
|
|
|
|
|
|
|
|
According to Sasha, the only time this code will ever be executed
|
|
|
|
is if we are recovering from a bug.
|
|
|
|
*/
|
|
|
|
if (rli->relay_log.find_next_log(&rli->linfo, !hot_log))
|
|
|
|
{
|
|
|
|
errmsg = "error switching to the next log";
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE;
|
|
|
|
strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
|
|
|
|
sizeof(rli->event_relay_log_name)-1);
|
|
|
|
flush_relay_log_info(rli);
|
2002-06-05 22:04:38 +02:00
|
|
|
}
|
2003-12-04 15:30:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Now we want to open this next log. To know if it's a hot log (the one
|
|
|
|
being written by the I/O thread now) or a cold log, we can use
|
|
|
|
is_active(); if it is hot, we use the I/O cache; if it's cold we open
|
|
|
|
the file normally. But if is_active() reports that the log is hot, this
|
|
|
|
may change between the test and the consequence of the test. So we may
|
|
|
|
open the I/O cache whereas the log is now cold, which is nonsense.
|
|
|
|
To guard against this, we need to have LOCK_log.
|
|
|
|
*/
|
|
|
|
|
|
|
|
DBUG_PRINT("info",("hot_log: %d",hot_log));
|
|
|
|
if (!hot_log) /* if hot_log, we already have this mutex */
|
|
|
|
pthread_mutex_lock(log_lock);
|
2002-06-05 22:04:38 +02:00
|
|
|
if (rli->relay_log.is_active(rli->linfo.log_file_name))
|
|
|
|
{
|
2002-01-20 03:16:52 +01:00
|
|
|
#ifdef EXTRA_DEBUG
|
2006-07-07 09:27:55 +02:00
|
|
|
if (global_system_variables.log_warnings)
|
|
|
|
sql_print_information("next log '%s' is currently active",
|
2004-09-15 21:10:31 +02:00
|
|
|
rli->linfo.log_file_name);
|
2006-07-07 09:27:55 +02:00
|
|
|
#endif
|
|
|
|
rli->cur_log= cur_log= rli->relay_log.get_log_file();
|
|
|
|
rli->cur_log_old_open_count= rli->relay_log.get_open_count();
|
|
|
|
DBUG_ASSERT(rli->cur_log_fd == -1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
Read pointer has to be at the start since we are the only
|
|
|
|
reader.
|
2003-12-04 15:30:14 +01:00
|
|
|
We must keep the LOCK_log to read the 4 first bytes, as this is a hot
|
|
|
|
log (same as when we call read_log_event() above: for a hot log we
|
|
|
|
take the mutex).
|
2006-07-07 09:27:55 +02:00
|
|
|
*/
|
|
|
|
if (check_binlog_magic(cur_log,&errmsg))
|
2003-12-04 15:30:14 +01:00
|
|
|
{
|
|
|
|
if (!hot_log) pthread_mutex_unlock(log_lock);
|
2006-07-07 09:27:55 +02:00
|
|
|
goto err;
|
2003-12-04 15:30:14 +01:00
|
|
|
}
|
|
|
|
if (!hot_log) pthread_mutex_unlock(log_lock);
|
2006-07-07 09:27:55 +02:00
|
|
|
continue;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2003-12-04 15:30:14 +01:00
|
|
|
if (!hot_log) pthread_mutex_unlock(log_lock);
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
if we get here, the log was not hot, so we will have to open it
|
|
|
|
ourselves. We are sure that the log is still not hot now (a log can get
|
|
|
|
from hot to cold, but not from cold to hot). No need for LOCK_log.
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
|
|
|
#ifdef EXTRA_DEBUG
|
2004-04-05 12:56:05 +02:00
|
|
|
if (global_system_variables.log_warnings)
|
2006-07-07 09:27:55 +02:00
|
|
|
sql_print_information("next log '%s' is not active",
|
2004-09-15 21:10:31 +02:00
|
|
|
rli->linfo.log_file_name);
|
2006-07-07 09:27:55 +02:00
|
|
|
#endif
|
2002-06-05 22:04:38 +02:00
|
|
|
// open_binlog() will check the magic header
|
|
|
|
if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
|
2006-07-07 09:27:55 +02:00
|
|
|
&errmsg)) <0)
|
|
|
|
goto err;
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
2002-06-05 22:04:38 +02:00
|
|
|
else
|
2002-01-20 03:16:52 +01:00
|
|
|
{
|
2002-06-05 22:04:38 +02:00
|
|
|
/*
|
2006-07-07 09:27:55 +02:00
|
|
|
Read failed with a non-EOF error.
|
|
|
|
TODO: come up with something better to handle this error
|
2002-06-05 22:04:38 +02:00
|
|
|
*/
|
|
|
|
if (hot_log)
|
2006-07-07 09:27:55 +02:00
|
|
|
pthread_mutex_unlock(log_lock);
|
2002-01-20 03:16:52 +01:00
|
|
|
sql_print_error("Slave SQL thread: I/O error reading \
|
2002-06-05 22:04:38 +02:00
|
|
|
event(errno: %d cur_log->error: %d)",
|
2006-07-07 09:27:55 +02:00
|
|
|
my_errno,cur_log->error);
|
2002-03-09 21:50:07 +01:00
|
|
|
// set read position to the beginning of the event
|
2003-04-24 15:29:25 +02:00
|
|
|
my_b_seek(cur_log,rli->event_relay_log_pos);
|
2002-04-16 01:09:30 +02:00
|
|
|
/* otherwise, we have had a partial read */
|
|
|
|
errmsg = "Aborting slave SQL thread because of partial event read";
|
2006-07-07 09:27:55 +02:00
|
|
|
break; // To end of function
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
}
|
2002-08-08 02:12:02 +02:00
|
|
|
if (!errmsg && global_system_variables.log_warnings)
|
2004-09-15 21:10:31 +02:00
|
|
|
{
|
2006-07-07 09:27:55 +02:00
|
|
|
sql_print_information("Error reading relay log event: %s",
|
2004-09-15 21:10:31 +02:00
|
|
|
"slave SQL thread was killed");
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
2002-06-05 22:04:38 +02:00
|
|
|
|
2002-01-20 03:16:52 +01:00
|
|
|
err:
|
2002-08-08 02:12:02 +02:00
|
|
|
if (errmsg)
|
|
|
|
sql_print_error("Error reading relay log event: %s", errmsg);
|
2002-06-05 22:04:38 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-01-20 03:16:52 +01:00
|
|
|
}
|
|
|
|
|
2003-07-06 17:59:54 +02:00
|
|
|
/*
|
|
|
|
Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
|
|
|
|
because of size is simpler because when we do it we already have all relevant
|
2006-07-07 09:27:55 +02:00
|
|
|
locks; here we don't, so this function is mainly taking locks).
|
2006-05-05 08:45:58 +02:00
|
|
|
Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
|
|
|
|
is void).
|
2003-07-06 17:59:54 +02:00
|
|
|
*/
|
|
|
|
|
2007-08-16 08:52:50 +02:00
|
|
|
void rotate_relay_log(Master_info* mi)
|
2003-07-06 17:59:54 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("rotate_relay_log");
|
2007-08-16 07:37:50 +02:00
|
|
|
Relay_log_info* rli= &mi->rli;
|
2003-07-11 14:26:44 +02:00
|
|
|
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
/* We don't lock rli->run_lock. This would lead to deadlocks. */
|
|
|
|
pthread_mutex_lock(&mi->run_lock);
|
|
|
|
|
2006-07-07 09:27:55 +02:00
|
|
|
/*
|
2003-07-11 14:26:44 +02:00
|
|
|
We need to test inited because otherwise, new_file() will attempt to lock
|
|
|
|
LOCK_log, which may not be inited (if we're not a slave).
|
|
|
|
*/
|
2003-07-06 17:59:54 +02:00
|
|
|
if (!rli->inited)
|
|
|
|
{
|
2003-07-08 23:55:07 +02:00
|
|
|
DBUG_PRINT("info", ("rli->inited == 0"));
|
2003-07-11 14:26:44 +02:00
|
|
|
goto end;
|
2003-07-06 17:59:54 +02:00
|
|
|
}
|
2003-07-08 23:55:07 +02:00
|
|
|
|
2003-07-06 17:59:54 +02:00
|
|
|
/* If the relay log is closed, new_file() will do nothing. */
|
2006-05-05 08:45:58 +02:00
|
|
|
rli->relay_log.new_file();
|
2003-07-08 23:55:07 +02:00
|
|
|
|
2003-07-06 17:59:54 +02:00
|
|
|
/*
|
|
|
|
We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
|
|
|
|
be counted, so imagine a succession of FLUSH LOGS and assume the slave
|
|
|
|
threads are started:
|
2003-07-08 23:55:07 +02:00
|
|
|
relay_log_space decreases by the size of the deleted relay log, but does
|
|
|
|
not increase, so flush-after-flush we may become negative, which is wrong.
|
|
|
|
Even if this will be corrected as soon as a query is replicated on the
|
|
|
|
slave (because the I/O thread will then call harvest_bytes_written() which
|
|
|
|
will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange
|
|
|
|
output in SHOW SLAVE STATUS meanwhile. So we harvest now.
|
2003-07-06 17:59:54 +02:00
|
|
|
If the log is closed, then this will just harvest the last writes, probably
|
|
|
|
0 as they probably have been harvested.
|
|
|
|
*/
|
|
|
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
2003-07-11 14:26:44 +02:00
|
|
|
end:
|
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.
2003-12-18 01:09:05 +01:00
|
|
|
pthread_mutex_unlock(&mi->run_lock);
|
2003-07-06 17:59:54 +02:00
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2001-10-23 21:28:03 +02:00
|
|
|
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
/**
|
|
|
|
Detects, based on master's version (as found in the relay log), if master
|
|
|
|
has a certain bug.
|
2007-08-16 07:37:50 +02:00
|
|
|
@param rli Relay_log_info which tells the master's version
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
@param bug_id Number of the bug as found in bugs.mysql.com
|
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting
using a trig in SP
For all 5.0 and up to 5.1.12 exclusive, when a stored routine or
trigger caused an INSERT into an AUTO_INCREMENT column, the
generated AUTO_INCREMENT value should not be written into the
binary log, which means if a statement does not generate
AUTO_INCREMENT value itself, there will be no Intvar event (SET
INSERT_ID) associated with it even if one of the stored routine
or trigger caused generation of such a value. And meanwhile, when
executing a stored routine or trigger, it would ignore the
INSERT_ID value even if there is a INSERT_ID value available set
by a SET INSERT_ID statement.
Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is
written into the binary log, and the value will be used if
available when executing the stored routine or trigger.
Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12
(referenced as the buggy versions in the text below), when a
statement that generates AUTO_INCREMENT value by the top
statement was executed in the body of a SP, all statements in the
SP after this statement would be treated as if they had generated
AUTO_INCREMENT by the top statement. When a statement that did
not generate AUTO_INCREMENT value by the top statement but by a
function/trigger called by it, an erroneous Intvar event would be
associated with the statement, this erroneous INSERT_ID value
wouldn't cause problem when replicating between masters and
slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID
value was not used when executing functions/triggers. But when
replicating from buggy versions to 5.1.12 or newer, which will
use the INSERT_ID value in functions/triggers, the erroneous
value will be used, which would cause duplicate entry error and
cause the slave to stop.
The patch for 5.1 fixed it to ignore the SET INSERT_ID value when
executing functions/triggers if it is replicating from a master
of buggy versions, another patch for 5.0 fixed it not to generate
the erroneous Intvar event.
2008-03-14 04:35:41 +01:00
|
|
|
@param report bool report error message, default TRUE
|
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for
the size of the CHAR field. However, instead of denoting the
number of characters in the field, field_length was used which
denotes the number of bytes in the field.
Since UTF-8 fields can have three bytes per character (and
has been extended to have four bytes per character in 6.0),
an extra two bits have been encoded in the field metadata
work for fields of type Field_string (i.e., CHAR fields).
Since the metadata word is filled, the extra bits have been
encoded in the upper 4 bits of the real type (the most
significant byte of the metadata word) by computing the
bitwise xor of the extra two bits. Since the upper 4 bits
of the real type always is 1111 for Field_string, this
means that for fields of length <256, the encoding is
identical to the encoding used in pre-5.1.26 servers, but
for lengths of 256 or more, an unrecognized type is formed,
causing an old slave (that does not handle lengths of 256
or more) to stop.
2008-06-30 22:11:18 +02:00
|
|
|
|
|
|
|
@param pred Predicate function that will be called with @c param to
|
|
|
|
check for the bug. If the function return @c true, the bug is present,
|
|
|
|
otherwise, it is not.
|
|
|
|
|
|
|
|
@param param State passed to @c pred function.
|
|
|
|
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
@return TRUE if master has the bug, FALSE if it does not.
|
|
|
|
*/
|
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for
the size of the CHAR field. However, instead of denoting the
number of characters in the field, field_length was used which
denotes the number of bytes in the field.
Since UTF-8 fields can have three bytes per character (and
has been extended to have four bytes per character in 6.0),
an extra two bits have been encoded in the field metadata
work for fields of type Field_string (i.e., CHAR fields).
Since the metadata word is filled, the extra bits have been
encoded in the upper 4 bits of the real type (the most
significant byte of the metadata word) by computing the
bitwise xor of the extra two bits. Since the upper 4 bits
of the real type always is 1111 for Field_string, this
means that for fields of length <256, the encoding is
identical to the encoding used in pre-5.1.26 servers, but
for lengths of 256 or more, an unrecognized type is formed,
causing an old slave (that does not handle lengths of 256
or more) to stop.
2008-06-30 22:11:18 +02:00
|
|
|
bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
|
|
|
|
bool (*pred)(const void *), const void *param)
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
{
|
|
|
|
struct st_version_range_for_one_bug {
|
|
|
|
uint bug_id;
|
|
|
|
const uchar introduced_in[3]; // first version with bug
|
|
|
|
const uchar fixed_in[3]; // first version with fix
|
|
|
|
};
|
|
|
|
static struct st_version_range_for_one_bug versions_for_all_bugs[]=
|
|
|
|
{
|
2007-02-23 15:32:51 +01:00
|
|
|
{24432, { 5, 0, 24 }, { 5, 0, 38 } },
|
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting
using a trig in SP
For all 5.0 and up to 5.1.12 exclusive, when a stored routine or
trigger caused an INSERT into an AUTO_INCREMENT column, the
generated AUTO_INCREMENT value should not be written into the
binary log, which means if a statement does not generate
AUTO_INCREMENT value itself, there will be no Intvar event (SET
INSERT_ID) associated with it even if one of the stored routine
or trigger caused generation of such a value. And meanwhile, when
executing a stored routine or trigger, it would ignore the
INSERT_ID value even if there is a INSERT_ID value available set
by a SET INSERT_ID statement.
Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is
written into the binary log, and the value will be used if
available when executing the stored routine or trigger.
Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12
(referenced as the buggy versions in the text below), when a
statement that generates AUTO_INCREMENT value by the top
statement was executed in the body of a SP, all statements in the
SP after this statement would be treated as if they had generated
AUTO_INCREMENT by the top statement. When a statement that did
not generate AUTO_INCREMENT value by the top statement but by a
function/trigger called by it, an erroneous Intvar event would be
associated with the statement, this erroneous INSERT_ID value
wouldn't cause problem when replicating between masters and
slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID
value was not used when executing functions/triggers. But when
replicating from buggy versions to 5.1.12 or newer, which will
use the INSERT_ID value in functions/triggers, the erroneous
value will be used, which would cause duplicate entry error and
cause the slave to stop.
The patch for 5.1 fixed it to ignore the SET INSERT_ID value when
executing functions/triggers if it is replicating from a master
of buggy versions, another patch for 5.0 fixed it not to generate
the erroneous Intvar event.
2008-03-14 04:35:41 +01:00
|
|
|
{24432, { 5, 1, 12 }, { 5, 1, 17 } },
|
|
|
|
{33029, { 5, 0, 0 }, { 5, 0, 58 } },
|
|
|
|
{33029, { 5, 1, 0 }, { 5, 1, 12 } },
|
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for
the size of the CHAR field. However, instead of denoting the
number of characters in the field, field_length was used which
denotes the number of bytes in the field.
Since UTF-8 fields can have three bytes per character (and
has been extended to have four bytes per character in 6.0),
an extra two bits have been encoded in the field metadata
work for fields of type Field_string (i.e., CHAR fields).
Since the metadata word is filled, the extra bits have been
encoded in the upper 4 bits of the real type (the most
significant byte of the metadata word) by computing the
bitwise xor of the extra two bits. Since the upper 4 bits
of the real type always is 1111 for Field_string, this
means that for fields of length <256, the encoding is
identical to the encoding used in pre-5.1.26 servers, but
for lengths of 256 or more, an unrecognized type is formed,
causing an old slave (that does not handle lengths of 256
or more) to stop.
2008-06-30 22:11:18 +02:00
|
|
|
{37426, { 5, 1, 0 }, { 5, 1, 26 } },
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
};
|
|
|
|
const uchar *master_ver=
|
|
|
|
rli->relay_log.description_event_for_exec->server_version_split;
|
|
|
|
|
|
|
|
DBUG_ASSERT(sizeof(rli->relay_log.description_event_for_exec->server_version_split) == 3);
|
|
|
|
|
|
|
|
for (uint i= 0;
|
|
|
|
i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
|
|
|
|
{
|
|
|
|
const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
|
|
|
|
*fixed_in= versions_for_all_bugs[i].fixed_in;
|
|
|
|
if ((versions_for_all_bugs[i].bug_id == bug_id) &&
|
|
|
|
(memcmp(introduced_in, master_ver, 3) <= 0) &&
|
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for
the size of the CHAR field. However, instead of denoting the
number of characters in the field, field_length was used which
denotes the number of bytes in the field.
Since UTF-8 fields can have three bytes per character (and
has been extended to have four bytes per character in 6.0),
an extra two bits have been encoded in the field metadata
work for fields of type Field_string (i.e., CHAR fields).
Since the metadata word is filled, the extra bits have been
encoded in the upper 4 bits of the real type (the most
significant byte of the metadata word) by computing the
bitwise xor of the extra two bits. Since the upper 4 bits
of the real type always is 1111 for Field_string, this
means that for fields of length <256, the encoding is
identical to the encoding used in pre-5.1.26 servers, but
for lengths of 256 or more, an unrecognized type is formed,
causing an old slave (that does not handle lengths of 256
or more) to stop.
2008-06-30 22:11:18 +02:00
|
|
|
(memcmp(fixed_in, master_ver, 3) > 0) &&
|
|
|
|
(pred == NULL || (*pred)(param)))
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
{
|
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting
using a trig in SP
For all 5.0 and up to 5.1.12 exclusive, when a stored routine or
trigger caused an INSERT into an AUTO_INCREMENT column, the
generated AUTO_INCREMENT value should not be written into the
binary log, which means if a statement does not generate
AUTO_INCREMENT value itself, there will be no Intvar event (SET
INSERT_ID) associated with it even if one of the stored routine
or trigger caused generation of such a value. And meanwhile, when
executing a stored routine or trigger, it would ignore the
INSERT_ID value even if there is a INSERT_ID value available set
by a SET INSERT_ID statement.
Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is
written into the binary log, and the value will be used if
available when executing the stored routine or trigger.
Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12
(referenced as the buggy versions in the text below), when a
statement that generates AUTO_INCREMENT value by the top
statement was executed in the body of a SP, all statements in the
SP after this statement would be treated as if they had generated
AUTO_INCREMENT by the top statement. When a statement that did
not generate AUTO_INCREMENT value by the top statement but by a
function/trigger called by it, an erroneous Intvar event would be
associated with the statement, this erroneous INSERT_ID value
wouldn't cause problem when replicating between masters and
slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID
value was not used when executing functions/triggers. But when
replicating from buggy versions to 5.1.12 or newer, which will
use the INSERT_ID value in functions/triggers, the erroneous
value will be used, which would cause duplicate entry error and
cause the slave to stop.
The patch for 5.1 fixed it to ignore the SET INSERT_ID value when
executing functions/triggers if it is replicating from a master
of buggy versions, another patch for 5.0 fixed it not to generate
the erroneous Intvar event.
2008-03-14 04:35:41 +01:00
|
|
|
if (!report)
|
|
|
|
return TRUE;
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
// a short message for SHOW SLAVE STATUS (message length constraints)
|
|
|
|
my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
|
|
|
|
" http://bugs.mysql.com/bug.php?id=%u"
|
|
|
|
" so slave stops; check error log on slave"
|
|
|
|
" for more info", MYF(0), bug_id);
|
Manual merge from 5.0-rpl, of fixes for:
1)
BUG#25507 "multi-row insert delayed + auto increment causes
duplicate key entries on slave" (two concurrrent connections doing
multi-row INSERT DELAYED to insert into an auto_increment column,
caused replication slave to stop with "duplicate key error" (and
binlog was wrong), and BUG#26116 "If multi-row INSERT
DELAYED has errors, statement-based binlogging breaks" (the binlog
was not accounting for all rows inserted, or slave could stop).
The fix is that: in statement-based binlogging, a multi-row INSERT
DELAYED is silently converted to a non-delayed INSERT.
This is supposed to not affect many 5.1 users as in 5.1, the default
binlog format is "mixed", which does not have the bug (the bug is
only with binlog_format=STATEMENT).
We should document how the system delayed_insert thread decides of
its binlog format (which is not modified by this patch):
this decision is taken when the thread is created
and holds until it is terminated (is not affected by any later change
via SET GLOBAL BINLOG_FORMAT). It is also not affected by the binlog
format of the connection which issues INSERT DELAYED (this binlog
format does not affect how the row will be binlogged).
If one wants to change the binlog format of its server with SET
GLOBAL BINLOG_FORMAT, it should do FLUSH TABLES to be sure all
delayed_insert threads terminate and thus new threads are created,
taking into account the new format.
2)
BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24/pre-5.1.12 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24/pre-5.1.12, breaks replication from a
[5.0.24,5.0.34]/[5.1.12,5.1.15]
master to a fixed (5.0.36/5.1.16) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication or 5.1.16->[5.1.12,5.1.15]
replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I have asked for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
3) note that I'll re-enable rpl_insert_id as soon as 5.1-rpl gets
the changes from the main 5.1.
2007-02-15 20:28:58 +01:00
|
|
|
// a verbose message for the error log
|
2007-06-11 22:15:39 +02:00
|
|
|
rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
|
|
|
|
"According to the master's version ('%s'),"
|
|
|
|
" it is probable that master suffers from this bug:"
|
Manual merge from 5.0-rpl, of fixes for:
1)
BUG#25507 "multi-row insert delayed + auto increment causes
duplicate key entries on slave" (two concurrrent connections doing
multi-row INSERT DELAYED to insert into an auto_increment column,
caused replication slave to stop with "duplicate key error" (and
binlog was wrong), and BUG#26116 "If multi-row INSERT
DELAYED has errors, statement-based binlogging breaks" (the binlog
was not accounting for all rows inserted, or slave could stop).
The fix is that: in statement-based binlogging, a multi-row INSERT
DELAYED is silently converted to a non-delayed INSERT.
This is supposed to not affect many 5.1 users as in 5.1, the default
binlog format is "mixed", which does not have the bug (the bug is
only with binlog_format=STATEMENT).
We should document how the system delayed_insert thread decides of
its binlog format (which is not modified by this patch):
this decision is taken when the thread is created
and holds until it is terminated (is not affected by any later change
via SET GLOBAL BINLOG_FORMAT). It is also not affected by the binlog
format of the connection which issues INSERT DELAYED (this binlog
format does not affect how the row will be binlogged).
If one wants to change the binlog format of its server with SET
GLOBAL BINLOG_FORMAT, it should do FLUSH TABLES to be sure all
delayed_insert threads terminate and thus new threads are created,
taking into account the new format.
2)
BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24/pre-5.1.12 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24/pre-5.1.12, breaks replication from a
[5.0.24,5.0.34]/[5.1.12,5.1.15]
master to a fixed (5.0.36/5.1.16) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication or 5.1.16->[5.1.12,5.1.15]
replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I have asked for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
3) note that I'll re-enable rpl_insert_id as soon as 5.1-rpl gets
the changes from the main 5.1.
2007-02-15 20:28:58 +01:00
|
|
|
" http://bugs.mysql.com/bug.php?id=%u"
|
|
|
|
" and thus replicating the current binary log event"
|
|
|
|
" may make the slave's data become different from the"
|
|
|
|
" master's data."
|
|
|
|
" To take no risk, slave refuses to replicate"
|
|
|
|
" this event and stops."
|
|
|
|
" We recommend that all updates be stopped on the"
|
|
|
|
" master and slave, that the data of both be"
|
|
|
|
" manually synchronized,"
|
|
|
|
" that master's binary logs be deleted,"
|
|
|
|
" that master be upgraded to a version at least"
|
|
|
|
" equal to '%d.%d.%d'. Then replication can be"
|
|
|
|
" restarted.",
|
|
|
|
rli->relay_log.description_event_for_exec->server_version,
|
|
|
|
bug_id,
|
|
|
|
fixed_in[0], fixed_in[1], fixed_in[2]);
|
Fix for BUG#24432
"INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values".
When in an INSERT ON DUPLICATE KEY UPDATE, using
an autoincrement column, we inserted some autogenerated values and
also updated some rows, some autogenerated values were not used
(for example, even if 10 was the largest autoinc value in the table
at the start of the statement, 12 could be the first autogenerated
value inserted by the statement, instead of 11). One autogenerated
value was lost per updated row. Led to exhausting the range of the
autoincrement column faster.
Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12.
This bug breaks replication from a pre-5.0.24 master.
But the present bugfix, as it makes INSERT ON DUP KEY UPDATE
behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34]
master to a fixed (5.0.36) slave! To warn users against this when
they upgrade their slave, as agreed with the support team, we add
code for a fixed slave to detect that it is connected to a buggy
master in a situation (INSERT ON DUP KEY UPDATE into autoinc column)
likely to break replication, in which case it cannot replicate so
stops and prints a message to the slave's error log and to SHOW SLAVE
STATUS.
For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master
does not know the slave's version (but we always recommended to users
to have slave at least as new as master).
As agreed with support, I'll also ask for an alert to be put into
the MySQL Network Monitoring and Advisory Service.
2007-02-08 15:53:14 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting
using a trig in SP
For all 5.0 and up to 5.1.12 exclusive, when a stored routine or
trigger caused an INSERT into an AUTO_INCREMENT column, the
generated AUTO_INCREMENT value should not be written into the
binary log, which means if a statement does not generate
AUTO_INCREMENT value itself, there will be no Intvar event (SET
INSERT_ID) associated with it even if one of the stored routine
or trigger caused generation of such a value. And meanwhile, when
executing a stored routine or trigger, it would ignore the
INSERT_ID value even if there is a INSERT_ID value available set
by a SET INSERT_ID statement.
Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is
written into the binary log, and the value will be used if
available when executing the stored routine or trigger.
Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12
(referenced as the buggy versions in the text below), when a
statement that generates AUTO_INCREMENT value by the top
statement was executed in the body of a SP, all statements in the
SP after this statement would be treated as if they had generated
AUTO_INCREMENT by the top statement. When a statement that did
not generate AUTO_INCREMENT value by the top statement but by a
function/trigger called by it, an erroneous Intvar event would be
associated with the statement, this erroneous INSERT_ID value
wouldn't cause problem when replicating between masters and
slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID
value was not used when executing functions/triggers. But when
replicating from buggy versions to 5.1.12 or newer, which will
use the INSERT_ID value in functions/triggers, the erroneous
value will be used, which would cause duplicate entry error and
cause the slave to stop.
The patch for 5.1 fixed it to ignore the SET INSERT_ID value when
executing functions/triggers if it is replicating from a master
of buggy versions, another patch for 5.0 fixed it not to generate
the erroneous Intvar event.
2008-03-14 04:35:41 +01:00
|
|
|
/**
|
|
|
|
BUG#33029, For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12
|
|
|
|
exclusive, if one statement in a SP generated AUTO_INCREMENT value
|
|
|
|
by the top statement, all statements after it would be considered
|
|
|
|
generated AUTO_INCREMENT value by the top statement, and a
|
|
|
|
erroneous INSERT_ID value might be associated with these statement,
|
|
|
|
which could cause duplicate entry error and stop the slave.
|
|
|
|
|
|
|
|
Detect buggy master to work around.
|
|
|
|
*/
|
|
|
|
bool rpl_master_erroneous_autoinc(THD *thd)
|
|
|
|
{
|
|
|
|
if (active_mi && active_mi->rli.sql_thd == thd)
|
|
|
|
{
|
|
|
|
Relay_log_info *rli= &active_mi->rli;
|
2008-06-19 20:47:59 +02:00
|
|
|
DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
|
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for
the size of the CHAR field. However, instead of denoting the
number of characters in the field, field_length was used which
denotes the number of bytes in the field.
Since UTF-8 fields can have three bytes per character (and
has been extended to have four bytes per character in 6.0),
an extra two bits have been encoded in the field metadata
work for fields of type Field_string (i.e., CHAR fields).
Since the metadata word is filled, the extra bits have been
encoded in the upper 4 bits of the real type (the most
significant byte of the metadata word) by computing the
bitwise xor of the extra two bits. Since the upper 4 bits
of the real type always is 1111 for Field_string, this
means that for fields of length <256, the encoding is
identical to the encoding used in pre-5.1.26 servers, but
for lengths of 256 or more, an unrecognized type is formed,
causing an old slave (that does not handle lengths of 256
or more) to stop.
2008-06-30 22:11:18 +02:00
|
|
|
return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL);
|
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting
using a trig in SP
For all 5.0 and up to 5.1.12 exclusive, when a stored routine or
trigger caused an INSERT into an AUTO_INCREMENT column, the
generated AUTO_INCREMENT value should not be written into the
binary log, which means if a statement does not generate
AUTO_INCREMENT value itself, there will be no Intvar event (SET
INSERT_ID) associated with it even if one of the stored routine
or trigger caused generation of such a value. And meanwhile, when
executing a stored routine or trigger, it would ignore the
INSERT_ID value even if there is a INSERT_ID value available set
by a SET INSERT_ID statement.
Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is
written into the binary log, and the value will be used if
available when executing the stored routine or trigger.
Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12
(referenced as the buggy versions in the text below), when a
statement that generates AUTO_INCREMENT value by the top
statement was executed in the body of a SP, all statements in the
SP after this statement would be treated as if they had generated
AUTO_INCREMENT by the top statement. When a statement that did
not generate AUTO_INCREMENT value by the top statement but by a
function/trigger called by it, an erroneous Intvar event would be
associated with the statement, this erroneous INSERT_ID value
wouldn't cause problem when replicating between masters and
slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID
value was not used when executing functions/triggers. But when
replicating from buggy versions to 5.1.12 or newer, which will
use the INSERT_ID value in functions/triggers, the erroneous
value will be used, which would cause duplicate entry error and
cause the slave to stop.
The patch for 5.1 fixed it to ignore the SET INSERT_ID value when
executing functions/triggers if it is replicating from a master
of buggy versions, another patch for 5.0 fixed it not to generate
the erroneous Intvar event.
2008-03-14 04:35:41 +01:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-06-22 11:08:28 +02:00
|
|
|
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
2000-07-31 21:29:14 +02:00
|
|
|
template class I_List_iterator<i_string>;
|
2000-10-21 20:17:08 +02:00
|
|
|
template class I_List_iterator<i_string_pair>;
|
2000-07-31 21:29:14 +02:00
|
|
|
#endif
|
2002-12-16 14:33:29 +01:00
|
|
|
|
BUG#32407: Impossible to do point-in-time recovery from older binlog
Problem: it is unsafe to read base64-printed events without first
reading the Format_description_log_event (FD). Currently, mysqlbinlog
cannot print the FD.
As a side effect, another bug has also been fixed: When mysqlbinlog
--start-position=X was specified, no ROLLBACK was printed. I changed
this, so that ROLLBACK is always printed.
This patch does several things:
- Format_description_log_event (FD) now print themselves in base64
format.
- mysqlbinlog is now able to print FD events. It has three modes:
--base64-output=auto Print row events in base64 output, and print
FD event. The FD event is printed even if
it is outside the range specified with
--start-position, because it would not be
safe to read row events otherwise. This is
the default.
--base64-output=always Like --base64-output=auto, but also print
base64 output for query events. This is
like the old --base64-output flag, which
is also a shorthand for
--base64-output=always
--base64-output=never Never print base64 output, generate error if
row events occur in binlog. This is
useful to suppress the FD event in binlogs
known not to contain row events (e.g.,
because BINLOG statement is unsafe,
requires root privileges, is not SQL, etc)
- the BINLOG statement now handles FD events correctly, by setting
the thread's rli's relay log's description_event_for_exec to the
loaded event.
In fact, executing a BINLOG statement is almost the same as reading
an event from a relay log. Before my patch, the code for this was
separated (exec_relay_log_event in slave.cc executes events from
the relay log, mysql_client_binlog_statement in sql_binlog.cc
executes BINLOG statements). I needed to augment
mysql_client_binlog_statement to do parts of what
exec_relay_log_event does. Hence, I did a small refactoring and
moved parts of exec_relay_log_event to a new function, which I
named apply_event_and_update_pos. apply_event_and_update_pos is
called both from exec_relay_log_event and from
mysql_client_binlog_statement.
- When a non-FD event is executed in a BINLOG statement, without
previously executing a FD event in a BINLOG statement, it generates
an error, because that's unsafe. I took a new error code for that:
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS.
In order to get a decent error message containing the name of the
event, I added the class method char*
Log_event::get_type_str(Log_event_type type), which returns a
string name for the given Log_event_type. This is just like the
existing char* Log_event::get_type_str(), except it is a class
method that takes the log event type as parameter.
I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(),
so that names of old rows event are properly printed.
- When reading an event, I added a check that the event type is known
by the current Format_description_log_event. Without this, it may
crash on bad input (and I was struck by this several times).
- I patched the following test cases, which all contain BINLOG
statements for row events which must be preceded by BINLOG
statements for FD events:
- rpl_bug31076
While I was here, I fixed some small things in log_event.cc:
- replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places
- replaced return by DBUG_VOID_RETURN in one place
- The name of the logfile can be '-' to indicate stdin. Before my
patch, the code just checked if the first character is '-'; now it
does a full strcmp(). Probably, all arguments that begin with a -
are already handled somewhere else as flags, but I still think it
is better that the code reflects what it is supposed to do, with as
little dependencies as possible on other parts of the code. If we
one day implement that all command line arguments after -- are
files (as most unix tools do), then we need this.
I also fixed the following in slave.cc:
- next_event() was declared twice, and queue_event was not static but
should be static (not used outside the file).
2007-12-14 19:02:02 +01:00
|
|
|
/**
|
|
|
|
@} (end of group Replication)
|
|
|
|
*/
|
|
|
|
|
2003-01-15 09:11:44 +01:00
|
|
|
#endif /* HAVE_REPLICATION */
|