List:Internals« Previous MessageNext Message »
From:Kay Roepke Date:June 6 2007 12:08pm
Subject:[PATCH] first version of proposed patch for #28760
View as plain text  
Hi!

Below is a patch for the new replication delay feature (see <http:// 
bugs.mysql.com/bug.php?id=28760>, <http://forge.mysql.com/worklog/ 
task.php?id=344> for implementation details).
The diff is against mysql-5.1-bk from last night, so it should apply  
cleanly.
It implements setting the replication delay by adding a new option to  
the CHANGE MASTER statement, but currently doesn't add any new  
options (like connect_retry and the like are).

The delay works as follows:
If the slave is already lagging behind, the delay will be the  
difference between the current lag and delay time specified via  
CHANGE MASTER TO MASTER_DELAY=xxx. Essentially the delay is a lower  
bound for the replication lag.

There are some points I'd like to clarify before I consider the patch  
"ready":
a) Should the delay setting be written to master.info and if it  
should, in which line should it go.
The reason I ask is because the SSL settings are optional in that  
file and adding 'delay' at the end could cause compatibility problems.
However adding it in the middle seems like a worse idea still.

b) While testing I noticed that the first log_event received by the  
slave is delayed by a shorter time than the delay parameter, but the  
second event will be delayed by the full amount specified. From the  
relay logs it seemed to me that rotate_log events where delayed also,  
does that make sense? At first sight I couldn't see a way to  
differentiate between query and other events, but I might have missed  
something.
The test scenario I used was:
preparation) master/slave: use test; create table test (a int);
1) start master on port 33306
2) start slave (port 33307) replicating db 'test' with a master.info  
already configured.
3) slave: stop slave;
4) slave: change master to master_delay=30;   # because that info is  
not yet in master.info
5) slave: start slave;
6) master: insert into test set a=42;
7) slave: delaying some event (looks like rotate_log to me) by some  
3-8 secs, afterwards delaying the insert for the full 30 secs.

This hasn't happened afterwards, though I have not yet generated a  
big amount of statements to cause log rotation. I'd like to gather  
some advice first ;)

c) Should there be a command line option for master_delay?
d) Is the format of the patch ok, I had problems sending attachments  
to the list, so I put it in the body...

cheers,
-k
-- 
Kay Röpke
http://classdump.org/




diff -urN mysql-5.1-bk-clean/sql/lex.h mysql-5.1-bk/sql/lex.h
--- mysql-5.1-bk-clean/sql/lex.h	2007-04-02 10:54:27.000000000 +0200
+++ mysql-5.1-bk/sql/lex.h	2007-06-06 01:11:43.000000000 +0200
@@ -300,6 +300,7 @@
    { "LOW_PRIORITY",	SYM(LOW_PRIORITY)},
    { "MASTER",           SYM(MASTER_SYM)},
    { "MASTER_CONNECT_RETRY",           SYM(MASTER_CONNECT_RETRY_SYM)},
+  { "MASTER_DELAY",           SYM(MASTER_DELAY_SYM)},
    { "MASTER_HOST",           SYM(MASTER_HOST_SYM)},
    { "MASTER_LOG_FILE",           SYM(MASTER_LOG_FILE_SYM)},
    { "MASTER_LOG_POS",           SYM(MASTER_LOG_POS_SYM)},
diff -urN mysql-5.1-bk-clean/sql/mysqld.cc mysql-5.1-bk/sql/mysqld.cc
--- mysql-5.1-bk-clean/sql/mysqld.cc	2007-06-04 12:14:18.000000000 +0200
+++ mysql-5.1-bk/sql/mysqld.cc	2007-06-06 03:02:56.000000000 +0200
@@ -574,7 +574,7 @@
File_parser_dummy_hook file_parser_dummy_hook;
/* replication parameters, if master_host is not NULL, we are a slave */
-uint master_port= MYSQL_PORT, master_connect_retry = 60;
+uint master_port= MYSQL_PORT, master_connect_retry= 60,  
master_delay= 0;
uint report_port= MYSQL_PORT;
ulong master_retry_count=0;
char *master_user, *master_password, *master_host, *master_info_file;
diff -urN mysql-5.1-bk-clean/sql/rpl_mi.cc mysql-5.1-bk/sql/rpl_mi.cc
--- mysql-5.1-bk-clean/sql/rpl_mi.cc	2007-04-16 18:16:13.000000000 +0200
+++ mysql-5.1-bk/sql/rpl_mi.cc	2007-06-06 03:03:36.000000000 +0200
@@ -30,7 +30,8 @@
MASTER_INFO::MASTER_INFO()
    :ssl(0), fd(-1),  io_thd(0), inited(0),
     abort_slave(0),slave_running(0),
-   ssl_verify_server_cert(0), slave_run_id(0)
+   ssl_verify_server_cert(0), slave_run_id(0),
+   delay(0)
{
    host[0] = 0; user[0] = 0; password[0] = 0;
    ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
@@ -67,8 +68,9 @@
      strmake(mi->user, master_user, sizeof(mi->user) - 1);
    if (master_password)
      strmake(mi->password, master_password, MAX_PASSWORD_LENGTH);
-  mi->port = master_port;
-  mi->connect_retry = master_connect_retry;
+  mi->port= master_port;
+  mi->connect_retry= master_connect_retry;
+  mi->delay= master_delay;
    mi->ssl= master_ssl;
    if (master_ssl_ca)
diff -urN mysql-5.1-bk-clean/sql/rpl_mi.h mysql-5.1-bk/sql/rpl_mi.h
--- mysql-5.1-bk-clean/sql/rpl_mi.h	2007-04-12 09:10:37.000000000 +0200
+++ mysql-5.1-bk/sql/rpl_mi.h	2007-06-06 03:03:10.000000000 +0200
@@ -99,6 +99,11 @@
    */
    long clock_diff_with_master;
+  /*
+     Delay replication by this amount (in seconds)
+  */
+  long delay;
+
};
void init_master_info_with_options(MASTER_INFO* mi);
diff -urN mysql-5.1-bk-clean/sql/slave.cc mysql-5.1-bk/sql/slave.cc
--- mysql-5.1-bk-clean/sql/slave.cc	2007-05-31 16:45:16.000000000 +0200
+++ mysql-5.1-bk/sql/slave.cc	2007-06-06 02:56:30.000000000 +0200
@@ -1212,6 +1212,8 @@
                                             MYSQL_TYPE_LONG));
    field_list.push_back(new Item_return_int("Connect_Retry", 10,
                                             MYSQL_TYPE_LONG));
+  field_list.push_back(new Item_return_int("Delay", 10,
+                                           MYSQL_TYPE_LONG));
    field_list.push_back(new Item_empty_string("Master_Log_File",
                                               FN_REFLEN));
    field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
@@ -1282,6 +1284,7 @@
      protocol->store(mi->user, &my_charset_bin);
      protocol->store((uint32) mi->port);
      protocol->store((uint32) mi->connect_retry);
+	protocol->store((uint32) mi->delay);
      protocol->store(mi->master_log_name, &my_charset_bin);
      protocol->store((ulonglong) mi->master_log_pos);
      protocol->store(mi->rli.group_relay_log_name +
@@ -1784,7 +1787,20 @@
        --rli->slave_skip_counter;
      pthread_mutex_unlock(&rli->data_lock);
      if (reason == Log_event::EVENT_SKIP_NOT)
+	{
+	  long now= (long)((time_t)time((time_t*) 0));
+	  DBUG_PRINT("info", ("ev->when= %lu  now= %lu  delay= %lu",
+							(long)ev->when, now, rli->mi->delay));
+	  if ((rli->mi->delay != 0) &&
+		  ((now - ev->when) < rli->mi->delay))
+	  {
+	    DBUG_PRINT("info", ("delaying replication event %lu secs",
+							rli->mi->delay - (now - ev->when)));
+		safe_sleep(thd,rli->mi->delay - (now - ev->when), 
(CHECK_KILLED_FUNC)sql_slave_killed,
+				   (void*)rli);
+	  }
        exec_res= ev->apply_event(rli);
+	}
#ifndef DBUG_OFF
      /*
        This only prints information to the debug trace.
diff -urN mysql-5.1-bk-clean/sql/slave.h mysql-5.1-bk/sql/slave.h
--- mysql-5.1-bk-clean/sql/slave.h	2007-05-10 11:59:28.000000000 +0200
+++ mysql-5.1-bk/sql/slave.h	2007-06-06 01:16:02.000000000 +0200
@@ -200,7 +200,7 @@
extern int disconnect_slave_event_count, abort_slave_event_count ;
/* the master variables are defaults read from my.cnf or command line */
-extern uint master_port, master_connect_retry, report_port;
+extern uint master_port, master_connect_retry, master_delay,  
report_port;
extern char * master_user, *master_password, *master_host;
extern char *master_info_file, *relay_log_info_file, *report_user;
extern char *report_host, *report_password;
diff -urN mysql-5.1-bk-clean/sql/sql_lex.h mysql-5.1-bk/sql/sql_lex.h
--- mysql-5.1-bk-clean/sql/sql_lex.h	2007-06-04 12:03:13.000000000 +0200
+++ mysql-5.1-bk/sql/sql_lex.h	2007-06-06 01:29:59.000000000 +0200
@@ -186,6 +186,7 @@
{
    char *host, *user, *password, *log_file_name;
    uint port, connect_retry;
+  long delay;
    ulonglong pos;
    ulong server_id;
    /*
diff -urN mysql-5.1-bk-clean/sql/sql_repl.cc mysql-5.1-bk/sql/ 
sql_repl.cc
--- mysql-5.1-bk-clean/sql/sql_repl.cc	2007-05-24 00:39:24.000000000  
+0200
+++ mysql-5.1-bk/sql/sql_repl.cc	2007-06-06 01:56:43.000000000 +0200
@@ -1130,7 +1130,9 @@
      mi->port = lex_mi->port;
    if (lex_mi->connect_retry)
      mi->connect_retry = lex_mi->connect_retry;
-
+  if (lex_mi->delay)
+    mi->delay= lex_mi->delay;
+	
    if (lex_mi->ssl != LEX_MASTER_INFO::SSL_UNCHANGED)
      mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::SSL_ENABLE);
diff -urN mysql-5.1-bk-clean/sql/sql_yacc.yy mysql-5.1-bk/sql/ 
sql_yacc.yy
--- mysql-5.1-bk-clean/sql/sql_yacc.yy	2007-06-04 12:14:21.000000000  
+0200
+++ mysql-5.1-bk/sql/sql_yacc.yy	2007-06-06 01:10:35.000000000 +0200
@@ -769,6 +769,7 @@
%token  LOW_PRIORITY
%token  LT                            /* OPERATOR */
%token  MASTER_CONNECT_RETRY_SYM
+%token  MASTER_DELAY_SYM
%token  MASTER_HOST_SYM
%token  MASTER_LOG_FILE_SYM
%token  MASTER_LOG_POS_SYM
@@ -1490,6 +1491,11 @@
         {
	 Lex->mi.connect_retry = $3;
         }
+	   |
+	   MASTER_DELAY_SYM EQ ulong_num
+	   {
+	 Lex->mi.delay = $3;
+	   }
         | MASTER_SSL_SYM EQ ulong_num
           {
             Lex->mi.ssl= $3 ?
@@ -9953,6 +9959,7 @@
	| MASTER_PASSWORD_SYM	{}
	| MASTER_SERVER_ID_SYM  {}
	| MASTER_CONNECT_RETRY_SYM	{}
+	| MASTER_DELAY_SYM	{}
	| MASTER_SSL_SYM	{}
	| MASTER_SSL_CA_SYM	{}
	| MASTER_SSL_CAPATH_SYM	{}


Thread
[PATCH] first version of proposed patch for #28760Kay Roepke6 Jun
  • Re: [PATCH] first version of proposed patch for #28760Mark Leith6 Jun
    • Re: [PATCH] first version of proposed patch for #28760Kay Roepke6 Jun
  • Re: [PATCH] first version of proposed patch for #28760Chad MILLER11 Jun
    • Re: [PATCH] first version of proposed patch for #28760Kay Roepke28 Jun