summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/mariadb-server-10.3.install2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_semi_sync.inc1
-rw-r--r--mysql-test/include/have_semisync.inc4
-rw-r--r--mysql-test/include/have_semisync.opt4
-rw-r--r--mysql-test/include/install_semisync.inc39
-rw-r--r--mysql-test/include/uninstall_semisync.inc29
-rw-r--r--mysql-test/r/mysqld--help.result28
-rw-r--r--mysql-test/suite/perfschema/r/dml_setup_instruments.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result73
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev359.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_event.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test132
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test1
-rw-r--r--mysql-test/suite/rpl/t/semisync_future-7591.test1
-rw-r--r--mysql-test/suite/rpl/t/semisync_memleak_4066.test1
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result98
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test1
-rw-r--r--mysql-test/t/mysqld--help.test2
-rw-r--r--plugin/semisync/CMakeLists.txt28
-rw-r--r--plugin/semisync/semisync_master_plugin.cc496
-rw-r--r--plugin/semisync/semisync_slave_plugin.cc234
-rw-r--r--sql/CMakeLists.txt3
-rw-r--r--sql/mysqld.cc66
-rw-r--r--sql/replication.h14
-rw-r--r--sql/rpl_handler.cc8
-rw-r--r--sql/semisync.cc (renamed from plugin/semisync/semisync.cc)0
-rw-r--r--sql/semisync.h (renamed from plugin/semisync/semisync.h)16
-rw-r--r--sql/semisync_master.cc (renamed from plugin/semisync/semisync_master.cc)356
-rw-r--r--sql/semisync_master.h (renamed from plugin/semisync/semisync_master.h)52
-rw-r--r--sql/semisync_slave.cc (renamed from plugin/semisync/semisync_slave.cc)156
-rw-r--r--sql/semisync_slave.h (renamed from plugin/semisync/semisync_slave.h)10
-rw-r--r--sql/sys_vars.cc182
38 files changed, 860 insertions, 1189 deletions
diff --git a/debian/mariadb-server-10.3.install b/debian/mariadb-server-10.3.install
index 23f8046baaf..604179c7dca 100644
--- a/debian/mariadb-server-10.3.install
+++ b/debian/mariadb-server-10.3.install
@@ -52,8 +52,6 @@ usr/lib/mysql/plugin/locales.so
usr/lib/mysql/plugin/metadata_lock_info.so
usr/lib/mysql/plugin/query_cache_info.so
usr/lib/mysql/plugin/query_response_time.so
-usr/lib/mysql/plugin/semisync_master.so
-usr/lib/mysql/plugin/semisync_slave.so
usr/lib/mysql/plugin/server_audit.so
usr/lib/mysql/plugin/simple_password_check.so
usr/lib/mysql/plugin/sql_errlog.so
diff --git a/mysql-test/extra/rpl_tests/rpl_semi_sync.inc b/mysql-test/extra/rpl_tests/rpl_semi_sync.inc
index 12053c54f4e..ed56e405e27 100644
--- a/mysql-test/extra/rpl_tests/rpl_semi_sync.inc
+++ b/mysql-test/extra/rpl_tests/rpl_semi_sync.inc
@@ -4,7 +4,6 @@
# Please check all dependent tests after modifying it
#
-source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
source include/master-slave.inc;
diff --git a/mysql-test/include/have_semisync.inc b/mysql-test/include/have_semisync.inc
deleted file mode 100644
index 243fad83717..00000000000
--- a/mysql-test/include/have_semisync.inc
+++ /dev/null
@@ -1,4 +0,0 @@
-if (`select count(*) < 2 from information_schema.plugins where plugin_name like 'rpl_semi_sync_%'`)
-{
- --skip Test requires semisync plugins
-}
diff --git a/mysql-test/include/have_semisync.opt b/mysql-test/include/have_semisync.opt
deleted file mode 100644
index 19e29c7e4de..00000000000
--- a/mysql-test/include/have_semisync.opt
+++ /dev/null
@@ -1,4 +0,0 @@
---plugin-load-add=$SEMISYNC_MASTER_SO
---plugin-load-add=$SEMISYNC_SLAVE_SO
---loose-rpl-semi-sync-master
---loose-rpl-semi-sync-slave
diff --git a/mysql-test/include/install_semisync.inc b/mysql-test/include/install_semisync.inc
deleted file mode 100644
index 9cc6df2072a..00000000000
--- a/mysql-test/include/install_semisync.inc
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-#
---let $include_filename= install_semisync.inc
---source include/begin_include_file.inc
-
---source include/not_embedded.inc
---source include/have_semisync_plugin.inc
-
---connection master
-
---disable_query_log
---let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1)
-if ($value == No such row)
-{
- SET sql_log_bin = 0;
- install plugin rpl_semi_sync_master soname 'semisync_master';
- SET GLOBAL rpl_semi_sync_master_enabled = 1;
- SET sql_log_bin = 1;
-}
---enable_query_log
-
---connection slave
---source include/stop_slave_io.inc
-
---disable_query_log
---let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1)
-if ($value == No such row)
-{
- SET sql_log_bin = 0;
- install plugin rpl_semi_sync_slave soname 'semisync_slave';
- SET GLOBAL rpl_semi_sync_slave_enabled = 1;
- SET sql_log_bin = 1;
-}
-START SLAVE IO_THREAD;
---source include/wait_for_slave_io_to_start.inc
---enable_query_log
-
---source include/end_include_file.inc
diff --git a/mysql-test/include/uninstall_semisync.inc b/mysql-test/include/uninstall_semisync.inc
deleted file mode 100644
index 0a4c55fa4f2..00000000000
--- a/mysql-test/include/uninstall_semisync.inc
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-#
---let $include_filename= uninstall_semisync.inc
---source include/begin_include_file.inc
-
---disable_query_log
---connection slave
---source include/stop_slave_io.inc
-
-# Uninstall rpl_semi_sync_slave first
---disable_warnings
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-
---connection master
-# After BUG#17638477 fix, uninstallation of rpl_semi_sync_master
-# is not allowed when there are semi sync slaves. Hence kill
-# all dump threads before uninstalling it.
-SET GLOBAL rpl_semi_sync_master_enabled = OFF;
---source include/stop_dump_threads.inc
-UNINSTALL PLUGIN rpl_semi_sync_master;
---enable_warnings
-
---connection slave
-START SLAVE IO_THREAD;
---source include/wait_for_slave_io_to_start.inc
---enable_query_log
-
---source include/end_include_file.inc
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index f76957fdcba..032c64b8040 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -998,6 +998,27 @@ The following options may be given as the first argument:
--rowid-merge-buff-size=#
The size of the buffers used [NOT] IN evaluation via
partial matching
+ --rpl-semi-sync-master-enabled
+ Enable semi-synchronous replication master (disabled by
+ default).
+ --rpl-semi-sync-master-timeout=#
+ The timeout value (in ms) for semi-synchronous
+ replication in the master
+ --rpl-semi-sync-master-trace-level=#
+ The tracing level for semi-sync replication.
+ --rpl-semi-sync-master-wait-no-slave
+ Wait until timeout when no semi-synchronous replication
+ slave available (enabled by default).
+ (Defaults to on; use --skip-rpl-semi-sync-master-wait-no-slave to disable.)
+ --rpl-semi-sync-master-wait-point=name
+ Should transaction wait for semi-sync ack after having
+ synced binlog, or after having committed in storage
+ engine.. One of: AFTER_SYNC, AFTER_COMMIT
+ --rpl-semi-sync-slave-enabled
+ Enable semi-synchronous replication slave (disabled by
+ default).
+ --rpl-semi-sync-slave-trace-level=#
+ The tracing level for semi-sync replication.
--safe-mode Skip some optimize stages (for testing). Deprecated.
--safe-user-create Don't allow new user creation by the user who has no
write privileges to the mysql.user table.
@@ -1569,6 +1590,13 @@ report-password (No default value)
report-port 0
report-user (No default value)
rowid-merge-buff-size 8388608
+rpl-semi-sync-master-enabled FALSE
+rpl-semi-sync-master-timeout 10000
+rpl-semi-sync-master-trace-level 32
+rpl-semi-sync-master-wait-no-slave TRUE
+rpl-semi-sync-master-wait-point AFTER_COMMIT
+rpl-semi-sync-slave-enabled FALSE
+rpl-semi-sync-slave-trace-level 32
safe-user-create FALSE
secure-auth TRUE
secure-file-priv (No default value)
diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result
index 83510e5827e..940839b105f 100644
--- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result
+++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result
@@ -13,7 +13,7 @@ wait/synch/mutex/sql/HA_DATA_PARTITION::LOCK_auto_inc YES YES
wait/synch/mutex/sql/LOCK_active_mi YES YES
wait/synch/mutex/sql/LOCK_after_binlog_sync YES YES
wait/synch/mutex/sql/LOCK_audit_mask YES YES
-wait/synch/mutex/sql/LOCK_binlog_state YES YES
+wait/synch/mutex/sql/LOCK_binlog YES YES
select * from performance_schema.setup_instruments
where name like 'Wait/Synch/Rwlock/sql/%'
and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock')
@@ -36,6 +36,7 @@ where name like 'Wait/Synch/Cond/sql/%'
'wait/synch/cond/sql/DEBUG_SYNC::cond')
order by name limit 10;
NAME ENABLED TIMED
+wait/synch/cond/sql/COND_binlog_send YES YES
wait/synch/cond/sql/COND_flush_thread_cache YES YES
wait/synch/cond/sql/COND_group_commit_orderer YES YES
wait/synch/cond/sql/COND_gtid_ignore_duplicates YES YES
@@ -45,7 +46,6 @@ wait/synch/cond/sql/COND_prepare_ordered YES YES
wait/synch/cond/sql/COND_queue_state YES YES
wait/synch/cond/sql/COND_rpl_thread YES YES
wait/synch/cond/sql/COND_rpl_thread_pool YES YES
-wait/synch/cond/sql/COND_rpl_thread_queue YES YES
select * from performance_schema.setup_instruments
where name='Wait';
select * from performance_schema.setup_instruments
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result b/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result
deleted file mode 100644
index 68ad4877927..00000000000
--- a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result
+++ /dev/null
@@ -1,73 +0,0 @@
-include/master-slave.inc
-[connection master]
-call mtr.add_suppression("Read semi-sync reply network error");
-call mtr.add_suppression("Timeout waiting for reply of binlog");
-INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
-connection slave;
-INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-connection master;
-UNINSTALL PLUGIN rpl_semi_sync_master;
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (1);
-DROP TABLE t1;
-connection slave;
-include/install_semisync.inc
-connection master;
-connection slave;
-connection slave;
-show global status like "Slave%_running";
-Variable_name Value
-Slave_running ON
-Slaves_running 1
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-Warnings:
-Warning 1620 Plugin is busy and will be uninstalled on shutdown
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-rpl_semi_sync_slave DELETED
-connection master;
-show global status like "Slave%_connect%";
-Variable_name Value
-Slave_connections 2
-Slaves_connected 1
-UNINSTALL PLUGIN rpl_semi_sync_master;
-Warnings:
-Warning 1620 Plugin is busy and will be uninstalled on shutdown
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-rpl_semi_sync_master DELETED
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (2);
-DROP TABLE t1;
-connection slave;
-show status like "Rpl_semi_sync_slave_status";
-Variable_name Value
-Rpl_semi_sync_slave_status ON
-connection master;
-show status like "Rpl_semi_sync_master_status";
-Variable_name Value
-Rpl_semi_sync_master_status ON
-show status like "Rpl_semi_sync_master_clients";
-Variable_name Value
-Rpl_semi_sync_master_clients 1
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-rpl_semi_sync_master DELETED
-connection slave;
-include/stop_slave.inc
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-connection master;
-create table t2 (a int);
-drop table t2;
-connection slave;
-include/start_slave.inc
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-plugin_name plugin_status
-connection master;
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (3);
-DROP TABLE t1;
-connection slave;
-include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mdev359.test b/mysql-test/suite/rpl/t/rpl_mdev359.test
index 3026c6d363e..5b02ecd72c0 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev359.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev359.test
@@ -1,4 +1,3 @@
---source include/have_semisync.inc
--source include/not_embedded.inc
--source include/have_debug_sync.inc
--source include/have_binlog_format_mixed_or_statement.inc
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test
index b8f3c8130be..d7685413a07 100644
--- a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test
@@ -1,4 +1,3 @@
-source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
source include/master-slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test b/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test
deleted file mode 100644
index 360706922ea..00000000000
--- a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test
+++ /dev/null
@@ -1,132 +0,0 @@
-###############################################################################
-# Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK
-# Problem: Uninstallation of Semi sync plugin should be blocked when it is
-# in use.
-# Test case: Uninstallation of semi sync should be allowed
-# On Master:
-# 1) When there is no dump thread
-# 2) When there are no semi sync slaves (i.e., async replication).
-# On Slave:
-# 1) When there is no I/O thread
-# 2) When there are no semi sync enabled I/O thread (i.e.,async replication).
-###############################################################################
-
---source include/have_semisync_plugin.inc
---source include/not_embedded.inc
---source include/have_binlog_format_statement.inc
---source include/master-slave.inc
-
-call mtr.add_suppression("Read semi-sync reply network error");
-call mtr.add_suppression("Timeout waiting for reply of binlog");
-
-###############################################################################
-# Case 1: Uninstallation of semi sync plugins should be allowed when it is
-# not in use i.e., when asynchronous replication is active.
-###############################################################################
-# Step 1.1: Install semi sync master plugin on master
-INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
-
-# Step 1.2: Install semi sync slave plugin on slave
---connection slave
-INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
-
-# Step 1.3: Uninstallation of semisync plugin on master and slave should be
-# allowed at this state as there is no semi sync replication enabled between
-# master and slave.
-UNINSTALL PLUGIN rpl_semi_sync_slave;
---connection master
-UNINSTALL PLUGIN rpl_semi_sync_master;
-
-# Step 1.4: Check that replication is working fine at the end of the test case.
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (1);
-DROP TABLE t1;
---sync_slave_with_master
-
-###############################################################################
-# Case 2: Uninstallation of semi sync plugins should be disallowed
-# when it is in use i.e., when semi sync replication is active
-###############################################################################
-# Step 2.1: Install and enable semi sync replication between master and slave
---source include/install_semisync.inc
-
-# Step 2.2: Check that rpl_semi_sync_slave uninstallation on Slave is not
-# possible at this state
---connection slave
-show global status like "Slave%_running";
-
-UNINSTALL PLUGIN rpl_semi_sync_slave;
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-# Step 2.3: Check that rpl_semi_sync_master uninstallation on Master is not
-# possible at this state
---connection master
-
-# The following is to catch errors if the next uninstall plugin would succeed
-show global status like "Slave%_connect%";
-
-UNINSTALL PLUGIN rpl_semi_sync_master;
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-# Step 2.4: Check that replication is working fine at the end of the test case.
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (2);
-DROP TABLE t1;
---sync_slave_with_master
-
-# Step 2.5: Make sure rpl_semi_sync_master_status on Master and
-# rpl_semi_sync_slave_staus on Slave are ON
-show status like "Rpl_semi_sync_slave_status";
-
-###############################################################################
-# Case 3: Uninstallation of semi sync plugin should be disallowed when there
-# are semi sync slaves even though rpl_semi_sync_master_enabled= OFF;.
-###############################################################################
-# Step 3.1: Disable semi sync on master
---connection master
-show status like "Rpl_semi_sync_master_status";
-
-# Step 3.2: Check that still Rpl_semi_sync_master_clients is 1
-show status like "Rpl_semi_sync_master_clients";
-
-# Step 3.3: Since Rpl_semi_sync_master_clients is 1, uninstallation of
-# rpl_semi_sync_master should be disallowed.
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-###############################################################################
-# Case 4: Uninstallation of semi sync plugin should be allowed when it is not
-# in use. Same as Case 1 but this case is to check the case after enabling and
-# disabling semi sync replication.
-###############################################################################
-
-# Step 4.1: Stop IO thread on slave.
---connection slave
---source include/stop_slave.inc
-
-# Step 4.2: Disable semi sync on slave.
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
---connection master
-# Send something to the slave so that the master would notice that nobody's listening.
-create table t2 (a int); drop table t2;
-# and wait for plugin to be unloaded automatically
-let $wait_condition=select count(*) = 0 from information_schema.plugins where plugin_name like 'rpl_%';
---source include/wait_condition.inc
-
---connection slave
-
-# Step 4.3: Start IO thread on slave.
---source include/start_slave.inc
-
-# Step 4.4: Uninstall semi sync plugin, it should be successful now.
-select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
-
-# Step 4.7: Check that replication is working fine at the end of the test case
---connection master
-CREATE TABLE t1(i int);
-INSERT INTO t1 values (3);
-DROP TABLE t1;
---sync_slave_with_master
-
-# Cleanup
-source include/rpl_end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test b/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test
index 6e4dc456a27..dcff4030fdb 100644
--- a/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test
@@ -1,4 +1,3 @@
-source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
diff --git a/mysql-test/suite/rpl/t/semisync_future-7591.test b/mysql-test/suite/rpl/t/semisync_future-7591.test
index daf3d2f8571..866041d2579 100644
--- a/mysql-test/suite/rpl/t/semisync_future-7591.test
+++ b/mysql-test/suite/rpl/t/semisync_future-7591.test
@@ -1,4 +1,3 @@
---source include/have_semisync.inc
--source include/master-slave.inc
call mtr.add_suppression("Timeout waiting for reply of binlog*");
diff --git a/mysql-test/suite/rpl/t/semisync_memleak_4066.test b/mysql-test/suite/rpl/t/semisync_memleak_4066.test
index f888f764b43..e88e2335696 100644
--- a/mysql-test/suite/rpl/t/semisync_memleak_4066.test
+++ b/mysql-test/suite/rpl/t/semisync_memleak_4066.test
@@ -1,7 +1,6 @@
#
# MDEV-4066 semisync_master + temporary tables causes memory leaks
#
-source include/have_semisync.inc;
source include/have_binlog_format_row.inc;
source include/master-slave.inc;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 8591f4b0c28..376123fa88d 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -4001,6 +4001,104 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_ENABLED
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Enable semi-synchronous replication master (disabled by default).
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TIMEOUT
+SESSION_VALUE NULL
+GLOBAL_VALUE 10000
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 10000
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT The timeout value (in ms) for semi-synchronous replication in the master
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TRACE_LEVEL
+SESSION_VALUE NULL
+GLOBAL_VALUE 32
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 32
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT The tracing level for semi-sync replication.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_WAIT_NO_SLAVE
+SESSION_VALUE NULL
+GLOBAL_VALUE ON
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE ON
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Wait until timeout when no semi-synchronous replication slave available (enabled by default).
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_MASTER_WAIT_POINT
+SESSION_VALUE NULL
+GLOBAL_VALUE AFTER_COMMIT
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE AFTER_COMMIT
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE ENUM
+VARIABLE_COMMENT Should transaction wait for semi-sync ack after having synced binlog, or after having committed in storage engine.
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST AFTER_SYNC,AFTER_COMMIT
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_ENABLED
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT Enable semi-synchronous replication slave (disabled by default).
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST OFF,ON
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
+VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_TRACE_LEVEL
+SESSION_VALUE NULL
+GLOBAL_VALUE 32
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 32
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT The tracing level for semi-sync replication.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SECURE_AUTH
SESSION_VALUE NULL
GLOBAL_VALUE ON
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
index 2ff03a53c42..da22d0535f4 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test
@@ -6,7 +6,6 @@
#
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_enabled;
SET @start_global_value = @@global.rpl_semi_sync_master_enabled;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
index 74d3c41150b..d312fa1c367 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test
@@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_timeout;
SET @start_global_value = @@global.rpl_semi_sync_master_timeout;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
index c41b53fe5e6..3419254bafd 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test
@@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_trace_level;
SET @start_global_value = @@global.rpl_semi_sync_master_trace_level;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
index d4a46a08140..60ca4425e5b 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test
@@ -6,7 +6,6 @@
#
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_wait_no_slave;
SET @start_global_value = @@global.rpl_semi_sync_master_wait_no_slave;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test
index 8125cf8d653..2f8cd8ec160 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_point_basic.test
@@ -1,5 +1,4 @@
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_wait_point;
SET @start_global_value = @@global.rpl_semi_sync_master_wait_point;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
index c7ce371970d..71be941cbdc 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test
@@ -6,7 +6,6 @@
#
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_slave_enabled;
SET @start_global_value = @@global.rpl_semi_sync_slave_enabled;
diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
index d7e001b7322..74b6ac0a6ae 100644
--- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
+++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test
@@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added
#
source include/not_embedded.inc;
-source include/have_semisync.inc;
select @@global.rpl_semi_sync_slave_trace_level;
SET @start_global_value = @@global.rpl_semi_sync_slave_trace_level;
diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test
index f859d7dd9d6..520384f3ab3 100644
--- a/mysql-test/t/mysqld--help.test
+++ b/mysql-test/t/mysqld--help.test
@@ -30,7 +30,7 @@ perl;
feedback debug temp-pool ssl des-key-file xtradb sequence
thread-concurrency super-large-pages mutex-deadlock-detector
connect null-audit aria oqgraph sphinx thread-handling
- test-sql-discovery rpl-semi-sync query-cache-info
+ test-sql-discovery query-cache-info
query-response-time metadata-lock-info locales unix-socket
wsrep file-key-management cracklib-password-check user-variables/;
diff --git a/plugin/semisync/CMakeLists.txt b/plugin/semisync/CMakeLists.txt
deleted file mode 100644
index 88998fb3093..00000000000
--- a/plugin/semisync/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SET(SEMISYNC_MASTER_SOURCES
- semisync.cc semisync_master.cc semisync_master_plugin.cc
- semisync.h semisync_master.h)
-
-MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES}
- RECOMPILE_FOR_EMBEDDED)
-
-SET(SEMISYNC_SLAVE_SOURCES semisync.cc semisync_slave.cc
- semisync_slave_plugin.cc semisync.h semisync_slave.h )
-
-MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES}
- RECOMPILE_FOR_EMBEDDED)
-
diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc
deleted file mode 100644
index b46cf5d79cb..00000000000
--- a/plugin/semisync/semisync_master_plugin.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-/* Copyright (C) 2007 Google Inc.
- Copyright (c) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
- Use is subject to license terms.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-
-#include <my_global.h>
-#include "semisync_master.h"
-#include "sql_class.h" // THD
-
-static ReplSemiSyncMaster repl_semisync;
-
-C_MODE_START
-
-int repl_semi_report_binlog_update(Binlog_storage_param *param,
- const char *log_file,
- my_off_t log_pos, uint32 flags)
-{
- int error= 0;
-
- if (repl_semisync.getMasterEnabled())
- {
- /*
- Let us store the binlog file name and the position, so that
- we know how long to wait for the binlog to the replicated to
- the slave in synchronous replication.
- */
- error= repl_semisync.writeTranxInBinlog(log_file,
- log_pos);
- }
-
- return error;
-}
-
-int repl_semi_request_commit(Trans_param *param)
-{
- return 0;
-}
-
-int repl_semi_report_binlog_sync(Binlog_storage_param *param,
- const char *log_file,
- my_off_t log_pos, uint32 flags)
-{
- int error= 0;
- if (rpl_semi_sync_master_wait_point ==
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC)
- {
- error = repl_semisync.commitTrx(log_file, log_pos);
- }
-
- return error;
-}
-
-int repl_semi_report_commit(Trans_param *param)
-{
- if (rpl_semi_sync_master_wait_point !=
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT)
- {
- return 0;
- }
-
- bool is_real_trans= param->flags & TRANS_IS_REAL_TRANS;
-
- if (is_real_trans && param->log_pos)
- {
- const char *binlog_name= param->log_file;
- return repl_semisync.commitTrx(binlog_name, param->log_pos);
- }
- return 0;
-}
-
-int repl_semi_report_rollback(Trans_param *param)
-{
- return repl_semi_report_commit(param);
-}
-
-int repl_semi_binlog_dump_start(Binlog_transmit_param *param,
- const char *log_file,
- my_off_t log_pos)
-{
- 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);
-
- return 0;
-}
-
-int repl_semi_binlog_dump_end(Binlog_transmit_param *param)
-{
- bool semi_sync_slave= repl_semisync.is_semi_sync_slave();
-
- sql_print_information("Stop %s binlog_dump to slave (server_id: %d)",
- semi_sync_slave ? "semi-sync" : "asynchronous",
- param->server_id);
- if (semi_sync_slave)
- {
- /* One less semi-sync slave */
- repl_semisync.remove_slave();
- }
- return 0;
-}
-
-int repl_semi_reserve_header(Binlog_transmit_param *param,
- unsigned char *header,
- unsigned long size, unsigned long *len)
-{
- *len += repl_semisync.reserveSyncHeader(header, size);
- return 0;
-}
-
-int repl_semi_before_send_event(Binlog_transmit_param *param,
- unsigned char *packet, unsigned long len,
- const char *log_file, my_off_t log_pos)
-{
- return repl_semisync.updateSyncHeader(packet,
- log_file,
- log_pos,
- param->server_id);
-}
-
-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;
-}
-
-int repl_semi_reset_master(Binlog_transmit_param *param)
-{
- if (repl_semisync.resetMaster())
- return 1;
- return 0;
-}
-
-C_MODE_END
-
-/*
- semisync system variables
- */
-static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val);
-
-static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val);
-
-static void fix_rpl_semi_sync_master_enabled(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). ",
- NULL, // check
- &fix_rpl_semi_sync_master_enabled, // update
- 0);
-
-/* NOTE: must match order of rpl_semi_sync_master_wait_point_t */
-static const char *rpl_semi_sync_master_wait_point_names[] =
-{
- "AFTER_SYNC",
- "AFTER_COMMIT",
- NullS
-};
-
-static TYPELIB rpl_semi_sync_master_wait_point_typelib =
-{
- array_elements(rpl_semi_sync_master_wait_point_names) - 1,
- "",
- rpl_semi_sync_master_wait_point_names,
- NULL
-};
-
-static MYSQL_SYSVAR_ENUM(
- wait_point,
- rpl_semi_sync_master_wait_point,
- PLUGIN_VAR_RQCMDARG,
- "Should transaction wait for semi-sync ack after having synced binlog, "
- "or after having committed in storeage engine.",
- NULL, // check
- NULL, // update
- SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT,
- &rpl_semi_sync_master_wait_point_typelib);
-
-static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout,
- PLUGIN_VAR_OPCMDARG,
- "The timeout value (in ms) for semi-synchronous replication in the master",
- NULL, // check
- fix_rpl_semi_sync_master_timeout, // update
- 10000, 0, ~0UL, 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.",
- NULL, // check
- &fix_rpl_semi_sync_master_trace_level, // update
- 32, 0, ~0UL, 1);
-
-static SYS_VAR* semi_sync_master_system_vars[]= {
- MYSQL_SYSVAR(enabled),
- MYSQL_SYSVAR(wait_point),
- MYSQL_SYSVAR(timeout),
- MYSQL_SYSVAR(wait_no_slave),
- MYSQL_SYSVAR(trace_level),
- NULL,
-};
-
-
-static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(unsigned long *)ptr= *(unsigned long *)val;
- repl_semisync.setWaitTimeout(rpl_semi_sync_master_timeout);
- return;
-}
-
-static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(unsigned long *)ptr= *(unsigned long *)val;
- repl_semisync.setTraceLevel(rpl_semi_sync_master_trace_level);
- return;
-}
-
-static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(char *)ptr= *(char *)val;
- if (rpl_semi_sync_master_enabled)
- {
- if (repl_semisync.enableMaster() != 0)
- rpl_semi_sync_master_enabled = false;
- }
- else
- {
- if (repl_semisync.disableMaster() != 0)
- rpl_semi_sync_master_enabled = true;
- }
-
- return;
-}
-
-Trans_observer trans_observer = {
- sizeof(Trans_observer), // len
-
- repl_semi_report_commit, // after_commit
- repl_semi_report_rollback, // after_rollback
-};
-
-Binlog_storage_observer storage_observer = {
- sizeof(Binlog_storage_observer), // len
-
- repl_semi_report_binlog_update, // report_update
- repl_semi_report_binlog_sync, // after_sync
-};
-
-Binlog_transmit_observer transmit_observer = {
- sizeof(Binlog_transmit_observer), // len
-
- repl_semi_binlog_dump_start, // start
- repl_semi_binlog_dump_end, // stop
- repl_semi_reserve_header, // reserve_header
- repl_semi_before_send_event, // before_send_event
- repl_semi_after_send_event, // after_send_event
- repl_semi_reset_master, // reset
-};
-
-
-#define SHOW_FNAME(name) \
- rpl_semi_sync_master_show_##name
-
-#define DEF_SHOW_FUNC(name, show_type) \
- static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \
- { \
- repl_semisync.setExportStats(); \
- var->type= show_type; \
- var->value= (char *)&rpl_semi_sync_master_##name; \
- return 0; \
- }
-
-DEF_SHOW_FUNC(status, SHOW_BOOL)
-DEF_SHOW_FUNC(clients, SHOW_LONG)
-DEF_SHOW_FUNC(wait_sessions, SHOW_LONG)
-DEF_SHOW_FUNC(trx_wait_time, SHOW_LONGLONG)
-DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG)
-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_status",
- (char*) &SHOW_FNAME(status),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_clients",
- (char*) &SHOW_FNAME(clients),
- SHOW_SIMPLE_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*) &SHOW_FNAME(wait_sessions),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_no_times",
- (char*) &rpl_semi_sync_master_off_times,
- SHOW_LONG},
- {"Rpl_semi_sync_master_timefunc_failures",
- (char*) &rpl_semi_sync_master_timefunc_fails,
- SHOW_LONG},
- {"Rpl_semi_sync_master_wait_pos_backtraverse",
- (char*) &rpl_semi_sync_master_wait_pos_backtraverse,
- SHOW_LONG},
- {"Rpl_semi_sync_master_tx_wait_time",
- (char*) &SHOW_FNAME(trx_wait_time),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_tx_waits",
- (char*) &SHOW_FNAME(trx_wait_num),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_tx_avg_wait_time",
- (char*) &SHOW_FNAME(avg_trx_wait_time),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_net_wait_time",
- (char*) &SHOW_FNAME(net_wait_time),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_net_waits",
- (char*) &SHOW_FNAME(net_wait_num),
- SHOW_SIMPLE_FUNC},
- {"Rpl_semi_sync_master_net_avg_wait_time",
- (char*) &SHOW_FNAME(avg_net_wait_time),
- SHOW_SIMPLE_FUNC},
- {NULL, NULL, SHOW_LONG},
-};
-
-#ifdef HAVE_PSI_INTERFACE
-PSI_mutex_key key_ss_mutex_LOCK_binlog_;
-
-static PSI_mutex_info all_semisync_mutexes[]=
-{
- { &key_ss_mutex_LOCK_binlog_, "LOCK_binlog_", 0}
-};
-
-PSI_cond_key key_ss_cond_COND_binlog_send_;
-
-static PSI_cond_info all_semisync_conds[]=
-{
- { &key_ss_cond_COND_binlog_send_, "COND_binlog_send_", 0}
-};
-#endif /* HAVE_PSI_INTERFACE */
-
-PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave=
-{ 0, "Waiting for semi-sync ACK from slave", 0};
-
-#ifdef HAVE_PSI_INTERFACE
-PSI_stage_info *all_semisync_stages[]=
-{
- & stage_waiting_for_semi_sync_ack_from_slave
-};
-
-static void init_semisync_psi_keys(void)
-{
- const char* category= "semisync";
- int count;
-
- count= array_elements(all_semisync_mutexes);
- mysql_mutex_register(category, all_semisync_mutexes, count);
-
- count= array_elements(all_semisync_conds);
- mysql_cond_register(category, all_semisync_conds, count);
-
- count= array_elements(all_semisync_stages);
- mysql_stage_register(category, all_semisync_stages, count);
-}
-#endif /* HAVE_PSI_INTERFACE */
-
-static int semi_sync_master_plugin_init(void *p)
-{
-#ifdef HAVE_PSI_INTERFACE
- init_semisync_psi_keys();
-#endif
-
- if (repl_semisync.initObject())
- return 1;
- if (register_trans_observer(&trans_observer, p))
- return 1;
- if (register_binlog_storage_observer(&storage_observer, p))
- return 1;
- if (register_binlog_transmit_observer(&transmit_observer, p))
- return 1;
- return 0;
-}
-
-static int semi_sync_master_plugin_deinit(void *p)
-{
- if (unregister_trans_observer(&trans_observer, p))
- {
- sql_print_error("unregister_trans_observer failed");
- return 1;
- }
- if (unregister_binlog_storage_observer(&storage_observer, p))
- {
- sql_print_error("unregister_binlog_storage_observer failed");
- return 1;
- }
- if (unregister_binlog_transmit_observer(&transmit_observer, p))
- {
- sql_print_error("unregister_binlog_transmit_observer failed");
- return 1;
- }
- repl_semisync.cleanup();
- sql_print_information("unregister_replicator OK");
- return 0;
-}
-
-struct Mysql_replication semi_sync_master_plugin= {
- MYSQL_REPLICATION_INTERFACE_VERSION
-};
-
-/*
- Plugin library descriptor
-*/
-maria_declare_plugin(semisync_master)
-{
- MYSQL_REPLICATION_PLUGIN,
- &semi_sync_master_plugin,
- "rpl_semi_sync_master",
- "He Zhenxing",
- "Semi-synchronous replication master",
- PLUGIN_LICENSE_GPL,
- semi_sync_master_plugin_init, /* Plugin Init */
- semi_sync_master_plugin_deinit, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
- semi_sync_master_status_vars, /* status variables */
- semi_sync_master_system_vars, /* system variables */
- "1.0",
- MariaDB_PLUGIN_MATURITY_STABLE
-}
-maria_declare_plugin_end;
-
diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc
deleted file mode 100644
index df9e8e10429..00000000000
--- a/plugin/semisync/semisync_slave_plugin.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Copyright (C) 2007 Google Inc.
- Copyright (C) 2008 MySQL AB
- Use is subject to license terms
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-
-#include <my_global.h>
-#include "semisync_slave.h"
-#include <mysql.h>
-
-static ReplSemiSyncSlave repl_semisync;
-
-/*
- indicate whether or not the slave should send a reply to the master.
-
- This is set to true in repl_semi_slave_read_event if the current
- event read is the last event of a transaction. And the value is
- checked in repl_semi_slave_queue_event.
-*/
-bool semi_sync_need_reply= false;
-
-C_MODE_START
-
-int repl_semi_reset_slave(Binlog_relay_IO_param *param)
-{
- // TODO: reset semi-sync slave status here
- return 0;
-}
-
-int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
- uint32 flags)
-{
- MYSQL *mysql= param->mysql;
- MYSQL_RES *res= 0;
- MYSQL_ROW row;
- const char *query;
-
- if (!repl_semisync.getSlaveEnabled())
- return 0;
-
- /* 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)) ||
- !(res= mysql_store_result(mysql)))
- {
- sql_print_error("Execution failed on master: %s", query);
- return 1;
- }
-
- row= mysql_fetch_row(res);
- if (!row)
- {
- /* 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;
- mysql_free_result(res);
- return 0;
- }
- mysql_free_result(res);
-
- /*
- Tell master dump thread that we want to do semi-sync
- replication
- */
- query= "SET @rpl_semi_sync_slave= 1";
- if (mysql_real_query(mysql, query, strlen(query)))
- {
- sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
- return 1;
- }
- mysql_free_result(mysql_store_result(mysql));
- rpl_semi_sync_slave_status= 1;
- return 0;
-}
-
-int repl_semi_slave_read_event(Binlog_relay_IO_param *param,
- const char *packet, unsigned long len,
- const char **event_buf, unsigned long *event_len)
-{
- if (rpl_semi_sync_slave_status)
- return repl_semisync.slaveReadSyncHeader(packet, len,
- &semi_sync_need_reply,
- event_buf, event_len);
- *event_buf= packet;
- *event_len= len;
- return 0;
-}
-
-int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
- const char *event_buf,
- unsigned long event_len,
- uint32 flags)
-{
- if (rpl_semi_sync_slave_status && semi_sync_need_reply)
- {
- /*
- 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;
-}
-
-int repl_semi_slave_io_start(Binlog_relay_IO_param *param)
-{
- return repl_semisync.slaveStart(param);
-}
-
-int repl_semi_slave_io_end(Binlog_relay_IO_param *param)
-{
- return repl_semisync.slaveStop(param);
-}
-
-C_MODE_END
-
-static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(char *)ptr= *(char *)val;
- repl_semisync.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0);
- return;
-}
-
-static void fix_rpl_semi_sync_trace_level(MYSQL_THD thd,
- SYS_VAR *var,
- void *ptr,
- const void *val)
-{
- *(unsigned long *)ptr= *(unsigned long *)val;
- repl_semisync.setTraceLevel(rpl_semi_sync_slave_trace_level);
- return;
-}
-
-/* plugin system variables */
-static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_slave_enabled,
- PLUGIN_VAR_OPCMDARG,
- "Enable semi-synchronous replication slave (disabled by default). ",
- NULL, // check
- &fix_rpl_semi_sync_slave_enabled, // update
- 0);
-
-static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level,
- PLUGIN_VAR_OPCMDARG,
- "The tracing level for semi-sync replication.",
- NULL, // check
- &fix_rpl_semi_sync_trace_level, // update
- 32, 0, ~0UL, 1);
-
-static SYS_VAR* semi_sync_slave_system_vars[]= {
- MYSQL_SYSVAR(enabled),
- MYSQL_SYSVAR(trace_level),
- NULL,
-};
-
-
-/* plugin status variables */
-static SHOW_VAR semi_sync_slave_status_vars[]= {
- {"Rpl_semi_sync_slave_status",
- (char*) &rpl_semi_sync_slave_status, SHOW_BOOL},
- {NULL, NULL, SHOW_BOOL},
-};
-
-Binlog_relay_IO_observer relay_io_observer = {
- sizeof(Binlog_relay_IO_observer), // len
-
- repl_semi_slave_io_start, // start
- repl_semi_slave_io_end, // stop
- repl_semi_slave_request_dump, // request_transmit
- repl_semi_slave_read_event, // after_read_event
- repl_semi_slave_queue_event, // after_queue_event
- repl_semi_reset_slave, // reset
-};
-
-static int semi_sync_slave_plugin_init(void *p)
-{
- if (repl_semisync.initObject())
- return 1;
- if (register_binlog_relay_io_observer(&relay_io_observer, p))
- return 1;
- return 0;
-}
-
-static int semi_sync_slave_plugin_deinit(void *p)
-{
- if (unregister_binlog_relay_io_observer(&relay_io_observer, p))
- return 1;
- return 0;
-}
-
-
-struct Mysql_replication semi_sync_slave_plugin= {
- MYSQL_REPLICATION_INTERFACE_VERSION
-};
-
-/*
- Plugin library descriptor
-*/
-maria_declare_plugin(semisync_slave)
-{
- MYSQL_REPLICATION_PLUGIN,
- &semi_sync_slave_plugin,
- "rpl_semi_sync_slave",
- "He Zhenxing",
- "Semi-synchronous replication slave",
- PLUGIN_LICENSE_GPL,
- semi_sync_slave_plugin_init, /* Plugin Init */
- semi_sync_slave_plugin_deinit, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
- semi_sync_slave_status_vars, /* status variables */
- semi_sync_slave_system_vars, /* system variables */
- "1.0",
- MariaDB_PLUGIN_MATURITY_STABLE
-}
-maria_declare_plugin_end;
-
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 0f67032bcbe..6c63f3feca3 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -36,7 +36,7 @@ ELSE()
ENDIF()
INCLUDE_DIRECTORIES(
-${CMAKE_SOURCE_DIR}/include
+${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/sql
${PCRE_INCLUDES}
${ZLIB_INCLUDE_DIR}
@@ -138,6 +138,7 @@ SET (SQL_SOURCE
my_apc.cc mf_iocache_encr.cc item_jsonfunc.cc
my_json_writer.cc
rpl_gtid.cc rpl_parallel.cc
+ semisync.cc semisync_master.cc semisync_slave.cc
sql_type.cc
item_windowfunc.cc sql_window.cc
sql_cte.cc
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f3cb39959a7..fc783ae5559 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -97,8 +97,9 @@
#include "set_var.h"
#include "rpl_injector.h"
-
#include "rpl_handler.h"
+#include "semisync_master.h"
+#include "semisync_slave.h"
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
@@ -934,6 +935,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
PSI_mutex_key key_RELAYLOG_LOCK_index;
PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
+PSI_mutex_key key_LOCK_binlog;
PSI_mutex_key key_LOCK_stats,
key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
@@ -1021,7 +1023,8 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
{ &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
{ &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
- { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0}
+ { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0},
+ { &key_LOCK_binlog, "LOCK_binlog", 0}
};
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
@@ -1062,7 +1065,7 @@ PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
key_rpl_group_info_sleep_cond,
key_TABLE_SHARE_cond, key_user_level_lock_cond,
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
- key_COND_start_thread,
+ key_COND_start_thread, key_COND_binlog_send,
key_BINLOG_COND_queue_busy;
PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
key_COND_wait_commit;
@@ -1124,7 +1127,8 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_slave_background, "COND_slave_background", 0},
{ &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL},
{ &key_COND_wait_gtid, "COND_wait_gtid", 0},
- { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}
+ { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0},
+ { &key_COND_binlog_send, "COND_binlog_send", 0}
};
PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
@@ -2217,6 +2221,10 @@ void clean_up(bool print_message)
ha_end();
if (tc_log)
tc_log->close();
+#ifdef HAVE_REPLICATION
+ semi_sync_master_deinit();
+ semi_sync_slave_deinit();
+#endif
delegates_destroy();
xid_cache_free();
tdc_deinit();
@@ -5170,6 +5178,9 @@ static int init_server_components()
"this server. However this will be ignored as the "
"--log-bin option is not defined.");
}
+
+ semi_sync_master_init();
+ semi_sync_slave_init();
#endif
if (opt_bin_log)
@@ -8230,6 +8241,27 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff,
return 0;
}
+#define SHOW_FNAME(name) \
+ rpl_semi_sync_master_show_##name
+
+#define DEF_SHOW_FUNC(name, show_type) \
+ static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \
+ { \
+ repl_semisync_master.setExportStats(); \
+ var->type= show_type; \
+ var->value= (char *)&rpl_semi_sync_master_##name; \
+ return 0; \
+ }
+
+DEF_SHOW_FUNC(status, SHOW_BOOL)
+DEF_SHOW_FUNC(clients, SHOW_LONG)
+DEF_SHOW_FUNC(wait_sessions, SHOW_LONG)
+DEF_SHOW_FUNC(trx_wait_time, SHOW_LONGLONG)
+DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG)
+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)
#ifdef HAVE_YASSL
@@ -8548,6 +8580,30 @@ SHOW_VAR status_vars[]= {
{"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
{"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
{"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
+#ifdef HAVE_REPLICATION
+ {"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*) &SHOW_FNAME(wait_sessions), SHOW_FUNC},
+ {"Rpl_semi_sync_master_no_times", (char*) &rpl_semi_sync_master_off_times, SHOW_LONG},
+ {"Rpl_semi_sync_master_timefunc_failures", (char*) &rpl_semi_sync_master_timefunc_fails, SHOW_LONG},
+ {"Rpl_semi_sync_master_wait_pos_backtraverse", (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},
+#ifdef HAVE_ACC_RECEIVER
+ {"Rpl_semi_sync_master_request_ack", (char*) &rpl_semi_sync_master_request_ack, SHOW_LONGLONG},
+ {"Rpl_semi_sync_master_get_ack", (char*)&rpl_semi_sync_master_get_ack, SHOW_LONGLONG},
+#endif
+ {"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL},
+#ifdef HAVE_ACC_RECEIVER
+ {"Rpl_semi_sync_slave_send_ack", (char*) &rpl_semi_sync_slave_send_ack, SHOW_LONGLONG},
+#endif
+#endif /* HAVE_REPLICATION */
#ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@@ -10285,6 +10341,8 @@ PSI_stage_info stage_waiting_for_insert= { 0, "Waiting for INSERT", 0};
PSI_stage_info stage_waiting_for_master_to_send_event= { 0, "Waiting for master to send event", 0};
PSI_stage_info stage_waiting_for_master_update= { 0, "Waiting for master update", 0};
PSI_stage_info stage_waiting_for_relay_log_space= { 0, "Waiting for the slave SQL thread to free enough relay log space", 0};
+PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave=
+{ 0, "Waiting for semi-sync ACK from slave", 0};
PSI_stage_info stage_waiting_for_slave_mutex_on_exit= { 0, "Waiting for slave mutex on exit", 0};
PSI_stage_info stage_waiting_for_slave_thread_to_start= { 0, "Waiting for slave thread to start", 0};
PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
diff --git a/sql/replication.h b/sql/replication.h
index 4731c2246ef..d8672310110 100644
--- a/sql/replication.h
+++ b/sql/replication.h
@@ -18,16 +18,14 @@
/***************************************************************************
NOTE: plugin locking.
- This API was created specifically for the semisync plugin and its locking
- logic is also matches semisync plugin usage pattern. In particular, a plugin
- is locked on Binlog_transmit_observer::transmit_start and is unlocked after
- Binlog_transmit_observer::transmit_stop. All other master observable events
- happen between these two and don't lock the plugin at all. This works well
- for the semisync_master plugin.
+
+ The plugin is locked on Binlog_transmit_observer::transmit_start and is
+ unlocked after Binlog_transmit_observer::transmit_stop. All other
+ master observable events happen between these two and don't lock the
+ plugin at all.
Also a plugin is locked on Binlog_relay_IO_observer::thread_start
- and unlocked after Binlog_relay_IO_observer::thread_stop. This works well for
- the semisync_slave plugin.
+ and unlocked after Binlog_relay_IO_observer::thread_stop.
***************************************************************************/
#include <mysql.h>
diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc
index e3ff2a17a6a..27e411ca6de 100644
--- a/sql/rpl_handler.cc
+++ b/sql/rpl_handler.cc
@@ -149,13 +149,17 @@ void delegates_destroy()
{
if (transaction_delegate)
transaction_delegate->~Trans_delegate();
+ transaction_delegate= 0;
if (binlog_storage_delegate)
binlog_storage_delegate->~Binlog_storage_delegate();
+ binlog_storage_delegate= 0;
#ifdef HAVE_REPLICATION
if (binlog_transmit_delegate)
binlog_transmit_delegate->~Binlog_transmit_delegate();
+ binlog_transmit_delegate= 0;
if (binlog_relay_io_delegate)
binlog_relay_io_delegate->~Binlog_relay_IO_delegate();
+ binlog_relay_io_delegate= 0;
#endif /* HAVE_REPLICATION */
}
@@ -171,13 +175,11 @@ void delegates_destroy()
Observer_info *info= iter++; \
for (; info; info= iter++) \
{ \
- if (do_lock) plugin_lock(thd, plugin_int_to_ref(info->plugin_int)); \
if (((Observer *)info->observer)->f \
&& ((Observer *)info->observer)->f args) \
{ \
r= 1; \
- sql_print_error("Run function '" #f "' in plugin '%s' failed", \
- info->plugin_int->name.str); \
+ sql_print_error("Run function '" #f "' failed"); \
break; \
} \
} \
diff --git a/plugin/semisync/semisync.cc b/sql/semisync.cc
index df37f03ec2f..df37f03ec2f 100644
--- a/plugin/semisync/semisync.cc
+++ b/sql/semisync.cc
diff --git a/plugin/semisync/semisync.h b/sql/semisync.h
index 28577296817..3142f920f1e 100644
--- a/plugin/semisync/semisync.h
+++ b/sql/semisync.h
@@ -1,6 +1,5 @@
/* Copyright (C) 2007 Google Inc.
Copyright (C) 2008 MySQL AB
- Use is subject to license terms
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,18 +18,9 @@
#ifndef SEMISYNC_H
#define SEMISYNC_H
-#define MYSQL_SERVER
-#define HAVE_REPLICATION
-#include <my_pthread.h>
-#include <sql_priv.h>
-#include <sql_class.h>
-#include "unireg.h"
-#include <replication.h>
-#include "log.h" /* sql_print_information */
-
-typedef struct st_mysql_show_var SHOW_VAR;
-typedef struct st_mysql_sys_var SYS_VAR;
-
+#include "mysqld.h"
+#include "log_event.h"
+#include "replication.h"
/**
This class is used to trace function calls and other process
diff --git a/plugin/semisync/semisync_master.cc b/sql/semisync_master.cc
index 975b2e13253..21c52addce9 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/sql/semisync_master.cc
@@ -24,34 +24,35 @@
#define TIME_BILLION 1000000000
/* This indicates whether semi-synchronous replication is enabled. */
-char rpl_semi_sync_master_enabled;
-unsigned long rpl_semi_sync_master_wait_point =
+my_bool rpl_semi_sync_master_enabled;
+my_bool rpl_semi_sync_master_wait_no_slave = 1;
+my_bool rpl_semi_sync_master_status = 0;
+ulong rpl_semi_sync_master_wait_point =
SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT;
-unsigned long rpl_semi_sync_master_timeout;
-unsigned long rpl_semi_sync_master_trace_level;
-char rpl_semi_sync_master_status = 0;
-unsigned long rpl_semi_sync_master_yes_transactions = 0;
-unsigned long rpl_semi_sync_master_no_transactions = 0;
-unsigned long rpl_semi_sync_master_off_times = 0;
-unsigned long rpl_semi_sync_master_timefunc_fails = 0;
-unsigned long rpl_semi_sync_master_wait_timeouts = 0;
-unsigned long rpl_semi_sync_master_wait_sessions = 0;
-unsigned long rpl_semi_sync_master_wait_pos_backtraverse = 0;
-unsigned long rpl_semi_sync_master_avg_trx_wait_time = 0;
-unsigned long long rpl_semi_sync_master_trx_wait_num = 0;
-unsigned long rpl_semi_sync_master_avg_net_wait_time = 0;
-unsigned long long rpl_semi_sync_master_net_wait_num = 0;
-unsigned long rpl_semi_sync_master_clients = 0;
-unsigned long long rpl_semi_sync_master_net_wait_time = 0;
-unsigned long long rpl_semi_sync_master_trx_wait_time = 0;
-char rpl_semi_sync_master_wait_no_slave = 1;
-
+ulong rpl_semi_sync_master_timeout;
+ulong rpl_semi_sync_master_trace_level;
+ulong rpl_semi_sync_master_yes_transactions = 0;
+ulong rpl_semi_sync_master_no_transactions = 0;
+ulong rpl_semi_sync_master_off_times = 0;
+ulong rpl_semi_sync_master_timefunc_fails = 0;
+ulong rpl_semi_sync_master_wait_timeouts = 0;
+ulong rpl_semi_sync_master_wait_sessions = 0;
+ulong rpl_semi_sync_master_wait_pos_backtraverse = 0;
+ulong rpl_semi_sync_master_avg_trx_wait_time = 0;
+ulonglong rpl_semi_sync_master_trx_wait_num = 0;
+ulong rpl_semi_sync_master_avg_net_wait_time = 0;
+ulonglong rpl_semi_sync_master_net_wait_num = 0;
+ulong rpl_semi_sync_master_clients = 0;
+ulonglong rpl_semi_sync_master_net_wait_time = 0;
+ulonglong rpl_semi_sync_master_trx_wait_time = 0;
+
+ReplSemiSyncMaster repl_semisync_master;
static int getWaitTime(const struct timespec& start_ts);
-static unsigned long long timespec_to_usec(const struct timespec *ts)
+static ulonglong timespec_to_usec(const struct timespec *ts)
{
- return (unsigned long long) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND;
+ return (ulonglong) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND;
}
/*******************************************************************************
@@ -61,7 +62,7 @@ static unsigned long long timespec_to_usec(const struct timespec *ts)
******************************************************************************/
ActiveTranx::ActiveTranx(mysql_mutex_t *lock,
- unsigned long trace_level)
+ ulong trace_level)
: Trace(trace_level), allocator_(max_connections),
num_entries_(max_connections << 1), /* Transaction hash table size
* is set to double the size
@@ -141,7 +142,7 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
if (!ins_node)
{
sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
- kWho, log_file_name, (unsigned long)log_file_pos);
+ kWho, log_file_name, (ulong)log_file_pos);
result = -1;
goto l_end;
}
@@ -174,8 +175,8 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
*/
sql_print_error("%s: binlog write out-of-order, tail (%s, %lu), "
"new node (%s, %lu)", kWho,
- trx_rear_->log_name_, (unsigned long)trx_rear_->log_pos_,
- ins_node->log_name_, (unsigned long)ins_node->log_pos_);
+ trx_rear_->log_name_, (ulong)trx_rear_->log_pos_,
+ ins_node->log_name_, (ulong)ins_node->log_pos_);
result = -1;
goto l_end;
}
@@ -187,7 +188,7 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
if (trace_level_ & kTraceDetail)
sql_print_information("%s: insert (%s, %lu) in entry(%u)", kWho,
- ins_node->log_name_, (unsigned long)ins_node->log_pos_,
+ ins_node->log_name_, (ulong)ins_node->log_pos_,
hash_val);
l_end:
@@ -213,7 +214,7 @@ bool ActiveTranx::is_tranx_end_pos(const char *log_file_name,
if (trace_level_ & kTraceDetail)
sql_print_information("%s: probe (%s, %lu) in entry(%u)", kWho,
- log_file_name, (unsigned long)log_file_pos, hash_val);
+ log_file_name, (ulong)log_file_pos, hash_val);
function_exit(kWho, (entry != NULL));
return (entry != NULL);
@@ -296,7 +297,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
if (trace_level_ & kTraceDetail)
sql_print_information("%s: cleared %d nodes back until pos (%s, %lu)",
kWho, n_frees,
- trx_front_->log_name_, (unsigned long)trx_front_->log_pos_);
+ trx_front_->log_name_, (ulong)trx_front_->log_pos_);
}
return function_exit(kWho, 0);
@@ -358,10 +359,10 @@ int ReplSemiSyncMaster::initObject()
setTraceLevel(rpl_semi_sync_master_trace_level);
/* Mutex initialization can only be done after MY_INIT(). */
- mysql_mutex_init(key_ss_mutex_LOCK_binlog_,
- &LOCK_binlog_, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_ss_cond_COND_binlog_send_,
- &COND_binlog_send_, NULL);
+ mysql_mutex_init(key_LOCK_binlog,
+ &LOCK_binlog, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_binlog_send,
+ &COND_binlog_send, NULL);
if (rpl_semi_sync_master_enabled)
result = enableMaster();
@@ -380,7 +381,7 @@ int ReplSemiSyncMaster::enableMaster()
if (!getMasterEnabled())
{
- active_tranxs_ = new ActiveTranx(&LOCK_binlog_, trace_level_);
+ active_tranxs_ = new ActiveTranx(&LOCK_binlog, trace_level_);
if (active_tranxs_ != NULL)
{
commit_file_name_inited_ = false;
@@ -389,6 +390,7 @@ int ReplSemiSyncMaster::enableMaster()
set_master_enabled(true);
state_ = true;
+ run_hooks_enabled= 1;
sql_print_information("Semi-sync replication enabled on the master.");
}
else
@@ -436,8 +438,8 @@ void ReplSemiSyncMaster::cleanup()
{
if (init_done_)
{
- mysql_mutex_destroy(&LOCK_binlog_);
- mysql_cond_destroy(&COND_binlog_send_);
+ mysql_mutex_destroy(&LOCK_binlog);
+ mysql_cond_destroy(&COND_binlog_send);
init_done_= 0;
}
@@ -446,17 +448,17 @@ void ReplSemiSyncMaster::cleanup()
void ReplSemiSyncMaster::lock()
{
- mysql_mutex_lock(&LOCK_binlog_);
+ mysql_mutex_lock(&LOCK_binlog);
}
void ReplSemiSyncMaster::unlock()
{
- mysql_mutex_unlock(&LOCK_binlog_);
+ mysql_mutex_unlock(&LOCK_binlog);
}
void ReplSemiSyncMaster::cond_broadcast()
{
- mysql_cond_broadcast(&COND_binlog_send_);
+ mysql_cond_broadcast(&COND_binlog_send);
}
int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time)
@@ -465,8 +467,8 @@ int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time)
int wait_res;
function_enter(kWho);
- wait_res= mysql_cond_timedwait(&COND_binlog_send_,
- &LOCK_binlog_, wait_time);
+ wait_res= mysql_cond_timedwait(&COND_binlog_send,
+ &LOCK_binlog, wait_time);
return function_exit(kWho, wait_res);
}
@@ -566,7 +568,7 @@ int ReplSemiSyncMaster::reportReplyBinlog(uint32 server_id,
if (trace_level_ & kTraceDetail)
sql_print_information("%s: Got reply at (%s, %lu)", kWho,
- log_file_name, (unsigned long)log_file_pos);
+ log_file_name, (ulong)log_file_pos);
}
if (rpl_semi_sync_master_wait_sessions > 0)
@@ -621,7 +623,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
lock();
/* This must be called after acquired the lock */
- THD_ENTER_COND(NULL, &COND_binlog_send_, &LOCK_binlog_,
+ THD_ENTER_COND(NULL, &COND_binlog_send, &LOCK_binlog,
& stage_waiting_for_semi_sync_ack_from_slave,
& old_stage);
@@ -632,7 +634,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
if (trace_level_ & kTraceDetail)
{
sql_print_information("%s: wait pos (%s, %lu), repl(%d)\n", kWho,
- trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
+ trx_wait_binlog_name, (ulong)trx_wait_binlog_pos,
(int)is_on());
}
@@ -649,7 +651,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
*/
if (trace_level_ & kTraceDetail)
sql_print_information("%s: Binlog reply is ahead (%s, %lu),",
- kWho, reply_file_name_, (unsigned long)reply_file_pos_);
+ kWho, reply_file_name_, (ulong)reply_file_pos_);
break;
}
}
@@ -670,7 +672,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
rpl_semi_sync_master_wait_pos_backtraverse++;
if (trace_level_ & kTraceDetail)
sql_print_information("%s: move back wait position (%s, %lu),",
- kWho, wait_file_name_, (unsigned long)wait_file_pos_);
+ kWho, wait_file_name_, (ulong)wait_file_pos_);
}
}
else
@@ -681,16 +683,16 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
if (trace_level_ & kTraceDetail)
sql_print_information("%s: init wait position (%s, %lu),",
- kWho, wait_file_name_, (unsigned long)wait_file_pos_);
+ kWho, wait_file_name_, (ulong)wait_file_pos_);
}
/* Calcuate the waiting period. */
- long diff_secs = (long) (wait_timeout_ / TIME_THOUSAND);
+ long diff_secs = (long) (wait_timeout_ / TIME_THOUSAND);
long diff_nsecs = (long) ((wait_timeout_ % TIME_THOUSAND) * TIME_MILLION);
long nsecs = start_ts.tv_nsec + diff_nsecs;
abstime.tv_sec = start_ts.tv_sec + diff_secs + nsecs/TIME_BILLION;
abstime.tv_nsec = nsecs % TIME_BILLION;
-
+
/* In semi-synchronous replication, we wait until the binlog-dump
* thread has received the reply on the relevant binlog segment from the
* replication slave.
@@ -700,31 +702,31 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
* these waiting threads.
*/
rpl_semi_sync_master_wait_sessions++;
-
+
if (trace_level_ & kTraceDetail)
sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)",
kWho, wait_timeout_,
- wait_file_name_, (unsigned long)wait_file_pos_);
-
+ wait_file_name_, (ulong)wait_file_pos_);
+
wait_result = cond_timewait(&abstime);
rpl_semi_sync_master_wait_sessions--;
-
+
if (wait_result != 0)
{
/* This is a real wait timeout. */
sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), "
"semi-sync up to file %s, position %lu.",
- trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
- reply_file_name_, (unsigned long)reply_file_pos_);
+ trx_wait_binlog_name, (ulong)trx_wait_binlog_pos,
+ reply_file_name_, (ulong)reply_file_pos_);
rpl_semi_sync_master_wait_timeouts++;
-
+
/* switch semi-sync off */
switch_off();
}
else
{
int wait_time;
-
+
wait_time = getWaitTime(start_ts);
if (wait_time < 0)
{
@@ -732,7 +734,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
{
sql_print_error("Replication semi-sync getWaitTime fail at "
"wait position (%s, %lu)",
- trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
+ trx_wait_binlog_name, (ulong)trx_wait_binlog_pos);
}
rpl_semi_sync_master_timefunc_fails++;
}
@@ -753,7 +755,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
assert(thd_killed(current_thd) || !active_tranxs_ ||
!active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name,
trx_wait_binlog_pos));
-
+
l_end:
/* Update the status counter. */
if (is_on())
@@ -770,7 +772,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
}
/* Indicate that semi-sync replication is OFF now.
- *
+ *
* What should we do when it is disabled? The problem is that we want
* the semi-sync replication enabled again when the slave catches up
* later. But, it is not that easy to detect that the slave has caught
@@ -842,14 +844,14 @@ int ReplSemiSyncMaster::try_switch_on(int server_id,
sql_print_information("Semi-sync replication switched ON with slave (server_id: %d) "
"at (%s, %lu)",
server_id, log_file_name,
- (unsigned long)log_file_pos);
+ (ulong)log_file_pos);
}
return function_exit(kWho, 0);
}
int ReplSemiSyncMaster::reserveSyncHeader(unsigned char *header,
- unsigned long size)
+ ulong size)
{
const char *kWho = "ReplSemiSyncMaster::reserveSyncHeader";
function_enter(kWho);
@@ -870,7 +872,7 @@ int ReplSemiSyncMaster::reserveSyncHeader(unsigned char *header,
disableMaster();
return 0;
}
-
+
/* Set the magic number and the sync status. By default, no sync
* is required.
*/
@@ -930,13 +932,13 @@ int ReplSemiSyncMaster::updateSyncHeader(unsigned char *packet,
{
cmp = 1;
}
-
+
/* If we are already waiting for some transaction replies which
* are later in binlog, do not wait for this one event.
*/
if (cmp >= 0)
{
- /*
+ /*
* We only wait if the event is a transaction's ending event.
*/
assert(active_tranxs_ != NULL);
@@ -961,7 +963,7 @@ int ReplSemiSyncMaster::updateSyncHeader(unsigned char *packet,
if (trace_level_ & kTraceDetail)
sql_print_information("%s: server(%d), (%s, %lu) sync(%d), repl(%d)",
kWho, server_id, log_file_name,
- (unsigned long)log_file_pos, sync, (int)is_on());
+ (ulong)log_file_pos, sync, (int)is_on());
l_end:
unlock();
@@ -1181,27 +1183,27 @@ void ReplSemiSyncMaster::setExportStats()
rpl_semi_sync_master_status = state_;
rpl_semi_sync_master_avg_trx_wait_time=
((rpl_semi_sync_master_trx_wait_num) ?
- (unsigned long)((double)rpl_semi_sync_master_trx_wait_time /
+ (ulong)((double)rpl_semi_sync_master_trx_wait_time /
((double)rpl_semi_sync_master_trx_wait_num)) : 0);
rpl_semi_sync_master_avg_net_wait_time=
((rpl_semi_sync_master_net_wait_num) ?
- (unsigned long)((double)rpl_semi_sync_master_net_wait_time /
+ (ulong)((double)rpl_semi_sync_master_net_wait_time /
((double)rpl_semi_sync_master_net_wait_num)) : 0);
unlock();
}
/* Get the waiting time given the wait's staring time.
- *
+ *
* Return:
* >= 0: the waiting time in microsecons(us)
* < 0: error in get time or time back traverse
*/
static int getWaitTime(const struct timespec& start_ts)
{
- unsigned long long start_usecs, end_usecs;
+ ulonglong start_usecs, end_usecs;
struct timespec end_ts;
-
+
/* Starting time in microseconds(us). */
start_usecs = timespec_to_usec(&start_ts);
@@ -1216,3 +1218,213 @@ static int getWaitTime(const struct timespec& start_ts)
return (int)(end_usecs - start_usecs);
}
+
+/***************************************************************************
+ Semisync master interface setup and deinit
+***************************************************************************/
+
+C_MODE_START
+
+int repl_semi_report_binlog_update(Binlog_storage_param *param,
+ const char *log_file,
+ my_off_t log_pos, uint32 flags)
+{
+ int error= 0;
+
+ if (repl_semisync_master.getMasterEnabled())
+ {
+ /*
+ Let us store the binlog file name and the position, so that
+ we know how long to wait for the binlog to the replicated to
+ the slave in synchronous replication.
+ */
+ error= repl_semisync_master.writeTranxInBinlog(log_file,
+ log_pos);
+ }
+
+ return error;
+}
+
+int repl_semi_request_commit(Trans_param *param)
+{
+ return 0;
+}
+
+int repl_semi_report_binlog_sync(Binlog_storage_param *param,
+ const char *log_file,
+ my_off_t log_pos, uint32 flags)
+{
+ int error= 0;
+ if (rpl_semi_sync_master_wait_point ==
+ SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC)
+ {
+ error= repl_semisync_master.commitTrx(log_file, log_pos);
+ }
+
+ return error;
+}
+
+int repl_semi_report_commit(Trans_param *param)
+{
+ if (rpl_semi_sync_master_wait_point !=
+ SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT)
+ {
+ return 0;
+ }
+
+ bool is_real_trans= param->flags & TRANS_IS_REAL_TRANS;
+
+ if (is_real_trans && param->log_pos)
+ {
+ const char *binlog_name= param->log_file;
+ return repl_semisync_master.commitTrx(binlog_name, param->log_pos);
+ }
+ return 0;
+}
+
+int repl_semi_report_rollback(Trans_param *param)
+{
+ return repl_semi_report_commit(param);
+}
+
+int repl_semi_binlog_dump_start(Binlog_transmit_param *param,
+ const char *log_file,
+ my_off_t log_pos)
+{
+ bool semi_sync_slave= repl_semisync_master.is_semi_sync_slave();
+
+ if (semi_sync_slave)
+ {
+ /* One more semi-sync slave */
+ repl_semisync_master.add_slave();
+
+ /*
+ Let's assume this semi-sync slave has already received all
+ binlog events before the filename and position it requests.
+ */
+ repl_semisync_master.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, (ulong)log_pos);
+
+ return 0;
+}
+
+int repl_semi_binlog_dump_end(Binlog_transmit_param *param)
+{
+ bool semi_sync_slave= repl_semisync_master.is_semi_sync_slave();
+
+ sql_print_information("Stop %s binlog_dump to slave (server_id: %d)",
+ semi_sync_slave ? "semi-sync" : "asynchronous",
+ param->server_id);
+ if (semi_sync_slave)
+ {
+ /* One less semi-sync slave */
+ repl_semisync_master.remove_slave();
+ }
+ return 0;
+}
+
+int repl_semi_reserve_header(Binlog_transmit_param *param,
+ unsigned char *header,
+ ulong size, ulong *len)
+{
+ *len += repl_semisync_master.reserveSyncHeader(header, size);
+ return 0;
+}
+
+int repl_semi_before_send_event(Binlog_transmit_param *param,
+ unsigned char *packet, ulong len,
+ const char *log_file, my_off_t log_pos)
+{
+ return repl_semisync_master.updateSyncHeader(packet,
+ log_file,
+ log_pos,
+ param->server_id);
+}
+
+int repl_semi_after_send_event(Binlog_transmit_param *param,
+ const char *event_buf, ulong len)
+{
+ if (repl_semisync_master.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_master.readSlaveReply(&thd->net,
+ param->server_id, event_buf);
+ thd->clear_error();
+ }
+ return 0;
+}
+
+int repl_semi_reset_master(Binlog_transmit_param *param)
+{
+ if (repl_semisync_master.resetMaster())
+ return 1;
+ return 0;
+}
+
+C_MODE_END
+
+Trans_observer trans_observer=
+{
+ sizeof(Trans_observer), // len
+
+ repl_semi_report_commit, // after_commit
+ repl_semi_report_rollback, // after_rollback
+};
+
+Binlog_storage_observer storage_observer=
+{
+ sizeof(Binlog_storage_observer), // len
+
+ repl_semi_report_binlog_update, // report_update
+ repl_semi_report_binlog_sync, // after_sync
+};
+
+Binlog_transmit_observer transmit_observer=
+{
+ sizeof(Binlog_transmit_observer), // len
+
+ repl_semi_binlog_dump_start, // start
+ repl_semi_binlog_dump_end, // stop
+ repl_semi_reserve_header, // reserve_header
+ repl_semi_before_send_event, // before_send_event
+ repl_semi_after_send_event, // after_send_event
+ repl_semi_reset_master, // reset
+};
+
+static bool semi_sync_master_inited= 0;
+
+int semi_sync_master_init()
+{
+ void *p= 0;
+ if (repl_semisync_master.initObject())
+ return 1;
+ if (register_trans_observer(&trans_observer, p))
+ return 1;
+ if (register_binlog_storage_observer(&storage_observer, p))
+ return 1;
+ if (register_binlog_transmit_observer(&transmit_observer, p))
+ return 1;
+ semi_sync_master_inited= 1;
+ return 0;
+}
+
+void semi_sync_master_deinit()
+{
+ void *p= 0;
+ if (!semi_sync_master_inited)
+ return;
+
+ unregister_trans_observer(&trans_observer, p);
+ unregister_binlog_storage_observer(&storage_observer, p);
+ unregister_binlog_transmit_observer(&transmit_observer, p);
+ repl_semisync_master.cleanup();
+ semi_sync_master_inited= 0;
+}
diff --git a/plugin/semisync/semisync_master.h b/sql/semisync_master.h
index c2862476ec8..ff1e3dd48b4 100644
--- a/plugin/semisync/semisync_master.h
+++ b/sql/semisync_master.h
@@ -22,8 +22,8 @@
#include "semisync.h"
#ifdef HAVE_PSI_INTERFACE
-extern PSI_mutex_key key_ss_mutex_LOCK_binlog_;
-extern PSI_cond_key key_ss_cond_COND_binlog_send_;
+extern PSI_mutex_key key_LOCK_binlog;
+extern PSI_cond_key key_COND_binlog_send;
#endif
extern PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave;
@@ -379,14 +379,14 @@ class ReplSemiSyncMaster
/* This cond variable is signaled when enough binlog has been sent to slave,
* so that a waiting trx can return the 'ok' to the client for a commit.
*/
- mysql_cond_t COND_binlog_send_;
+ mysql_cond_t COND_binlog_send;
/* Mutex that protects the following state variables and the active
* transaction list.
* Under no cirumstances we can acquire mysql_bin_log.LOCK_log if we are
* already holding LOCK_binlog_ because it can cause deadlocks.
*/
- mysql_mutex_t LOCK_binlog_;
+ mysql_mutex_t LOCK_binlog;
/* This is set to true when reply_file_name_ contains meaningful data. */
bool reply_file_name_inited_;
@@ -600,26 +600,26 @@ enum rpl_semi_sync_master_wait_point_t {
};
/* 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_wait_point;
-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 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_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_time;
-extern unsigned long long rpl_semi_sync_master_trx_wait_time;
+extern my_bool rpl_semi_sync_master_enabled;
+extern my_bool rpl_semi_sync_master_status;
+extern ulong rpl_semi_sync_master_wait_point;
+extern ulong rpl_semi_sync_master_clients;
+extern ulong rpl_semi_sync_master_timeout;
+extern ulong rpl_semi_sync_master_trace_level;
+extern ulong rpl_semi_sync_master_yes_transactions;
+extern ulong rpl_semi_sync_master_no_transactions;
+extern ulong rpl_semi_sync_master_off_times;
+extern ulong rpl_semi_sync_master_wait_timeouts;
+extern ulong rpl_semi_sync_master_timefunc_fails;
+extern ulong rpl_semi_sync_master_num_timeouts;
+extern ulong rpl_semi_sync_master_wait_sessions;
+extern ulong rpl_semi_sync_master_wait_pos_backtraverse;
+extern ulong rpl_semi_sync_master_avg_trx_wait_time;
+extern ulong rpl_semi_sync_master_avg_net_wait_time;
+extern ulonglong rpl_semi_sync_master_net_wait_num;
+extern ulonglong rpl_semi_sync_master_trx_wait_num;
+extern ulonglong rpl_semi_sync_master_net_wait_time;
+extern ulonglong rpl_semi_sync_master_trx_wait_time;
/*
This indicates whether we should keep waiting if no semi-sync slave
@@ -628,5 +628,9 @@ extern unsigned long long rpl_semi_sync_master_trx_wait_time;
1 (default) : keep waiting until timeout even no available semi-sync slave.
*/
extern char rpl_semi_sync_master_wait_no_slave;
+extern ReplSemiSyncMaster repl_semisync_master;
+
+int semi_sync_master_init();
+void semi_sync_master_deinit();
#endif /* SEMISYNC_MASTER_H */
diff --git a/plugin/semisync/semisync_slave.cc b/sql/semisync_slave.cc
index ff8a40aafac..63bf9dca0e8 100644
--- a/plugin/semisync/semisync_slave.cc
+++ b/sql/semisync_slave.cc
@@ -18,9 +18,20 @@
#include <my_global.h>
#include "semisync_slave.h"
-char rpl_semi_sync_slave_enabled;
-char rpl_semi_sync_slave_status= 0;
-unsigned long rpl_semi_sync_slave_trace_level;
+my_bool rpl_semi_sync_slave_enabled;
+my_bool rpl_semi_sync_slave_status= 0;
+ulong rpl_semi_sync_slave_trace_level;
+ReplSemiSyncSlave repl_semisync_slave;
+
+/*
+ indicate whether or not the slave should send a reply to the master.
+
+ This is set to true in repl_semi_slave_read_event if the current
+ event read is the last event of a transaction. And the value is
+ checked in repl_semi_slave_queue_event.
+*/
+bool semi_sync_need_reply= false;
+
int ReplSemiSyncSlave::initObject()
{
@@ -73,7 +84,7 @@ int ReplSemiSyncSlave::slaveReadSyncHeader(const char *header,
int ReplSemiSyncSlave::slaveStart(Binlog_relay_IO_param *param)
{
bool semi_sync= getSlaveEnabled();
-
+
sql_print_information("Slave I/O thread: Start %s replication to\
master '%s@%s:%d' in log '%s' at position %lu",
semi_sync ? "semi-sync" : "asynchronous",
@@ -138,3 +149,140 @@ int ReplSemiSyncSlave::slaveReply(MYSQL *mysql,
return function_exit(kWho, reply_res);
}
+
+/***************************************************************************
+ Semisync slave interface setup and deinit
+***************************************************************************/
+
+C_MODE_START
+
+int repl_semi_reset_slave(Binlog_relay_IO_param *param)
+{
+ // TODO: reset semi-sync slave status here
+ return 0;
+}
+
+int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
+ uint32 flags)
+{
+ MYSQL *mysql= param->mysql;
+ MYSQL_RES *res= 0;
+ MYSQL_ROW row;
+ const char *query;
+
+ if (!repl_semisync_slave.getSlaveEnabled())
+ return 0;
+
+ /* 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)) ||
+ !(res= mysql_store_result(mysql)))
+ {
+ sql_print_error("Execution failed on master: %s", query);
+ return 1;
+ }
+
+ row= mysql_fetch_row(res);
+ if (!row)
+ {
+ /* 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;
+ mysql_free_result(res);
+ return 0;
+ }
+ mysql_free_result(res);
+
+ /*
+ Tell master dump thread that we want to do semi-sync
+ replication
+ */
+ query= "SET @rpl_semi_sync_slave= 1";
+ if (mysql_real_query(mysql, query, strlen(query)))
+ {
+ sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
+ return 1;
+ }
+ mysql_free_result(mysql_store_result(mysql));
+ rpl_semi_sync_slave_status= 1;
+ return 0;
+}
+
+int repl_semi_slave_read_event(Binlog_relay_IO_param *param,
+ const char *packet, unsigned long len,
+ const char **event_buf, unsigned long *event_len)
+{
+ if (rpl_semi_sync_slave_status)
+ return repl_semisync_slave.slaveReadSyncHeader(packet, len,
+ &semi_sync_need_reply,
+ event_buf, event_len);
+ *event_buf= packet;
+ *event_len= len;
+ return 0;
+}
+
+int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
+ const char *event_buf,
+ unsigned long event_len,
+ uint32 flags)
+{
+ if (rpl_semi_sync_slave_status && semi_sync_need_reply)
+ {
+ /*
+ 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_slave.slaveReply(param->mysql,
+ param->master_log_name,
+ param->master_log_pos);
+ }
+ return 0;
+}
+
+int repl_semi_slave_io_start(Binlog_relay_IO_param *param)
+{
+ return repl_semisync_slave.slaveStart(param);
+}
+
+int repl_semi_slave_io_end(Binlog_relay_IO_param *param)
+{
+ return repl_semisync_slave.slaveStop(param);
+}
+
+C_MODE_END
+
+Binlog_relay_IO_observer relay_io_observer=
+{
+ sizeof(Binlog_relay_IO_observer), // len
+
+ repl_semi_slave_io_start, // start
+ repl_semi_slave_io_end, // stop
+ repl_semi_slave_request_dump, // request_transmit
+ repl_semi_slave_read_event, // after_read_event
+ repl_semi_slave_queue_event, // after_queue_event
+ repl_semi_reset_slave, // reset
+};
+
+static bool semi_sync_slave_inited= 0;
+
+int semi_sync_slave_init()
+{
+ void *p= 0;
+ if (repl_semisync_slave.initObject())
+ return 1;
+ if (register_binlog_relay_io_observer(&relay_io_observer, p))
+ return 1;
+ semi_sync_slave_inited= 1;
+ return 0;
+}
+
+void semi_sync_slave_deinit()
+{
+ void *p= 0;
+ if (!semi_sync_slave_inited)
+ return;
+ unregister_binlog_relay_io_observer(&relay_io_observer, p);
+ semi_sync_slave_inited= 0;
+}
diff --git a/plugin/semisync/semisync_slave.h b/sql/semisync_slave.h
index 1bf8cf31972..9cca8bbbdb4 100644
--- a/plugin/semisync/semisync_slave.h
+++ b/sql/semisync_slave.h
@@ -90,8 +90,12 @@ private:
/* System and status variables for the slave component */
-extern char rpl_semi_sync_slave_enabled;
-extern unsigned long rpl_semi_sync_slave_trace_level;
-extern char rpl_semi_sync_slave_status;
+extern my_bool rpl_semi_sync_slave_enabled;
+extern my_bool rpl_semi_sync_slave_status;
+extern ulong rpl_semi_sync_slave_trace_level;
+extern ReplSemiSyncSlave repl_semisync_slave;
+
+int semi_sync_slave_init();
+void semi_sync_slave_deinit();
#endif /* SEMISYNC_SLAVE_H */
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 82f8359fefc..e897b6c21ce 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -61,6 +61,8 @@
#include "sql_repl.h"
#include "opt_range.h"
#include "rpl_parallel.h"
+#include "semisync_master.h"
+#include "semisync_slave.h"
#include <ssl_compat.h>
/*
@@ -3039,8 +3041,188 @@ static Sys_var_replicate_events_marked_for_skip Replicate_events_marked_for_skip
"the slave).",
GLOBAL_VAR(opt_replicate_events_marked_for_skip), CMD_LINE(REQUIRED_ARG),
replicate_events_marked_for_skip_names, DEFAULT(RPL_SKIP_REPLICATE));
+
+/* new options for semisync */
+
+static bool fix_rpl_semi_sync_master_enabled(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ if (rpl_semi_sync_master_enabled)
+ {
+ if (repl_semisync_master.enableMaster() != 0)
+ rpl_semi_sync_master_enabled= false;
+#ifdef HAVE_ACC_RECEIVER
+ else if (ack_receiver.start())
+ {
+ repl_semisync_master.disableMaster();
+ rpl_semi_sync_master_enabled= false;
+ }
+#endif
+ }
+ else
+ {
+ if (repl_semisync_master.disableMaster() != 0)
+ rpl_semi_sync_master_enabled= true;
+#ifdef HAVE_ACC_RECEIVER
+ if (!rpl_semi_sync_master_enabled)
+ ack_receiver.stop();
+#endif
+ }
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_timeout(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_master.setWaitTimeout(rpl_semi_sync_master_timeout);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_trace_level(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_master.setTraceLevel(rpl_semi_sync_master_trace_level);
+#ifdef HAVE_ACC_RECEIVER
+ ack_receiver.setTraceLevel(rpl_semi_sync_master_trace_level);
+#endif
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_wait_point(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+#ifdef HAVE_ACC_RECEIVER
+ repl_semisync_master.setWaitPoint(rpl_semi_sync_master_wait_point);
#endif
+ return false;
+}
+
+static bool fix_rpl_semi_sync_master_wait_no_slave(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+#ifdef HAVE_ACC_RECEIVER
+ repl_semisync_master.checkAndSwitch();
+#endif
+ return false;
+}
+
+static Sys_var_mybool Sys_semisync_master_enabled(
+ "rpl_semi_sync_master_enabled",
+ "Enable semi-synchronous replication master (disabled by default).",
+ GLOBAL_VAR(rpl_semi_sync_master_enabled),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_enabled));
+
+static Sys_var_ulong Sys_semisync_master_timeout(
+ "rpl_semi_sync_master_timeout",
+ "The timeout value (in ms) for semi-synchronous replication in the "
+ "master",
+ GLOBAL_VAR(rpl_semi_sync_master_timeout),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0,~0L),DEFAULT(10000),BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_timeout));
+static Sys_var_mybool Sys_semisync_master_wait_no_slave(
+ "rpl_semi_sync_master_wait_no_slave",
+ "Wait until timeout when no semi-synchronous replication slave "
+ "available (enabled by default).",
+ GLOBAL_VAR(rpl_semi_sync_master_wait_no_slave),
+ CMD_LINE(OPT_ARG), DEFAULT(TRUE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_wait_no_slave));
+
+static Sys_var_ulong Sys_semisync_master_trace_level(
+ "rpl_semi_sync_master_trace_level",
+ "The tracing level for semi-sync replication.",
+ GLOBAL_VAR(rpl_semi_sync_master_trace_level),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0,~0L),DEFAULT(32),BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_trace_level));
+
+static const char *repl_semisync_wait_point[]=
+{"AFTER_SYNC", "AFTER_COMMIT", NullS};
+
+static Sys_var_enum Sys_semisync_master_wait_point(
+ "rpl_semi_sync_master_wait_point",
+ "Should transaction wait for semi-sync ack after having synced binlog, "
+ "or after having committed in storage engine.",
+ GLOBAL_VAR(rpl_semi_sync_master_wait_point), CMD_LINE(REQUIRED_ARG),
+ repl_semisync_wait_point, DEFAULT(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG,ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_master_wait_point));
+
+static bool fix_rpl_semi_sync_slave_enabled(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_slave_trace_level(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.setTraceLevel(rpl_semi_sync_slave_trace_level);
+ return false;
+}
+
+#ifdef HAVE_ACC_RECEIVER
+static bool fix_rpl_semi_sync_slave_delay_master(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.setDelayMaster(rpl_semi_sync_slave_delay_master);
+ return false;
+}
+
+static bool fix_rpl_semi_sync_slave_kill_conn_timeout(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ repl_semisync_slave.setKillConnTimeout(rpl_semi_sync_slave_kill_conn_timeout);
+ return false;
+}
+#endif
+
+
+static Sys_var_mybool Sys_semisync_slave_enabled(
+ "rpl_semi_sync_slave_enabled",
+ "Enable semi-synchronous replication slave (disabled by default).",
+ GLOBAL_VAR(rpl_semi_sync_slave_enabled),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_enabled));
+
+static Sys_var_ulong Sys_semisync_slave_trace_level(
+ "rpl_semi_sync_slave_trace_level",
+ "The tracing level for semi-sync replication.",
+ GLOBAL_VAR(rpl_semi_sync_slave_trace_level),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0,~0L),DEFAULT(32),BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_trace_level));
+
+#ifdef HAVE_ACC_RECEIVER
+static Sys_var_mybool Sys_semisync_slave_delay_master(
+ "rpl_semi_sync_slave_delay_master",
+ "Only write master info file when ack is needed.",
+ GLOBAL_VAR(rpl_semi_sync_slave_delay_master),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_delay_master));
+
+static Sys_var_uint Sys_semisync_slave_kill_conn_timeout(
+ "rpl_semi_sync_slave_kill_conn_timeout",
+ "Timeout for the mysql connection used to kill the slave io_thread's "
+ "connection on master. This timeout comes into play when stop slave "
+ "is executed.",
+ GLOBAL_VAR(rpl_semi_sync_slave_kill_conn_timeout),
+ CMD_LINE(OPT_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(5), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_rpl_semi_sync_slave_kill_conn_timeout));
+#endif
+#endif /* HAVE_REPLICATION */
static Sys_var_ulong Sys_slow_launch_time(
"slow_launch_time",