MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
semisync_slave.cc
1 /* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc.
2  Use is subject to license terms.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16 
17 
18 #include "semisync_slave.h"
19 
20 char rpl_semi_sync_slave_enabled;
21 char rpl_semi_sync_slave_status= 0;
22 unsigned long rpl_semi_sync_slave_trace_level;
23 
24 int ReplSemiSyncSlave::initObject()
25 {
26  int result= 0;
27  const char *kWho = "ReplSemiSyncSlave::initObject";
28 
29  if (init_done_)
30  {
31  fprintf(stderr, "%s called twice\n", kWho);
32  return 1;
33  }
34  init_done_ = true;
35 
36  /* References to the parameter works after set_options(). */
37  setSlaveEnabled(rpl_semi_sync_slave_enabled);
38  setTraceLevel(rpl_semi_sync_slave_trace_level);
39 
40  return result;
41 }
42 
43 int ReplSemiSyncSlave::slaveReadSyncHeader(const char *header,
44  unsigned long total_len,
45  bool *need_reply,
46  const char **payload,
47  unsigned long *payload_len)
48 {
49  const char *kWho = "ReplSemiSyncSlave::slaveReadSyncHeader";
50  int read_res = 0;
51  function_enter(kWho);
52 
53  if ((unsigned char)(header[0]) == kPacketMagicNum)
54  {
55  *need_reply = (header[1] & kPacketFlagSync);
56  *payload_len = total_len - 2;
57  *payload = header + 2;
58 
59  if (trace_level_ & kTraceDetail)
60  sql_print_information("%s: reply - %d", kWho, *need_reply);
61  }
62  else
63  {
64  sql_print_error("Missing magic number for semi-sync packet, packet "
65  "len: %lu", total_len);
66  read_res = -1;
67  }
68 
69  return function_exit(kWho, read_res);
70 }
71 
72 int ReplSemiSyncSlave::slaveStart(Binlog_relay_IO_param *param)
73 {
74  bool semi_sync= getSlaveEnabled();
75 
76  sql_print_information("Slave I/O thread: Start %s replication to\
77  master '%s@%s:%d' in log '%s' at position %lu",
78  semi_sync ? "semi-sync" : "asynchronous",
79  param->user, param->host, param->port,
80  param->master_log_name[0] ? param->master_log_name : "FIRST",
81  (unsigned long)param->master_log_pos);
82 
83  if (semi_sync && !rpl_semi_sync_slave_status)
84  rpl_semi_sync_slave_status= 1;
85  return 0;
86 }
87 
88 int ReplSemiSyncSlave::slaveStop(Binlog_relay_IO_param *param)
89 {
90  if (rpl_semi_sync_slave_status)
91  rpl_semi_sync_slave_status= 0;
92  if (mysql_reply)
93  mysql_close(mysql_reply);
94  mysql_reply= 0;
95  return 0;
96 }
97 
98 int ReplSemiSyncSlave::slaveReply(MYSQL *mysql,
99  const char *binlog_filename,
100  my_off_t binlog_filepos)
101 {
102  const char *kWho = "ReplSemiSyncSlave::slaveReply";
103  NET *net= &mysql->net;
104  uchar reply_buffer[REPLY_MAGIC_NUM_LEN
105  + REPLY_BINLOG_POS_LEN
106  + REPLY_BINLOG_NAME_LEN];
107  int reply_res, name_len = strlen(binlog_filename);
108 
109  function_enter(kWho);
110 
111  /* Prepare the buffer of the reply. */
112  reply_buffer[REPLY_MAGIC_NUM_OFFSET] = kPacketMagicNum;
113  int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos);
114  memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET,
115  binlog_filename,
116  name_len + 1 /* including trailing '\0' */);
117 
118  if (trace_level_ & kTraceDetail)
119  sql_print_information("%s: reply (%s, %lu)", kWho,
120  binlog_filename, (ulong)binlog_filepos);
121 
122  net_clear(net, 0);
123  /* Send the reply. */
124  reply_res = my_net_write(net, reply_buffer,
125  name_len + REPLY_BINLOG_NAME_OFFSET);
126  if (!reply_res)
127  {
128  reply_res = net_flush(net);
129  if (reply_res)
130  sql_print_error("Semi-sync slave net_flush() reply failed");
131  }
132  else
133  {
134  sql_print_error("Semi-sync slave send reply failed: %s (%d)",
135  net->last_error, net->last_errno);
136  }
137 
138  return function_exit(kWho, reply_res);
139 }