~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to plugin/semisync/semisync_slave_plugin.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2007 Google Inc.
 
2
   Copyright (C) 2008 MySQL AB
 
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
#include <mysql.h>
 
20
 
 
21
ReplSemiSyncSlave repl_semisync;
 
22
 
 
23
/*
 
24
  indicate whether or not the slave should send a reply to the master.
 
25
 
 
26
  This is set to true in repl_semi_slave_read_event if the current
 
27
  event read is the last event of a transaction. And the value is
 
28
  checked in repl_semi_slave_queue_event.
 
29
*/
 
30
bool semi_sync_need_reply= false;
 
31
 
 
32
C_MODE_START
 
33
 
 
34
int repl_semi_reset_slave(Binlog_relay_IO_param *param)
 
35
{
 
36
  // TODO: reset semi-sync slave status here
 
37
  return 0;
 
38
}
 
39
 
 
40
int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
 
41
                                 uint32 flags)
 
42
{
 
43
  MYSQL *mysql= param->mysql;
 
44
  MYSQL_RES *res= 0;
 
45
  MYSQL_ROW row;
 
46
  const char *query;
 
47
 
 
48
  if (!repl_semisync.getSlaveEnabled())
 
49
    return 0;
 
50
 
 
51
  /* Check if master server has semi-sync plugin installed */
 
52
  query= "SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'";
 
53
  if (mysql_real_query(mysql, query, strlen(query)) ||
 
54
      !(res= mysql_store_result(mysql)))
 
55
  {
 
56
    sql_print_error("Execution failed on master: %s", query);
 
57
    return 1;
 
58
  }
 
59
 
 
60
  row= mysql_fetch_row(res);
 
61
  if (!row)
 
62
  {
 
63
    /* Master does not support semi-sync */
 
64
    sql_print_warning("Master server does not support semi-sync, "
 
65
                      "fallback to asynchronous replication");
 
66
    rpl_semi_sync_slave_status= 0;
 
67
    mysql_free_result(res);
 
68
    return 0;
 
69
  }
 
70
  mysql_free_result(res);
 
71
 
 
72
  /*
 
73
    Tell master dump thread that we want to do semi-sync
 
74
    replication
 
75
  */
 
76
  query= "SET @rpl_semi_sync_slave= 1";
 
77
  if (mysql_real_query(mysql, query, strlen(query)))
 
78
  {
 
79
    sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
 
80
    return 1;
 
81
  }
 
82
  mysql_free_result(mysql_store_result(mysql));
 
83
  rpl_semi_sync_slave_status= 1;
 
84
  return 0;
 
85
}
 
86
 
 
87
int repl_semi_slave_read_event(Binlog_relay_IO_param *param,
 
88
                               const char *packet, unsigned long len,
 
89
                               const char **event_buf, unsigned long *event_len)
 
90
{
 
91
  if (rpl_semi_sync_slave_status)
 
92
    return repl_semisync.slaveReadSyncHeader(packet, len,
 
93
                                             &semi_sync_need_reply,
 
94
                                             event_buf, event_len);
 
95
  *event_buf= packet;
 
96
  *event_len= len;
 
97
  return 0;
 
98
}
 
99
 
 
100
int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
 
101
                                const char *event_buf,
 
102
                                unsigned long event_len,
 
103
                                uint32 flags)
 
104
{
 
105
  if (rpl_semi_sync_slave_status && semi_sync_need_reply)
 
106
  {
 
107
    /*
 
108
      We deliberately ignore the error in slaveReply, such error
 
109
      should not cause the slave IO thread to stop, and the error
 
110
      messages are already reported.
 
111
    */
 
112
    (void) repl_semisync.slaveReply(param->mysql,
 
113
                                    param->master_log_name,
 
114
                                    param->master_log_pos);
 
115
  }
 
116
  return 0;
 
117
}
 
118
 
 
119
int repl_semi_slave_io_start(Binlog_relay_IO_param *param)
 
120
{
 
121
  return repl_semisync.slaveStart(param);
 
122
}
 
123
 
 
124
int repl_semi_slave_io_end(Binlog_relay_IO_param *param)
 
125
{
 
126
  return repl_semisync.slaveStop(param);
 
127
}
 
128
 
 
129
C_MODE_END
 
130
 
 
131
static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd,
 
132
                                            SYS_VAR *var,
 
133
                                            void *ptr,
 
134
                                            const void *val)
 
135
{
 
136
  *(char *)ptr= *(char *)val;
 
137
  repl_semisync.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0);
 
138
  return;
 
139
}
 
140
 
 
141
static void fix_rpl_semi_sync_trace_level(MYSQL_THD thd,
 
142
                                          SYS_VAR *var,
 
143
                                          void *ptr,
 
144
                                          const void *val)
 
145
{
 
146
  *(unsigned long *)ptr= *(unsigned long *)val;
 
147
  repl_semisync.setTraceLevel(rpl_semi_sync_slave_trace_level);
 
148
  return;
 
149
}
 
150
 
 
151
/* plugin system variables */
 
152
static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_slave_enabled,
 
153
  PLUGIN_VAR_OPCMDARG,
 
154
 "Enable semi-synchronous replication slave (disabled by default). ",
 
155
  NULL,                            // check
 
156
  &fix_rpl_semi_sync_slave_enabled, // update
 
157
  0);
 
158
 
 
159
static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level,
 
160
  PLUGIN_VAR_OPCMDARG,
 
161
 "The tracing level for semi-sync replication.",
 
162
  NULL,                           // check
 
163
  &fix_rpl_semi_sync_trace_level, // update
 
164
  32, 0, ~0UL, 1);
 
165
 
 
166
static SYS_VAR* semi_sync_slave_system_vars[]= {
 
167
  MYSQL_SYSVAR(enabled),
 
168
  MYSQL_SYSVAR(trace_level),
 
169
  NULL,
 
170
};
 
171
 
 
172
 
 
173
/* plugin status variables */
 
174
static SHOW_VAR semi_sync_slave_status_vars[]= {
 
175
  {"Rpl_semi_sync_slave_status",
 
176
   (char*) &rpl_semi_sync_slave_status,    SHOW_BOOL},
 
177
  {NULL, NULL, SHOW_BOOL},
 
178
};
 
179
 
 
180
Binlog_relay_IO_observer relay_io_observer = {
 
181
  sizeof(Binlog_relay_IO_observer), // len
 
182
 
 
183
  repl_semi_slave_io_start,     // start
 
184
  repl_semi_slave_io_end,       // stop
 
185
  repl_semi_slave_request_dump, // request_transmit
 
186
  repl_semi_slave_read_event,   // after_read_event
 
187
  repl_semi_slave_queue_event,  // after_queue_event
 
188
  repl_semi_reset_slave,        // reset
 
189
};
 
190
 
 
191
static int semi_sync_slave_plugin_init(void *p)
 
192
{
 
193
  if (repl_semisync.initObject())
 
194
    return 1;
 
195
  if (register_binlog_relay_io_observer(&relay_io_observer, p))
 
196
    return 1;
 
197
  return 0;
 
198
}
 
199
 
 
200
static int semi_sync_slave_plugin_deinit(void *p)
 
201
{
 
202
  if (unregister_binlog_relay_io_observer(&relay_io_observer, p))
 
203
    return 1;
 
204
  return 0;
 
205
}
 
206
 
 
207
 
 
208
struct Mysql_replication semi_sync_slave_plugin= {
 
209
  MYSQL_REPLICATION_INTERFACE_VERSION
 
210
};
 
211
 
 
212
/*
 
213
  Plugin library descriptor
 
214
*/
 
215
mysql_declare_plugin(semi_sync_slave)
 
216
{
 
217
  MYSQL_REPLICATION_PLUGIN,
 
218
  &semi_sync_slave_plugin,
 
219
  "rpl_semi_sync_slave",
 
220
  "He Zhenxing",
 
221
  "Semi-synchronous replication slave",
 
222
  PLUGIN_LICENSE_GPL,
 
223
  semi_sync_slave_plugin_init, /* Plugin Init */
 
224
  semi_sync_slave_plugin_deinit, /* Plugin Deinit */
 
225
  0x0100 /* 1.0 */,
 
226
  semi_sync_slave_status_vars,  /* status variables */
 
227
  semi_sync_slave_system_vars,  /* system variables */
 
228
  NULL,                         /* config options */
 
229
  0,                            /* flags */
 
230
}
 
231
mysql_declare_plugin_end;