1
/* Copyright (C) 2007 Google Inc.
2
Copyright (C) 2008 MySQL AB
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.
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.
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 */
18
#include "semisync_slave.h"
21
ReplSemiSyncSlave repl_semisync;
24
indicate whether or not the slave should send a reply to the master.
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.
30
bool semi_sync_need_reply= false;
34
int repl_semi_reset_slave(Binlog_relay_IO_param *param)
36
// TODO: reset semi-sync slave status here
40
int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
43
MYSQL *mysql= param->mysql;
48
if (!repl_semisync.getSlaveEnabled())
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)))
56
sql_print_error("Execution failed on master: %s", query);
60
row= mysql_fetch_row(res);
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);
70
mysql_free_result(res);
73
Tell master dump thread that we want to do semi-sync
76
query= "SET @rpl_semi_sync_slave= 1";
77
if (mysql_real_query(mysql, query, strlen(query)))
79
sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
82
mysql_free_result(mysql_store_result(mysql));
83
rpl_semi_sync_slave_status= 1;
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)
91
if (rpl_semi_sync_slave_status)
92
return repl_semisync.slaveReadSyncHeader(packet, len,
93
&semi_sync_need_reply,
94
event_buf, event_len);
100
int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
101
const char *event_buf,
102
unsigned long event_len,
105
if (rpl_semi_sync_slave_status && semi_sync_need_reply)
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.
112
(void) repl_semisync.slaveReply(param->mysql,
113
param->master_log_name,
114
param->master_log_pos);
119
int repl_semi_slave_io_start(Binlog_relay_IO_param *param)
121
return repl_semisync.slaveStart(param);
124
int repl_semi_slave_io_end(Binlog_relay_IO_param *param)
126
return repl_semisync.slaveStop(param);
131
static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd,
136
*(char *)ptr= *(char *)val;
137
repl_semisync.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0);
141
static void fix_rpl_semi_sync_trace_level(MYSQL_THD thd,
146
*(unsigned long *)ptr= *(unsigned long *)val;
147
repl_semisync.setTraceLevel(rpl_semi_sync_slave_trace_level);
151
/* plugin system variables */
152
static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_slave_enabled,
154
"Enable semi-synchronous replication slave (disabled by default). ",
156
&fix_rpl_semi_sync_slave_enabled, // update
159
static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level,
161
"The tracing level for semi-sync replication.",
163
&fix_rpl_semi_sync_trace_level, // update
166
static SYS_VAR* semi_sync_slave_system_vars[]= {
167
MYSQL_SYSVAR(enabled),
168
MYSQL_SYSVAR(trace_level),
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},
180
Binlog_relay_IO_observer relay_io_observer = {
181
sizeof(Binlog_relay_IO_observer), // len
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
191
static int semi_sync_slave_plugin_init(void *p)
193
if (repl_semisync.initObject())
195
if (register_binlog_relay_io_observer(&relay_io_observer, p))
200
static int semi_sync_slave_plugin_deinit(void *p)
202
if (unregister_binlog_relay_io_observer(&relay_io_observer, p))
208
struct Mysql_replication semi_sync_slave_plugin= {
209
MYSQL_REPLICATION_INTERFACE_VERSION
213
Plugin library descriptor
215
mysql_declare_plugin(semi_sync_slave)
217
MYSQL_REPLICATION_PLUGIN,
218
&semi_sync_slave_plugin,
219
"rpl_semi_sync_slave",
221
"Semi-synchronous replication slave",
223
semi_sync_slave_plugin_init, /* Plugin Init */
224
semi_sync_slave_plugin_deinit, /* Plugin Deinit */
226
semi_sync_slave_status_vars, /* status variables */
227
semi_sync_slave_system_vars, /* system variables */
228
NULL, /* config options */
231
mysql_declare_plugin_end;