Commit 1a260574 authored by unknown's avatar unknown
Browse files

Making rpl_until more robust if machine is slow. Removing rpl_trunc_binlog

which is wrong now that slave recovers gracefully from a crashed binlog (thx Serg).
stat -> my_stat in my_copy.c so that failing stat() does not hang client connection.


BitKeeper/deleted/.del-rpl_trunc_binlog.test~961b1f6ac73d37c8:
  Delete: mysql-test/t/rpl_trunc_binlog.test
BitKeeper/deleted/.del-rpl_trunc_binlog.result~14b4a61886a332e8:
  Delete: mysql-test/r/rpl_trunc_binlog.result
mysql-test/std_data/trunc_binlog.000001:
  Rename: BitKeeper/deleted/.del-trunc_binlog.000001~b504d840c7efde25 -> mysql-test/std_data/trunc_binlog.000001
mysql-test/t/rpl_until.test:
  making test more robust if machine is slow. We still need to sleep before testing if slave SQL thread stopped, because otherwise it may not have started yet when we test for stop, then we would return too early. When we have "START SLAVE" wait a few secs until slave threads actually started well (WL#2688) these "sleep 2" could be removed.
mysys/my_copy.c:
  Using my_stat() instead of stat(). Reason is that my_stat() reports an error message if wanted (MY_WME),
  which is critical for an error being sent to the client. Before this patch, a failing stat() caused
  the client connection to hang (because error was not set because my_error was never called).
  Adding an assertion to match the comment at the start of the function.
parent ba50dc04
Loading
Loading
Loading
Loading
+0 −17
Original line number Diff line number Diff line
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
stop slave;
flush logs;
create table t1 (a int) engine=bdb;
reset slave;
start slave;
show slave status;
Slave_IO_State	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	Replicate_Do_Table	Replicate_Ignore_Table	Replicate_Wild_Do_Table	Replicate_Wild_Ignore_Table	Last_Errno	Last_Error	Skip_Counter	Exec_Master_Log_Pos	Relay_Log_Space	Until_Condition	Until_Log_File	Until_Log_Pos	Master_SSL_Allowed	Master_SSL_CA_File	Master_SSL_CA_Path	Master_SSL_Cert	Master_SSL_Cipher	Master_SSL_Key	Seconds_Behind_Master
#	127.0.0.1	root	MASTER_PORT	1	master-bin.000002	4	#	#	master-bin.000002	Yes	Yes							0	Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log.	0	4	#	None		0	No						#
select * from t1;
a
drop table t1;
+0 −35
Original line number Diff line number Diff line
# We are testing if a binlog which contains BEGIN but not COMMIT (the
# master died while writing the transaction to the binlog) triggers a
# rollback on slave.  So we use such a truncated binlog and simulate that
# the master restarted after this.

source include/master-slave.inc;

connection slave;
# If we are not supporting transactions in the slave, the unfinished
# transaction won't cause any error, so we need to skip the test. In the 4.0
# testsuite, the slave always runs without InnoDB, so we check for BDB.
source include/have_bdb.inc;
stop slave;

connection master;
flush logs;
system mv -f var/log/master-bin.000001 var/log/master-bin.000002;
system cp std_data/trunc_binlog.000001 var/log/master-bin.000001;

connection slave;

# truncated binlog contains: BEGIN; INSERT t1 VALUES (1);
# so let's create the table t1 on slave

create table t1 (a int) engine=bdb;
reset slave;
start slave;
# can't sync_with_master so we must sleep
sleep 3;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
select * from t1;
drop table t1;
+6 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ show binlog events;
connection slave;
start slave until master_log_file='master-bin.000001', master_log_pos=319;
sleep 2;
wait_for_slave_to_stop;
# here table should be still not deleted
select * from t1;
--replace_result $MASTER_MYPORT MASTER_MYPORT
@@ -37,13 +38,15 @@ start slave until master_log_file='master-no-such-bin.000001', master_log_pos=29
# again this table should be still not deleted
select * from t1;
sleep 2;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 23 # 33 #
show slave status;

# try replicate all until second insert to t2;
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
sleep 4;
sleep 2;
wait_for_slave_to_stop;
select * from t2;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 23 # 33 #
@@ -59,8 +62,8 @@ stop slave;

# this should stop immediately as we are already there
start slave until master_log_file='master-bin.000001', master_log_pos=776;
# 2 is not enough when running with valgrind
real_sleep 4
sleep 2;
wait_for_slave_to_stop;
# here the sql slave thread should be stopped
--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
--replace_column 1 # 9 # 23 # 33 #
+10 −8
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

#define USES_TYPES				/* sys/types is included */
#include "mysys_priv.h"
#include <sys/stat.h>
#include <my_dir.h> /* for stat */
#include <m_string.h>
#if defined(HAVE_UTIME_H)
#include <utime.h>
@@ -53,26 +53,28 @@ struct utimbuf {
int my_copy(const char *from, const char *to, myf MyFlags)
{
  uint Count;
  int new_file_stat, create_flag;
  my_bool new_file_stat; /* 1 if we could stat "to" */
  int create_flag;
  File from_file,to_file;
  char buff[IO_SIZE];
  struct stat stat_buff,new_stat_buff;
  MY_STAT stat_buff,new_stat_buff;
  DBUG_ENTER("my_copy");
  DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));

  from_file=to_file= -1;
  new_file_stat=0;
  LINT_INIT(new_file_stat);
  DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */
  if (MyFlags & MY_HOLD_ORIGINAL_MODES)		/* Copy stat if possible */
    new_file_stat=stat((char*) to, &new_stat_buff);
    new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0)));

  if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0)
  {
    if (stat(from,&stat_buff))
    if (!my_stat(from, &stat_buff, MyFlags))
    {
      my_errno=errno;
      goto err;
    }
    if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
    if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
      stat_buff=new_stat_buff;
    create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;

@@ -91,7 +93,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)

    /* Copy modes if possible */

    if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
    if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
	DBUG_RETURN(0);			/* File copyed but not stat */
    VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */
#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)