Below is the list of changes that have just been committed into a
4.0 repository of sasha. When sasha does a push, they will be propogated 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://www.mysql.com/doc/I/n/Installing_source_tree.html
ChangeSet@stripped, 2002-01-24 22:49:47-07:00, sasha@stripped
more predicatable slave behaviour with wait_for_slave_stop in mysqltest
fixed a couple of bugs with SEQ_READ_APPEND cache
rpl000016 still has non-deterministic result, but I am going to commit and
push since what I have is now better than what is in the main repository
sql/log_event.cc
1.73 02/01/24 22:49:47 sasha@stripped +38 -26
3.23 master compat
sql/slave.cc
1.148 02/01/24 22:49:47 sasha@stripped +72 -17
3.23 master compat
sql/sql_class.h
1.108 02/01/24 22:49:47 sasha@stripped +1 -0
compat with 3.23 master
client/mysqltest.c
1.76 02/01/24 22:49:46 sasha@stripped +51 -6
added wait_for_slave_to_stop
cleaned up TODO and comments
include/my_sys.h
1.64 02/01/24 22:49:46 sasha@stripped +4 -1
fixed race in flush_io_cache in SEQ_READ_APPEND cache
mysql-test/r/rpl000016.result
1.23 02/01/24 22:49:46 sasha@stripped +1 -2
updated result
mysql-test/t/rpl000016.test
1.27 02/01/24 22:49:46 sasha@stripped +1 -3
use wait_for_slave_to_stop to have deterministic slave behaviour for the test
mysys/mf_iocache.c
1.18 02/01/24 22:49:46 sasha@stripped +19 -3
fixed race in flush_io_cache()
fixed failure to unlock mutex in my_b_append()
sql/log.cc
1.73 02/01/24 22:49:46 sasha@stripped +25 -0
be compatible with 3.23 master
# 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: sasha
# Host: mysql.sashanet.com
# Root: /reiser-data/mysql-4.0
--- 1.63/include/my_sys.h Sat Jan 19 19:22:41 2002
+++ 1.64/include/my_sys.h Thu Jan 24 22:49:46 2002
@@ -643,7 +643,10 @@
extern int my_b_append(IO_CACHE *info,const byte *Buffer,uint Count);
extern int my_block_write(IO_CACHE *info, const byte *Buffer,
uint Count, my_off_t pos);
-extern int flush_io_cache(IO_CACHE *info);
+extern int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
+
+#define flush_io_cache(info) _flush_io_cache((info),1)
+
extern int end_io_cache(IO_CACHE *info);
extern uint my_b_fill(IO_CACHE *info);
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
--- 1.17/mysys/mf_iocache.c Sat Jan 19 19:22:42 2002
+++ 1.18/mysys/mf_iocache.c Thu Jan 24 22:49:46 2002
@@ -808,13 +808,19 @@
Buffer+=rest_length;
Count-=rest_length;
info->write_pos+=rest_length;
- if (flush_io_cache(info))
+ if (_flush_io_cache(info,0))
+ {
+ unlock_append_buffer(info);
return 1;
+ }
if (Count >= IO_SIZE)
{ /* Fill first intern buffer */
length=Count & (uint) ~(IO_SIZE-1);
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
+ {
+ unlock_append_buffer(info);
return info->error= -1;
+ }
Count-=length;
Buffer+=length;
}
@@ -883,14 +889,16 @@
/* Flush write cache */
-int flush_io_cache(IO_CACHE *info)
+int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
{
uint length;
my_bool append_cache;
my_off_t pos_in_file;
DBUG_ENTER("flush_io_cache");
- append_cache = (info->type == SEQ_READ_APPEND);
+ if (!(append_cache = (info->type == SEQ_READ_APPEND)))
+ need_append_buffer_lock=0;
+
if (info->type == WRITE_CACHE || append_cache)
{
if (info->file == -1)
@@ -898,6 +906,8 @@
if (real_open_cached_file(info))
DBUG_RETURN((info->error= -1));
}
+ if (need_append_buffer_lock)
+ lock_append_buffer(info);
if ((length=(uint) (info->write_pos - info->write_buffer)))
{
pos_in_file=info->pos_in_file;
@@ -909,6 +919,8 @@
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
{
+ if (need_append_buffer_lock)
+ unlock_append_buffer(info);
DBUG_RETURN((info->error= -1));
}
if (!append_cache)
@@ -932,6 +944,8 @@
info->end_of_file+=(info->write_pos-info->append_read_pos);
info->append_read_pos=info->write_pos=info->write_buffer;
+ if (need_append_buffer_lock)
+ unlock_append_buffer(info);
DBUG_RETURN(info->error);
}
}
@@ -942,6 +956,8 @@
info->inited=0;
}
#endif
+ if (need_append_buffer_lock)
+ unlock_append_buffer(info);
DBUG_RETURN(0);
}
--- 1.72/sql/log.cc Sat Jan 19 22:46:23 2002
+++ 1.73/sql/log.cc Thu Jan 24 22:49:46 2002
@@ -703,11 +703,36 @@
}
}
+bool MYSQL_LOG::append(Log_event* ev)
+{
+ bool error = 0;
+ pthread_mutex_lock(&LOCK_log);
+
+ DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
+ // Log_event::write() is smart enough to use my_b_write() or
+ // my_b_append() depending on the kind of cache we have
+ if (ev->write(&log_file))
+ {
+ error=1;
+ goto err;
+ }
+ if ((uint)my_b_append_tell(&log_file) > max_binlog_size)
+ {
+ new_file(1);
+ }
+ signal_update();
+err:
+ pthread_mutex_unlock(&LOCK_log);
+ return error;
+}
+
bool MYSQL_LOG::appendv(const char* buf, uint len,...)
{
bool error = 0;
va_list(args);
va_start(args,len);
+
+ DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
pthread_mutex_lock(&LOCK_log);
do
--- 1.72/sql/log_event.cc Tue Jan 22 15:05:10 2002
+++ 1.73/sql/log_event.cc Thu Jan 24 22:49:47 2002
@@ -26,6 +26,18 @@
#include <assert.h>
+inline int my_b_safe_write(IO_CACHE* file, const char* buf,
+ int len)
+{
+ // Sasha: We are not writing this with the ? operator to avoid hitting
+ // a possible compiler bug. At least gcc 2.95 cannot deal with
+ // several layers of ternary operators that evaluated comma(,) operator
+ // expressions inside - I do have a test case if somebody wants it
+ if (file->type == SEQ_READ_APPEND)
+ return my_b_append(file,buf,len);
+ return my_b_write(file,buf,len);
+ }
+
#ifdef MYSQL_CLIENT
static void pretty_print_str(FILE* file, char* str, int len)
{
@@ -403,7 +415,7 @@
pos += 4;
int2store(pos, flags);
pos += 2;
- return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
+ return (my_b_safe_write(file, (byte*) buf, (uint) (pos - buf)));
}
#ifndef MYSQL_CLIENT
@@ -677,7 +689,7 @@
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
int4store(buff + ST_CREATED_OFFSET,created);
- return (my_b_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
+ return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
}
Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
@@ -714,8 +726,8 @@
{
char buf[ROTATE_HEADER_LEN];
int8store(buf, pos + R_POS_OFFSET);
- return my_b_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
- my_b_write(file, (byte*)new_log_ident, (uint) ident_len);
+ return my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
+ my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len);
}
#ifndef MYSQL_CLIENT
@@ -812,9 +824,9 @@
buf[Q_DB_LEN_OFFSET] = (char)db_len;
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
- return (my_b_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
- my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
- my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
+ return (my_b_safe_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
+ my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
+ my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
}
Intvar_log_event::Intvar_log_event(const char* buf, bool old_format):
@@ -840,7 +852,7 @@
char buf[9];
buf[I_TYPE_OFFSET] = type;
int8store(buf + I_VAL_OFFSET, val);
- return my_b_write(file, (byte*) buf, sizeof(buf));
+ return my_b_safe_write(file, (byte*) buf, sizeof(buf));
}
#ifdef MYSQL_CLIENT
@@ -878,7 +890,7 @@
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
buf[L_DB_LEN_OFFSET] = (char)db_len;
int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
- return my_b_write(file, (byte*)buf, LOAD_HEADER_LEN);
+ return my_b_safe_write(file, (byte*)buf, LOAD_HEADER_LEN);
}
int Load_log_event::write_data_body(IO_CACHE* file)
@@ -886,20 +898,20 @@
if (sql_ex.write_data(file)) return 1;
if (num_fields && fields && field_lens)
{
- if (my_b_write(file, (byte*)field_lens, num_fields) ||
- my_b_write(file, (byte*)fields, field_block_len))
+ if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
+ my_b_safe_write(file, (byte*)fields, field_block_len))
return 1;
}
- return (my_b_write(file, (byte*)table_name, table_name_len + 1) ||
- my_b_write(file, (byte*)db, db_len + 1) ||
- my_b_write(file, (byte*)fname, fname_len));
+ return (my_b_safe_write(file, (byte*)table_name, table_name_len + 1) ||
+ my_b_safe_write(file, (byte*)db, db_len + 1) ||
+ my_b_safe_write(file, (byte*)fname, fname_len));
}
static bool write_str(IO_CACHE *file, char *str, byte length)
{
- return (my_b_write(file, &length, 1) ||
- my_b_write(file, (byte*) str, (int) length));
+ return (my_b_safe_write(file, &length, 1) ||
+ my_b_safe_write(file, (byte*) str, (int) length));
}
int sql_ex_info::write_data(IO_CACHE* file)
@@ -911,7 +923,7 @@
write_str(file, line_term, line_term_len) ||
write_str(file, line_start, line_start_len) ||
write_str(file, escaped, escaped_len) ||
- my_b_write(file,(byte*) &opt_flags,1));
+ my_b_safe_write(file,(byte*) &opt_flags,1));
}
else
{
@@ -923,7 +935,7 @@
old_ex.escaped= *escaped;
old_ex.opt_flags= opt_flags;
old_ex.empty_flags=empty_flags;
- return my_b_write(file, (byte*) &old_ex, sizeof(old_ex));
+ return my_b_safe_write(file, (byte*) &old_ex, sizeof(old_ex));
}
}
@@ -1280,7 +1292,7 @@
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
// log and host are already there
- return my_b_write(file, (byte*)mem_pool, get_data_size());
+ return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
}
void Slave_log_event::init_from_mem_pool(int data_size)
@@ -1330,8 +1342,8 @@
int res;
if ((res = Load_log_event::write_data_body(file)) || fake_base)
return res;
- return (my_b_write(file, (byte*) "", 1) ||
- my_b_write(file, (byte*) block, block_len));
+ return (my_b_safe_write(file, (byte*) "", 1) ||
+ my_b_safe_write(file, (byte*) block, block_len));
}
int Create_file_log_event::write_data_header(IO_CACHE* file)
@@ -1341,7 +1353,7 @@
return res;
byte buf[CREATE_FILE_HEADER_LEN];
int4store(buf + CF_FILE_ID_OFFSET, file_id);
- return my_b_write(file, buf, CREATE_FILE_HEADER_LEN);
+ return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN);
}
int Create_file_log_event::write_base(IO_CACHE* file)
@@ -1423,8 +1435,8 @@
{
byte buf[APPEND_BLOCK_HEADER_LEN];
int4store(buf + AB_FILE_ID_OFFSET, file_id);
- return (my_b_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
- my_b_write(file, (byte*) block, block_len));
+ return (my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
+ my_b_safe_write(file, (byte*) block, block_len));
}
#ifdef MYSQL_CLIENT
@@ -1473,7 +1485,7 @@
{
byte buf[DELETE_FILE_HEADER_LEN];
int4store(buf + DF_FILE_ID_OFFSET, file_id);
- return my_b_write(file, buf, DELETE_FILE_HEADER_LEN);
+ return my_b_safe_write(file, buf, DELETE_FILE_HEADER_LEN);
}
#ifdef MYSQL_CLIENT
@@ -1520,7 +1532,7 @@
{
byte buf[EXEC_LOAD_HEADER_LEN];
int4store(buf + EL_FILE_ID_OFFSET, file_id);
- return my_b_write(file, buf, EXEC_LOAD_HEADER_LEN);
+ return my_b_safe_write(file, buf, EXEC_LOAD_HEADER_LEN);
}
#ifdef MYSQL_CLIENT
--- 1.147/sql/slave.cc Tue Jan 22 15:05:10 2002
+++ 1.148/sql/slave.cc Thu Jan 24 22:49:47 2002
@@ -54,6 +54,9 @@
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
void skip_load_data_infile(NET* net);
+static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev);
+static int queue_old_event(MASTER_INFO* mi, const char* buf,
+ uint event_len);
static inline bool slave_killed(THD* thd,MASTER_INFO* mi);
static inline bool slave_killed(THD* thd,RELAY_LOG_INFO* rli);
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
@@ -1918,34 +1921,86 @@
DBUG_RETURN(0); // Can't return anything here
}
+static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev)
+{
+ if (!rev->is_valid())
+ return 1;
+ DBUG_ASSERT(rev->ident_len<sizeof(mi->master_log_name));
+ memcpy(mi->master_log_name,rev->new_log_ident,
+ rev->ident_len);
+ mi->master_log_name[rev->ident_len] = 0;
+ mi->master_log_pos = rev->pos;
+#ifndef DBUG_OFF
+ /* if we do not do this, we will be getting the first
+ rotate event forever, so
+ we need to not disconnect after one
+ */
+ if (disconnect_slave_event_count)
+ events_till_disconnect++;
+#endif
+ return 0;
+}
+
+static int queue_old_event(MASTER_INFO* mi, const char* buf,
+ uint event_len)
+{
+ const char* errmsg = 0;
+ bool inc_pos = 1;
+ Log_event* ev = Log_event::read_log_event(buf,event_len, &errmsg,
+ 1/*old format*/);
+ if (!ev)
+ {
+ sql_print_error("Read invalid event from master: '%s',\
+ master could be corrupt but a more likely cause of this is a bug",
+ errmsg);
+ return 1;
+ }
+ ev->log_pos = mi->master_log_pos;
+ switch (ev->get_type_code())
+ {
+ case ROTATE_EVENT:
+ if (process_io_rotate(mi,(Rotate_log_event*)ev))
+ {
+ delete ev;
+ return 1;
+ }
+ inc_pos = 0;
+ break;
+ case LOAD_EVENT:
+ // TODO: actually process it
+ mi->master_log_pos += event_len;
+ return 0;
+ break;
+ default:
+ break;
+ }
+ if (mi->rli.relay_log.append(ev))
+ {
+ delete ev;
+ return 1;
+ }
+ delete ev;
+ if (inc_pos)
+ mi->master_log_pos += event_len;
+ return 0;
+}
+
int queue_event(MASTER_INFO* mi,const char* buf,uint event_len)
{
int error;
bool inc_pos = 1;
if (mi->old_format)
- return 1; // TODO: deal with old format
-
+ return queue_old_event(mi,buf,event_len);
+ // TODO: figure out if other events in addition to Rotate
+ // require special processing
switch (buf[EVENT_TYPE_OFFSET])
{
case ROTATE_EVENT:
{
Rotate_log_event rev(buf,event_len,0);
- if (!rev.is_valid())
+ if (process_io_rotate(mi,&rev))
return 1;
- DBUG_ASSERT(rev.ident_len<sizeof(mi->master_log_name));
- memcpy(mi->master_log_name,rev.new_log_ident,
- rev.ident_len);
- mi->master_log_name[rev.ident_len] = 0;
- mi->master_log_pos = rev.pos;
- inc_pos = 0;
-#ifndef DBUG_OFF
- /* if we do not do this, we will be getting the first
- rotate event forever, so
- we need to not disconnect after one
- */
- if (disconnect_slave_event_count)
- events_till_disconnect++;
-#endif
+ inc_pos=0;
break;
}
default:
--- 1.107/sql/sql_class.h Tue Jan 22 15:05:10 2002
+++ 1.108/sql/sql_class.h Thu Jan 24 22:49:47 2002
@@ -108,6 +108,7 @@
//v stands for vector
//invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
bool appendv(const char* buf,uint len,...);
+ bool append(Log_event* ev);
int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident);
--- 1.75/client/mysqltest.c Sat Dec 22 06:13:31 2001
+++ 1.76/client/mysqltest.c Thu Jan 24 22:49:46 2002
@@ -15,7 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* mysqltest test tool
- * See man page for more information.
+ * See the manual for more information
+ * TODO: document better how mysqltest works
*
* Written by:
* Sasha Pachev <sasha@stripped>
@@ -26,9 +27,6 @@
/**********************************************************************
TODO:
-- Print also the queries that returns a result to the log file; This makes
- it much easier to find out what's wrong.
-
- Do comparison line by line, instead of doing a full comparison of
the text file. This will save space as we don't need to keep many
results in memory. It will also make it possible to do simple
@@ -43,7 +41,7 @@
**********************************************************************/
-#define MTEST_VERSION "1.13"
+#define MTEST_VERSION "1.14"
#include <my_global.h>
#include <mysql_embed.h>
@@ -88,6 +86,12 @@
#define CON_RETRY_SLEEP 2
#define MAX_CON_TRIES 5
+#ifndef OS2
+#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
+#else
+#defile SLAVE_POLL_INTERVAL 0.3
+#endif
+
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT};
@@ -187,6 +191,7 @@
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
+Q_WAIT_FOR_SLAVE_TO_STOP,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
Q_COMMENT_WITH_COMMAND
@@ -222,7 +227,7 @@
"enable_query_log", "disable_query_log",
"enable_result_log", "disable_result_log",
"server_start", "server_stop",
- "require_manager",
+ "require_manager", "wait_for_slave_to_stop",
0
};
@@ -653,6 +658,45 @@
return 0;
}
+/* ugly long name, but we are following the convention */
+int do_wait_for_slave_to_stop(struct st_query* __attribute__((unused)) q)
+{
+ MYSQL* mysql = &cur_con->mysql;
+#ifndef OS2
+ struct timeval t;
+#endif
+ for (;;)
+ {
+ MYSQL_RES* res;
+ MYSQL_ROW row;
+ int done;
+ LINT_INIT(res);
+
+ if (mysql_query(mysql,"show status like 'Slave_running'")
+ || !(res=mysql_store_result(mysql)))
+ die("Query failed while probing slave for stop: %s",
+ mysql_error(mysql));
+ if (!(row=mysql_fetch_row(res)) || !row[1])
+ {
+ mysql_free_result(res);
+ die("Strange result from query while probing slave for stop");
+ }
+ done = !strcmp(row[1],"OFF");
+ mysql_free_result(res);
+ if (done)
+ break;
+#ifndef OS2
+ t.tv_sec=0;
+ t.tv_usec=SLAVE_POLL_INTERVAL;
+ select(0,0,0,0,&t); /* sleep */
+#else
+ DosSleep(OS2_SLAVE_POLL_INTERVAL);
+#endif
+ }
+
+ return 0;
+}
+
int do_require_manager(struct st_query* __attribute__((unused)) q)
{
if (!manager)
@@ -2335,6 +2379,7 @@
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
case Q_SOURCE: do_source(q); break;
case Q_SLEEP: do_sleep(q); break;
+ case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break;
case Q_REQUIRE_MANAGER: do_require_manager(q); break;
#ifndef EMBEDDED_LIBRARY
case Q_SERVER_START: do_server_start(q); break;
--- 1.22/mysql-test/r/rpl000016.result Tue Jan 22 15:05:10 2002
+++ 1.23/mysql-test/r/rpl000016.result Thu Jan 24 22:49:46 2002
@@ -33,7 +33,6 @@
insert into t2 values(1234);
set insert_id=1234;
insert into t2 values(NULL);
-slave stop;
set sql_slave_skip_counter=1;
slave start;
purge master logs to 'master-bin.003';
@@ -66,7 +65,7 @@
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
-127.0.0.1 root MASTER_PORT 60 master-bin.006 445 mysql-relay-bin.004 1312 master-bin.006 Yes Yes 0 0 445
+127.0.0.1 root MASTER_PORT 60 master-bin.006 445 mysql-relay-bin.004 1376 master-bin.006 Yes Yes 0 0 445
lock tables t3 read;
select count(*) from t3 where n >= 4;
count(*)
--- 1.26/mysql-test/t/rpl000016.test Fri Dec 14 19:41:20 2001
+++ 1.27/mysql-test/t/rpl000016.test Thu Jan 24 22:49:46 2002
@@ -51,9 +51,7 @@
connection slave;
sync_with_master;
-#the slave may have already stopped, so we ignore the error
---error 0,1199
-!slave stop;
+wait_for_slave_to_stop;
#restart slave skipping one event
set sql_slave_skip_counter=1;
| Thread |
|---|
| • bk commit into 4.0 tree | sasha | 25 Jan |