Below is the list of changes that have just been committed into a local
5.1 repository of mkindahl. When mkindahl does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-07-11 12:17:19+02:00, mkindahl@stripped +31 -0
Merge dl145k.mysql.com:/data0/mkindahl/bkroot/mysql-5.1-new-rpl
into dl145k.mysql.com:/data0/mkindahl/bk/MERGE/mysql-5.1-merge
MERGE: 1.2226.6.16
include/my_sys.h@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -1
Auto merged
MERGE: 1.201.1.1
mysql-test/mysql-test-run.pl@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.128.1.4
mysql-test/r/rpl_row_create_table.result@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.5.1.1
mysql-test/t/disabled.def@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.170.1.2
mysql-test/t/rpl_row_create_table.test@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.5.1.1
mysys/my_malloc.c@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -1
Auto merged
MERGE: 1.10.1.1
mysys/safemalloc.c@stripped, 2006-07-11 11:34:09+02:00, mkindahl@stripped +2 -2
Merge of mysql-5.1-new-rpl into mysql-5.1
MERGE: 1.25.1.1
server-tools/instance-manager/parse.h@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -1
Auto merged
MERGE: 1.7.1.1
sql/ha_federated.cc@stripped, 2006-07-11 11:36:13+02:00, mkindahl@stripped +0 -2
d
Merge of mysql-5.1-new-rpl into mysql-5.1
MERGE: 1.62.1.2
sql/ha_ndbcluster.cc@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.336.2.3
sql/handler.h@stripped, 2006-07-11 11:33:06+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.222.1.2
sql/log.cc@stripped, 2006-07-11 11:33:07+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.218.1.2
sql/log_event.cc@stripped, 2006-07-11 11:33:07+02:00, mkindahl@stripped +0 -2
Auto merged
MERGE: 1.230.1.3
sql/mysql_priv.h@stripped, 2006-07-11 11:33:07+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.416.1.1
sql/set_var.cc@stripped, 2006-07-11 11:37:29+02:00, mkindahl@stripped +0 -3
Merge of mysql-5.1-new-rpl with mysql-5.1
MERGE: 1.178.1.3
sql/set_var.h@stripped, 2006-07-11 11:33:07+02:00, mkindahl@stripped +0 -1
Auto merged
MERGE: 1.89.1.1
sql/slave.cc@stripped, 2006-07-11 11:38:45+02:00, mkindahl@stripped +6 -9
Merge of mysql-5.1-new-rpl into mysql-5.1
MERGE: 1.275.1.3
sql/sp.cc@stripped, 2006-07-11 11:33:07+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.112.1.1
sql/sp_head.cc@stripped, 2006-07-11 11:33:07+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.225.1.1
sql/sp_head.h@stripped, 2006-07-11 11:33:08+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.87.1.1
sql/sql_base.cc@stripped, 2006-07-11 11:33:08+02:00, mkindahl@stripped +1 -1
Auto merged
MERGE: 1.332.1.5
sql/sql_class.cc@stripped, 2006-07-11 11:33:08+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.271.1.1
sql/sql_class.h@stripped, 2006-07-11 12:17:13+02:00, mkindahl@stripped +31 -35
Merge of mysql-5.1-new-rpl into mysql-5.1
MERGE: 1.304.1.1
sql/sql_insert.cc@stripped, 2006-07-11 11:33:08+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.207.1.7
sql/sql_lex.h@stripped, 2006-07-11 11:33:08+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.234.1.1
sql/sql_parse.cc@stripped, 2006-07-11 11:33:08+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.565.1.3
sql/sql_select.cc@stripped, 2006-07-11 11:33:09+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.418.1.1
sql/sql_table.cc@stripped, 2006-07-11 11:33:09+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.353.1.1
sql/sql_update.cc@stripped, 2006-07-11 11:33:09+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.197.1.1
sql/sql_view.cc@stripped, 2006-07-11 11:33:09+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.94.1.1
sql/sql_yacc.yy@stripped, 2006-07-11 11:33:10+02:00, mkindahl@stripped +0 -0
Auto merged
MERGE: 1.484.1.1
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mkindahl
# Host: dl145k.mysql.com
# Root: /data0/mkindahl/bk/MERGE/mysql-5.1-merge/RESYNC
--- 1.202/include/my_sys.h 2006-07-11 12:17:30 +02:00
+++ 1.203/include/my_sys.h 2006-07-11 12:17:30 +02:00
@@ -587,7 +587,7 @@
const char *sFile, uint uLine,myf MyFlag);
extern my_string _my_strdup(const char *from, const char *sFile, uint uLine,
myf MyFlag);
-extern char *_my_strndup(const byte *from, uint length,
+extern char *_my_strndup(const char *from, uint length,
const char *sFile, uint uLine,
myf MyFlag);
--- 1.26/mysys/safemalloc.c 2006-07-11 12:17:30 +02:00
+++ 1.27/mysys/safemalloc.c 2006-07-11 12:17:30 +02:00
@@ -525,8 +525,9 @@
} /* _my_strdup */
-char *_my_strndup(const char *from, uint length, const char *filename,
- uint lineno, myf MyFlags)
+char *_my_strndup(const char *from, uint length,
+ const char *filename, uint lineno,
+ myf MyFlags)
{
gptr ptr;
if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0)
--- 1.223/sql/handler.h 2006-07-11 12:17:30 +02:00
+++ 1.224/sql/handler.h 2006-07-11 12:17:30 +02:00
@@ -906,16 +906,37 @@
uint ref_length;
FT_INFO *ft_handler;
enum {NONE=0, INDEX, RND} inited;
- bool auto_increment_column_changed;
bool implicit_emptied; /* Can be !=0 only if HEAP */
const COND *pushed_cond;
+ /*
+ next_insert_id is the next value which should be inserted into the
+ auto_increment column: in a inserting-multi-row statement (like INSERT
+ SELECT), for the first row where the autoinc value is not specified by the
+ statement, get_auto_increment() called and asked to generate a value,
+ next_insert_id is set to the next value, then for all other rows
+ next_insert_id is used (and increased each time) without calling
+ get_auto_increment().
+ */
+ ulonglong next_insert_id;
+ /*
+ insert id for the current row (*autogenerated*; if not
+ autogenerated, it's 0).
+ At first successful insertion, this variable is stored into
+ THD::first_successful_insert_id_in_cur_stmt.
+ */
+ ulonglong insert_id_for_cur_row;
+ /*
+ Interval returned by get_auto_increment() and being consumed by the
+ inserter.
+ */
+ Discrete_interval auto_inc_interval_for_cur_row;
handler(const handlerton *ht_arg, TABLE_SHARE *share_arg)
:table_share(share_arg), estimation_rows_to_insert(0), ht(ht_arg),
ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE), implicit_emptied(0),
- pushed_cond(NULL)
+ pushed_cond(NULL), next_insert_id(0), insert_id_for_cur_row(0)
{}
virtual ~handler(void)
{
@@ -954,6 +975,7 @@
return TRUE;
}
int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
+ void adjust_next_insert_id_after_explicit_value(ulonglong nr);
bool update_auto_increment();
void print_keydup_error(uint key_nr, const char *msg);
virtual void print_error(int error, myf errflag);
@@ -1247,9 +1269,30 @@
ulonglong nb_desired_values,
ulonglong *first_value,
ulonglong *nb_reserved_values);
+private:
virtual void release_auto_increment() { return; };
- virtual void restore_auto_increment();
-
+public:
+ void ha_release_auto_increment();
+ void set_next_insert_id(ulonglong id)
+ {
+ DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
+ next_insert_id= id;
+ }
+ void restore_auto_increment(ulonglong prev_insert_id)
+ {
+ /*
+ Insertion of a row failed, re-use the lastly generated auto_increment
+ id, for the next row. This is achieved by resetting next_insert_id to
+ what it was before the failed insertion (that old value is provided by
+ the caller). If that value was 0, it was the first row of the INSERT;
+ then if insert_id_for_cur_row contains 0 it means no id was generated
+ for this first row, so no id was generated since the INSERT started, so
+ we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
+ is the generated id of the first and failed row, so we use it.
+ */
+ next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
+ insert_id_for_cur_row;
+ }
/*
Reset the auto-increment counter to the given value, i.e. the next row
inserted will get the given value. This is called e.g. after TRUNCATE
--- 1.219/sql/log.cc 2006-07-11 12:17:30 +02:00
+++ 1.220/sql/log.cc 2006-07-11 12:17:30 +02:00
@@ -432,16 +432,23 @@
table->field[6]->set_notnull();
}
- if (thd->last_insert_id_used)
+ if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
{
- table->field[7]->store((longlong) thd->current_insert_id, TRUE);
+ table->field[7]->store((longlong)
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog, TRUE);
table->field[7]->set_notnull();
}
- /* set value if we do an insert on autoincrement column */
- if (thd->insert_id_used)
+ /*
+ Set value if we do an insert on autoincrement column. Note that for
+ some engines (those for which get_auto_increment() does not leave a
+ table lock until the statement ends), this is just the first value and
+ the next ones used may not be contiguous to it.
+ */
+ if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
- table->field[8]->store((longlong) thd->last_insert_id, TRUE);
+ table->field[8]->store((longlong)
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(), TRUE);
table->field[8]->set_notnull();
}
@@ -731,7 +738,6 @@
Security_context *sctx= thd->security_ctx;
uint message_buff_len= 0, user_host_len= 0;
longlong query_time= 0, lock_time= 0;
- longlong last_insert_id= 0, insert_id= 0;
/*
Print the message to the buffer if we have slow log enabled
@@ -766,13 +772,6 @@
lock_time= (longlong) (thd->time_after_lock - query_start_arg);
}
- if (thd->last_insert_id_used)
- last_insert_id= (longlong) thd->current_insert_id;
-
- /* set value if we do an insert on autoincrement column */
- if (thd->insert_id_used)
- insert_id= (longlong) thd->last_insert_id;
-
if (!query)
{
is_command= TRUE;
@@ -1931,18 +1930,22 @@
tmp_errno= errno;
strmov(db,thd->db);
}
- if (thd->last_insert_id_used)
+ if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
{
end=strmov(end, ",last_insert_id=");
- end=longlong10_to_str((longlong) thd->current_insert_id, end, -10);
+ end=longlong10_to_str((longlong)
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog,
+ end, -10);
}
// Save value if we do an insert.
- if (thd->insert_id_used)
+ if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
{
end=strmov(end,",insert_id=");
- end=longlong10_to_str((longlong) thd->last_insert_id, end, -10);
+ end=longlong10_to_str((longlong)
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(),
+ end, -10);
}
}
@@ -3363,21 +3366,24 @@
{
if (!thd->current_stmt_binlog_row_based)
{
- if (thd->last_insert_id_used)
+ if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
{
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
- thd->current_insert_id);
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog);
if (e.write(file))
goto err;
}
- if (thd->insert_id_used)
+ if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
+ DBUG_PRINT("info",("number of auto_inc intervals: %lu",
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements()));
/*
If the auto_increment was second in a table's index (possible with
MyISAM or BDB) (table->next_number_key_offset != 0), such event is
in fact not necessary. We could avoid logging it.
*/
- Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
+ Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum());
if (e.write(file))
goto err;
}
@@ -3404,6 +3410,9 @@
}
}
}
+ /* Forget those values, for next binlogger: */
+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
}
/*
--- 1.233/sql/log_event.cc 2006-07-11 12:17:30 +02:00
+++ 1.234/sql/log_event.cc 2006-07-11 12:17:30 +02:00
@@ -1934,6 +1934,16 @@
thd->query_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
close_thread_tables(thd);
+ /*
+ As a disk space optimization, future masters will not log an event for
+ LAST_INSERT_ID() if that function returned 0 (and thus they will be able
+ to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
+ variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
+ resetting below we are ready to support that.
+ */
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
+ thd->first_successful_insert_id_in_prev_stmt= 0;
+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
/*
If there was an error we stop. Otherwise we increment positions. Note that
@@ -3425,11 +3435,11 @@
{
switch (type) {
case LAST_INSERT_ID_EVENT:
- thd->last_insert_id_used = 1;
- thd->last_insert_id = val;
+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
+ thd->first_successful_insert_id_in_prev_stmt= val;
break;
case INSERT_ID_EVENT:
- thd->next_insert_id = val;
+ thd->force_one_auto_inc_interval(val);
break;
}
rli->inc_event_relay_log_pos();
@@ -5353,10 +5363,10 @@
/*
lock_tables() reads the contents of thd->lex, so they must be
- initialized, so we should call lex_start(); to be even safer, we
- call mysql_init_query() which does a more complete set of inits.
+ initialized. Contrary to in Table_map_log_event::exec_event() we don't
+ call mysql_init_query() as that may reset the binlog format.
*/
- mysql_init_query(thd, NULL, 0);
+ lex_start(thd, NULL, 0);
while ((error= lock_tables(thd, rli->tables_to_lock,
rli->tables_to_lock_count, &need_reopen)))
@@ -5860,6 +5870,12 @@
else
{
/*
+ open_tables() reads the contents of thd->lex, so they must be
+ initialized, so we should call lex_start(); to be even safer, we
+ call mysql_init_query() which does a more complete set of inits.
+ */
+ mysql_init_query(thd, NULL, 0);
+ /*
Check if the slave is set to use SBR. If so, it should switch
to using RBR until the end of the "statement", i.e., next
STMT_END_F or next error.
@@ -5875,12 +5891,6 @@
Note that for any table that should not be replicated, a filter is needed.
*/
uint count;
- /*
- open_tables() reads the contents of thd->lex, so they must be
- initialized, so we should call lex_start(); to be even safer, we
- call mysql_init_query() which does a more complete set of inits.
- */
- mysql_init_query(thd, NULL, 0);
if ((error= open_tables(thd, &table_list, &count, 0)))
{
if (thd->query_error || thd->is_fatal_error)
--- 1.417/sql/mysql_priv.h 2006-07-11 12:17:30 +02:00
+++ 1.418/sql/mysql_priv.h 2006-07-11 12:17:30 +02:00
@@ -1972,6 +1972,17 @@
}
/*
+ is_user_table()
+ return true if the table was created explicitly
+*/
+
+inline bool is_user_table(TABLE * table)
+{
+ const char *name= table->s->table_name.str;
+ return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
+}
+
+/*
Some functions that are different in the embedded library and the normal
server
*/
--- 1.276/sql/slave.cc 2006-07-11 12:17:30 +02:00
+++ 1.277/sql/slave.cc 2006-07-11 12:17:30 +02:00
@@ -63,14 +63,14 @@
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool suppress_warnings);
+ bool suppress_warnings);
static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool reconnect, bool suppress_warnings);
+ bool reconnect, bool suppress_warnings);
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
- void* thread_killed_arg);
+ void* thread_killed_arg);
static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
- const char* table_name, bool overwrite);
+ const char* table_name, bool overwrite);
static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi);
/*
@@ -78,17 +78,17 @@
SYNOPSIS
init_thread_mask()
- mask Return value here
- mi master_info for slave
- inverse If set, returns which threads are not running
+ mask Return value here
+ mi master_info for slave
+ inverse If set, returns which threads are not running
IMPLEMENTATION
Get a bit mask for which threads are running so that we can later restart
these threads.
RETURN
- mask If inverse == 0, running threads
- If inverse == 1, stopped threads
+ mask If inverse == 0, running threads
+ If inverse == 1, stopped threads
*/
void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse)
@@ -168,7 +168,7 @@
}
if (init_master_info(active_mi,master_info_file,relay_log_info_file,
- !master_host, (SLAVE_IO | SLAVE_SQL)))
+ !master_host, (SLAVE_IO | SLAVE_SQL)))
{
sql_print_error("Failed to initialize the master info structure");
goto err;
@@ -182,11 +182,11 @@
if (master_host && !opt_skip_slave_start)
{
if (start_slave_threads(1 /* need mutex */,
- 0 /* no wait for start*/,
- active_mi,
- master_info_file,
- relay_log_info_file,
- SLAVE_IO | SLAVE_SQL))
+ 0 /* no wait for start*/,
+ active_mi,
+ master_info_file,
+ relay_log_info_file,
+ SLAVE_IO | SLAVE_SQL))
{
sql_print_error("Failed to create slave threads");
goto err;
@@ -206,12 +206,12 @@
SYNOPSIS
init_relay_log_pos()
- rli Relay information (will be initialized)
- log Name of relay log file to read from. NULL = First log
- pos Position in relay log file
- need_data_lock Set to 1 if this functions should do mutex locks
- errmsg Store pointer to error message here
- look_for_description_event
+ rli Relay information (will be initialized)
+ log Name of relay log file to read from. NULL = First log
+ pos Position in relay log file
+ need_data_lock Set to 1 if this functions should do mutex locks
+ errmsg Store pointer to error message here
+ look_for_description_event
1 if we should look for such an event. We only need
this when the SQL thread starts and opens an existing
relay log and has to execute it (possibly from an
@@ -229,13 +229,13 @@
- check proper initialization of group_master_log_name/group_master_log_pos
RETURN VALUES
- 0 ok
- 1 error. errmsg is set to point to the error message
+ 0 ok
+ 1 error. errmsg is set to point to the error message
*/
int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
- ulonglong pos, bool need_data_lock,
- const char** errmsg,
+ ulonglong pos, bool need_data_lock,
+ const char** errmsg,
bool look_for_description_event)
{
DBUG_ENTER("init_relay_log_pos");
@@ -243,7 +243,7 @@
*errmsg=0;
pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
-
+
if (need_data_lock)
pthread_mutex_lock(&rli->data_lock);
@@ -260,13 +260,13 @@
By default the relay log is in binlog format 3 (4.0).
Even if format is 4, this will work enough to read the first event
(Format_desc) (remember that format 4 is just lenghtened compared to format
- 3; format 3 is a prefix of format 4).
+ 3; format 3 is a prefix of format 4).
*/
rli->relay_log.description_event_for_exec= new
Format_description_log_event(3);
-
+
pthread_mutex_lock(log_lock);
-
+
/* Close log file and free buffers if it's already open */
if (rli->cur_log_fd >= 0)
{
@@ -274,7 +274,7 @@
my_close(rli->cur_log_fd, MYF(MY_WME));
rli->cur_log_fd = -1;
}
-
+
rli->group_relay_log_pos = rli->event_relay_log_pos = pos;
/*
@@ -293,9 +293,9 @@
goto err;
}
strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->group_relay_log_name)-1);
+ sizeof(rli->group_relay_log_name)-1);
strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->event_relay_log_name)-1);
+ sizeof(rli->event_relay_log_name)-1);
if (rli->relay_log.is_active(rli->linfo.log_file_name))
{
/*
@@ -314,7 +314,7 @@
Open the relay log and set rli->cur_log to point at this one
*/
if ((rli->cur_log_fd=open_binlog(&rli->cache_buf,
- rli->linfo.log_file_name,errmsg)) < 0)
+ rli->linfo.log_file_name,errmsg)) < 0)
goto err;
rli->cur_log = &rli->cache_buf;
}
@@ -325,7 +325,7 @@
if (pos > BIN_LOG_HEADER_SIZE) /* If pos<=4, we stay at 4 */
{
Log_event* ev;
- while (look_for_description_event)
+ while (look_for_description_event)
{
/*
Read the possible Format_description_log_event; if position
@@ -378,7 +378,7 @@
or Format_desc.
*/
}
- else
+ else
{
DBUG_PRINT("info",("found event of another type=%d",
ev->get_type_code()));
@@ -391,7 +391,7 @@
{
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
- llstr(my_b_tell(rli->cur_log),llbuf1),
+ llstr(my_b_tell(rli->cur_log),llbuf1),
llstr(rli->event_relay_log_pos,llbuf2)));
}
#endif
@@ -406,7 +406,7 @@
if (!relay_log_purge)
rli->log_space_limit= 0;
pthread_cond_broadcast(&rli->data_cond);
-
+
pthread_mutex_unlock(log_lock);
if (need_data_lock)
@@ -423,7 +423,7 @@
SYNOPSIS
init_slave_skip_errors()
- arg List of errors numbers to skip, separated with ','
+ arg List of errors numbers to skip, separated with ','
NOTES
Called from get_options() in mysqld.cc on start-up
@@ -462,7 +462,7 @@
void st_relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
- bool skip_lock)
+ bool skip_lock)
{
DBUG_ENTER("st_relay_log_info::inc_group_relay_log_pos");
@@ -471,10 +471,10 @@
inc_event_relay_log_pos();
group_relay_log_pos= event_relay_log_pos;
strmake(group_relay_log_name,event_relay_log_name,
- sizeof(group_relay_log_name)-1);
+ sizeof(group_relay_log_name)-1);
notify_group_relay_log_name_update();
-
+
/*
If the slave does not support transactions and replicates a transaction,
users should not trust group_master_log_pos (which they can display with
@@ -506,7 +506,7 @@
With the end_log_pos solution, we avoid computations involving lengthes.
*/
DBUG_PRINT("info", ("log_pos: %lu group_master_log_pos: %lu",
- (long) log_pos, (long) group_master_log_pos));
+ (long) log_pos, (long) group_master_log_pos));
if (log_pos) // 3.23 binlogs don't have log_posx
{
group_master_log_pos= log_pos;
@@ -546,7 +546,7 @@
*/
int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
- const char** errmsg)
+ const char** errmsg)
{
int error=0;
DBUG_ENTER("purge_relay_logs");
@@ -584,10 +584,10 @@
rli->slave_skip_counter=0;
pthread_mutex_lock(&rli->data_lock);
- /*
- we close the relay log fd possibly left open by the slave SQL thread,
+ /*
+ we close the relay log fd possibly left open by the slave SQL thread,
to be able to delete it; the relay log fd possibly left open by the slave
- I/O thread will be closed naturally in reset_logs() by the
+ I/O thread will be closed naturally in reset_logs() by the
close(LOG_CLOSE_TO_BE_OPENED) call
*/
if (rli->cur_log_fd >= 0)
@@ -605,9 +605,9 @@
}
/* Save name of used relay log file */
strmake(rli->group_relay_log_name, rli->relay_log.get_log_fname(),
- sizeof(rli->group_relay_log_name)-1);
+ sizeof(rli->group_relay_log_name)-1);
strmake(rli->event_relay_log_name, rli->relay_log.get_log_fname(),
- sizeof(rli->event_relay_log_name)-1);
+ sizeof(rli->event_relay_log_name)-1);
rli->group_relay_log_pos= rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
if (count_relay_log_space(rli))
{
@@ -617,12 +617,12 @@
if (!just_reset)
error= init_relay_log_pos(rli, rli->group_relay_log_name,
rli->group_relay_log_pos,
- 0 /* do not need data lock */, errmsg, 0);
-
+ 0 /* do not need data lock */, errmsg, 0);
+
err:
#ifndef DBUG_OFF
char buf[22];
-#endif
+#endif
DBUG_PRINT("info",("log_space_total: %s",llstr(rli->log_space_total,buf)));
pthread_mutex_unlock(&rli->data_lock);
DBUG_RETURN(error);
@@ -641,7 +641,7 @@
sql_cond_lock=sql_lock;
io_cond_lock=io_lock;
-
+
if (skip_lock)
{
sql_lock = io_lock = 0;
@@ -651,10 +651,10 @@
DBUG_PRINT("info",("Terminating IO thread"));
mi->abort_slave=1;
if ((error=terminate_slave_thread(mi->io_thd,io_lock,
- io_cond_lock,
- &mi->stop_cond,
- &mi->slave_running)) &&
- !force_all)
+ io_cond_lock,
+ &mi->stop_cond,
+ &mi->slave_running)) &&
+ !force_all)
DBUG_RETURN(error);
}
if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running)
@@ -663,10 +663,10 @@
DBUG_ASSERT(mi->rli.sql_thd != 0) ;
mi->rli.abort_slave=1;
if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock,
- sql_cond_lock,
- &mi->rli.stop_cond,
- &mi->rli.slave_running)) &&
- !force_all)
+ sql_cond_lock,
+ &mi->rli.stop_cond,
+ &mi->rli.slave_running)) &&
+ !force_all)
DBUG_RETURN(error);
}
DBUG_RETURN(0);
@@ -674,9 +674,9 @@
int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
- pthread_mutex_t *cond_lock,
- pthread_cond_t* term_cond,
- volatile uint *slave_running)
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t* term_cond,
+ volatile uint *slave_running)
{
DBUG_ENTER("terminate_slave_thread");
if (term_lock)
@@ -695,7 +695,7 @@
be referening freed memory trying to kick it
*/
- while (*slave_running) // Should always be true
+ while (*slave_running) // Should always be true
{
DBUG_PRINT("loop", ("killing slave thread"));
KICK_SLAVE(thd);
@@ -714,11 +714,11 @@
int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
- pthread_mutex_t *cond_lock,
- pthread_cond_t *start_cond,
- volatile uint *slave_running,
- volatile ulong *slave_run_id,
- MASTER_INFO* mi,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t *start_cond,
+ volatile uint *slave_running,
+ volatile ulong *slave_run_id,
+ MASTER_INFO* mi,
bool high_priority)
{
pthread_t th;
@@ -738,7 +738,7 @@
sql_print_error("Server id not set, will not start slave");
DBUG_RETURN(ER_BAD_SLAVE);
}
-
+
if (*slave_running)
{
if (start_cond)
@@ -764,12 +764,12 @@
{
DBUG_PRINT("sleep",("Waiting for slave thread to start"));
const char* old_msg = thd->enter_cond(start_cond,cond_lock,
- "Waiting for slave thread to start");
+ "Waiting for slave thread to start");
pthread_cond_wait(start_cond,cond_lock);
thd->exit_cond(old_msg);
pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
if (thd->killed)
- DBUG_RETURN(thd->killed_errno());
+ DBUG_RETURN(thd->killed_errno());
}
}
if (start_lock)
@@ -788,14 +788,14 @@
*/
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
- MASTER_INFO* mi, const char* master_info_fname,
- const char* slave_info_fname, int thread_mask)
+ MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname, int thread_mask)
{
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;
DBUG_ENTER("start_slave_threads");
-
+
if (need_slave_mutex)
{
lock_io = &mi->run_lock;
@@ -811,15 +811,15 @@
if (thread_mask & SLAVE_IO)
error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
- cond_io,
- &mi->slave_running, &mi->slave_run_id,
- mi, 1); //high priority, to read the most possible
+ cond_io,
+ &mi->slave_running, &mi->slave_run_id,
+ mi, 1); //high priority, to read the most possible
if (!error && (thread_mask & SLAVE_SQL))
{
error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
- cond_sql,
- &mi->rli.slave_running, &mi->rli.slave_run_id,
- mi, 0);
+ cond_sql,
+ &mi->rli.slave_running, &mi->rli.slave_run_id,
+ mi, 0);
if (error)
terminate_slave_threads(mi, thread_mask & SLAVE_IO, 0);
}
@@ -997,8 +997,8 @@
DBUG_ENTER("skip_load_data_infile");
(void)net_request_file(net, "/dev/null");
- (void)my_net_read(net); // discard response
- (void)net_write_command(net, 0, "", 0, "", 0); // Send ok
+ (void)my_net_read(net); // discard response
+ (void)net_write_command(net, 0, "", 0, "", 0); // Send ok
DBUG_VOID_RETURN;
}
@@ -1024,7 +1024,7 @@
}
static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val)
+ const char *default_val)
{
uint length;
DBUG_ENTER("init_strvar_from_file");
@@ -1037,8 +1037,8 @@
else
{
/*
- If we truncated a line or stopped on last char, remove all chars
- up to and including newline.
+ If we truncated a line or stopped on last char, remove all chars
+ up to and including newline.
*/
int c;
while (((c=my_b_get(f)) != '\n' && c != my_b_EOF));
@@ -1059,8 +1059,8 @@
char buf[32];
DBUG_ENTER("init_intvar_from_file");
-
- if (my_b_gets(f, buf, sizeof(buf)))
+
+ if (my_b_gets(f, buf, sizeof(buf)))
{
*var = atoi(buf);
DBUG_RETURN(0);
@@ -1081,7 +1081,7 @@
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).
-
+
RETURNS
0 ok
1 error
@@ -1098,7 +1098,7 @@
*/
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= 0;
-
+
if (!my_isdigit(&my_charset_bin,*mysql->server_version))
errmsg = "Master reported unrecognized MySQL version";
else
@@ -1106,7 +1106,7 @@
/*
Note the following switch will bug when we have MySQL branch 30 ;)
*/
- switch (*mysql->server_version)
+ switch (*mysql->server_version)
{
case '0':
case '1':
@@ -1115,13 +1115,13 @@
break;
case '3':
mi->rli.relay_log.description_event_for_queue= new
- Format_description_log_event(1, mysql->server_version);
+ Format_description_log_event(1, mysql->server_version);
break;
case '4':
mi->rli.relay_log.description_event_for_queue= new
- Format_description_log_event(3, mysql->server_version);
+ Format_description_log_event(3, mysql->server_version);
break;
- default:
+ default:
/*
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
@@ -1131,18 +1131,18 @@
master is 3.23, 4.0, etc.
*/
mi->rli.relay_log.description_event_for_queue= new
- Format_description_log_event(4, mysql->server_version);
+ Format_description_log_event(4, mysql->server_version);
break;
}
}
-
- /*
+
+ /*
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.
*/
-
+
if (errmsg)
{
sql_print_error(errmsg);
@@ -1162,12 +1162,12 @@
*/
MYSQL_RES *master_res= 0;
MYSQL_ROW master_row;
-
+
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
(master_res= mysql_store_result(mysql)) &&
(master_row= mysql_fetch_row(master_res)))
{
- mi->clock_diff_with_master=
+ mi->clock_diff_with_master=
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
}
else
@@ -1177,8 +1177,8 @@
do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS");
}
if (master_res)
- mysql_free_result(master_res);
-
+ mysql_free_result(master_res);
+
/*
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,
@@ -1245,9 +1245,9 @@
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
- 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
+ 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
'SYSTEM' time zone).
This check is only necessary for 4.x masters (and < 5.0.4 masters but
those were alpha).
@@ -1257,7 +1257,7 @@
(master_res= mysql_store_result(mysql)))
{
if ((master_row= mysql_fetch_row(master_res)) &&
- strcmp(master_row[0],
+ strcmp(master_row[0],
global_system_variables.time_zone->get_name()->ptr()))
errmsg= "The slave I/O thread stops because master and slave have \
different values for the TIME_ZONE global variable. The values must \
@@ -1287,7 +1287,7 @@
*/
static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
- const char* table_name, bool overwrite)
+ const char* table_name, bool overwrite)
{
ulong packet_len;
char *query, *save_db;
@@ -1309,10 +1309,10 @@
}
if (net->read_pos[0] == 255) // error from master
{
- char *err_msg;
+ char *err_msg;
err_msg= (char*) net->read_pos + ((mysql->server_capabilities &
- CLIENT_PROTOCOL_41) ?
- 3+SQLSTATE_LENGTH+1 : 3);
+ CLIENT_PROTOCOL_41) ?
+ 3+SQLSTATE_LENGTH+1 : 3);
my_error(ER_MASTER, MYF(0), err_msg);
DBUG_RETURN(1);
}
@@ -1347,15 +1347,16 @@
// save old db in case we are creating in a different database
save_db = thd->db;
save_db_length= thd->db_length;
- DBUG_ASSERT(db != 0);
- thd->reset_db((char*)db, strlen(db));
+ thd->db = (char*)db;
+ DBUG_ASSERT(thd->db != 0);
+ thd->db_length= strlen(thd->db);
mysql_parse(thd, thd->query, packet_len); // run create table
- thd->db = save_db; // leave things the way the were before
+ thd->db = save_db; // leave things the way the were before
thd->db_length= save_db_length;
thd->options = save_options;
-
+
if (thd->query_error)
- goto err; // mysql_parse took care of the error send
+ goto err; // mysql_parse took care of the error send
thd->proc_info = "Opening master dump table";
tables.lock_type = TL_WRITE;
@@ -1364,7 +1365,7 @@
sql_print_error("create_table_from_dump: could not open created table");
goto err;
}
-
+
file = tables.table->file;
thd->proc_info = "Reading master dump table data";
/* Copy the data file */
@@ -1395,22 +1396,22 @@
err:
close_thread_tables(thd);
thd->net.no_send_ok = 0;
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
- MASTER_INFO *mi, MYSQL *mysql, bool overwrite)
+ MASTER_INFO *mi, MYSQL *mysql, bool overwrite)
{
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'",
- db_name,table_name));
+ db_name,table_name));
if (!called_connected)
- {
+ {
if (!(mysql = mysql_init(NULL)))
{
DBUG_RETURN(1);
@@ -1441,7 +1442,7 @@
goto err;
}
if (create_table_from_dump(thd, mysql, db_name,
- table_name, overwrite))
+ table_name, overwrite))
goto err; // create_table_from_dump have sent the error already
error = 0;
@@ -1451,7 +1452,7 @@
mysql_close(mysql);
if (errmsg && thd->vio_ok())
my_message(error, errmsg, MYF(0));
- DBUG_RETURN(test(error)); // Return 1 on error
+ DBUG_RETURN(test(error)); // Return 1 on error
}
@@ -1567,44 +1568,44 @@
goto err;
}
if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
+ MYF(MY_WME)))
{
sql_print_error("Failed to create a cache on relay log info file '%s'",
- fname);
+ fname);
msg= current_thd->net.last_error;
goto err;
}
/* Init relay log with first entry in the relay index file */
if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
- &msg, 0))
+ &msg, 0))
{
sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
goto err;
}
rli->group_master_log_name[0]= 0;
- rli->group_master_log_pos= 0;
+ rli->group_master_log_pos= 0;
rli->info_fd= info_fd;
}
else // file exists
{
if (info_fd >= 0)
reinit_io_cache(&rli->info_file, READ_CACHE, 0L,0,0);
- else
+ else
{
int error=0;
if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
{
sql_print_error("\
Failed to open the existing relay log info file '%s' (errno %d)",
- fname, my_errno);
+ fname, my_errno);
error= 1;
}
else if (init_io_cache(&rli->info_file, info_fd,
IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME)))
{
sql_print_error("Failed to create a cache on relay log info file '%s'",
- fname);
+ fname);
error= 1;
}
if (error)
@@ -1617,16 +1618,16 @@
DBUG_RETURN(1);
}
}
-
+
rli->info_fd = info_fd;
int relay_log_pos, master_log_pos;
if (init_strvar_from_file(rli->group_relay_log_name,
- sizeof(rli->group_relay_log_name),
+ sizeof(rli->group_relay_log_name),
&rli->info_file, "") ||
init_intvar_from_file(&relay_log_pos,
- &rli->info_file, BIN_LOG_HEADER_SIZE) ||
+ &rli->info_file, BIN_LOG_HEADER_SIZE) ||
init_strvar_from_file(rli->group_master_log_name,
- sizeof(rli->group_master_log_name),
+ sizeof(rli->group_master_log_name),
&rli->info_file, "") ||
init_intvar_from_file(&master_log_pos, &rli->info_file, 0))
{
@@ -1639,15 +1640,15 @@
rli->group_master_log_pos= master_log_pos;
if (init_relay_log_pos(rli,
- rli->group_relay_log_name,
- rli->group_relay_log_pos,
- 0 /* no data lock*/,
- &msg, 0))
+ rli->group_relay_log_name,
+ rli->group_relay_log_pos,
+ 0 /* no data lock*/,
+ &msg, 0))
{
char llbuf[22];
sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)",
- rli->group_relay_log_name,
- llstr(rli->group_relay_log_pos, llbuf));
+ rli->group_relay_log_name,
+ llstr(rli->group_relay_log_pos, llbuf));
goto err;
}
}
@@ -1656,7 +1657,7 @@
{
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
- llstr(my_b_tell(rli->cur_log),llbuf1),
+ llstr(my_b_tell(rli->cur_log),llbuf1),
llstr(rli->event_relay_log_pos,llbuf2)));
DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->event_relay_log_pos);
@@ -1698,14 +1699,14 @@
if (!my_stat(linfo->log_file_name,&s,MYF(0)))
{
sql_print_error("log %s listed in the index, but failed to stat",
- linfo->log_file_name);
+ linfo->log_file_name);
DBUG_RETURN(1);
}
rli->log_space_total += s.st_size;
#ifndef DBUG_OFF
char buf[22];
DBUG_PRINT("info",("log_space_total: %s", llstr(rli->log_space_total,buf)));
-#endif
+#endif
DBUG_RETURN(0);
}
@@ -1720,11 +1721,11 @@
pthread_mutex_lock(&rli->log_space_lock);
save_proc_info= thd->enter_cond(&rli->log_space_cond,
- &rli->log_space_lock,
- "\
+ &rli->log_space_lock,
+ "\
Waiting for the slave SQL thread to free enough relay log space");
while (rli->log_space_limit < rli->log_space_total &&
- !(slave_killed=io_slave_killed(thd,mi)) &&
+ !(slave_killed=io_slave_killed(thd,mi)) &&
!rli->ignore_log_space_limit)
pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
thd->exit_cond(save_proc_info);
@@ -1747,9 +1748,9 @@
if (add_relay_log(rli,&linfo))
DBUG_RETURN(1);
} while (!rli->relay_log.find_next_log(&linfo, 1));
- /*
+ /*
As we have counted everything, including what may have written in a
- preceding write, we must reset bytes_written, or we may count some space
+ preceding write, we must reset bytes_written, or we may count some space
twice.
*/
rli->relay_log.reset_bytes_written();
@@ -1815,8 +1816,8 @@
DBUG_ENTER("init_master_info_with_options");
mi->master_log_name[0] = 0;
- mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
-
+ mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
+
if (master_host)
strmake(mi->host, master_host, sizeof(mi->host) - 1);
if (master_user)
@@ -1825,7 +1826,7 @@
strmake(mi->password, master_password, MAX_PASSWORD_LENGTH);
mi->port = master_port;
mi->connect_retry = master_connect_retry;
-
+
mi->ssl= master_ssl;
if (master_ssl_ca)
strmake(mi->ssl_ca, master_ssl_ca, sizeof(mi->ssl_ca)-1);
@@ -1934,7 +1935,7 @@
goto err;
}
if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
+ MYF(MY_WME)))
{
sql_print_error("Failed to create a cache on master info file (\
file '%s')", fname);
@@ -1994,8 +1995,8 @@
overwritten by the second row later.
*/
if (init_strvar_from_file(mi->master_log_name,
- sizeof(mi->master_log_name), &mi->file,
- ""))
+ sizeof(mi->master_log_name), &mi->file,
+ ""))
goto errwithmsg;
lines= strtoul(mi->master_log_name, &first_non_digit, 10);
@@ -2011,15 +2012,15 @@
lines= 7;
if (init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
- init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
- master_host) ||
- init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
- master_user) ||
+ init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
+ master_host) ||
+ init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
+ master_user) ||
init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1,
&mi->file, master_password) ||
- init_intvar_from_file(&port, &mi->file, master_port) ||
- init_intvar_from_file(&connect_retry, &mi->file,
- master_connect_retry))
+ init_intvar_from_file(&port, &mi->file, master_port) ||
+ init_intvar_from_file(&connect_retry, &mi->file,
+ master_connect_retry))
goto errwithmsg;
/*
@@ -2058,8 +2059,8 @@
mi->ssl= (my_bool) ssl;
}
DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
- mi->master_log_name,
- (ulong) mi->master_log_pos));
+ mi->master_log_name,
+ (ulong) mi->master_log_pos));
mi->rli.mi = mi;
if (init_relay_log_info(&mi->rli, slave_info_fname))
@@ -2104,23 +2105,23 @@
/* 30 is a good safety margin */
if (report_host_len + report_user_len + report_password_len + 30 >
sizeof(buf))
- DBUG_RETURN(0); // safety
+ DBUG_RETURN(0); // safety
int4store(pos, server_id); pos+= 4;
- pos= net_store_data(pos, report_host, report_host_len);
+ pos= net_store_data(pos, report_host, report_host_len);
pos= net_store_data(pos, report_user, report_user_len);
pos= net_store_data(pos, report_password, report_password_len);
int2store(pos, (uint16) report_port); pos+= 2;
- int4store(pos, rpl_recovery_rank); pos+= 4;
+ int4store(pos, rpl_recovery_rank); pos+= 4;
/* The master will fill in master_id */
- int4store(pos, 0); pos+= 4;
+ int4store(pos, 0); pos+= 4;
if (simple_command(mysql, COM_REGISTER_SLAVE, (char*) buf,
- (uint) (pos- buf), 0))
+ (uint) (pos- buf), 0))
{
sql_print_error("Error on COM_REGISTER_SLAVE: %d '%s'",
- mysql_errno(mysql),
- mysql_error(mysql));
+ mysql_errno(mysql),
+ mysql_error(mysql));
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@@ -2135,25 +2136,25 @@
DBUG_ENTER("show_master_info");
field_list.push_back(new Item_empty_string("Slave_IO_State",
- 14));
+ 14));
field_list.push_back(new Item_empty_string("Master_Host",
- sizeof(mi->host)));
+ sizeof(mi->host)));
field_list.push_back(new Item_empty_string("Master_User",
- sizeof(mi->user)));
+ sizeof(mi->user)));
field_list.push_back(new Item_return_int("Master_Port", 7,
- MYSQL_TYPE_LONG));
+ MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("Connect_Retry", 10,
- MYSQL_TYPE_LONG));
+ MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Master_Log_File",
- FN_REFLEN));
+ FN_REFLEN));
field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
- MYSQL_TYPE_LONGLONG));
+ MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Relay_Log_File",
- FN_REFLEN));
+ FN_REFLEN));
field_list.push_back(new Item_return_int("Relay_Log_Pos", 10,
- MYSQL_TYPE_LONGLONG));
+ MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
- FN_REFLEN));
+ FN_REFLEN));
field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20));
@@ -2162,33 +2163,33 @@
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",
- 28));
+ 28));
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,
- MYSQL_TYPE_LONG));
+ MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10,
- MYSQL_TYPE_LONGLONG));
+ MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_return_int("Relay_Log_Space", 10,
- MYSQL_TYPE_LONGLONG));
+ MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Until_Condition", 6));
field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
- field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
+ field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
MYSQL_TYPE_LONGLONG));
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)));
- field_list.push_back(new Item_empty_string("Master_SSL_CA_Path",
+ field_list.push_back(new Item_empty_string("Master_SSL_CA_Path",
sizeof(mi->ssl_capath)));
- field_list.push_back(new Item_empty_string("Master_SSL_Cert",
+ field_list.push_back(new Item_empty_string("Master_SSL_Cert",
sizeof(mi->ssl_cert)));
- field_list.push_back(new Item_empty_string("Master_SSL_Cipher",
+ field_list.push_back(new Item_empty_string("Master_SSL_Cipher",
sizeof(mi->ssl_cipher)));
- field_list.push_back(new Item_empty_string("Master_SSL_Key",
+ field_list.push_back(new Item_empty_string("Master_SSL_Key",
sizeof(mi->ssl_key)));
field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10,
MYSQL_TYPE_LONGLONG));
-
+
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
@@ -2198,7 +2199,7 @@
DBUG_PRINT("info",("host is set: '%s'", mi->host));
String *packet= &thd->packet;
protocol->prepare_for_resend();
-
+
/*
TODO: we read slave_running without run_lock, whereas these variables
are updated under run_lock and not data_lock. In 5.0 we should lock
@@ -2215,8 +2216,8 @@
protocol->store(mi->master_log_name, &my_charset_bin);
protocol->store((ulonglong) mi->master_log_pos);
protocol->store(mi->rli.group_relay_log_name +
- dirname_length(mi->rli.group_relay_log_name),
- &my_charset_bin);
+ dirname_length(mi->rli.group_relay_log_name),
+ &my_charset_bin);
protocol->store((ulonglong) mi->rli.group_relay_log_pos);
protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
@@ -2243,13 +2244,13 @@
protocol->store((ulonglong) mi->rli.log_space_total);
protocol->store(
- mi->rli.until_condition==RELAY_LOG_INFO::UNTIL_NONE ? "None":
+ mi->rli.until_condition==RELAY_LOG_INFO::UNTIL_NONE ? "None":
( mi->rli.until_condition==RELAY_LOG_INFO::UNTIL_MASTER_POS? "Master":
"Relay"), &my_charset_bin);
protocol->store(mi->rli.until_log_name, &my_charset_bin);
protocol->store((ulonglong) mi->rli.until_log_pos);
-
-#ifdef HAVE_OPENSSL
+
+#ifdef HAVE_OPENSSL
protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
#else
protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
@@ -2354,10 +2355,10 @@
my_b_seek(file, 0L);
my_b_printf(file, "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n",
- LINES_IN_MASTER_INFO_WITH_SSL,
+ LINES_IN_MASTER_INFO_WITH_SSL,
mi->master_log_name, llstr(mi->master_log_pos, lbuf),
- mi->host, mi->user,
- mi->password, mi->port, mi->connect_retry,
+ mi->host, mi->user,
+ mi->password, mi->port, mi->connect_retry,
(int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
mi->ssl_cipher, mi->ssl_key);
DBUG_RETURN(-flush_io_cache(file));
@@ -2418,7 +2419,7 @@
wait_for_pos()
thd client thread that sent SELECT MASTER_POS_WAIT
log_name log name to wait for
- log_pos position to wait for
+ log_pos position to wait for
timeout timeout in seconds before giving up waiting
NOTES
@@ -2457,7 +2458,7 @@
msg= thd->enter_cond(&data_cond, &data_lock,
"Waiting for the slave SQL thread to "
"advance position");
- /*
+ /*
This function will abort when it notices that some CHANGE MASTER or
RESET MASTER has changed the master info.
To catch this, these commands modify abort_pos_wait ; We just monitor
@@ -2503,7 +2504,7 @@
{
error= -2;
goto err;
- }
+ }
/* The "compare and wait" main loop */
while (!thd->killed &&
@@ -2563,7 +2564,7 @@
}
//wait for master update, with optional timeout.
-
+
DBUG_PRINT("info",("Waiting for master update"));
/*
We are going to pthread_cond_(timed)wait(); if the SQL thread stops it
@@ -2573,7 +2574,7 @@
{
/*
Note that pthread_cond_timedwait checks for the timeout
- before for the condition ; i.e. it returns ETIMEDOUT
+ before for the condition ; i.e. it returns ETIMEDOUT
if the system time equals or exceeds the time specified by abstime
before the condition variable is signaled or broadcast, _or_ if
the absolute time specified by abstime has already passed at the time
@@ -2607,7 +2608,7 @@
(int) (error == -2),
(int) (error == -1)));
if (thd->killed || init_abort_pos_wait != abort_pos_wait ||
- !slave_running)
+ !slave_running)
{
error= -2;
}
@@ -2647,13 +2648,13 @@
{
DBUG_ENTER("init_slave_thread");
thd->system_thread = (thd_type == SLAVE_THD_SQL) ?
- SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
+ SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
thd->security_ctx->skip_grants();
my_net_init(&thd->net, 0);
thd->net.read_timeout = slave_net_timeout;
thd->slave_thread = 1;
set_slave_thread_options(thd);
- /*
+ /*
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
@@ -2679,7 +2680,7 @@
#if !defined(__WIN__) && !defined(__NETWARE__)
sigset_t set;
- VOID(sigemptyset(&set)); // Get mask in use
+ VOID(sigemptyset(&set)); // Get mask in use
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
@@ -2694,7 +2695,7 @@
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
- void* thread_killed_arg)
+ void* thread_killed_arg)
{
int nap_time;
thr_alarm_t alarmed;
@@ -2715,7 +2716,7 @@
thr_alarm(&alarmed, 2 * nap_time, &alarm_buff);
sleep(nap_time);
thr_end_alarm(&alarmed);
-
+
if ((*thread_killed)(thd,thread_killed_arg))
DBUG_RETURN(1);
start_time=time((time_t*) 0);
@@ -2725,7 +2726,7 @@
static int request_dump(MYSQL* mysql, MASTER_INFO* mi,
- bool *suppress_warnings)
+ bool *suppress_warnings)
{
char buf[FN_REFLEN + 10];
int len;
@@ -2747,11 +2748,11 @@
now we just fill up the error log :-)
*/
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
- *suppress_warnings= 1; // Suppress reconnect warning
+ *suppress_warnings= 1; // Suppress reconnect warning
else
sql_print_error("Error on COM_BINLOG_DUMP: %d %s, will retry in %d secs",
- mysql_errno(mysql), mysql_error(mysql),
- master_connect_retry);
+ mysql_errno(mysql), mysql_error(mysql),
+ master_connect_retry);
DBUG_RETURN(1);
}
@@ -2771,14 +2772,14 @@
{
sql_print_error("request_table_dump: Buffer overrun");
DBUG_RETURN(1);
- }
-
+ }
+
*p++ = db_len;
memcpy(p, db, db_len);
p += db_len;
*p++ = table_len;
memcpy(p, table, table_len);
-
+
if (simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
{
sql_print_error("request_table_dump: Error sending the table dump \
@@ -2792,19 +2793,19 @@
/*
Read one event from the master
-
+
SYNOPSIS
read_event()
- 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.
+ 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.
RETURN VALUES
- 'packet_error' Error
- number Length of packet
+ 'packet_error' Error
+ number Length of packet
*/
static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
@@ -2819,24 +2820,24 @@
*/
#ifndef DBUG_OFF
if (disconnect_slave_event_count && !(mi->events_till_disconnect--))
- DBUG_RETURN(packet_error);
+ DBUG_RETURN(packet_error);
#endif
-
+
len = net_safe_read(mysql);
if (len == packet_error || (long) len < 1)
{
if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
{
/*
- We are trying a normal reconnect after a read timeout;
- we suppress prints to .err file as long as the reconnect
- happens without problems
+ We are trying a normal reconnect after a read timeout;
+ we suppress prints to .err file as long as the reconnect
+ happens without problems
*/
*suppress_warnings= TRUE;
}
else
sql_print_error("Error reading packet from server: %s ( server_errno=%d)",
- mysql_error(mysql), mysql_errno(mysql));
+ mysql_error(mysql), mysql_errno(mysql));
DBUG_RETURN(packet_error);
}
@@ -2845,13 +2846,13 @@
{
sql_print_information("Slave: received end packet from server, apparent "
"master shutdown: %s",
- mysql_error(mysql));
+ mysql_error(mysql));
DBUG_RETURN(packet_error);
}
-
+
DBUG_PRINT("info",( "len=%u, net->read_pos[4] = %d\n",
- len, mysql->net.read_pos[4]));
- DBUG_RETURN(len - 1);
+ len, mysql->net.read_pos[4]));
+ DBUG_RETURN(len - 1);
}
@@ -2861,8 +2862,8 @@
switch (expected_error) {
case ER_NET_READ_ERROR:
- case ER_NET_ERROR_ON_WRITE:
- case ER_SERVER_SHUTDOWN:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
case ER_NEW_ABORTING_CONNECTION:
DBUG_RETURN(1);
default:
@@ -2875,25 +2876,25 @@
SYNOPSYS
st_relay_log_info::is_until_satisfied()
DESCRIPTION
- Checks if UNTIL condition is reached. Uses caching result of last
- comparison of current log file name and target log file name. So cached
- value should be invalidated if current log file name changes
+ Checks if UNTIL condition is reached. Uses caching result of last
+ comparison of current log file name and target log file name. So cached
+ value should be invalidated if current log file name changes
(see st_relay_log_info::notify_... functions).
-
- This caching is needed to avoid of expensive string comparisons and
+
+ This caching is needed to avoid of expensive string comparisons and
strtol() conversions needed for log names comparison. We don't need to
- compare them each time this function is called, we only need to do this
- when current log name changes. If we have UNTIL_MASTER_POS condition we
- need to do this only after Rotate_log_event::exec_event() (which is
- rare, so caching gives real benifit), and if we have UNTIL_RELAY_POS
- condition then we should invalidate cached comarison value after
+ compare them each time this function is called, we only need to do this
+ when current log name changes. If we have UNTIL_MASTER_POS condition we
+ need to do this only after Rotate_log_event::exec_event() (which is
+ rare, so caching gives real benifit), and if we have UNTIL_RELAY_POS
+ condition then we should invalidate cached comarison value after
inc_group_relay_log_pos() which called for each group of events (so we
- have some benefit if we have something like queries that use
+ have some benefit if we have something like queries that use
autoincrement or if we have transactions).
-
+
Should be called ONLY if until_condition != UNTIL_NONE !
RETURN VALUE
- true - condition met or error happened (condition seems to have
+ true - condition met or error happened (condition seems to have
bad log file name)
false - condition not met
*/
@@ -2905,7 +2906,7 @@
DBUG_ENTER("st_relay_log_info::is_until_satisfied");
DBUG_ASSERT(until_condition != UNTIL_NONE);
-
+
if (until_condition == UNTIL_MASTER_POS)
{
log_name= group_master_log_name;
@@ -2916,7 +2917,7 @@
log_name= group_relay_log_name;
log_pos= group_relay_log_pos;
}
-
+
if (until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_UNKNOWN)
{
/*
@@ -2930,7 +2931,7 @@
if (*log_name)
{
const char *basename= log_name + dirname_length(log_name);
-
+
const char *q= (const char*)(fn_ext(basename)+1);
if (strncmp(basename, until_log_name, (int)(q-basename)) == 0)
{
@@ -2940,11 +2941,11 @@
if (log_name_extension < until_log_name_extension)
until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_LESS;
else
- until_log_names_cmp_result=
- (log_name_extension > until_log_name_extension) ?
+ until_log_names_cmp_result=
+ (log_name_extension > until_log_name_extension) ?
UNTIL_LOG_NAMES_CMP_GREATER : UNTIL_LOG_NAMES_CMP_EQUAL ;
}
- else
+ else
{
/* Probably error so we aborting */
sql_print_error("Slave SQL thread is stopped because UNTIL "
@@ -2955,8 +2956,8 @@
else
DBUG_RETURN(until_log_pos == 0);
}
-
- DBUG_RETURN(((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL &&
+
+ DBUG_RETURN(((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL &&
log_pos >= until_log_pos) ||
until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
}
@@ -3142,7 +3143,7 @@
pthread_mutex_unlock(&rli->data_lock);
thd->server_id = ev->server_id; // use the original server id for logging
- thd->set_time(); // time the query
+ thd->set_time(); // time the query
thd->lex->current_select= 0;
if (!ev->when)
ev->when = time(NULL);
@@ -3191,16 +3192,16 @@
{
exec_res= 0;
end_trans(thd, ROLLBACK);
- /* chance for concurrent connection to get more locks */
+ /* chance for concurrent connection to get more locks */
safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
- (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
- rli->trans_retries++;
+ rli->trans_retries++;
rli->retried_trans++;
pthread_mutex_unlock(&rli->data_lock);
DBUG_PRINT("info", ("Slave retries transaction "
"rli->trans_retries: %lu", rli->trans_retries));
- }
+ }
}
else
sql_print_error("Slave SQL thread retried transaction %lu time(s) "
@@ -3284,8 +3285,8 @@
pthread_cond_broadcast(&mi->start_cond);
DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
- mi->master_log_name,
- llstr(mi->master_log_pos,llbuff)));
+ mi->master_log_name,
+ llstr(mi->master_log_pos,llbuff)));
if (!(mi->mysql = mysql = mysql_init(NULL)))
{
@@ -3298,9 +3299,9 @@
if (!safe_connect(thd, mysql, mi))
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,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
else
{
sql_print_information("Slave I/O thread killed while connecting to master");
@@ -3338,9 +3339,9 @@
sql_print_error("Failed on request_dump()");
if (io_slave_killed(thd,mi))
{
- sql_print_information("Slave I/O thread killed while requesting master \
+ sql_print_information("Slave I/O thread killed while requesting master \
dump");
- goto err;
+ goto err;
}
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
@@ -3350,35 +3351,35 @@
#endif
end_server(mysql);
/*
- First time retry immediately, assuming that we can recover
- right away - if first time fails, sleep between re-tries
- hopefuly the admin can fix the problem sometime
+ First time retry immediately, assuming that we can recover
+ right away - if first time fails, sleep between re-tries
+ hopefuly the admin can fix the problem sometime
*/
if (retry_count++)
{
- if (retry_count > master_retry_count)
- goto err; // Don't retry forever
- safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
- (void*)mi);
+ if (retry_count > master_retry_count)
+ goto err; // Don't retry forever
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*)mi);
}
if (io_slave_killed(thd,mi))
{
- sql_print_information("Slave I/O thread killed while retrying master \
+ sql_print_information("Slave I/O thread killed while retrying master \
dump");
- goto err;
+ goto err;
}
thd->proc_info = "Reconnecting after a failed binlog dump request";
if (!suppress_warnings)
- sql_print_error("Slave I/O thread: failed dump request, \
+ sql_print_error("Slave I/O thread: failed dump request, \
reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ llstr(mi->master_log_pos,llbuff));
if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
- io_slave_killed(thd,mi))
+ io_slave_killed(thd,mi))
{
- sql_print_information("Slave I/O thread killed during or \
+ sql_print_information("Slave I/O thread killed during or \
after reconnect");
- goto err;
+ goto err;
}
goto connected;
@@ -3397,72 +3398,72 @@
ulong event_len = read_event(mysql, mi, &suppress_warnings);
if (io_slave_killed(thd,mi))
{
- if (global_system_variables.log_warnings)
- sql_print_information("Slave I/O thread killed while reading event");
- goto err;
+ if (global_system_variables.log_warnings)
+ sql_print_information("Slave I/O thread killed while reading event");
+ goto err;
}
if (event_len == packet_error)
{
- uint mysql_error_number= mysql_errno(mysql);
- if (mysql_error_number == ER_NET_PACKET_TOO_LARGE)
- {
- sql_print_error("\
+ uint mysql_error_number= mysql_errno(mysql);
+ if (mysql_error_number == ER_NET_PACKET_TOO_LARGE)
+ {
+ sql_print_error("\
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",
- thd->variables.max_allowed_packet);
- goto err;
- }
- if (mysql_error_number == ER_MASTER_FATAL_ERROR_READING_BINLOG)
- {
- sql_print_error(ER(mysql_error_number), mysql_error_number,
- mysql_error(mysql));
- goto err;
- }
+ thd->variables.max_allowed_packet);
+ goto err;
+ }
+ if (mysql_error_number == ER_MASTER_FATAL_ERROR_READING_BINLOG)
+ {
+ sql_print_error(ER(mysql_error_number), mysql_error_number,
+ mysql_error(mysql));
+ goto err;
+ }
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
- thd->proc_info = "Waiting to reconnect after a failed master event read";
+ thd->proc_info = "Waiting to reconnect after a failed master event read";
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->clear_active_vio();
#endif
- end_server(mysql);
- if (retry_count++)
- {
- if (retry_count > master_retry_count)
- goto err; // Don't retry forever
- safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
- (void*) mi);
- }
- if (io_slave_killed(thd,mi))
- {
- if (global_system_variables.log_warnings)
- sql_print_information("Slave I/O thread killed while waiting to \
+ end_server(mysql);
+ if (retry_count++)
+ {
+ if (retry_count > master_retry_count)
+ goto err; // Don't retry forever
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*) mi);
+ }
+ if (io_slave_killed(thd,mi))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("Slave I/O thread killed while waiting to \
reconnect after a failed read");
- goto err;
- }
- thd->proc_info = "Reconnecting after a failed master event read";
- if (!suppress_warnings)
- sql_print_information("Slave I/O thread: Failed reading log event, \
+ goto err;
+ }
+ thd->proc_info = "Reconnecting after a failed master event read";
+ if (!suppress_warnings)
+ sql_print_information("Slave I/O thread: Failed reading log event, \
reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos, llbuff));
- if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
- io_slave_killed(thd,mi))
- {
- if (global_system_variables.log_warnings)
- sql_print_information("Slave I/O thread killed during or after a \
+ llstr(mi->master_log_pos, llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_information("Slave I/O thread killed during or after a \
reconnect done to recover from failed read");
- goto err;
- }
- goto connected;
+ goto err;
+ }
+ goto connected;
} // if (event_len == packet_error)
- retry_count=0; // ok event, reset retry counter
+ retry_count=0; // ok event, reset retry counter
thd->proc_info = "Queueing master event to the relay log";
if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
- event_len))
+ event_len))
{
- sql_print_error("Slave I/O thread could not queue event from master");
- goto err;
+ sql_print_error("Slave I/O thread could not queue event from master");
+ goto err;
}
if (flush_master_info(mi, 1))
{
@@ -3488,31 +3489,30 @@
ignore_log_space_limit=%d",
llstr(rli->log_space_limit,llbuf1),
llstr(rli->log_space_total,llbuf2),
- (int) rli->ignore_log_space_limit));
+ (int) rli->ignore_log_space_limit));
}
#endif
if (rli->log_space_limit && rli->log_space_limit <
- rli->log_space_total &&
+ rli->log_space_total &&
!rli->ignore_log_space_limit)
- if (wait_for_relay_log_space(rli))
- {
- sql_print_error("Slave I/O thread aborted while waiting for relay \
+ if (wait_for_relay_log_space(rli))
+ {
+ sql_print_error("Slave I/O thread aborted while waiting for relay \
log space");
- goto err;
- }
- }
+ goto err;
+ }
+ }
}
// error = 0;
err:
// print the current replication position
sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
- IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
+ IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query= 0; // extra safety
- thd->query_length= 0;
- thd->reset_db(NULL, 0);
+ thd->query = thd->db = 0; // extra safety
+ thd->query_length= thd->db_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (mysql)
{
@@ -3533,15 +3533,12 @@
write_ignored_events_info_to_relay_log(thd, mi);
thd->proc_info = "Waiting for slave mutex on exit";
pthread_mutex_lock(&mi->run_lock);
- mi->slave_running = 0;
- mi->io_thd = 0;
/* Forget the relay log's format */
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= 0;
// TODO: make rpl_status part of MASTER_INFO
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
- mi->abort_slave = 0; // TODO: check if this is needed
DBUG_ASSERT(thd->net.buff != 0);
net_end(&thd->net); // destructor will not free it, because net.vio is 0
close_thread_tables(thd, 0);
@@ -3549,11 +3546,14 @@
THD_CHECK_SENTRY(thd);
delete thd;
pthread_mutex_unlock(&LOCK_thread_count);
- pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
+ mi->abort_slave = 0;
+ mi->slave_running = 0;
+ mi->io_thd = 0;
pthread_mutex_unlock(&mi->run_lock);
+ pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(0); // Can't return anything here
+ DBUG_RETURN(0); // Can't return anything here
}
@@ -3561,7 +3561,7 @@
pthread_handler_t handle_slave_sql(void *arg)
{
- THD *thd; /* needs to be first for thread_stack */
+ THD *thd; /* needs to be first for thread_stack */
char llbuff[22],llbuff1[22];
RELAY_LOG_INFO* rli = &((MASTER_INFO*)arg)->rli;
@@ -3575,13 +3575,13 @@
pthread_mutex_lock(&rli->run_lock);
DBUG_ASSERT(!rli->slave_running);
errmsg= 0;
-#ifndef DBUG_OFF
+#ifndef DBUG_OFF
rli->events_till_abort = abort_slave_event_count;
-#endif
+#endif
thd = new THD; // note that contructor of THD uses DBUG_ !
thd->thread_stack = (char*)&thd; // remember where our stack is
-
+
/* Inform waiting threads that slave has started */
rli->slave_run_id++;
@@ -3635,13 +3635,13 @@
rli->trans_retries= 0; // start from "no error"
if (init_relay_log_pos(rli,
- rli->group_relay_log_name,
- rli->group_relay_log_pos,
- 1 /*need data lock*/, &errmsg,
+ rli->group_relay_log_name,
+ rli->group_relay_log_pos,
+ 1 /*need data lock*/, &errmsg,
1 /*look for a description_event*/))
{
sql_print_error("Error initializing relay log position: %s",
- errmsg);
+ errmsg);
goto err;
}
THD_CHECK_SENTRY(thd);
@@ -3649,7 +3649,7 @@
{
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
- llstr(my_b_tell(rli->cur_log),llbuf1),
+ llstr(my_b_tell(rli->cur_log),llbuf1),
llstr(rli->event_relay_log_pos,llbuf2)));
DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
/*
@@ -3672,13 +3672,13 @@
DBUG_ASSERT(rli->sql_thd == thd);
DBUG_PRINT("master_info",("log_file_name: %s position: %s",
- rli->group_master_log_name,
- llstr(rli->group_master_log_pos,llbuff)));
+ rli->group_master_log_name,
+ llstr(rli->group_master_log_pos,llbuff)));
if (global_system_variables.log_warnings)
sql_print_information("Slave SQL thread initialized, starting replication in \
log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
- llstr(rli->group_master_log_pos,llbuff),rli->group_relay_log_name,
- llstr(rli->group_relay_log_pos,llbuff1));
+ llstr(rli->group_master_log_pos,llbuff),rli->group_relay_log_name,
+ llstr(rli->group_relay_log_pos,llbuff1));
/* execute init_slave variable */
if (sys_init_slave.value_length)
@@ -3742,8 +3742,8 @@
/* Thread stopped. Print the current replication position to the log */
sql_print_information("Slave SQL thread exiting, replication stopped in log "
- "'%s' at position %s",
- RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
+ "'%s' at position %s",
+ RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
err:
@@ -3760,10 +3760,8 @@
should already have done these assignments (each event which sets these
variables is supposed to set them to 0 before terminating)).
*/
- thd->catalog= 0;
- thd->reset_db(NULL, 0);
- thd->query= 0;
- thd->query_length= 0;
+ thd->query= thd->db= thd->catalog= 0;
+ thd->query_length= thd->db_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->proc_info = "Waiting for slave mutex on exit";
pthread_mutex_lock(&rli->run_lock);
@@ -3771,7 +3769,7 @@
pthread_mutex_lock(&rli->data_lock);
DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
/* When master_pos_wait() wakes up it will check this and terminate */
- rli->slave_running= 0;
+ rli->slave_running= 0;
/* Forget the relay log's format */
delete rli->relay_log.description_event_for_exec;
rli->relay_log.description_event_for_exec= 0;
@@ -3803,7 +3801,7 @@
pthread_mutex_unlock(&rli->run_lock);
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(0); // Can't return anything here
+ DBUG_RETURN(0); // Can't return anything here
}
@@ -3832,11 +3830,11 @@
thd->file_id = cev->file_id = mi->file_id++;
thd->server_id = cev->server_id;
cev_not_written = 1;
-
+
if (unlikely(net_request_file(net,cev->fname)))
{
sql_print_error("Slave I/O: failed requesting download of '%s'",
- cev->fname);
+ cev->fname);
goto err;
}
@@ -3847,18 +3845,18 @@
*/
{
Append_block_log_event aev(thd,0,0,0,0);
-
+
for (;;)
{
if (unlikely((num_bytes=my_net_read(net)) == packet_error))
{
- sql_print_error("Network read error downloading '%s' from master",
- cev->fname);
- goto err;
+ sql_print_error("Network read error downloading '%s' from master",
+ cev->fname);
+ goto err;
}
if (unlikely(!num_bytes)) /* eof */
{
- net_write_command(net, 0, "", 0, "", 0);/* 3.23 master wants it */
+ net_write_command(net, 0, "", 0, "", 0);/* 3.23 master wants it */
/*
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,
@@ -3866,43 +3864,43 @@
INFILE had not existed, i.e. write nothing.
*/
if (unlikely(cev_not_written))
- break;
- Execute_load_log_event xev(thd,0,0);
- xev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&xev)))
- {
- sql_print_error("Slave I/O: error writing Exec_load event to \
+ break;
+ Execute_load_log_event xev(thd,0,0);
+ xev.log_pos = cev->log_pos;
+ if (unlikely(mi->rli.relay_log.append(&xev)))
+ {
+ sql_print_error("Slave I/O: error writing Exec_load event to \
relay log");
- goto err;
- }
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
- break;
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ break;
}
if (unlikely(cev_not_written))
{
- cev->block = (char*)net->read_pos;
- cev->block_len = num_bytes;
- if (unlikely(mi->rli.relay_log.append(cev)))
- {
- sql_print_error("Slave I/O: error writing Create_file event to \
+ cev->block = (char*)net->read_pos;
+ cev->block_len = num_bytes;
+ if (unlikely(mi->rli.relay_log.append(cev)))
+ {
+ sql_print_error("Slave I/O: error writing Create_file event to \
relay log");
- goto err;
- }
- cev_not_written=0;
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ goto err;
+ }
+ cev_not_written=0;
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
}
else
{
- aev.block = (char*)net->read_pos;
- aev.block_len = num_bytes;
- aev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&aev)))
- {
- sql_print_error("Slave I/O: error writing Append_block event to \
+ aev.block = (char*)net->read_pos;
+ aev.block_len = num_bytes;
+ aev.log_pos = cev->log_pos;
+ if (unlikely(mi->rli.relay_log.append(&aev)))
+ {
+ sql_print_error("Slave I/O: error writing Append_block event to \
relay log");
- goto err;
- }
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
}
}
}
@@ -3917,8 +3915,8 @@
SYNOPSIS
process_io_rotate()
- mi master_info for the slave
- rev The rotate log event read from the binary log
+ mi master_info for the slave
+ rev The rotate log event read from the binary log
DESCRIPTION
Updates the master info with the place in the next binary
@@ -3929,8 +3927,8 @@
We assume we already locked mi->data_lock
RETURN VALUES
- 0 ok
- 1 Log event is illegal
+ 0 ok
+ 1 Log event is illegal
*/
@@ -3946,7 +3944,7 @@
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
mi->master_log_pos= rev->pos;
DBUG_PRINT("info", ("master_log_pos: '%s' %d",
- mi->master_log_name, (ulong) mi->master_log_pos));
+ mi->master_log_name, (ulong) mi->master_log_pos));
#ifndef DBUG_OFF
/*
If we do not do this, we will be getting the first
@@ -3983,7 +3981,7 @@
copied from MySQL 4.0.
*/
static int queue_binlog_ver_1_event(MASTER_INFO *mi, const char *buf,
- ulong event_len)
+ ulong event_len)
{
const char *errmsg = 0;
ulong inc_pos;
@@ -4027,7 +4025,7 @@
{
sql_print_error("Read invalid event from master: '%s',\
master could be corrupt but a more likely cause of this is a bug",
- errmsg);
+ errmsg);
my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(1);
}
@@ -4073,8 +4071,8 @@
}
if (likely(!ignore_event))
{
- if (ev->log_pos)
- /*
+ if (ev->log_pos)
+ /*
Don't do it for fake Rotate events (see comment in
Log_event::Log_event(const char* buf...) in log_event.cc).
*/
@@ -4099,7 +4097,7 @@
from queue_binlog_ver_1_event(), with some affordable simplifications.
*/
static int queue_binlog_ver_3_event(MASTER_INFO *mi, const char *buf,
- ulong event_len)
+ ulong event_len)
{
const char *errmsg = 0;
ulong inc_pos;
@@ -4114,7 +4112,7 @@
{
sql_print_error("Read invalid event from master: '%s',\
master could be corrupt but a more likely cause of this is a bug",
- errmsg);
+ errmsg);
my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(1);
}
@@ -4157,13 +4155,13 @@
(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.
- TODO:
+ TODO:
Test this code before release - it has to be tested on a separate
setup with 3.23 master or 4.0 master
*/
static int queue_old_event(MASTER_INFO *mi, const char *buf,
- ulong event_len)
+ ulong event_len)
{
DBUG_ENTER("queue_old_event");
@@ -4175,7 +4173,7 @@
DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
default: /* unsupported format; eg version 2 */
DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
- mi->rli.relay_log.description_event_for_queue->binlog_version));
+ mi->rli.relay_log.description_event_for_queue->binlog_version));
DBUG_RETURN(1);
}
}
@@ -4213,7 +4211,7 @@
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
prepared statements' deletion are TODO only when we binlog prep stmts).
-
+
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
@@ -4222,7 +4220,7 @@
goto err;
case ROTATE_EVENT:
{
- Rotate_log_event rev(buf,event_len,mi->rli.relay_log.description_event_for_queue);
+ Rotate_log_event rev(buf,event_len,mi->rli.relay_log.description_event_for_queue);
if (unlikely(process_io_rotate(mi,&rev)))
{
error= 1;
@@ -4257,17 +4255,17 @@
}
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= tmp;
- /*
+ /*
Though this does some conversion to the slave's format, this will
- preserve the master's binlog format version, and number of event types.
+ preserve the master's binlog format version, and number of event types.
*/
- /*
+ /*
If the event was not requested by the slave (the slave did not ask for
- it), i.e. has end_log_pos=0, we do not increment mi->master_log_pos
+ it), i.e. has end_log_pos=0, we do not increment mi->master_log_pos
*/
inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
DBUG_PRINT("info",("binlog format is now %d",
- mi->rli.relay_log.description_event_for_queue->binlog_version));
+ mi->rli.relay_log.description_event_for_queue->binlog_version));
}
break;
@@ -4276,8 +4274,8 @@
break;
}
- /*
- If this event is originating from this server, don't queue it.
+ /*
+ If this event is originating from this server, don't queue it.
We don't check this for 3.23 events because it's simpler like this; 3.23
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
@@ -4319,7 +4317,7 @@
}
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server, ignored", (ulong) mi->master_log_pos));
- }
+ }
else
{
/* write the event to the relay log */
@@ -4378,13 +4376,13 @@
SYNPOSIS
safe_connect()
- thd Thread handler for slave
- mysql MySQL connection handle
- mi Replication handle
+ thd Thread handler for slave
+ mysql MySQL connection handle
+ mi Replication handle
RETURN
- 0 ok
- # Error
+ 0 ok
+ # Error
*/
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
@@ -4405,10 +4403,10 @@
*/
static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool reconnect, bool suppress_warnings)
+ bool reconnect, bool suppress_warnings)
{
int slave_was_killed;
- int last_errno= -2; // impossible error
+ int last_errno= -2; // impossible error
ulong err_count=0;
char llbuff[22];
DBUG_ENTER("connect_to_master");
@@ -4418,16 +4416,16 @@
#endif
ulong client_flag= CLIENT_REMEMBER_OPTIONS;
if (opt_slave_compressed_protocol)
- client_flag=CLIENT_COMPRESS; /* We will use compression */
+ client_flag=CLIENT_COMPRESS; /* We will use compression */
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
-
+
#ifdef HAVE_OPENSSL
if (mi->ssl)
- mysql_ssl_set(mysql,
+ mysql_ssl_set(mysql,
mi->ssl_key[0]?mi->ssl_key:0,
- mi->ssl_cert[0]?mi->ssl_cert:0,
+ mi->ssl_cert[0]?mi->ssl_cert:0,
mi->ssl_ca[0]?mi->ssl_ca:0,
mi->ssl_capath[0]?mi->ssl_capath:0,
mi->ssl_cipher[0]?mi->ssl_cipher:0);
@@ -4438,9 +4436,9 @@
mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
- (reconnect ? mysql_reconnect(mysql) != 0 :
- mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
- mi->port, 0, client_flag) == 0))
+ (reconnect ? mysql_reconnect(mysql) != 0 :
+ mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
+ mi->port, 0, client_flag) == 0))
{
/* Don't repeat last error */
if ((int)mysql_errno(mysql) != last_errno)
@@ -4450,11 +4448,11 @@
sql_print_error("Slave I/O thread: error %s to master \
'%s@%s:%d': \
Error: '%s' errno: %d retry-time: %d retries: %d",
- (reconnect ? "reconnecting" : "connecting"),
- mi->user,mi->host,mi->port,
- mysql_error(mysql), last_errno,
- mi->connect_retry,
- master_retry_count);
+ (reconnect ? "reconnecting" : "connecting"),
+ mi->user,mi->host,mi->port,
+ mysql_error(mysql), last_errno,
+ mi->connect_retry,
+ master_retry_count);
}
/*
By default we try forever. The reason is that failure will trigger
@@ -4470,19 +4468,19 @@
break;
}
safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
- (void*)mi);
+ (void*)mi);
}
if (!slave_was_killed)
{
if (reconnect)
- {
+ {
if (!suppress_warnings && global_system_variables.log_warnings)
- sql_print_information("Slave: connected to master '%s@%s:%d',\
+ sql_print_information("Slave: connected to master '%s@%s:%d',\
replication resumed in log '%s' at position %s", mi->user,
- mi->host, mi->port,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
}
else
{
@@ -4492,7 +4490,7 @@
}
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->set_active_vio(mysql->net.vio);
-#endif
+#endif
}
mysql->reconnect= 1;
DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
@@ -4509,7 +4507,7 @@
*/
static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool suppress_warnings)
+ bool suppress_warnings)
{
DBUG_ENTER("safe_reconnect");
DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings));
@@ -4522,7 +4520,7 @@
SYNOPSIS
flush_relay_log_info()
- rli Relay log information
+ rli Relay log information
NOTES
- As this is only called by the slave thread, we don't need to
@@ -4541,8 +4539,8 @@
longlong2str.
RETURN VALUES
- 0 ok
- 1 write error
+ 0 ok
+ 1 write error
*/
bool flush_relay_log_info(RELAY_LOG_INFO* rli)
@@ -4587,12 +4585,12 @@
IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
if ((rli->cur_log_fd=open_binlog(cur_log,rli->event_relay_log_name,
- errmsg)) <0)
+ errmsg)) <0)
DBUG_RETURN(0);
/*
We want to start exactly where we was before:
- relay_log_pos Current log pos
- pending Number of bytes already processed from the event
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
*/
rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
my_b_seek(cur_log,rli->event_relay_log_pos);
@@ -4624,7 +4622,7 @@
pthread_cond_wait() with the non-data_lock mutex
*/
safe_mutex_assert_owner(&rli->data_lock);
-
+
while (!sql_slave_killed(thd,rli))
{
/*
@@ -4645,17 +4643,17 @@
pthread_mutex_lock(log_lock);
/*
- Reading xxx_file_id is safe because the log will only
- be rotated when we hold relay_log.LOCK_log
+ Reading xxx_file_id is safe because the log will only
+ be rotated when we hold relay_log.LOCK_log
*/
if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count)
{
- // 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
+ // 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
}
}
@@ -4693,25 +4691,25 @@
*/
rli->future_event_relay_log_pos= my_b_tell(cur_log);
if (hot_log)
- pthread_mutex_unlock(log_lock);
+ pthread_mutex_unlock(log_lock);
DBUG_RETURN(ev);
}
DBUG_ASSERT(thd==rli->sql_thd);
- if (opt_reckless_slave) // For mysql-test
+ if (opt_reckless_slave) // For mysql-test
cur_log->error = 0;
if (cur_log->error < 0)
{
errmsg = "slave SQL thread aborted because of I/O error";
if (hot_log)
- pthread_mutex_unlock(log_lock);
+ pthread_mutex_unlock(log_lock);
goto err;
}
if (!cur_log->error) /* EOF */
{
/*
- 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
+ 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
*/
if (hot_log)
{
@@ -4730,7 +4728,7 @@
time_t save_timestamp= rli->last_master_timestamp;
rli->last_master_timestamp= 0;
- DBUG_ASSERT(rli->relay_log.get_open_count() ==
+ DBUG_ASSERT(rli->relay_log.get_open_count() ==
rli->cur_log_old_open_count);
if (rli->ign_master_log_name_end[0])
@@ -4752,14 +4750,14 @@
DBUG_RETURN(ev);
}
- /*
- 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);
+ /*
+ 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);
/*
- Possible deadlock :
+ Possible deadlock :
- the I/O thread has reached log_space_limit
- the SQL thread has read all relay logs, but cannot purge for some
reason:
@@ -4771,10 +4769,10 @@
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
- master does not send anything). Then the I/O thread stops waiting
+ master does not send anything). Then the I/O thread stops waiting
and reads more events.
The SQL thread decides when the I/O thread should take log_space_limit
- into account again : ignore_log_space_limit is reset to 0
+ into account again : ignore_log_space_limit is reset to 0
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
@@ -4784,7 +4782,7 @@
*/
pthread_mutex_lock(&rli->log_space_lock);
// prevent the I/O thread from blocking next times
- rli->ignore_log_space_limit= 1;
+ rli->ignore_log_space_limit= 1;
/*
If the I/O thread is blocked, unblock it.
Ok to broadcast after unlock, because the mutex is only destroyed in
@@ -4798,21 +4796,21 @@
// re-acquire data lock since we released it earlier
pthread_mutex_lock(&rli->data_lock);
rli->last_master_timestamp= save_timestamp;
- continue;
+ continue;
}
/*
- 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
+ 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
*/
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;
-
+
if (relay_log_purge)
{
- /*
+ /*
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),
@@ -4823,33 +4821,33 @@
- I see no better detection method
- purge_first_log is not called that often
*/
- if (rli->relay_log.purge_first_log
+ if (rli->relay_log.purge_first_log
(rli,
rli->group_relay_log_pos == rli->event_relay_log_pos
&& !strcmp(rli->group_relay_log_name,rli->event_relay_log_name)))
- {
- errmsg = "Error purging processed logs";
- goto err;
- }
+ {
+ errmsg = "Error purging processed logs";
+ goto err;
+ }
}
else
{
- /*
- 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);
+ /*
+ 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);
}
/*
@@ -4868,66 +4866,66 @@
if (rli->relay_log.is_active(rli->linfo.log_file_name))
{
#ifdef EXTRA_DEBUG
- if (global_system_variables.log_warnings)
- sql_print_information("next log '%s' is currently active",
+ if (global_system_variables.log_warnings)
+ sql_print_information("next log '%s' is currently active",
rli->linfo.log_file_name);
-#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.
+#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.
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).
- */
- if (check_binlog_magic(cur_log,&errmsg))
+ */
+ if (check_binlog_magic(cur_log,&errmsg))
{
if (!hot_log) pthread_mutex_unlock(log_lock);
- goto err;
+ goto err;
}
if (!hot_log) pthread_mutex_unlock(log_lock);
- continue;
+ continue;
}
if (!hot_log) pthread_mutex_unlock(log_lock);
/*
- 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.
+ 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.
*/
#ifdef EXTRA_DEBUG
if (global_system_variables.log_warnings)
- sql_print_information("next log '%s' is not active",
+ sql_print_information("next log '%s' is not active",
rli->linfo.log_file_name);
-#endif
+#endif
// open_binlog() will check the magic header
if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
- &errmsg)) <0)
- goto err;
+ &errmsg)) <0)
+ goto err;
}
else
{
/*
- Read failed with a non-EOF error.
- TODO: come up with something better to handle this error
+ Read failed with a non-EOF error.
+ TODO: come up with something better to handle this error
*/
if (hot_log)
- pthread_mutex_unlock(log_lock);
+ pthread_mutex_unlock(log_lock);
sql_print_error("Slave SQL thread: I/O error reading \
event(errno: %d cur_log->error: %d)",
- my_errno,cur_log->error);
+ my_errno,cur_log->error);
// set read position to the beginning of the event
my_b_seek(cur_log,rli->event_relay_log_pos);
/* otherwise, we have had a partial read */
errmsg = "Aborting slave SQL thread because of partial event read";
- break; // To end of function
+ break; // To end of function
}
}
if (!errmsg && global_system_variables.log_warnings)
{
- sql_print_information("Error reading relay log event: %s",
+ sql_print_information("Error reading relay log event: %s",
"slave SQL thread was killed");
DBUG_RETURN(0);
}
@@ -4941,7 +4939,7 @@
/*
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
- locks; here we don't, so this function is mainly taking locks).
+ locks; here we don't, so this function is mainly taking locks).
Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
is void).
*/
@@ -4954,7 +4952,7 @@
/* We don't lock rli->run_lock. This would lead to deadlocks. */
pthread_mutex_lock(&mi->run_lock);
- /*
+ /*
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).
*/
@@ -5003,7 +5001,7 @@
Sorted array of table names, please keep it sorted since we are
using bsearch() on it below.
*/
-static st_reload_entry s_mysql_tables[] =
+static st_reload_entry s_mysql_tables[] =
{
{ "columns_priv", st_relay_log_info::RELOAD_GRANT_F },
{ "db", st_relay_log_info::RELOAD_ACCESS_F },
@@ -5026,7 +5024,7 @@
}
void st_relay_log_info::touching_table(char const* db, char const* table,
- ulong table_id)
+ ulong table_id)
{
DBUG_ENTER("st_relay_log_info::touching_table");
@@ -5053,7 +5051,7 @@
DBUG_VOID_RETURN;
}
-void st_relay_log_info::transaction_end(THD* thd)
+void st_relay_log_info::transaction_end(THD* thd)
{
DBUG_ENTER("st_relay_log_info::transaction_end");
@@ -5108,4 +5106,3 @@
#endif
#endif /* HAVE_REPLICATION */
-
--- 1.333/sql/sql_base.cc 2006-07-11 12:17:30 +02:00
+++ 1.334/sql/sql_base.cc 2006-07-11 12:17:30 +02:00
@@ -49,6 +49,8 @@
static void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
bool send_refresh);
static bool reopen_table(TABLE *table);
+static bool
+has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables);
extern "C" byte *table_cache_key(const byte *record,uint *length,
@@ -1179,135 +1181,134 @@
void close_temporary_tables(THD *thd)
{
- TABLE *next, *prev_table, *table;
- char *query= 0, *end;
- uint query_buf_size, max_names_len;
- bool found_user_tables;
-
+ TABLE *table;
if (!thd->temporary_tables)
return;
-
- LINT_INIT(end);
- query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
- /*
- insertion sort of temp tables by pseudo_thread_id to build ordered list
+ if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
+ {
+ TABLE *next;
+ for (table= thd->temporary_tables; table; table= next)
+ {
+ next=table->next;
+ close_temporary(table, 1, 1);
+ }
+ thd->temporary_tables= 0;
+ return;
+ }
+
+ TABLE *next,
+ *prev_table /* TODO: 5.1 maintaines prev link in temporary_tables
+ double-linked list so we could fix it. But it is not necessary
+ at this time when the list is being destroyed */;
+ bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
+ // Better add "if exists", in case a RESET MASTER has been done
+ const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
+ uint stub_len= sizeof(stub) - 1;
+ char buf[256];
+ memcpy(buf, stub, stub_len);
+ String s_query= String(buf, sizeof(buf), system_charset_info);
+ bool found_user_tables= false;
+ LINT_INIT(next);
+
+ /*
+ insertion sort of temp tables by pseudo_thread_id to build ordered list
of sublists of equal pseudo_thread_id
*/
- for (prev_table= thd->temporary_tables,
- table= prev_table->next,
- found_user_tables= (prev_table->s->table_name.str[0] != '#');
+
+ for (prev_table= thd->temporary_tables, table= prev_table->next;
table;
prev_table= table, table= table->next)
{
- TABLE *prev_sorted /* same as for prev_table */,
- *sorted;
- /*
- table not created directly by the user is moved to the tail.
- Fixme/todo: nothing (I checked the manual) prevents user to create temp
- with `#'
- */
- if (table->s->table_name.str[0] == '#')
- continue;
- else
+ TABLE *prev_sorted /* same as for prev_table */, *sorted;
+ if (is_user_table(table))
{
- found_user_tables = 1;
- }
- for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
- prev_sorted= sorted, sorted= sorted->next)
- {
- if (sorted->s->table_name.str[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
+ if (!found_user_tables)
+ found_user_tables= true;
+ for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
+ prev_sorted= sorted, sorted= sorted->next)
{
- /* move into the sorted part of the list from the unsorted */
- prev_table->next= table->next;
- table->next= sorted;
- if (prev_sorted)
+ if (!is_user_table(sorted) ||
+ tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
{
- prev_sorted->next= table;
- }
- else
- {
- thd->temporary_tables= table;
+ /* move into the sorted part of the list from the unsorted */
+ prev_table->next= table->next;
+ table->next= sorted;
+ if (prev_sorted)
+ {
+ prev_sorted->next= table;
+ }
+ else
+ {
+ thd->temporary_tables= table;
+ }
+ table= prev_table;
+ break;
}
- table= prev_table;
- break;
}
}
- }
- /*
- calc query_buf_size as max per sublists, one sublist per pseudo thread id.
- Also stop at first occurence of `#'-named table that starts
- all implicitly created temp tables
- */
- for (max_names_len= 0, table=thd->temporary_tables;
- table && table->s->table_name.str[0] != '#';
- table=table->next)
- {
- uint tmp_names_len;
- for (tmp_names_len= table->s->table_cache_key.length + 1;
- table->next && table->s->table_name.str[0] != '#' &&
- tmpkeyval(thd, table) == tmpkeyval(thd, table->next);
- table=table->next)
- {
- /*
- We are going to add 4 ` around the db/table names, so 1 might not look
- enough; indeed it is enough, because table->s->table_cache_key.length is
- greater (by 8, because of server_id and thread_id) than db||table.
- */
- tmp_names_len += table->next->s->table_cache_key.length + 1;
- }
- if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
}
-
- /* allocate */
- if (found_user_tables && mysql_bin_log.is_open() &&
- !thd->current_stmt_binlog_row_based &&
- (query = alloc_root(thd->mem_root, query_buf_size+= max_names_len)))
- // Better add "if exists", in case a RESET MASTER has been done
- end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
+
+ /* We always quote db,table names though it is slight overkill */
+ if (found_user_tables &&
+ !(was_quote_show= (thd->options & OPTION_QUOTE_SHOW_CREATE)))
+ {
+ thd->options |= OPTION_QUOTE_SHOW_CREATE;
+ }
/* scan sorted tmps to generate sequence of DROP */
- for (table=thd->temporary_tables; table; table= next)
+ for (table= thd->temporary_tables; table; table= next)
{
- if (query // we might be out of memory, but this is not fatal
- && table->s->table_name.str[0] != '#')
+ if (is_user_table(table))
{
- char *end_cur;
/* Set pseudo_thread_id to be that of the processed table */
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
/* Loop forward through all tables within the sublist of
common pseudo_thread_id to create single DROP query */
- for (end_cur= end;
- table && table->s->table_name.str[0] != '#' &&
+ for (s_query.length(stub_len);
+ table && is_user_table(table) &&
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
table= next)
{
- end_cur= strxmov(end_cur, "`", table->s->db.str, "`.`",
- table->s->table_name.str, "`,", NullS);
+ /*
+ We are going to add 4 ` around the db/table names and possible more
+ due to special characters in the names
+ */
+ append_identifier(thd, &s_query, table->s->db.str, strlen(table->s->db.str));
+ s_query.q_append('.');
+ append_identifier(thd, &s_query, table->s->table_name.str,
+ strlen(table->s->table_name.str));
+ s_query.q_append(',');
next= table->next;
close_temporary(table, 1, 1);
}
thd->clear_error();
- /* The -1 is to remove last ',' */
- Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE);
+ CHARSET_INFO *cs_save= thd->variables.character_set_client;
+ thd->variables.character_set_client= system_charset_info;
+ Query_log_event qinfo(thd, s_query.ptr(),
+ s_query.length() - 1 /* to remove trailing ',' */,
+ 0, FALSE);
+ thd->variables.character_set_client= cs_save;
/*
- Imagine the thread had created a temp table, then was doing a SELECT,
- and the SELECT was killed. Then it's not clever to mark the statement
- above as "killed", because it's not really a statement updating data,
- and there are 99.99% chances it will succeed on slave. If a real update
- (one updating a persistent table) was killed on the master, then this
- real update will be logged with error_code=killed, rightfully causing
- the slave to stop.
+ Imagine the thread had created a temp table, then was doing a SELECT, and
+ the SELECT was killed. Then it's not clever to mark the statement above as
+ "killed", because it's not really a statement updating data, and there
+ are 99.99% chances it will succeed on slave.
+ If a real update (one updating a persistent table) was killed on the
+ master, then this real update will be logged with error_code=killed,
+ rightfully causing the slave to stop.
*/
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
}
- else
+ else
{
next= table->next;
close_temporary(table, 1, 1);
}
}
+ if (!was_quote_show)
+ thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
thd->temporary_tables=0;
}
@@ -3317,6 +3318,14 @@
*need_reopen= FALSE;
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ CREATE ... SELECT UUID() locks no tables, we have to test here.
+ */
+ if (thd->lex->binlog_row_based_if_mixed)
+ thd->set_current_stmt_binlog_row_based_if_mixed();
+#endif /*HAVE_ROW_BASED_REPLICATION*/
+
if (!tables)
DBUG_RETURN(0);
@@ -3347,6 +3356,19 @@
{
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ If we have >= 2 different tables to update with auto_inc columns,
+ statement-based binlogging won't work. We can solve this problem in
+ mixed mode by switching to row-based binlogging:
+ */
+ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
+ has_two_write_locked_tables_with_auto_increment(tables))
+ {
+ thd->lex->binlog_row_based_if_mixed= TRUE;
+ thd->set_current_stmt_binlog_row_based_if_mixed();
+ }
+#endif
}
if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
@@ -6479,3 +6501,46 @@
DBUG_VOID_RETURN;
}
+
+/*
+ Tells if two (or more) tables have auto_increment columns and we want to
+ lock those tables with a write lock.
+
+ SYNOPSIS
+ has_two_write_locked_tables_with_auto_increment
+ tables Table list
+
+ NOTES:
+ Call this function only when you have established the list of all tables
+ which you'll want to update (including stored functions, triggers, views
+ inside your statement).
+
+ RETURN
+ 0 No
+ 1 Yes
+*/
+
+static bool
+has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables)
+{
+ char *first_table_name= NULL, *first_db;
+ for (TABLE_LIST *table= tables; table; table= table->next_global)
+ {
+ /* we must do preliminary checks as table->table may be NULL */
+ if (!table->placeholder() && !table->schema_table &&
+ table->table->found_next_number_field &&
+ (table->lock_type >= TL_WRITE_ALLOW_WRITE))
+ {
+ if (first_table_name == NULL)
+ {
+ first_table_name= table->table_name;
+ first_db= table->db;
+ DBUG_ASSERT(first_db);
+ }
+ else if (strcmp(first_db, table->db) ||
+ strcmp(first_table_name, table->table_name))
+ return 1;
+ }
+ }
+ return 0;
+}
--- 1.274/sql/sql_class.cc 2006-07-11 12:17:30 +02:00
+++ 1.275/sql/sql_class.cc 2006-07-11 12:17:30 +02:00
@@ -1021,7 +1021,7 @@
Protocol *protocol= thd->protocol;
char buff[MAX_FIELD_WIDTH];
String buffer(buff, sizeof(buff), &my_charset_bin);
- DBUG_ENTER("send_data");
+ DBUG_ENTER("select_send::send_data");
protocol->prepare_for_resend();
Item *item;
@@ -1234,7 +1234,7 @@
bool select_export::send_data(List<Item> &items)
{
- DBUG_ENTER("send_data");
+ DBUG_ENTER("select_export::send_data");
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
bool space_inited=0;
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
@@ -1391,7 +1391,7 @@
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
tmp.length(0);
Item *item;
- DBUG_ENTER("send_data");
+ DBUG_ENTER("select_dump::send_data");
if (unit->offset_limit_cnt)
{ // using limit offset,count
--- 1.308/sql/sql_class.h 2006-07-11 12:17:30 +02:00
+++ 1.309/sql/sql_class.h 2006-07-11 12:17:30 +02:00
@@ -1250,7 +1250,7 @@
uint tmp_table, global_read_lock;
uint server_status,open_options;
enum enum_thread_type system_thread;
- uint32 db_length;
+ uint db_length;
uint select_number; //number of select (used for EXPLAIN)
/* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation;
@@ -1571,6 +1571,46 @@
#else
current_stmt_binlog_row_based= FALSE;
#endif
+
+ /*
+ Initialize the current database from a NULL-terminated string with length
+ */
+ void set_db(const char *new_db, uint new_db_len)
+ {
+ if (new_db)
+ {
+ /* Do not reallocate memory if current chunk is big enough. */
+ if (db && db_length >= new_db_len)
+ memcpy(db, new_db, new_db_len+1);
+ else
+ {
+ safeFree(db);
+ db= my_strndup(new_db, new_db_len, MYF(MY_WME));
+ }
+ db_length= db ? new_db_len: 0;
+ }
+ }
+ void reset_db(char *new_db, uint new_db_len)
+ {
+ db= new_db;
+ db_length= new_db_len;
+ }
+ /*
+ Copy the current database to the argument. Use the current arena to
+ allocate memory for a deep copy: current database may be freed after
+ a statement is parsed but before it's executed.
+ */
+ bool copy_db_to(char **p_db, uint *p_db_length)
+ {
+ if (db == NULL)
+ {
+ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
+ return TRUE;
+ }
+ *p_db= strmake(db, db_length);
+ if (p_db_length)
+ *p_db_length= db_length;
+ return FALSE;
}
};
@@ -1920,7 +1960,7 @@
class Table_ident :public Sql_alloc
{
- public:
+public:
LEX_STRING db;
LEX_STRING table;
SELECT_LEX_UNIT *sel;
--- 1.210/sql/sql_insert.cc 2006-07-11 12:17:30 +02:00
+++ 1.211/sql/sql_insert.cc 2006-07-11 12:17:30 +02:00
@@ -64,8 +64,8 @@
static int check_null_fields(THD *thd,TABLE *entry);
#ifndef EMBEDDED_LIBRARY
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
-static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, bool ignore,
- char *query, uint query_length, bool log_on);
+static int write_delayed(THD *thd, TABLE *table, enum_duplicates dup,
+ LEX_STRING query, bool ignore, bool log_on);
static void end_delayed_insert(THD *thd);
pthread_handler_t handle_delayed_insert(void *arg);
static void unlink_blobs(register TABLE *table);
@@ -448,7 +448,6 @@
table->next_number_field=table->found_next_number_field;
error=0;
- id=0;
thd->proc_info="update";
if (duplic != DUP_ERROR || ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@@ -548,22 +547,13 @@
#ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED)
{
- error=write_delayed(thd, table, duplic, ignore, query, thd->query_length, log_on);
+ LEX_STRING const st_query = { query, thd->query_length };
+ error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
query=0;
}
else
#endif
error=write_record(thd, table ,&info);
- /*
- If auto_increment values are used, save the first one
- for LAST_INSERT_ID() and for the update log.
- We can't use insert_id() as we don't want to touch the
- last_insert_id_used flag.
- */
- if (! id && thd->insert_id_used)
- { // Get auto increment value
- id= thd->last_insert_id;
- }
if (error)
break;
thd->row_count++;
@@ -571,6 +561,7 @@
free_underlaid_joins(thd, &thd->lex->select_lex);
joins_freed= TRUE;
+ table->file->ha_release_auto_increment();
/*
Now all rows are inserted. Time to update logs and sends response to
@@ -581,7 +572,6 @@
{
if (!error)
{
- id=0; // No auto_increment id
info.copied=values_list.elements;
end_delayed_insert(thd);
}
@@ -595,11 +585,6 @@
table->file->print_error(my_errno,MYF(0));
error=1;
}
- if (id && values_list.elements != 1)
- thd->insert_id(id); // For update log
- else if (table->next_number_field && info.copied)
- id=table->next_number_field->val_int(); // Return auto_increment value
-
transactional_table= table->file->has_transactions();
if ((changed= (info.copied || info.deleted || info.updated)))
@@ -648,18 +633,27 @@
}
}
thd->proc_info="end";
+ /*
+ We'll report to the client this id:
+ - if the table contains an autoincrement column and we successfully
+ inserted an autogenerated value, the autogenerated value.
+ - if the table contains no autoincrement column and LAST_INSERT_ID(X) was
+ called, X.
+ - if the table contains an autoincrement column, and some rows were
+ inserted, the id of the last "inserted" row (if IGNORE, that value may not
+ have been really inserted but ignored).
+ */
+ id= (thd->first_successful_insert_id_in_cur_stmt > 0) ?
+ thd->first_successful_insert_id_in_cur_stmt :
+ (thd->arg_of_last_insert_id_function ?
+ thd->first_successful_insert_id_in_prev_stmt :
+ ((table->next_number_field && info.copied) ?
+ table->next_number_field->val_int() : 0));
table->next_number_field=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
- thd->next_insert_id=0; // Reset this if wrongly used
if (duplic != DUP_ERROR || ignore)
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
- /* Reset value of LAST_INSERT_ID if no rows where inserted */
- if (!info.copied && thd->insert_id_used)
- {
- thd->insert_id(0);
- id=0;
- }
if (error)
goto abort;
if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
@@ -681,8 +675,6 @@
thd->row_count_func= info.copied+info.deleted+info.updated;
::send_ok(thd, (ulong) thd->row_count_func, id, buff);
}
- if (table != NULL)
- table->file->release_auto_increment();
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
@@ -692,7 +684,7 @@
end_delayed_insert(thd);
#endif
if (table != NULL)
- table->file->release_auto_increment();
+ table->file->ha_release_auto_increment();
if (!joins_freed)
free_underlaid_joins(thd, &thd->lex->select_lex);
thd->abort_on_warning= 0;
@@ -1001,6 +993,8 @@
int error, trg_error= 0;
char *key=0;
MY_BITMAP *save_read_set, *save_write_set;
+ ulonglong prev_insert_id= table->file->next_insert_id;
+ ulonglong insert_id_for_cur_row= 0;
DBUG_ENTER("write_record");
info->records++;
@@ -1013,10 +1007,20 @@
while ((error=table->file->ha_write_row(table->record[0])))
{
uint key_nr;
+ /*
+ If we do more than one iteration of this loop, from the second one the
+ row will have an explicit value in the autoinc field, which was set at
+ the first call of handler::update_auto_increment(). So we must save
+ the autogenerated value to avoid thd->insert_id_for_cur_row to become
+ 0.
+ */
+ if (table->file->insert_id_for_cur_row > 0)
+ insert_id_for_cur_row= table->file->insert_id_for_cur_row;
+ else
+ table->file->insert_id_for_cur_row= insert_id_for_cur_row;
bool is_duplicate_key_error;
if (table->file->is_fatal_error(error, HA_CHECK_DUP))
goto err;
- table->file->restore_auto_increment(); // it's too early here! BUG#20188
is_duplicate_key_error= table->file->is_fatal_error(error, 0);
if (!is_duplicate_key_error)
{
@@ -1044,7 +1048,7 @@
if (info->handle_duplicates == DUP_REPLACE &&
table->next_number_field &&
key_nr == table->s->next_number_index &&
- table->file->auto_increment_column_changed)
+ (insert_id_for_cur_row > 0))
goto err;
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{
@@ -1103,22 +1107,29 @@
if (res == VIEW_CHECK_ERROR)
goto before_trg_err;
- if (thd->clear_next_insert_id)
- {
- /* Reset auto-increment cacheing if we do an update */
- thd->clear_next_insert_id= 0;
- thd->next_insert_id= 0;
- }
if ((error=table->file->ha_update_row(table->record[1],
table->record[0])))
{
if (info->ignore &&
!table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
+ {
+ table->file->restore_auto_increment(prev_insert_id);
goto ok_or_after_trg_err;
+ }
goto err;
}
info->updated++;
-
+ /*
+ If ON DUP KEY UPDATE updates a row instead of inserting one, and
+ there is an auto_increment column, then SELECT LAST_INSERT_ID()
+ returns the id of the updated row:
+ */
+ if (table->next_number_field)
+ {
+ longlong field_val= table->next_number_field->val_int();
+ thd->record_first_successful_insert_id_in_cur_stmt(field_val);
+ table->file->adjust_next_insert_id_after_explicit_value(field_val);
+ }
trg_error= (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE));
@@ -1147,16 +1158,11 @@
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) &&
(!table->triggers || !table->triggers->has_delete_triggers()))
{
- if (thd->clear_next_insert_id)
- {
- /* Reset auto-increment cacheing if we do an update */
- thd->clear_next_insert_id= 0;
- thd->next_insert_id= 0;
- }
if ((error=table->file->ha_update_row(table->record[1],
table->record[0])))
goto err;
info->deleted++;
+ thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
/*
Since we pretend that we have done insert we should call
its after triggers.
@@ -1185,6 +1191,7 @@
}
}
}
+ thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
/*
Restore column maps if they where replaced during an duplicate key
problem.
@@ -1198,12 +1205,13 @@
if (!info->ignore ||
table->file->is_fatal_error(error, HA_CHECK_DUP))
goto err;
- table->file->restore_auto_increment();
+ table->file->restore_auto_increment(prev_insert_id);
goto ok_or_after_trg_err;
}
after_trg_n_copied_inc:
info->copied++;
+ thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
trg_error= (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_AFTER, TRUE));
@@ -1223,6 +1231,7 @@
table->file->print_error(error,MYF(0));
before_trg_err:
+ table->file->restore_auto_increment(prev_insert_id);
if (key)
my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH);
table->column_bitmaps_set(save_read_set, save_write_set);
@@ -1285,14 +1294,20 @@
char *record;
enum_duplicates dup;
time_t start_time;
- bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
- ulonglong last_insert_id;
+ bool query_start_used, ignore, log_query;
+ bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
+ ulonglong first_successful_insert_id_in_prev_stmt;
timestamp_auto_set_type timestamp_field_type;
+ LEX_STRING query;
- delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg)
- :record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
+ delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg,
+ bool ignore_arg, bool log_query_arg)
+ : record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg),
+ query(query_arg)
+ {}
~delayed_row()
{
+ x_free(query.str);
x_free(record);
}
};
@@ -1300,9 +1315,6 @@
class delayed_insert :public ilink {
uint locks_in_memory;
- char *query;
- ulong query_length;
- ulong query_allocated;
public:
THD thd;
TABLE *table;
@@ -1316,7 +1328,7 @@
TABLE_LIST table_list; // Argument
delayed_insert()
- :locks_in_memory(0), query(0), query_length(0), query_allocated(0),
+ :locks_in_memory(0),
table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
group_count(0)
{
@@ -1327,6 +1339,11 @@
thd.command=COM_DELAYED_INSERT;
thd.lex->current_select= 0; // for my_message_sql
thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock()
+ /*
+ Statement-based replication of INSERT DELAYED has problems with RAND()
+ and user vars, so in mixed mode we go to row-based.
+ */
+ thd.set_current_stmt_binlog_row_based_if_mixed();
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
bzero((char*) &table_list, sizeof(table_list)); // Safety
@@ -1342,7 +1359,6 @@
}
~delayed_insert()
{
- my_free(query, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
/* The following is not really needed, but just for safety */
delayed_row *row;
while ((row=rows.get()))
@@ -1362,25 +1378,6 @@
VOID(pthread_cond_broadcast(&COND_thread_count)); /* Tell main we are ready */
}
- int set_query(char const *q, ulong qlen) {
- if (q && qlen > 0)
- {
- if (query_allocated < qlen + 1)
- {
- ulong const flags(MY_WME|MY_FREE_ON_ERROR|MY_ALLOW_ZERO_PTR);
- query= my_realloc(query, qlen + 1, MYF(flags));
- if (query == 0)
- return HA_ERR_OUT_OF_MEM;
- query_allocated= qlen;
- }
- query_length= qlen;
- memcpy(query, q, qlen + 1);
- }
- else
- query_length= 0;
- return 0;
- }
-
/* The following is for checking when we can delete ourselves */
inline void lock()
{
@@ -1658,13 +1655,14 @@
/* Put a question in queue */
-static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic,
- bool ignore, char *query, uint query_length,
- bool log_on)
+static int
+write_delayed(THD *thd,TABLE *table, enum_duplicates duplic,
+ LEX_STRING query, bool ignore, bool log_on)
{
- delayed_row *row=0;
+ delayed_row *row;
delayed_insert *di=thd->di;
DBUG_ENTER("write_delayed");
+ DBUG_PRINT("enter", ("query = '%s' length %u", query.str, query.length));
thd->proc_info="waiting for handler insert";
pthread_mutex_lock(&di->mutex);
@@ -1672,18 +1670,44 @@
pthread_cond_wait(&di->cond_client,&di->mutex);
thd->proc_info="storing row into queue";
- if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on)))
+ if (thd->killed)
goto err;
+ /*
+ Take a copy of the query string, if there is any. The string will
+ be free'ed when the row is destroyed. If there is no query string,
+ we don't do anything special.
+ */
+
+ if (query.str)
+ {
+ char *str;
+ if (!(str= my_strndup(query.str, query.length, MYF(MY_WME))))
+ goto err;
+ query.str= str;
+ }
+ row= new delayed_row(query, duplic, ignore, log_on);
+ if (row == NULL)
+ {
+ my_free(query.str, MYF(MY_WME));
+ goto err;
+ }
+
if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME))))
goto err;
memcpy(row->record, table->record[0], table->s->reclength);
- di->set_query(query, query_length);
row->start_time= thd->start_time;
row->query_start_used= thd->query_start_used;
- row->last_insert_id_used= thd->last_insert_id_used;
- row->insert_id_used= thd->insert_id_used;
- row->last_insert_id= thd->last_insert_id;
+ /*
+ those are for the binlog: LAST_INSERT_ID() has been evaluated at this
+ time, so record does not need it, but statement-based binlogging of the
+ INSERT will need when the row is actually inserted.
+ As for SET INSERT_ID, DELAYED does not honour it (BUG#20830).
+ */
+ row->stmt_depends_on_first_successful_insert_id_in_prev_stmt=
+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
+ row->first_successful_insert_id_in_prev_stmt=
+ thd->first_successful_insert_id_in_prev_stmt;
row->timestamp_field_type= table->timestamp_field_type;
di->rows.push_back(row);
@@ -1937,6 +1961,7 @@
MYSQL_LOCK *lock=thd->lock;
thd->lock=0;
pthread_mutex_unlock(&di->mutex);
+ di->table->file->ha_release_auto_increment();
mysql_unlock_tables(thd, lock);
di->group_count=0;
pthread_mutex_lock(&di->mutex);
@@ -2037,7 +2062,7 @@
if (thd.killed || table->s->version != refresh_version)
{
thd.killed= THD::KILL_CONNECTION;
- max_rows= ~(ulong)0; // Do as much as possible
+ max_rows= ULONG_MAX; // Do as much as possible
}
/*
@@ -2049,13 +2074,6 @@
table->file->extra(HA_EXTRA_WRITE_CACHE);
pthread_mutex_lock(&mutex);
- /* Reset auto-increment cacheing */
- if (thd.clear_next_insert_id)
- {
- thd.next_insert_id= 0;
- thd.clear_next_insert_id= 0;
- }
-
while ((row=rows.get()))
{
stacked_inserts--;
@@ -2064,9 +2082,12 @@
thd.start_time=row->start_time;
thd.query_start_used=row->query_start_used;
- thd.last_insert_id=row->last_insert_id;
- thd.last_insert_id_used=row->last_insert_id_used;
- thd.insert_id_used=row->insert_id_used;
+ /* for the binlog, forget auto_increment ids generated by previous rows */
+// thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
+ thd.first_successful_insert_id_in_prev_stmt=
+ row->first_successful_insert_id_in_prev_stmt;
+ thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt=
+ row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
table->timestamp_field_type= row->timestamp_field_type;
info.ignore= row->ignore;
@@ -2084,11 +2105,28 @@
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
row->log_query = 0;
}
+
if (using_ignore)
{
using_ignore=0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
}
+
+ if (row->log_query && row->query.str != NULL && mysql_bin_log.is_open())
+ {
+ /*
+ If the query has several rows to insert, only the first row will come
+ here. In row-based binlogging, this means that the first row will be
+ written to binlog as one Table_map event and one Rows event (due to an
+ event flush done in binlog_query()), then all other rows of this query
+ will be binlogged together as one single Table_map event and one
+ single Rows event.
+ */
+ thd.binlog_query(THD::ROW_QUERY_TYPE,
+ row->query.str, row->query.length,
+ FALSE, FALSE);
+ }
+
if (table->s->blob_fields)
free_delayed_insert_blobs(table);
thread_safe_sub(delayed_rows_in_use,1,&LOCK_delayed_status);
@@ -2135,13 +2173,25 @@
pthread_cond_broadcast(&cond_client); // If waiting clients
}
}
-
thd.proc_info=0;
pthread_mutex_unlock(&mutex);
- /* After releasing the mutex, to prevent deadlocks. */
- if (mysql_bin_log.is_open())
- thd.binlog_query(THD::ROW_QUERY_TYPE, query, query_length, FALSE, FALSE);
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ We need to flush the pending event when using row-based
+ replication since the flushing normally done in binlog_query() is
+ not done last in the statement: for delayed inserts, the insert
+ statement is logged *before* all rows are inserted.
+
+ We can flush the pending event without checking the thd->lock
+ since the delayed insert *thread* is not inside a stored function
+ or trigger.
+
+ TODO: Move the logging to last in the sequence of rows.
+ */
+ if (thd.current_stmt_binlog_row_based)
+ thd.binlog_flush_pending_rows_event(TRUE);
+#endif /* HAVE_ROW_BASED_REPLICATION */
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{ // This shouldn't happen
@@ -2229,7 +2279,7 @@
enum_duplicates duplic,
bool ignore_check_option_errors)
:table_list(table_list_par), table(table_par), fields(fields_par),
- last_insert_id(0),
+ autoinc_value_of_last_inserted_row(0),
insert_into_view(table_list_par && table_list_par->view != 0)
{
bzero((char*) &info,sizeof(info));
@@ -2438,15 +2488,20 @@
if (table->next_number_field)
{
/*
+ If no value has been autogenerated so far, we need to remember the
+ value we just saw, we may need to send it to client in the end.
+ */
+ if (thd->first_successful_insert_id_in_cur_stmt == 0) // optimization
+ autoinc_value_of_last_inserted_row=
+ table->next_number_field->val_int();
+ /*
Clear auto-increment field for the next record, if triggers are used
we will clear it twice, but this should be cheap.
*/
table->next_number_field->reset();
- if (!last_insert_id && thd->insert_id_used)
- last_insert_id= thd->insert_id();
}
}
- table->file->release_auto_increment();
+ table->file->ha_release_auto_increment();
DBUG_RETURN(error);
}
@@ -2508,8 +2563,6 @@
{
if (!table->file->has_transactions())
{
- if (last_insert_id)
- thd->insert_id(last_insert_id); // For binary log
if (mysql_bin_log.is_open())
{
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
@@ -2529,6 +2582,7 @@
bool select_insert::send_eof()
{
int error,error2;
+ ulonglong id;
DBUG_ENTER("select_insert::send_eof");
error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
@@ -2554,8 +2608,6 @@
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (last_insert_id)
- thd->insert_id(last_insert_id); // For binary log
/*
Write to binlog before commiting transaction. No statement will
be written by the binlog_query() below in RBR mode. All the
@@ -2585,7 +2637,13 @@
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields);
thd->row_count_func= info.copied+info.deleted+info.updated;
- ::send_ok(thd, (ulong) thd->row_count_func, last_insert_id, buff);
+
+ id= (thd->first_successful_insert_id_in_cur_stmt > 0) ?
+ thd->first_successful_insert_id_in_cur_stmt :
+ (thd->arg_of_last_insert_id_function ?
+ thd->first_successful_insert_id_in_prev_stmt :
+ (info.copied ? autoinc_value_of_last_inserted_row : 0));
+ ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
DBUG_RETURN(0);
}
@@ -2751,21 +2809,6 @@
}
-class MY_HOOKS : public TABLEOP_HOOKS
-{
-public:
- MY_HOOKS(select_create *x) : ptr(x) { }
- virtual void do_prelock(TABLE **tables, uint count)
- {
- if (ptr->get_thd()->current_stmt_binlog_row_based)
- ptr->binlog_show_create_table(tables, count);
- }
-
-private:
- select_create *ptr;
-};
-
-
int
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
@@ -2778,8 +2821,9 @@
MY_HOOKS(select_create *x) : ptr(x) { }
virtual void do_prelock(TABLE **tables, uint count)
{
- if (ptr->get_thd()->current_stmt_binlog_row_based)
- ptr->binlog_show_create_table(tables, count);
+ if (ptr->get_thd()->current_stmt_binlog_row_based &&
+ !(ptr->get_create_info()->options & HA_LEX_CREATE_TMP_TABLE))
+ ptr->binlog_show_create_table(tables, count);
}
private:
--- 1.235/sql/sql_lex.h 2006-07-11 12:17:30 +02:00
+++ 1.236/sql/sql_lex.h 2006-07-11 12:17:30 +02:00
@@ -793,6 +793,16 @@
byte **sroutines_list_own_last;
uint sroutines_list_own_elements;
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ Tells if the parsing stage detected that some items require row-based
+ binlogging to give a reliable binlog/replication, or if we will use
+ stored functions or triggers which themselves need require row-based
+ binlogging.
+ */
+ bool binlog_row_based_if_mixed;
+#endif
+
/*
These constructor and destructor serve for creation/destruction
of Query_tables_list instances which are used as backup storage.
@@ -975,11 +985,7 @@
uint8 create_view_check;
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
bool in_comment, ignore_space, verbose, no_write_to_binlog;
- /*
- binlog_row_based_if_mixed tells if the parsing stage detected that some
- items require row-based binlogging to give a reliable binlog/replication.
- */
- bool tx_chain, tx_release, binlog_row_based_if_mixed;
+ bool tx_chain, tx_release;
/*
Special JOIN::prepare mode: changing of query is prohibited.
When creating a view, we need to just check its syntax omitting
--- 1.569/sql/sql_parse.cc 2006-07-11 12:17:30 +02:00
+++ 1.570/sql/sql_parse.cc 2006-07-11 12:17:31 +02:00
@@ -2563,11 +2563,6 @@
statistic_increment(thd->status_var.com_stat[lex->sql_command],
&LOCK_status);
-#ifdef HAVE_ROW_BASED_REPLICATION
- if (lex->binlog_row_based_if_mixed)
- thd->set_current_stmt_binlog_row_based_if_mixed();
-#endif /*HAVE_ROW_BASED_REPLICATION*/
-
switch (lex->sql_command) {
case SQLCOM_SHOW_EVENTS:
if ((res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
@@ -3394,8 +3389,9 @@
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
lex->update_list, lex->value_list,
lex->duplicates, lex->ignore);
+ /* do not show last insert ID if VIEW does not have auto_inc */
if (first_table->view && !first_table->contain_auto_increment)
- thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
+ thd->first_successful_insert_id_in_cur_stmt= 0;
break;
}
case SQLCOM_REPLACE_SELECT:
@@ -3455,9 +3451,9 @@
/* revert changes for SP */
select_lex->table_list.first= (byte*) first_table;
}
-
+ /* do not show last insert ID if VIEW does not have auto_inc */
if (first_table->view && !first_table->contain_auto_increment)
- thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
+ thd->first_successful_insert_id_in_cur_stmt= 0;
break;
}
case SQLCOM_TRUNCATE:
@@ -5201,9 +5197,6 @@
*/
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
reset_one_shot_variables(thd);
-#ifdef HAVE_ROW_BASED_REPLICATION
- thd->reset_current_stmt_binlog_row_based();
-#endif /*HAVE_ROW_BASED_REPLICATION*/
/*
The return value for ROW_COUNT() is "implementation dependent" if the
@@ -5835,6 +5828,7 @@
DESCRIPTION
This needs to be called before execution of every statement
(prepared or conventional).
+ It is not called by substatements of routines.
TODO
Make it a method of THD and align its name with the rest of
@@ -5845,9 +5839,12 @@
void mysql_reset_thd_for_next_command(THD *thd)
{
DBUG_ENTER("mysql_reset_thd_for_next_command");
+ DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
thd->free_list= 0;
thd->select_number= 1;
- thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt=
+ thd->query_start_used= 0;
thd->is_fatal_error= thd->time_zone_used= 0;
thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
SERVER_QUERY_NO_INDEX_USED |
@@ -5874,6 +5871,12 @@
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
}
+ /*
+ Because we come here only for start of top-statements, binlog format is
+ constant inside a complex statement (using stored functions) etc.
+ */
+ thd->reset_current_stmt_binlog_row_based();
+
DBUG_VOID_RETURN;
}
--- 1.419/sql/sql_select.cc 2006-07-11 12:17:31 +02:00
+++ 1.420/sql/sql_select.cc 2006-07-11 12:17:31 +02:00
@@ -7895,7 +7895,7 @@
Field *field=((Item_field*) args[0])->field;
if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
(thd->options & OPTION_AUTO_IS_NULL) &&
- thd->insert_id())
+ (thd->first_successful_insert_id_in_prev_stmt > 0))
{
#ifdef HAVE_QUERY_CACHE
query_cache_abort(&thd->net);
@@ -7903,7 +7903,7 @@
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],
new Item_int("last_insert_id()",
- thd->insert_id(),
+ thd->read_first_successful_insert_id_in_prev_stmt(),
21))))
{
cond=new_cond;
@@ -7914,7 +7914,11 @@
*/
cond->fix_fields(thd, &cond);
}
- thd->insert_id(0); // Clear for next request
+ /*
+ IS NULL should be mapped to LAST_INSERT_ID only for first row, so
+ clear for next row
+ */
+ thd->first_successful_insert_id_in_prev_stmt= 0;
}
/* fix to replace 'NULL' dates with '0' (shreeve@stripped) */
else if (((field->type() == FIELD_TYPE_DATE) ||
--- 1.356/sql/sql_table.cc 2006-07-11 12:17:31 +02:00
+++ 1.357/sql/sql_table.cc 2006-07-11 12:17:31 +02:00
@@ -4967,7 +4967,6 @@
char path[FN_REFLEN];
char reg_path[FN_REFLEN+1];
ha_rows copied,deleted;
- ulonglong next_insert_id;
uint db_create_options, used_fields;
handlerton *old_db_type, *new_db_type;
HA_CREATE_INFO *create_info;
@@ -5787,7 +5786,6 @@
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
thd->proc_info="copy to tmp table";
- next_insert_id=thd->next_insert_id; // Remember for logging
copied=deleted=0;
if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
{
@@ -5798,7 +5796,6 @@
handle_duplicates, ignore,
order_num, order, &copied, &deleted);
}
- thd->last_insert_id=next_insert_id; // Needed for correct log
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
/* If we did not need to copy, we might still need to add/drop indexes. */
@@ -6228,6 +6225,7 @@
ha_rows examined_rows;
bool auto_increment_field_copied= 0;
ulong save_sql_mode;
+ ulonglong prev_insert_id;
DBUG_ENTER("copy_data_between_tables");
/*
@@ -6334,6 +6332,7 @@
{
copy_ptr->do_copy(copy_ptr);
}
+ prev_insert_id= to->file->next_insert_id;
if ((error=to->file->ha_write_row((byte*) to->record[0])))
{
if (!ignore || handle_duplicates != DUP_ERROR ||
@@ -6357,7 +6356,7 @@
to->file->print_error(error,MYF(0));
break;
}
- to->file->restore_auto_increment();
+ to->file->restore_auto_increment(prev_insert_id);
delete_count++;
}
else
@@ -6391,6 +6390,7 @@
free_io_cache(from);
*copied= found_count;
*deleted=delete_count;
+ to->file->ha_release_auto_increment();
if (to->file->ha_external_lock(thd,F_UNLCK))
error=1;
DBUG_RETURN(error > 0 ? -1 : 0);
--- 1.198/sql/sql_update.cc 2006-07-11 12:17:31 +02:00
+++ 1.199/sql/sql_update.cc 2006-07-11 12:17:31 +02:00
@@ -135,7 +135,8 @@
SQL_SELECT *select;
READ_RECORD info;
SELECT_LEX *select_lex= &thd->lex->select_lex;
- bool need_reopen;
+ bool need_reopen;
+ ulonglong id;
DBUG_ENTER("mysql_update");
for ( ; ; )
@@ -676,6 +677,10 @@
thd->lock=0;
}
+ /* If LAST_INSERT_ID(X) was used, report X */
+ id= thd->arg_of_last_insert_id_function ?
+ thd->first_successful_insert_id_in_prev_stmt : 0;
+
if (error < 0)
{
char buff[STRING_BUFFER_USUAL_SIZE];
@@ -683,8 +688,7 @@
(ulong) thd->cuted_fields);
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
- send_ok(thd, (ulong) thd->row_count_func,
- thd->insert_id_used ? thd->insert_id() : 0L,buff);
+ send_ok(thd, (ulong) thd->row_count_func, id, buff);
DBUG_PRINT("info",("%d records updated",updated));
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
@@ -1634,6 +1638,7 @@
bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
+ ulonglong id;
thd->proc_info="updating reference tables";
/* Does updates for the last n - 1 tables, returns 0 if ok */
@@ -1686,12 +1691,12 @@
return TRUE;
}
-
+ id= thd->arg_of_last_insert_id_function ?
+ thd->first_successful_insert_id_in_prev_stmt : 0;
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
(ulong) thd->cuted_fields);
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
- ::send_ok(thd, (ulong) thd->row_count_func,
- thd->insert_id_used ? thd->insert_id() : 0L,buff);
+ ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
return FALSE;
}
--- 1.485/sql/sql_yacc.yy 2006-07-11 12:17:31 +02:00
+++ 1.486/sql/sql_yacc.yy 2006-07-11 12:17:31 +02:00
@@ -6403,7 +6403,7 @@
if (udf->type == UDFTYPE_AGGREGATE)
Select->in_sum_expr--;
- Lex->binlog_row_based_if_mixed= 1;
+ Lex->binlog_row_based_if_mixed= TRUE;
switch (udf->returns) {
case STRING_RESULT:
--- 1.95/sql/sql_view.cc 2006-07-11 12:17:31 +02:00
+++ 1.96/sql/sql_view.cc 2006-07-11 12:17:31 +02:00
@@ -996,6 +996,15 @@
table->next_global= view_tables;
}
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ If the view's body needs row-based binlogging (e.g. the VIEW is created
+ from SELECT UUID()), the top statement also needs it.
+ */
+ if (lex->binlog_row_based_if_mixed)
+ old_lex->binlog_row_based_if_mixed= TRUE;
+#endif
+
/*
If we are opening this view as part of implicit LOCK TABLES, then
this view serves as simple placeholder and we should not continue
--- 1.129/mysql-test/mysql-test-run.pl 2006-07-11 12:17:31 +02:00
+++ 1.130/mysql-test/mysql-test-run.pl 2006-07-11 12:17:31 +02:00
@@ -216,6 +216,7 @@
our $opt_fast;
our $opt_force;
our $opt_reorder;
+our $opt_enable_disabled;
our $opt_gcov;
our $opt_gcov_err;
@@ -290,7 +291,7 @@
our $opt_valgrind= 0;
our $opt_valgrind_mysqld= 0;
our $opt_valgrind_mysqltest= 0;
-our $default_valgrind_options= "-v --show-reachable=yes";
+our $default_valgrind_options= "--show-reachable=yes";
our $opt_valgrind_options;
our $opt_valgrind_path;
@@ -665,6 +666,7 @@
'netware' => \$opt_netware,
'old-master' => \$opt_old_master,
'reorder' => \$opt_reorder,
+ 'enable-disabled' => \$opt_enable_disabled,
'script-debug' => \$opt_script_debug,
'sleep=i' => \$opt_sleep,
'socket=s' => \$opt_socket,
@@ -1799,12 +1801,12 @@
mtr_print_thick_line();
- mtr_report("Finding Tests in the '$suite' suite");
-
mtr_timer_start($glob_timers,"suite", 60 * $opt_suite_timeout);
mtr_report("Starting Tests in the '$suite' suite");
+ mtr_report_tests_not_skipped_though_disabled($tests);
+
mtr_print_header();
foreach my $tinfo ( @$tests )
@@ -3278,9 +3280,16 @@
}
+sub generate_cmdline_mysqldump ($) {
+ my($info) = @_;
+ return
+ "$exe_mysqldump --no-defaults -uroot " .
+ "--port=$info->[0]->{'path_myport'} " .
+ "--socket=$info->[0]->{'path_mysock'} --password=";
+}
+
sub run_mysqltest ($) {
my $tinfo= shift;
-
my $cmdline_mysqlcheck= "$exe_mysqlcheck --no-defaults -uroot " .
"--port=$master->[0]->{'path_myport'} " .
"--socket=$master->[0]->{'path_mysock'} --password=";
@@ -3290,17 +3299,15 @@
" --debug=d:t:A,$opt_vardir_trace/log/mysqlcheck.trace";
}
- my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
- "--port=$master->[0]->{'path_myport'} " .
- "--socket=$master->[0]->{'path_mysock'} --password=";
-
- my $cmdline_mysqldumpslave= "$exe_mysqldump --no-defaults -uroot " .
- "--socket=$slave->[0]->{'path_mysock'} --password=";
+ my $cmdline_mysqldump= generate_cmdline_mysqldump $master;
+ my $cmdline_mysqldumpslave= generate_cmdline_mysqldump $slave;
if ( $opt_debug )
{
$cmdline_mysqldump .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqldump.trace";
+ " --debug=d:t:A,$opt_vardir_trace/log/mysqldump-master.trace";
+ $cmdline_mysqldumpslave .=
+ " --debug=d:t:A,$opt_vardir_trace/log/mysqldump-slave.trace";
}
my $cmdline_mysqlslap;
@@ -3356,6 +3363,12 @@
"$exe_mysql_client_test --no-defaults --testcase --user=root --silent " .
"--port=$master->[0]->{'path_myport'} " .
"--socket=$master->[0]->{'path_mysock'}";
+
+ if ( $opt_debug )
+ {
+ $cmdline_mysql_client_test .=
+ " --debug=d:t:A,$opt_vardir_trace/log/mysql_client_test.trace";
+ }
if ( $glob_use_embedded_server )
{
--- 1.174/mysql-test/t/disabled.def 2006-07-11 12:17:31 +02:00
+++ 1.175/mysql-test/t/disabled.def 2006-07-11 12:17:31 +02:00
@@ -29,7 +29,6 @@
rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
#rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ
rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
-rpl_switch_stm_row_mixed : BUG#18590 2006-03-28 brian
rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly
rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed
rpl_sp : BUG#16456 2006-02-16 jmiller
--- 1.6/mysql-test/r/rpl_row_create_table.result 2006-07-11 12:17:31 +02:00
+++ 1.7/mysql-test/r/rpl_row_create_table.result 2006-07-11 12:17:31 +02:00
@@ -178,6 +178,7 @@
CREATE TABLE t9 LIKE tt4;
CREATE TEMPORARY TABLE tt5 LIKE t4;
CREATE TEMPORARY TABLE tt6 LIKE tt4;
+CREATE TEMPORARY TABLE tt7 SELECT 1;
**** On Master ****
SHOW CREATE TABLE t8;
Table t8
--- 1.6/mysql-test/t/rpl_row_create_table.test 2006-07-11 12:17:31 +02:00
+++ 1.7/mysql-test/t/rpl_row_create_table.test 2006-07-11 12:17:31 +02:00
@@ -97,6 +97,7 @@
CREATE TABLE t9 LIKE tt4;
CREATE TEMPORARY TABLE tt5 LIKE t4;
CREATE TEMPORARY TABLE tt6 LIKE tt4;
+CREATE TEMPORARY TABLE tt7 SELECT 1;
--echo **** On Master ****
--query_vertical SHOW CREATE TABLE t8
--query_vertical SHOW CREATE TABLE t9
--- 1.341/sql/ha_ndbcluster.cc 2006-07-11 12:17:31 +02:00
+++ 1.342/sql/ha_ndbcluster.cc 2006-07-11 12:17:31 +02:00
@@ -2473,9 +2473,7 @@
m_skip_auto_increment= FALSE;
update_auto_increment();
- /* Ensure that handler is always called for auto_increment values */
- thd->next_insert_id= 0;
- m_skip_auto_increment= !auto_increment_column_changed;
+ m_skip_auto_increment= (insert_id_for_cur_row == 0);
}
}
--- 1.180/sql/set_var.cc 2006-07-11 12:17:31 +02:00
+++ 1.181/sql/set_var.cc 2006-07-11 12:17:31 +02:00
@@ -1343,9 +1343,9 @@
return 1;
}
/*
- if in a stored function, it's too late to change mode
+ if in a stored function/trigger, it's too late to change mode
*/
- if (thd->spcont && thd->prelocked_mode)
+ if (thd->in_sub_stmt)
{
my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
return 1;
@@ -2794,7 +2794,8 @@
bool sys_var_last_insert_id::update(THD *thd, set_var *var)
{
- thd->insert_id(var->save_result.ulonglong_value);
+ thd->first_successful_insert_id_in_prev_stmt=
+ var->save_result.ulonglong_value;
return 0;
}
@@ -2802,14 +2803,19 @@
byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
- thd->sys_var_tmp.long_value= (long) thd->insert_id();
- return (byte*) &thd->last_insert_id;
+ /*
+ this tmp var makes it robust againt change of type of
+ read_first_successful_insert_id_in_prev_stmt().
+ */
+ thd->sys_var_tmp.ulonglong_value=
+ thd->read_first_successful_insert_id_in_prev_stmt();
+ return (byte*) &thd->sys_var_tmp.ulonglong_value;
}
bool sys_var_insert_id::update(THD *thd, set_var *var)
{
- thd->next_insert_id= var->save_result.ulonglong_value;
+ thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
return 0;
}
@@ -2817,7 +2823,9 @@
byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
- return (byte*) &thd->next_insert_id;
+ thd->sys_var_tmp.ulonglong_value=
+ thd->auto_inc_intervals_forced.minimum();
+ return (byte*) &thd->sys_var_tmp.ulonglong_value;
}
--- 1.63/sql/ha_federated.cc 2006-07-11 12:17:31 +02:00
+++ 1.64/sql/ha_federated.cc 2006-07-11 12:17:31 +02:00
@@ -630,7 +630,8 @@
DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length,
table->s->connect_string.str));
share->scheme= my_strndup(table->s->connect_string.str,
- table->s->connect_string.length, MYF(0));
+ table->s->connect_string.length,
+ MYF(0));
// Add a null for later termination of table name
share->scheme[table->s->connect_string.length]= 0;
@@ -1708,14 +1709,15 @@
This method ensures that last_insert_id() works properly. What it simply does
is calls last_insert_id() on the foreign database immediately after insert
(if the table has an auto_increment field) and sets the insert id via
- thd->insert_id(ID) (as well as storing thd->prev_insert_id)
+ thd->insert_id(ID)).
*/
void ha_federated::update_auto_increment(void)
{
THD *thd= current_thd;
DBUG_ENTER("ha_federated::update_auto_increment");
- thd->insert_id(mysql->last_used_con->insert_id);
+ thd->first_successful_insert_id_in_cur_stmt=
+ mysql->last_used_con->insert_id;
DBUG_PRINT("info",("last_insert_id %d", stats.auto_increment_value));
DBUG_VOID_RETURN;
--- 1.113/sql/sp.cc 2006-07-11 12:17:31 +02:00
+++ 1.114/sql/sp.cc 2006-07-11 12:17:31 +02:00
@@ -1630,6 +1630,7 @@
sp->add_used_tables_to_table_list(thd, &lex->query_tables_last,
rt->belong_to_view);
}
+ sp->propagate_attributes(lex);
}
first= FALSE;
}
@@ -1727,14 +1728,16 @@
{
for (int j= 0; j < (int)TRG_ACTION_MAX; j++)
{
- if (triggers->bodies[i][j])
+ sp_head *trigger_body= triggers->bodies[i][j];
+ if (trigger_body)
{
- (void)triggers->bodies[i][j]->
- add_used_tables_to_table_list(thd, &lex->query_tables_last,
- table->belong_to_view);
+ (void)trigger_body->
+ add_used_tables_to_table_list(thd, &lex->query_tables_last,
+ table->belong_to_view);
sp_update_stmt_used_routines(thd, lex,
- &triggers->bodies[i][j]->m_sroutines,
+ &trigger_body->m_sroutines,
table->belong_to_view);
+ trigger_body->propagate_attributes(lex);
}
}
}
--- 1.228/sql/sp_head.cc 2006-07-11 12:17:31 +02:00
+++ 1.229/sql/sp_head.cc 2006-07-11 12:17:31 +02:00
@@ -1661,6 +1661,16 @@
oldlex->next_state= sublex->next_state;
oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ If this substatement needs row-based, the entire routine does too (we
+ cannot switch from statement-based to row-based only for this
+ substatement).
+ */
+ if (sublex->binlog_row_based_if_mixed)
+ m_flags|= BINLOG_ROW_BASED_IF_MIXED;
+#endif
+
/*
Add routines which are used by statement to respective set for
this routine.
--- 1.88/sql/sp_head.h 2006-07-11 12:17:31 +02:00
+++ 1.89/sql/sp_head.h 2006-07-11 12:17:31 +02:00
@@ -117,7 +117,8 @@
/* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */
HAS_COMMIT_OR_ROLLBACK= 128,
LOG_SLOW_STATEMENTS= 256, // Used by events
- LOG_GENERAL_LOG= 512 // Used by events
+ LOG_GENERAL_LOG= 512, // Used by events
+ BINLOG_ROW_BASED_IF_MIXED= 1024
};
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
@@ -341,6 +342,25 @@
#ifndef DBUG_OFF
int show_routine_code(THD *thd);
#endif
+
+ /*
+ This method is intended for attributes of a routine which need
+ to propagate upwards to the LEX of the caller (when a property of a
+ sp_head needs to "taint" the caller).
+ */
+ void propagate_attributes(LEX *lex)
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ If this routine needs row-based binary logging, the entire top statement
+ too (we cannot switch from statement-based to row-based only for this
+ routine, as in statement-based the top-statement may be binlogged and
+ the substatements not).
+ */
+ if (m_flags & BINLOG_ROW_BASED_IF_MIXED)
+ lex->binlog_row_based_if_mixed= TRUE;
+#endif
+ }
private:
| Thread |
|---|
| • bk commit into 5.1 tree (mkindahl:1.2249) | Mats Kindahl | 11 Jul |