mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK
Fix the bug properly (plugin cannot be unloaded as long as it's locked). Enable and fix the test case. Significantly reduce number of LOCK_plugin locks for semisync (practically all locks were removed)
This commit is contained in:
parent
359d764b79
commit
50e192a04f
7 changed files with 99 additions and 121 deletions
|
@ -1,4 +1,3 @@
|
||||||
rpl_semi_sync_uninstall_plugin: waiting for the fix
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# List the test cases that are to be disabled temporarily.
|
# List the test cases that are to be disabled temporarily.
|
||||||
|
|
|
@ -1,36 +1,61 @@
|
||||||
include/master-slave.inc
|
include/master-slave.inc
|
||||||
[connection master]
|
[connection master]
|
||||||
INSTALL PLUGIN rpl_semi_sync_master SONAME 'SEMISYNC_MASTER_PLUGIN';
|
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
|
||||||
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'SEMISYNC_SLAVE_PLUGIN';
|
[connection slave]
|
||||||
|
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
||||||
|
[connection master]
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
UNINSTALL PLUGIN rpl_semi_sync_master;
|
||||||
CREATE TABLE t1(i int);
|
CREATE TABLE t1(i int);
|
||||||
INSERT INTO t1 values (1);
|
INSERT INTO t1 values (1);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
[connection slave]
|
||||||
include/install_semisync.inc
|
include/install_semisync.inc
|
||||||
call mtr.add_suppression("Plugin 'rpl_semi_sync_slave' cannot be uninstalled now");
|
[connection slave]
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
||||||
ERROR HY000: Unknown error
|
Warnings:
|
||||||
call mtr.add_suppression("Plugin 'rpl_semi_sync_master' cannot be uninstalled now");
|
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]
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
UNINSTALL PLUGIN rpl_semi_sync_master;
|
||||||
ERROR HY000: Unknown error
|
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);
|
CREATE TABLE t1(i int);
|
||||||
INSERT INTO t1 values (2);
|
INSERT INTO t1 values (2);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
include/assert.inc [semi sync slave status should be ON.]
|
[connection slave]
|
||||||
include/assert.inc [semi sync master status should be ON.]
|
show status like "Rpl_semi_sync_slave_status";
|
||||||
include/assert.inc [semi sync master clients should be 1.]
|
Variable_name Value
|
||||||
SET GLOBAL rpl_semi_sync_master_enabled = OFF;
|
Rpl_semi_sync_slave_status ON
|
||||||
include/assert.inc [semi sync master clients should be 1.]
|
[connection master]
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
show status like "Rpl_semi_sync_master_status";
|
||||||
ERROR HY000: Unknown error
|
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
|
include/stop_slave.inc
|
||||||
SET GLOBAL rpl_semi_sync_slave_enabled = OFF;
|
select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
|
||||||
|
plugin_name plugin_status
|
||||||
include/start_slave.inc
|
include/start_slave.inc
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
|
||||||
include/assert.inc [semi sync master clients should be 0.]
|
plugin_name plugin_status
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
[connection master]
|
||||||
|
show status like "Rpl_semi_sync_master_clients";
|
||||||
|
Variable_name Value
|
||||||
|
select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
|
||||||
|
plugin_name plugin_status
|
||||||
CREATE TABLE t1(i int);
|
CREATE TABLE t1(i int);
|
||||||
INSERT INTO t1 values (3);
|
INSERT INTO t1 values (3);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
[connection slave]
|
||||||
include/rpl_end.inc
|
include/rpl_end.inc
|
||||||
|
|
|
@ -21,19 +21,19 @@
|
||||||
# not in use i.e., when asynchronous replication is active.
|
# not in use i.e., when asynchronous replication is active.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Step 1.1: Install semi sync master plugin on master
|
# Step 1.1: Install semi sync master plugin on master
|
||||||
--replace_result $SEMISYNC_MASTER_PLUGIN SEMISYNC_MASTER_PLUGIN
|
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
|
||||||
eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_PLUGIN';
|
|
||||||
|
|
||||||
# Step 1.2: Install semi sync slave plugin on slave
|
# Step 1.2: Install semi sync slave plugin on slave
|
||||||
--connection slave
|
--connection slave
|
||||||
--replace_result $SEMISYNC_SLAVE_PLUGIN SEMISYNC_SLAVE_PLUGIN
|
--echo [connection slave]
|
||||||
eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_PLUGIN';
|
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
|
||||||
|
|
||||||
# Step 1.3: Uninstallation of semisync plugin on master and slave should be
|
# 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
|
# allowed at this state as there is no semi sync replication enabled between
|
||||||
# master and slave.
|
# master and slave.
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
||||||
--connection master
|
--connection master
|
||||||
|
--echo [connection master]
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
UNINSTALL PLUGIN rpl_semi_sync_master;
|
||||||
|
|
||||||
# Step 1.4: Check that replication is working fine at the end of the test case.
|
# Step 1.4: Check that replication is working fine at the end of the test case.
|
||||||
|
@ -41,6 +41,7 @@ CREATE TABLE t1(i int);
|
||||||
INSERT INTO t1 values (1);
|
INSERT INTO t1 values (1);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--sync_slave_with_master
|
--sync_slave_with_master
|
||||||
|
--echo [connection slave]
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Case 2: Uninstallation of semi sync plugins should be disallowed
|
# Case 2: Uninstallation of semi sync plugins should be disallowed
|
||||||
|
@ -52,40 +53,27 @@ DROP TABLE t1;
|
||||||
# Step 2.2: Check that rpl_semi_sync_slave uninstallation on Slave is not
|
# Step 2.2: Check that rpl_semi_sync_slave uninstallation on Slave is not
|
||||||
# possible at this state
|
# possible at this state
|
||||||
--connection slave
|
--connection slave
|
||||||
call mtr.add_suppression("Plugin 'rpl_semi_sync_slave' cannot be uninstalled now");
|
--echo [connection slave]
|
||||||
--error ER_UNKNOWN_ERROR
|
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
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
|
# Step 2.3: Check that rpl_semi_sync_master uninstallation on Master is not
|
||||||
# possible at this state
|
# possible at this state
|
||||||
--connection master
|
--connection master
|
||||||
call mtr.add_suppression("Plugin 'rpl_semi_sync_master' cannot be uninstalled now");
|
--echo [connection master]
|
||||||
--error ER_UNKNOWN_ERROR
|
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
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.
|
# Step 2.4: Check that replication is working fine at the end of the test case.
|
||||||
CREATE TABLE t1(i int);
|
CREATE TABLE t1(i int);
|
||||||
INSERT INTO t1 values (2);
|
INSERT INTO t1 values (2);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--sync_slave_with_master
|
--sync_slave_with_master
|
||||||
|
--echo [connection slave]
|
||||||
|
|
||||||
# Step 2.5: Make sure rpl_semi_sync_master_status on Master and
|
# Step 2.5: Make sure rpl_semi_sync_master_status on Master and
|
||||||
# rpl_semi_sync_slave_staus on Slave are ON
|
# rpl_semi_sync_slave_staus on Slave are ON
|
||||||
--let $slave_status=[show status like "Rpl_semi_sync_slave_status", Value, 1]
|
show status like "Rpl_semi_sync_slave_status";
|
||||||
--let assert_cond= "$slave_status" = "ON"
|
|
||||||
--let assert_text= semi sync slave status should be ON.
|
|
||||||
--source include/assert.inc
|
|
||||||
|
|
||||||
--connection master
|
|
||||||
--let $master_status=[show status like "Rpl_semi_sync_master_status", Value, 1]
|
|
||||||
--let assert_cond= "$master_status" = "ON"
|
|
||||||
--let assert_text= semi sync master status should be ON.
|
|
||||||
--source include/assert.inc
|
|
||||||
|
|
||||||
--let $master_clients=[show status like "Rpl_semi_sync_master_clients", Value, 1]
|
|
||||||
--let assert_cond= $master_clients = 1
|
|
||||||
--let assert_text= semi sync master clients should be 1.
|
|
||||||
--source include/assert.inc
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Case 3: Uninstallation of semi sync plugin should be disallowed when there
|
# Case 3: Uninstallation of semi sync plugin should be disallowed when there
|
||||||
|
@ -93,18 +81,15 @@ DROP TABLE t1;
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Step 3.1: Disable semi sync on master
|
# Step 3.1: Disable semi sync on master
|
||||||
--connection master
|
--connection master
|
||||||
SET GLOBAL rpl_semi_sync_master_enabled = OFF;
|
--echo [connection master]
|
||||||
|
show status like "Rpl_semi_sync_master_status";
|
||||||
|
|
||||||
# Step 3.2: Check that still Rpl_semi_sync_master_clients is 1
|
# Step 3.2: Check that still Rpl_semi_sync_master_clients is 1
|
||||||
--let $master_clients=[show status like "Rpl_semi_sync_master_clients", Value, 1]
|
show status like "Rpl_semi_sync_master_clients";
|
||||||
--let assert_cond= $master_clients = 1
|
|
||||||
--let assert_text= semi sync master clients should be 1.
|
|
||||||
--source include/assert.inc
|
|
||||||
|
|
||||||
# Step 3.3: Since Rpl_semi_sync_master_clients is 1, uninstallation of
|
# Step 3.3: Since Rpl_semi_sync_master_clients is 1, uninstallation of
|
||||||
# rpl_semi_sync_master should be disallowed.
|
# rpl_semi_sync_master should be disallowed.
|
||||||
--error ER_UNKNOWN_ERROR
|
select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Case 4: Uninstallation of semi sync plugin should be allowed when it is not
|
# Case 4: Uninstallation of semi sync plugin should be allowed when it is not
|
||||||
|
@ -114,32 +99,32 @@ UNINSTALL PLUGIN rpl_semi_sync_master;
|
||||||
|
|
||||||
# Step 4.1: Stop IO thread on slave.
|
# Step 4.1: Stop IO thread on slave.
|
||||||
--connection slave
|
--connection slave
|
||||||
|
--echo [connection slave]
|
||||||
--source include/stop_slave.inc
|
--source include/stop_slave.inc
|
||||||
|
|
||||||
# Step 4.2: Disable semi sync on slave.
|
# Step 4.2: Disable semi sync on slave.
|
||||||
SET GLOBAL rpl_semi_sync_slave_enabled = OFF;
|
select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
|
||||||
|
|
||||||
# Step 4.3: Start IO thread on slave.
|
# Step 4.3: Start IO thread on slave.
|
||||||
--source include/start_slave.inc
|
--source include/start_slave.inc
|
||||||
|
|
||||||
# Step 4.4: Uninstall semi sync plugin, it should be successful now.
|
# Step 4.4: Uninstall semi sync plugin, it should be successful now.
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_slave;
|
select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
|
||||||
|
|
||||||
# Step 4.5: On Master, check that semi sync slaves are now '0'.
|
# Step 4.5: On Master, check that semi sync slaves are now '0'.
|
||||||
--connection master
|
--connection master
|
||||||
--let $master_clients=[show status like "Rpl_semi_sync_master_clients", Value, 1]
|
--echo [connection master]
|
||||||
--let assert_cond= $master_clients = 0
|
show status like "Rpl_semi_sync_master_clients";
|
||||||
--let assert_text= semi sync master clients should be 0.
|
|
||||||
--source include/assert.inc
|
|
||||||
|
|
||||||
# Step 4.6: So uninstalling semi sync plugin should be allowed
|
# Step 4.6: So uninstalling semi sync plugin should be allowed
|
||||||
UNINSTALL PLUGIN rpl_semi_sync_master;
|
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
|
# Step 4.7: Check that replication is working fine at the end of the test case
|
||||||
CREATE TABLE t1(i int);
|
CREATE TABLE t1(i int);
|
||||||
INSERT INTO t1 values (3);
|
INSERT INTO t1 values (3);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--sync_slave_with_master
|
--sync_slave_with_master
|
||||||
|
--echo [connection slave]
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
source include/rpl_end.inc;
|
source include/rpl_end.inc;
|
||||||
|
|
|
@ -16,6 +16,20 @@
|
||||||
#ifndef REPLICATION_H
|
#ifndef REPLICATION_H
|
||||||
#define REPLICATION_H
|
#define REPLICATION_H
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
|
|
||||||
typedef struct st_mysql MYSQL;
|
typedef struct st_mysql MYSQL;
|
||||||
|
|
|
@ -170,40 +170,16 @@ void delegates_destroy()
|
||||||
/*
|
/*
|
||||||
This macro is used by almost all the Delegate methods to iterate
|
This macro is used by almost all the Delegate methods to iterate
|
||||||
over all the observers running given callback function of the
|
over all the observers running given callback function of the
|
||||||
delegate .
|
delegate.
|
||||||
|
|
||||||
Add observer plugins to the thd->lex list, after each statement, all
|
|
||||||
plugins add to thd->lex will be automatically unlocked.
|
|
||||||
*/
|
*/
|
||||||
#define FOREACH_OBSERVER(r, f, thd, args) \
|
#define FOREACH_OBSERVER(r, f, do_lock, args) \
|
||||||
param.server_id= thd->server_id; \
|
param.server_id= thd->server_id; \
|
||||||
/*
|
|
||||||
Use a struct to make sure that they are allocated adjacent, check
|
|
||||||
delete_dynamic().
|
|
||||||
*/ \
|
|
||||||
struct { \
|
|
||||||
DYNAMIC_ARRAY plugins; \
|
|
||||||
/* preallocate 8 slots */ \
|
|
||||||
plugin_ref plugins_buffer[8]; \
|
|
||||||
} s; \
|
|
||||||
DYNAMIC_ARRAY *plugins= &s.plugins; \
|
|
||||||
plugin_ref *plugins_buffer= s.plugins_buffer; \
|
|
||||||
my_init_dynamic_array2(plugins, sizeof(plugin_ref), \
|
|
||||||
plugins_buffer, 8, 8); \
|
|
||||||
read_lock(); \
|
read_lock(); \
|
||||||
Observer_info_iterator iter= observer_info_iter(); \
|
Observer_info_iterator iter= observer_info_iter(); \
|
||||||
Observer_info *info= iter++; \
|
Observer_info *info= iter++; \
|
||||||
for (; info; info= iter++) \
|
for (; info; info= iter++) \
|
||||||
{ \
|
{ \
|
||||||
plugin_ref plugin= \
|
if (do_lock) plugin_lock(thd, plugin_int_to_ref(info->plugin_int)); \
|
||||||
my_plugin_lock(0, info->plugin); \
|
|
||||||
if (!plugin) \
|
|
||||||
{ \
|
|
||||||
/* plugin is not intialized or deleted, this is not an error */ \
|
|
||||||
r= 0; \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
insert_dynamic(plugins, (uchar *)&plugin); \
|
|
||||||
if (((Observer *)info->observer)->f \
|
if (((Observer *)info->observer)->f \
|
||||||
&& ((Observer *)info->observer)->f args) \
|
&& ((Observer *)info->observer)->f args) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -213,17 +189,7 @@ void delegates_destroy()
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
unlock(); \
|
unlock();
|
||||||
/*
|
|
||||||
Unlock plugins should be done after we released the Delegate lock
|
|
||||||
to avoid possible deadlock when this is the last user of the
|
|
||||||
plugin, and when we unlock the plugin, it will try to
|
|
||||||
deinitialize the plugin, which will try to lock the Delegate in
|
|
||||||
order to remove the observers.
|
|
||||||
*/ \
|
|
||||||
plugin_unlock_list(0, (plugin_ref*)plugins->buffer, \
|
|
||||||
plugins->elements); \
|
|
||||||
delete_dynamic(plugins)
|
|
||||||
|
|
||||||
|
|
||||||
int Trans_delegate::after_commit(THD *thd, bool all)
|
int Trans_delegate::after_commit(THD *thd, bool all)
|
||||||
|
@ -240,7 +206,7 @@ int Trans_delegate::after_commit(THD *thd, bool all)
|
||||||
param.log_pos= log_info ? log_info->log_pos : 0;
|
param.log_pos= log_info ? log_info->log_pos : 0;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_commit, thd, (¶m));
|
FOREACH_OBSERVER(ret, after_commit, false, (¶m));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the end of a real transaction or autocommit statement, we
|
This is the end of a real transaction or autocommit statement, we
|
||||||
|
@ -268,7 +234,7 @@ int Trans_delegate::after_rollback(THD *thd, bool all)
|
||||||
param.log_pos= log_info ? log_info->log_pos : 0;
|
param.log_pos= log_info ? log_info->log_pos : 0;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_rollback, thd, (¶m));
|
FOREACH_OBSERVER(ret, after_rollback, false, (¶m));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the end of a real transaction or autocommit statement, we
|
This is the end of a real transaction or autocommit statement, we
|
||||||
|
@ -307,7 +273,7 @@ int Binlog_storage_delegate::after_flush(THD *thd,
|
||||||
log_info->log_pos = log_pos;
|
log_info->log_pos = log_pos;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_flush, thd,
|
FOREACH_OBSERVER(ret, after_flush, false,
|
||||||
(¶m, log_info->log_file, log_info->log_pos, flags));
|
(¶m, log_info->log_file, log_info->log_pos, flags));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -321,7 +287,7 @@ int Binlog_transmit_delegate::transmit_start(THD *thd, ushort flags,
|
||||||
param.flags= flags;
|
param.flags= flags;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, transmit_start, thd, (¶m, log_file, log_pos));
|
FOREACH_OBSERVER(ret, transmit_start, true, (¶m, log_file, log_pos));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +297,7 @@ int Binlog_transmit_delegate::transmit_stop(THD *thd, ushort flags)
|
||||||
param.flags= flags;
|
param.flags= flags;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, transmit_stop, thd, (¶m));
|
FOREACH_OBSERVER(ret, transmit_stop, false, (¶m));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,13 +322,6 @@ int Binlog_transmit_delegate::reserve_header(THD *thd, ushort flags,
|
||||||
Observer_info *info= iter++;
|
Observer_info *info= iter++;
|
||||||
for (; info; info= iter++)
|
for (; info; info= iter++)
|
||||||
{
|
{
|
||||||
plugin_ref plugin=
|
|
||||||
my_plugin_lock(thd, info->plugin);
|
|
||||||
if (!plugin)
|
|
||||||
{
|
|
||||||
ret= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
hlen= 0;
|
hlen= 0;
|
||||||
if (((Observer *)info->observer)->reserve_header
|
if (((Observer *)info->observer)->reserve_header
|
||||||
&& ((Observer *)info->observer)->reserve_header(¶m,
|
&& ((Observer *)info->observer)->reserve_header(¶m,
|
||||||
|
@ -371,10 +330,8 @@ int Binlog_transmit_delegate::reserve_header(THD *thd, ushort flags,
|
||||||
&hlen))
|
&hlen))
|
||||||
{
|
{
|
||||||
ret= 1;
|
ret= 1;
|
||||||
plugin_unlock(thd, plugin);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
plugin_unlock(thd, plugin);
|
|
||||||
if (hlen == 0)
|
if (hlen == 0)
|
||||||
continue;
|
continue;
|
||||||
if (hlen > RESERVE_HEADER_SIZE || packet->append((char *)header, hlen))
|
if (hlen > RESERVE_HEADER_SIZE || packet->append((char *)header, hlen))
|
||||||
|
@ -396,7 +353,7 @@ int Binlog_transmit_delegate::before_send_event(THD *thd, ushort flags,
|
||||||
param.flags= flags;
|
param.flags= flags;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, before_send_event, thd,
|
FOREACH_OBSERVER(ret, before_send_event, false,
|
||||||
(¶m, (uchar *)packet->c_ptr(),
|
(¶m, (uchar *)packet->c_ptr(),
|
||||||
packet->length(),
|
packet->length(),
|
||||||
log_file+dirname_length(log_file), log_pos));
|
log_file+dirname_length(log_file), log_pos));
|
||||||
|
@ -410,7 +367,7 @@ int Binlog_transmit_delegate::after_send_event(THD *thd, ushort flags,
|
||||||
param.flags= flags;
|
param.flags= flags;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_send_event, thd,
|
FOREACH_OBSERVER(ret, after_send_event, false,
|
||||||
(¶m, packet->c_ptr(), packet->length()));
|
(¶m, packet->c_ptr(), packet->length()));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +379,7 @@ int Binlog_transmit_delegate::after_reset_master(THD *thd, ushort flags)
|
||||||
param.flags= flags;
|
param.flags= flags;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_reset_master, thd, (¶m));
|
FOREACH_OBSERVER(ret, after_reset_master, false, (¶m));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +400,7 @@ int Binlog_relay_IO_delegate::thread_start(THD *thd, Master_info *mi)
|
||||||
init_param(¶m, mi);
|
init_param(¶m, mi);
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, thread_start, thd, (¶m));
|
FOREACH_OBSERVER(ret, thread_start, true, (¶m));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +412,7 @@ int Binlog_relay_IO_delegate::thread_stop(THD *thd, Master_info *mi)
|
||||||
init_param(¶m, mi);
|
init_param(¶m, mi);
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, thread_stop, thd, (¶m));
|
FOREACH_OBSERVER(ret, thread_stop, false, (¶m));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +424,7 @@ int Binlog_relay_IO_delegate::before_request_transmit(THD *thd,
|
||||||
init_param(¶m, mi);
|
init_param(¶m, mi);
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, before_request_transmit, thd, (¶m, (uint32)flags));
|
FOREACH_OBSERVER(ret, before_request_transmit, false, (¶m, (uint32)flags));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +437,7 @@ int Binlog_relay_IO_delegate::after_read_event(THD *thd, Master_info *mi,
|
||||||
init_param(¶m, mi);
|
init_param(¶m, mi);
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_read_event, thd,
|
FOREACH_OBSERVER(ret, after_read_event, false,
|
||||||
(¶m, packet, len, event_buf, event_len));
|
(¶m, packet, len, event_buf, event_len));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -498,7 +455,7 @@ int Binlog_relay_IO_delegate::after_queue_event(THD *thd, Master_info *mi,
|
||||||
flags |= BINLOG_STORAGE_IS_SYNCED;
|
flags |= BINLOG_STORAGE_IS_SYNCED;
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_queue_event, thd,
|
FOREACH_OBSERVER(ret, after_queue_event, false,
|
||||||
(¶m, event_buf, event_len, flags));
|
(¶m, event_buf, event_len, flags));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -510,7 +467,7 @@ int Binlog_relay_IO_delegate::after_reset_slave(THD *thd, Master_info *mi)
|
||||||
init_param(¶m, mi);
|
init_param(¶m, mi);
|
||||||
|
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
FOREACH_OBSERVER(ret, after_reset_slave, thd, (¶m));
|
FOREACH_OBSERVER(ret, after_reset_slave, false, (¶m));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
|
@ -26,13 +26,10 @@ class Observer_info {
|
||||||
public:
|
public:
|
||||||
void *observer;
|
void *observer;
|
||||||
st_plugin_int *plugin_int;
|
st_plugin_int *plugin_int;
|
||||||
plugin_ref plugin;
|
|
||||||
|
|
||||||
Observer_info(void *ob, st_plugin_int *p)
|
Observer_info(void *ob, st_plugin_int *p)
|
||||||
:observer(ob), plugin_int(p)
|
:observer(ob), plugin_int(p)
|
||||||
{
|
{ }
|
||||||
plugin= plugin_int_to_ref(plugin_int);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Delegate {
|
class Delegate {
|
||||||
|
|
|
@ -3388,9 +3388,10 @@ err_during_init:
|
||||||
DBUG_ASSERT(thd->net.buff != 0);
|
DBUG_ASSERT(thd->net.buff != 0);
|
||||||
net_end(&thd->net); // destructor will not free it, because net.vio is 0
|
net_end(&thd->net); // destructor will not free it, because net.vio is 0
|
||||||
mysql_mutex_lock(&LOCK_thread_count);
|
mysql_mutex_lock(&LOCK_thread_count);
|
||||||
|
thd->unlink();
|
||||||
|
mysql_mutex_unlock(&LOCK_thread_count);
|
||||||
THD_CHECK_SENTRY(thd);
|
THD_CHECK_SENTRY(thd);
|
||||||
delete thd;
|
delete thd;
|
||||||
mysql_mutex_unlock(&LOCK_thread_count);
|
|
||||||
mi->abort_slave= 0;
|
mi->abort_slave= 0;
|
||||||
mi->slave_running= 0;
|
mi->slave_running= 0;
|
||||||
mi->io_thd= 0;
|
mi->io_thd= 0;
|
||||||
|
|
Loading…
Reference in a new issue