Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
b289e515
Commit
b289e515
authored
Oct 13, 2009
by
He Zhenxing
Browse files
Options
Browse Files
Download
Plain Diff
Auto merge 5.1-rep-semisync
parents
2151a821
dab1162b
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
519 additions
and
284 deletions
+519
-284
mysql-test/suite/rpl/r/rpl_semi_sync.result
mysql-test/suite/rpl/r/rpl_semi_sync.result
+68
-26
mysql-test/suite/rpl/t/rpl_semi_sync.test
mysql-test/suite/rpl/t/rpl_semi_sync.test
+88
-21
plugin/semisync/Makefile.am
plugin/semisync/Makefile.am
+1
-0
plugin/semisync/semisync.h
plugin/semisync/semisync.h
+13
-17
plugin/semisync/semisync_master.cc
plugin/semisync/semisync_master.cc
+182
-89
plugin/semisync/semisync_master.h
plugin/semisync/semisync_master.h
+35
-27
plugin/semisync/semisync_master_plugin.cc
plugin/semisync/semisync_master_plugin.cc
+74
-61
plugin/semisync/semisync_slave.cc
plugin/semisync/semisync_slave.cc
+38
-22
plugin/semisync/semisync_slave.h
plugin/semisync/semisync_slave.h
+7
-10
plugin/semisync/semisync_slave_plugin.cc
plugin/semisync/semisync_slave_plugin.cc
+13
-11
No files found.
mysql-test/suite/rpl/r/rpl_semi_sync.result
View file @
b289e515
...
...
@@ -29,13 +29,13 @@ set global rpl_semi_sync_master_enabled = 1;
show variables like 'rpl_semi_sync_master_enabled';
Variable_name Value
rpl_semi_sync_master_enabled ON
[ status of semi-sync on master should be O
FF
without any semi-sync slaves ]
[ status of semi-sync on master should be O
N even
without any semi-sync slaves ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 0
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status O
FF
Rpl_semi_sync_master_status O
N
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 0
...
...
@@ -81,7 +81,7 @@ Rpl_semi_sync_master_no_tx 0
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 0
create table t1(
n
int) engine = ENGINE_TYPE;
create table t1(
a
int) engine = ENGINE_TYPE;
[ master state after CREATE TABLE statement ]
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
...
...
@@ -92,6 +92,9 @@ Rpl_semi_sync_master_no_tx 0
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 1
select CONNECTIONS_NORMAL_SLAVE - CONNECTIONS_NORMAL_SLAVE as 'Should be 0';
Should be 0
0
[ insert records to table ]
[ master status after inserts ]
show status like 'Rpl_semi_sync_master_status';
...
...
@@ -108,15 +111,19 @@ Rpl_semi_sync_master_yes_tx 301
show status like 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status ON
select count(distinct
n
) from t1;
count(distinct
n
)
select count(distinct
a
) from t1;
count(distinct
a
)
300
select min(
n
) from t1;
min(
n
)
select min(
a
) from t1;
min(
a
)
1
select max(
n
) from t1;
max(
n
)
select max(
a
) from t1;
max(
a
)
300
#
# Test semi-sync master will switch OFF after one transacton
# timeout waiting for slave reply.
#
include/stop_slave.inc
[ on master ]
[ master status should be ON ]
...
...
@@ -134,7 +141,16 @@ Variable_name Value
Rpl_semi_sync_master_clients 1
[ semi-sync replication of these transactions will fail ]
insert into t1 values (500);
delete from t1 where n < 500;
[ master status should be OFF ]
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status OFF
show status like 'Rpl_semi_sync_master_no_tx';
Variable_name Value
Rpl_semi_sync_master_no_tx 1
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 301
insert into t1 values (100);
[ master status should be OFF ]
show status like 'Rpl_semi_sync_master_status';
...
...
@@ -142,10 +158,13 @@ Variable_name Value
Rpl_semi_sync_master_status OFF
show status like 'Rpl_semi_sync_master_no_tx';
Variable_name Value
Rpl_semi_sync_master_no_tx 3
Rpl_semi_sync_master_no_tx 3
02
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 301
#
# Test semi-sync status on master will be ON again when slave catches up
#
[ on slave ]
[ slave status should be OFF ]
show status like 'Rpl_semi_sync_slave_status';
...
...
@@ -156,33 +175,53 @@ include/start_slave.inc
show status like 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status ON
select count(distinct
n
) from t1;
count(distinct
n
)
select count(distinct
a
) from t1;
count(distinct
a
)
2
select min(
n
) from t1;
min(
n
)
select min(
a
) from t1;
min(
a
)
100
select max(
n
) from t1;
max(
n
)
select max(
a
) from t1;
max(
a
)
500
[ on master ]
[ do something to activate semi-sync ]
drop table t1;
[ master status should be ON again ]
[ master status should be ON again after slave catches up ]
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status ON
show status like 'Rpl_semi_sync_master_no_tx';
Variable_name Value
Rpl_semi_sync_master_no_tx 3
Rpl_semi_sync_master_no_tx 3
02
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 30
2
Rpl_semi_sync_master_yes_tx 30
1
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
#
# Test disable/enable master semi-sync on the fly.
#
drop table t1;
[ on slave ]
include/stop_slave.inc
#
# Flush status
#
[ Semi-sync master status variables before FLUSH STATUS ]
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';
Variable_name Value
Rpl_semi_sync_master_no_tx 302
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 302
FLUSH NO_WRITE_TO_BINLOG STATUS;
[ Semi-sync master status variables after FLUSH STATUS ]
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';
Variable_name Value
Rpl_semi_sync_master_no_tx 0
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 0
[ on master ]
show master logs;
Log_name master-bin.000001
...
...
@@ -206,6 +245,9 @@ rpl_semi_sync_master_enabled ON
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status ON
#
# Test RESET MASTER/SLAVE
#
[ on slave ]
include/start_slave.inc
[ on master ]
...
...
@@ -313,7 +355,7 @@ Variable_name Value
Rpl_semi_sync_master_clients 0
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status O
FF
Rpl_semi_sync_master_status O
N
set global rpl_semi_sync_master_enabled= 0;
[ on slave ]
SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
...
...
@@ -322,17 +364,17 @@ rpl_semi_sync_slave_enabled ON
include/start_slave.inc
[ on master ]
insert into t1 values (8);
[ master semi-sync clients should be
0
, status should be OFF ]
[ master semi-sync clients should be
1
, status should be OFF ]
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients
0
Rpl_semi_sync_master_clients
1
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status OFF
[ on slave ]
show status like 'Rpl_semi_sync_slave_status';
Variable_name Value
Rpl_semi_sync_slave_status O
FF
Rpl_semi_sync_slave_status O
N
include/stop_slave.inc
[ on master ]
set sql_log_bin=0;
...
...
mysql-test/suite/rpl/t/rpl_semi_sync.test
View file @
b289e515
...
...
@@ -11,12 +11,17 @@ let $engine_type= InnoDB;
disable_query_log
;
connection
master
;
call
mtr
.
add_suppression
(
"Timeout waiting for reply of binlog"
);
call
mtr
.
add_suppression
(
"Read semi-sync reply"
);
connection
slave
;
call
mtr
.
add_suppression
(
"Master server does not support"
);
# These will be removed after fix bug#45852
call
mtr
.
add_suppression
(
"Set 'rpl_semi_sync_master_reply_log_file_pos' on master failed"
);
call
mtr
.
add_suppression
(
"Slave I/O: Fatal error: Failed to run 'after_queue_event' hook, Error_code: 1593"
);
call
mtr
.
add_suppression
(
"Master server does not support semi-sync"
);
call
mtr
.
add_suppression
(
"Semi-sync slave .* reply"
);
enable_query_log
;
connection
master
;
# After fix of BUG#45848, semi-sync slave should not create any extra
# connections on master, save the count of connections before start
# semi-sync slave for comparison below.
let
$_connections_normal_slave
=
query_get_value
(
SHOW
STATUS
LIKE
'Threads_connected'
,
Value
,
1
);
--
echo
#
--
echo
# Uninstall semi-sync plugins on master and slave
...
...
@@ -69,7 +74,7 @@ echo [ enable semi-sync on master ];
set
global
rpl_semi_sync_master_enabled
=
1
;
show
variables
like
'rpl_semi_sync_master_enabled'
;
echo
[
status
of
semi
-
sync
on
master
should
be
O
FF
without
any
semi
-
sync
slaves
];
echo
[
status
of
semi
-
sync
on
master
should
be
O
N
even
without
any
semi
-
sync
slaves
];
show
status
like
'Rpl_semi_sync_master_clients'
;
show
status
like
'Rpl_semi_sync_master_status'
;
show
status
like
'Rpl_semi_sync_master_yes_tx'
;
...
...
@@ -150,13 +155,20 @@ show status like 'Rpl_semi_sync_master_no_tx';
show
status
like
'Rpl_semi_sync_master_yes_tx'
;
replace_result
$engine_type
ENGINE_TYPE
;
eval
create
table
t1
(
n
int
)
engine
=
$engine_type
;
eval
create
table
t1
(
a
int
)
engine
=
$engine_type
;
echo
[
master
state
after
CREATE
TABLE
statement
];
show
status
like
'Rpl_semi_sync_master_status'
;
show
status
like
'Rpl_semi_sync_master_no_tx'
;
show
status
like
'Rpl_semi_sync_master_yes_tx'
;
# After fix of BUG#45848, semi-sync slave should not create any extra
# connections on master.
let
$_connections_semisync_slave
=
query_get_value
(
SHOW
STATUS
LIKE
'Threads_connected'
,
Value
,
1
);
replace_result
$_connections_semisync_slave
CONNECTIONS_SEMISYNC_SLAVE
;
replace_result
$_connections_normal_slave
CONNECTIONS_NORMAL_SLAVE
;
eval
select
$_connections_semisync_slave
-
$_connections_normal_slave
as
'Should be 0'
;
let
$i
=
300
;
echo
[
insert
records
to
table
];
disable_query_log
;
...
...
@@ -178,10 +190,15 @@ echo [ on slave ];
echo
[
slave
status
after
replicated
inserts
];
show
status
like
'Rpl_semi_sync_slave_status'
;
select
count
(
distinct
n
)
from
t1
;
select
min
(
n
)
from
t1
;
select
max
(
n
)
from
t1
;
select
count
(
distinct
a
)
from
t1
;
select
min
(
a
)
from
t1
;
select
max
(
a
)
from
t1
;
--
echo
#
--
echo
# Test semi-sync master will switch OFF after one transacton
--
echo
# timeout waiting for slave reply.
--
echo
#
connection
slave
;
source
include
/
stop_slave
.
inc
;
connection
master
;
...
...
@@ -197,8 +214,11 @@ show status like 'Rpl_semi_sync_master_clients';
echo
[
semi
-
sync
replication
of
these
transactions
will
fail
];
insert
into
t1
values
(
500
);
delete
from
t1
where
n
<
500
;
insert
into
t1
values
(
100
);
# Wait for the semi-sync replication of this transaction to timeout
let
$status_var
=
Rpl_semi_sync_master_status
;
let
$status_var_value
=
OFF
;
source
include
/
wait_for_status_var
.
inc
;
# The second semi-sync check should be off because one transaction
# times out during waiting.
...
...
@@ -207,6 +227,28 @@ show status like 'Rpl_semi_sync_master_status';
show
status
like
'Rpl_semi_sync_master_no_tx'
;
show
status
like
'Rpl_semi_sync_master_yes_tx'
;
# Semi-sync status on master is now OFF, so all these transactions
# will be replicated asynchronously.
let
$i
=
300
;
disable_query_log
;
while
(
$i
)
{
eval
delete
from
t1
where
a
=
$i
;
dec
$i
;
}
enable_query_log
;
insert
into
t1
values
(
100
);
echo
[
master
status
should
be
OFF
];
show
status
like
'Rpl_semi_sync_master_status'
;
show
status
like
'Rpl_semi_sync_master_no_tx'
;
show
status
like
'Rpl_semi_sync_master_yes_tx'
;
--
echo
#
--
echo
# Test semi-sync status on master will be ON again when slave catches up
--
echo
#
# Save the master position for later use.
save_master_pos
;
...
...
@@ -221,28 +263,44 @@ sync_with_master;
echo
[
slave
status
should
be
ON
];
show
status
like
'Rpl_semi_sync_slave_status'
;
select
count
(
distinct
n
)
from
t1
;
select
min
(
n
)
from
t1
;
select
max
(
n
)
from
t1
;
select
count
(
distinct
a
)
from
t1
;
select
min
(
a
)
from
t1
;
select
max
(
a
)
from
t1
;
connection
master
;
echo
[
on
master
];
echo
[
do
something
to
activate
semi
-
sync
];
drop
table
t1
;
# The third semi-sync check should be on again.
echo
[
master
status
should
be
ON
again
];
# The master semi-sync status should be on again after slave catches up.
echo
[
master
status
should
be
ON
again
after
slave
catches
up
];
show
status
like
'Rpl_semi_sync_master_status'
;
show
status
like
'Rpl_semi_sync_master_no_tx'
;
show
status
like
'Rpl_semi_sync_master_yes_tx'
;
show
status
like
'Rpl_semi_sync_master_clients'
;
--
echo
#
--
echo
# Test disable/enable master semi-sync on the fly.
--
echo
#
drop
table
t1
;
sync_slave_with_master
;
echo
[
on
slave
];
source
include
/
stop_slave
.
inc
;
--
echo
#
--
echo
# Flush status
--
echo
#
connection
master
;
echo
[
Semi
-
sync
master
status
variables
before
FLUSH
STATUS
];
SHOW
STATUS
LIKE
'Rpl_semi_sync_master_no_tx'
;
SHOW
STATUS
LIKE
'Rpl_semi_sync_master_yes_tx'
;
# Do not write the FLUSH STATUS to binlog, to make sure we'll get a
# clean status after this.
FLUSH
NO_WRITE_TO_BINLOG
STATUS
;
echo
[
Semi
-
sync
master
status
variables
after
FLUSH
STATUS
];
SHOW
STATUS
LIKE
'Rpl_semi_sync_master_no_tx'
;
SHOW
STATUS
LIKE
'Rpl_semi_sync_master_yes_tx'
;
connection
master
;
echo
[
on
master
];
...
...
@@ -259,6 +317,10 @@ set global rpl_semi_sync_master_enabled=1;
show
variables
like
'rpl_semi_sync_master_enabled'
;
show
status
like
'Rpl_semi_sync_master_status'
;
--
echo
#
--
echo
# Test RESET MASTER/SLAVE
--
echo
#
connection
slave
;
echo
[
on
slave
];
...
...
@@ -435,7 +497,10 @@ source include/start_slave.inc;
connection
master
;
echo
[
on
master
];
insert
into
t1
values
(
8
);
echo
[
master
semi
-
sync
clients
should
be
0
,
status
should
be
OFF
];
let
$status_var
=
Rpl_semi_sync_master_clients
;
let
$status_var_value
=
1
;
source
include
/
wait_for_status_var
.
inc
;
echo
[
master
semi
-
sync
clients
should
be
1
,
status
should
be
OFF
];
show
status
like
'Rpl_semi_sync_master_clients'
;
show
status
like
'Rpl_semi_sync_master_status'
;
sync_slave_with_master
;
...
...
@@ -512,6 +577,8 @@ source include/start_slave.inc;
connection
master
;
drop
table
t1
;
sync_slave_with_master
;
connection
master
;
drop
user
rpl
@
127.0
.
0.1
;
flush
privileges
;
sync_slave_with_master
;
plugin/semisync/Makefile.am
View file @
b289e515
...
...
@@ -18,6 +18,7 @@
pkgplugindir
=
$(pkglibdir)
/plugin
INCLUDES
=
-I
$(top_srcdir)
/include
\
-I
$(top_srcdir)
/sql
\
-I
$(top_srcdir)
/regex
\
-I
$(srcdir)
noinst_HEADERS
=
semisync.h semisync_master.h semisync_slave.h
...
...
plugin/semisync/semisync.h
View file @
b289e515
...
...
@@ -18,25 +18,9 @@
#ifndef SEMISYNC_H
#define SEMISYNC_H
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <mysql.h>
typedef
uint32_t
uint32
;
typedef
unsigned
long
long
my_off_t
;
#define FN_REFLEN 512
/* Max length of full path-name */
void
sql_print_error
(
const
char
*
format
,
...);
void
sql_print_warning
(
const
char
*
format
,
...);
void
sql_print_information
(
const
char
*
format
,
...);
extern
unsigned
long
max_connections
;
#define MYSQL_SERVER
#define HAVE_REPLICATION
#include <mysql_priv.h>
#include <my_global.h>
#include <my_pthread.h>
#include <mysql/plugin.h>
...
...
@@ -92,4 +76,16 @@ public:
static
const
unsigned
char
kPacketFlagSync
;
};
/* The layout of a semisync slave reply packet:
1 byte for the magic num
8 bytes for the binlog positon
n bytes for the binlog filename, terminated with a '\0'
*/
#define REPLY_MAGIC_NUM_LEN 1
#define REPLY_BINLOG_POS_LEN 8
#define REPLY_BINLOG_NAME_LEN (FN_REFLEN + 1)
#define REPLY_MAGIC_NUM_OFFSET 0
#define REPLY_BINLOG_POS_OFFSET (REPLY_MAGIC_NUM_OFFSET + REPLY_MAGIC_NUM_LEN)
#define REPLY_BINLOG_NAME_OFFSET (REPLY_BINLOG_POS_OFFSET + REPLY_BINLOG_POS_LEN)
#endif
/* SEMISYNC_H */
plugin/semisync/semisync_master.cc
View file @
b289e515
This diff is collapsed.
Click to expand it.
plugin/semisync/semisync_master.h
View file @
b289e515
...
...
@@ -81,7 +81,7 @@ public:
/* Insert an active transaction node with the specified position.
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
insert_tranx_node
(
const
char
*
log_file_name
,
my_off_t
log_file_pos
);
...
...
@@ -91,7 +91,7 @@ public:
* list and the hash table will be reset to empty.
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
clear_active_tranx_nodes
(
const
char
*
log_file_name
,
my_off_t
log_file_pos
);
...
...
@@ -175,19 +175,7 @@ class ReplSemiSyncMaster
volatile
bool
master_enabled_
;
/* semi-sync is enabled on the master */
unsigned
long
wait_timeout_
;
/* timeout period(ms) during tranx wait */
/* All status variables. */
bool
state_
;
/* whether semi-sync is switched */
unsigned
long
enabled_transactions_
;
/* semi-sync'ed tansactions */
unsigned
long
disabled_transactions_
;
/* non-semi-sync'ed tansactions */
unsigned
long
switched_off_times_
;
/* how many times are switched off? */
unsigned
long
timefunc_fails_
;
/* how many time function fails? */
unsigned
long
total_wait_timeouts_
;
/* total number of wait timeouts */
unsigned
long
wait_sessions_
;
/* how many sessions wait for replies? */
unsigned
long
wait_backtraverse_
;
/* wait position back traverses */
unsigned
long
long
total_trx_wait_num_
;
/* total trx waits: non-timeout ones */
unsigned
long
long
total_trx_wait_time_
;
/* total trx wait time: in us */
unsigned
long
long
total_net_wait_num_
;
/* total network waits */
unsigned
long
long
total_net_wait_time_
;
/* total network wait time */
/* The number of maximum active transactions. This should be the same as
* maximum connections because MySQL does not do connection sharing now.
...
...
@@ -253,8 +241,6 @@ class ReplSemiSyncMaster
/* Is the slave servered by the thread requested semi-sync */
bool
is_semi_sync_slave
();
int
reportReplyBinlog
(
const
char
*
log_file_pos
);
/* In semi-sync replication, reports up to which binlog position we have
* received replies from the slave indicating that it already get the events.
*
...
...
@@ -265,7 +251,7 @@ class ReplSemiSyncMaster
* the replies from the slave
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
reportReplyBinlog
(
uint32
server_id
,
const
char
*
log_file_name
,
...
...
@@ -284,7 +270,7 @@ class ReplSemiSyncMaster
* trx_wait_binlog_pos - (IN) ending position's file offset
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
commitTrx
(
const
char
*
trx_wait_binlog_name
,
my_off_t
trx_wait_binlog_pos
);
...
...
@@ -313,7 +299,7 @@ class ReplSemiSyncMaster
* server_id - (IN) master server id number
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
updateSyncHeader
(
unsigned
char
*
packet
,
const
char
*
log_file_name
,
...
...
@@ -330,10 +316,23 @@ class ReplSemiSyncMaster
* log_file_pos - (IN) transaction ending position's file offset
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
writeTranxInBinlog
(
const
char
*
log_file_name
,
my_off_t
log_file_pos
);
/* Read the slave's reply so that we know how much progress the slave makes
* on receive replication events.
*
* Input:
* net - (IN) the connection to master
* server_id - (IN) master server id number
* event_buf - (IN) pointer to the event packet
*
* Return:
* 0: success; non-zero: error
*/
int
readSlaveReply
(
NET
*
net
,
uint32
server_id
,
const
char
*
event_buf
);
/* Export internal statistics for semi-sync replication. */
void
setExportStats
();
...
...
@@ -345,22 +344,31 @@ class ReplSemiSyncMaster
/* System and status variables for the master component */
extern
char
rpl_semi_sync_master_enabled
;
extern
char
rpl_semi_sync_master_status
;
extern
unsigned
long
rpl_semi_sync_master_clients
;
extern
unsigned
long
rpl_semi_sync_master_timeout
;
extern
unsigned
long
rpl_semi_sync_master_trace_level
;
extern
char
rpl_semi_sync_master_status
;
extern
unsigned
long
rpl_semi_sync_master_yes_transactions
;
extern
unsigned
long
rpl_semi_sync_master_no_transactions
;
extern
unsigned
long
rpl_semi_sync_master_off_times
;
extern
unsigned
long
rpl_semi_sync_master_wait_timeouts
;
extern
unsigned
long
rpl_semi_sync_master_timefunc_fails
;
extern
unsigned
long
rpl_semi_sync_master_num_timeouts
;
extern
unsigned
long
rpl_semi_sync_master_wait_sessions
;
extern
unsigned
long
rpl_semi_sync_master_
back_wait_pos
;
extern
unsigned
long
rpl_semi_sync_master_trx_wait_time
;
extern
unsigned
long
rpl_semi_sync_master_net_wait_time
;
extern
unsigned
long
rpl_semi_sync_master_
wait_pos_backtraverse
;
extern
unsigned
long
rpl_semi_sync_master_
avg_
trx_wait_time
;
extern
unsigned
long
rpl_semi_sync_master_
avg_
net_wait_time
;
extern
unsigned
long
long
rpl_semi_sync_master_net_wait_num
;
extern
unsigned
long
long
rpl_semi_sync_master_trx_wait_num
;
extern
unsigned
long
long
rpl_semi_sync_master_net_wait_total_time
;
extern
unsigned
long
long
rpl_semi_sync_master_trx_wait_total_time
;
extern
unsigned
long
rpl_semi_sync_master_clients
;
extern
unsigned
long
long
rpl_semi_sync_master_net_wait_time
;
extern
unsigned
long
long
rpl_semi_sync_master_trx_wait_time
;
/*
This indicates whether we should keep waiting if no semi-sync slave
is available.
0 : stop waiting if detected no avaialable semi-sync slave.
1 (default) : keep waiting until timeout even no available semi-sync slave.
*/
extern
char
rpl_semi_sync_master_wait_no_slave
;
#endif
/* SEMISYNC_MASTER_H */
plugin/semisync/semisync_master_plugin.cc
View file @
b289e515
...
...
@@ -69,8 +69,16 @@ int repl_semi_binlog_dump_start(Binlog_transmit_param *param,
bool
semi_sync_slave
=
repl_semisync
.
is_semi_sync_slave
();
if
(
semi_sync_slave
)
{
/* One more semi-sync slave */
repl_semisync
.
add_slave
();
/*
Let's assume this semi-sync slave has already received all
binlog events before the filename and position it requests.
*/
repl_semisync
.
reportReplyBinlog
(
param
->
server_id
,
log_file
,
log_pos
);
}
sql_print_information
(
"Start %s binlog_dump to slave (server_id: %d), pos(%s, %lu)"
,
semi_sync_slave
?
"semi-sync"
:
"asynchronous"
,
param
->
server_id
,
log_file
,
(
unsigned
long
)
log_pos
);
...
...
@@ -114,6 +122,18 @@ int repl_semi_before_send_event(Binlog_transmit_param *param,
int
repl_semi_after_send_event
(
Binlog_transmit_param
*
param
,
const
char
*
event_buf
,
unsigned
long
len
)
{
if
(
repl_semisync
.
is_semi_sync_slave
())
{
THD
*
thd
=
current_thd
;
/*
Possible errors in reading slave reply are ignored deliberately
because we do not want dump thread to quit on this. Error
messages are already reported.
*/
(
void
)
repl_semisync
.
readSlaveReply
(
&
thd
->
net
,
param
->
server_id
,
event_buf
);
thd
->
clear_error
();
}
return
0
;
}
...
...
@@ -142,11 +162,6 @@ static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
void
*
ptr
,
const
void
*
val
);
static
void
fix_rpl_semi_sync_master_reply_log_file_pos
(
MYSQL_THD
thd
,
SYS_VAR
*
var
,
void
*
ptr
,
const
void
*
val
);
static
MYSQL_SYSVAR_BOOL
(
enabled
,
rpl_semi_sync_master_enabled
,
PLUGIN_VAR_OPCMDARG
,
"Enable semi-synchronous replication master (disabled by default). "
,
...
...
@@ -161,6 +176,13 @@ static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout,
fix_rpl_semi_sync_master_timeout
,
// update
10000
,
0
,
~
0L
,
1
);
static
MYSQL_SYSVAR_BOOL
(
wait_no_slave
,
rpl_semi_sync_master_wait_no_slave
,
PLUGIN_VAR_OPCMDARG
,
"Wait until timeout when no semi-synchronous replication slave available (enabled by default). "
,
NULL
,
// check
NULL
,
// update
1
);
static
MYSQL_SYSVAR_ULONG
(
trace_level
,
rpl_semi_sync_master_trace_level
,
PLUGIN_VAR_OPCMDARG
,
"The tracing level for semi-sync replication."
,
...
...
@@ -168,22 +190,11 @@ static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level,
&
fix_rpl_semi_sync_master_trace_level
,
// update
32
,
0
,
~
0L
,
1
);
/*
Use a SESSION instead of GLOBAL variable for slave to send reply to
avoid requiring SUPER privilege.
*/
static
MYSQL_THDVAR_STR
(
reply_log_file_pos
,
PLUGIN_VAR_NOCMDOPT
,
"The log filename and position slave has queued to relay log."
,
NULL
,
// check
&
fix_rpl_semi_sync_master_reply_log_file_pos
,
""
);
static
SYS_VAR
*
semi_sync_master_system_vars
[]
=
{
MYSQL_SYSVAR
(
enabled
),
MYSQL_SYSVAR
(
timeout
),
MYSQL_SYSVAR
(
wait_no_slave
),
MYSQL_SYSVAR
(
trace_level
),
MYSQL_SYSVAR
(
reply_log_file_pos
),
NULL
,
};
...
...
@@ -228,19 +239,6 @@ static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
return
;
}
static
void
fix_rpl_semi_sync_master_reply_log_file_pos
(
MYSQL_THD
thd
,
SYS_VAR
*
var
,
void
*
ptr
,
const
void
*
val
)
{
const
char
*
log_file_pos
=
*
(
char
**
)
val
;
if
(
repl_semisync
.
reportReplyBinlog
(
log_file_pos
))
sql_print_error
(
"report slave binlog reply failed."
);
return
;
}
Trans_observer
trans_observer
=
{
sizeof
(
Trans_observer
),
// len
...
...
@@ -278,45 +276,60 @@ Binlog_transmit_observer transmit_observer = {
return 0; \
}
DEF_SHOW_FUNC
(
clients
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
net_wait_time
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
net_wait_total_time
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
net_wait_num
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
off_times
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
no_transactions
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
status
,
SHOW_BOOL
)
DEF_SHOW_FUNC
(
timefunc_fails
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
trx_wait_time
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
trx_wait_total_time
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
clients
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
trx_wait_time
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
trx_wait_num
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
back_wait_pos
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
wait_sessions
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
yes_transactions
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
net_wait_time
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
net_wait_num
,
SHOW_LONGLONG
)
DEF_SHOW_FUNC
(
avg_net_wait_time
,
SHOW_LONG
)
DEF_SHOW_FUNC
(
avg_trx_wait_time
,
SHOW_LONG
)
/* plugin status variables */
static
SHOW_VAR
semi_sync_master_status_vars
[]
=
{
{
"Rpl_semi_sync_master_clients"
,
(
char
*
)
&
SHOW_FNAME
(
clients
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_net_avg_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
net_wait_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_net_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
net_wait_total_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_net_waits"
,
(
char
*
)
&
SHOW_FNAME
(
net_wait_num
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_no_times"
,
(
char
*
)
&
SHOW_FNAME
(
off_times
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_no_tx"
,
(
char
*
)
&
SHOW_FNAME
(
no_transactions
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_status"
,
(
char
*
)
&
SHOW_FNAME
(
status
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_status"
,
(
char
*
)
&
SHOW_FNAME
(
status
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_clients"
,
(
char
*
)
&
SHOW_FNAME
(
clients
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_yes_tx"
,
(
char
*
)
&
rpl_semi_sync_master_yes_transactions
,
SHOW_LONG
},
{
"Rpl_semi_sync_master_no_tx"
,
(
char
*
)
&
rpl_semi_sync_master_no_transactions
,
SHOW_LONG
},
{
"Rpl_semi_sync_master_wait_sessions"
,
(
char
*
)
&
rpl_semi_sync_master_wait_sessions
,
SHOW_LONG
},
{
"Rpl_semi_sync_master_no_times"
,
(
char
*
)
&
rpl_semi_sync_master_off_times
,
SHOW_LONG
},
{
"Rpl_semi_sync_master_timefunc_failures"
,
(
char
*
)
&
SHOW_FNAME
(
timefunc_fails
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_tx_avg_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
trx_wait_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_tx_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
trx_wait_total_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_tx_waits"
,
(
char
*
)
&
SHOW_FNAME
(
trx_wait_num
),
SHOW_FUNC
},
(
char
*
)
&
rpl_semi_sync_master_timefunc_fails
,
SHOW_LONG
},
{
"Rpl_semi_sync_master_wait_pos_backtraverse"
,
(
char
*
)
&
SHOW_FNAME
(
back_wait_pos
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_wait_sessions"
,
(
char
*
)
&
SHOW_FNAME
(
wait_sessions
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_yes_tx"
,
(
char
*
)
&
SHOW_FNAME
(
yes_transactions
),
SHOW_FUNC
},
(
char
*
)
&
rpl_semi_sync_master_wait_pos_backtraverse
,
SHOW_LONG
},
{
"Rpl_semi_sync_master_tx_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
trx_wait_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_tx_waits"
,
(
char
*
)
&
SHOW_FNAME
(
trx_wait_num
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_tx_avg_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
avg_trx_wait_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_net_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
net_wait_time
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_net_waits"
,
(
char
*
)
&
SHOW_FNAME
(
net_wait_num
),
SHOW_FUNC
},
{
"Rpl_semi_sync_master_net_avg_wait_time"
,
(
char
*
)
&
SHOW_FNAME
(
avg_net_wait_time
),
SHOW_FUNC
},
{
NULL
,
NULL
,
SHOW_LONG
},
};
...
...
plugin/semisync/semisync_slave.cc
View file @
b289e515
...
...
@@ -39,16 +39,6 @@ int ReplSemiSyncSlave::initObject()
return
result
;
}
int
ReplSemiSyncSlave
::
slaveReplyConnect
()
{
if
(
!
mysql_reply
&&
!
(
mysql_reply
=
rpl_connect_master
(
NULL
)))
{
sql_print_error
(
"Semisync slave connect to master for reply failed"
);
return
1
;
}
return
0
;
}
int
ReplSemiSyncSlave
::
slaveReadSyncHeader
(
const
char
*
header
,
unsigned
long
total_len
,
bool
*
need_reply
,
...
...
@@ -104,19 +94,45 @@ int ReplSemiSyncSlave::slaveStop(Binlog_relay_IO_param *param)
return
0
;
}
int
ReplSemiSyncSlave
::
slaveReply
(
const
char
*
log_name
,
my_off_t
log_pos
)
int
ReplSemiSyncSlave
::
slaveReply
(
MYSQL
*
mysql
,
const
char
*
binlog_filename
,
my_off_t
binlog_filepos
)
{
char
query
[
FN_REFLEN
+
100
];
sprintf
(
query
,
"SET SESSION rpl_semi_sync_master_reply_log_file_pos='%llu:%s'"
,
(
unsigned
long
long
)
log_pos
,
log_name
);
if
(
mysql_real_query
(
mysql_reply
,
query
,
strlen
(
query
)))
const
char
*
kWho
=
"ReplSemiSyncSlave::slaveReply"
;
NET
*
net
=
&
mysql
->
net
;
uchar
reply_buffer
[
REPLY_MAGIC_NUM_LEN
+
REPLY_BINLOG_POS_LEN
+
REPLY_BINLOG_NAME_LEN
];
int
reply_res
,
name_len
=
strlen
(
binlog_filename
);
function_enter
(
kWho
);
/* Prepare the buffer of the reply. */
reply_buffer
[
REPLY_MAGIC_NUM_OFFSET
]
=
kPacketMagicNum
;
int8store
(
reply_buffer
+
REPLY_BINLOG_POS_OFFSET
,
binlog_filepos
);
memcpy
(
reply_buffer
+
REPLY_BINLOG_NAME_OFFSET
,
binlog_filename
,
name_len
+
1
/* including trailing '\0' */
);
if
(
trace_level_
&
kTraceDetail
)
sql_print_information
(
"%s: reply (%s, %lu)"
,
kWho
,
binlog_filename
,
(
ulong
)
binlog_filepos
);
net_clear
(
net
,
0
);
/* Send the reply. */
reply_res
=
my_net_write
(
net
,
reply_buffer
,
name_len
+
REPLY_BINLOG_NAME_OFFSET
);
if
(
!
reply_res
)
{
sql_print_error
(
"Set 'rpl_semi_sync_master_reply_log_file_pos' on master failed"
);
mysql_free_result
(
mysql_store_result
(
mysql_reply
));
mysql_close
(
mysql_reply
);
mysql_reply
=
0
;
return
1
;
reply_res
=
net_flush
(
net
);
if
(
reply_res
)
sql_print_error
(
"Semi-sync slave net_flush() reply failed"
);
}
mysql_free_result
(
mysql_store_result
(
mysql_reply
));
return
0
;
else
{
sql_print_error
(
"Semi-sync slave send reply failed: %s (%d)"
,
net
->
last_error
,
net
->
last_errno
);
}
return
function_exit
(
kWho
,
reply_res
);
}
plugin/semisync/semisync_slave.h
View file @
b289e515
...
...
@@ -57,7 +57,7 @@ public:
* payload_len - (IN) payload length
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
slaveReadSyncHeader
(
const
char
*
header
,
unsigned
long
total_len
,
bool
*
need_reply
,
const
char
**
payload
,
unsigned
long
*
payload_len
);
...
...
@@ -67,19 +67,16 @@ public:
* binlog position.
*
* Input:
* log_name - (IN) the reply point's binlog file name
* log_pos - (IN) the reply point's binlog file offset
* mysql - (IN) the mysql network connection
* binlog_filename - (IN) the reply point's binlog file name
* binlog_filepos - (IN) the reply point's binlog file offset
*
* Return:
* 0: success;
-1 or otherwise
: error
* 0: success;
non-zero
: error
*/
int
slaveReply
(
const
char
*
log_name
,
my_off_t
log_pos
);
int
slaveReply
(
MYSQL
*
mysql
,
const
char
*
binlog_filename
,
my_off_t
binlog_filepos
);
/*
Connect to master for sending reply
*/
int
slaveReplyConnect
();
int
slaveStart
(
Binlog_relay_IO_param
*
param
);
int
slaveStop
(
Binlog_relay_IO_param
*
param
);
...
...
plugin/semisync/semisync_slave_plugin.cc
View file @
b289e515
...
...
@@ -45,13 +45,6 @@ int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
if
(
!
repl_semisync
.
getSlaveEnabled
())
return
0
;
/*
Create the connection that is used to send slave ACK replies to
master
*/
if
(
repl_semisync
.
slaveReplyConnect
())
return
1
;
/* Check if master server has semi-sync plugin installed */
query
=
"SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'"
;
if
(
mysql_real_query
(
mysql
,
query
,
strlen
(
query
))
||
...
...
@@ -63,10 +56,11 @@ int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
}
row
=
mysql_fetch_row
(
res
);
if
(
!
row
||
strcmp
(
row
[
1
],
"ON"
)
)
if
(
!
row
)
{
/* Master does not support or not configured semi-sync */
sql_print_warning
(
"Master server does not support or not configured semi-sync replication, fallback to asynchronous"
);
/* Master does not support semi-sync */
sql_print_warning
(
"Master server does not support semi-sync, "
"fallback to asynchronous replication"
);
rpl_semi_sync_slave_status
=
0
;
return
0
;
}
...
...
@@ -106,8 +100,16 @@ int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
uint32
flags
)
{
if
(
rpl_semi_sync_slave_status
&&
semi_sync_need_reply
)
return
repl_semisync
.
slaveReply
(
param
->
master_log_name
,
{
/*
We deliberately ignore the error in slaveReply, such error
should not cause the slave IO thread to stop, and the error
messages are already reported.
*/
(
void
)
repl_semisync
.
slaveReply
(
param
->
mysql
,
param
->
master_log_name
,
param
->
master_log_pos
);
}
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment