System Versioning 1.0 pre7

Merge branch '10.3' into trunk
This commit is contained in:
Aleksey Midenkov 2017-12-21 11:16:42 +03:00
commit 5c0a19c873
167 changed files with 9535 additions and 4519 deletions

View File

@ -2736,7 +2736,7 @@ static Exit_status check_header(IO_CACHE* file,
Format_description_log_event *new_description_event; Format_description_log_event *new_description_event;
my_b_seek(file, tmp_pos); /* seek back to event's start */ my_b_seek(file, tmp_pos); /* seek back to event's start */
if (!(new_description_event= (Format_description_log_event*) if (!(new_description_event= (Format_description_log_event*)
Log_event::read_log_event(file, 0, glob_description_event, Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum))) opt_verify_binlog_checksum)))
/* EOF can't be hit here normally, so it's a real error */ /* EOF can't be hit here normally, so it's a real error */
{ {
@ -2770,7 +2770,7 @@ static Exit_status check_header(IO_CACHE* file,
{ {
Log_event *ev; Log_event *ev;
my_b_seek(file, tmp_pos); /* seek back to event's start */ my_b_seek(file, tmp_pos); /* seek back to event's start */
if (!(ev= Log_event::read_log_event(file, 0, glob_description_event, if (!(ev= Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum))) opt_verify_binlog_checksum)))
{ {
/* EOF can't be hit here normally, so it's a real error */ /* EOF can't be hit here normally, so it's a real error */
@ -2884,7 +2884,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
char llbuff[21]; char llbuff[21];
my_off_t old_off = my_b_tell(file); my_off_t old_off = my_b_tell(file);
Log_event* ev = Log_event::read_log_event(file, 0, glob_description_event, Log_event* ev = Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum); opt_verify_binlog_checksum);
if (!ev) if (!ev)
{ {

View File

@ -52,8 +52,6 @@ usr/lib/mysql/plugin/locales.so
usr/lib/mysql/plugin/metadata_lock_info.so usr/lib/mysql/plugin/metadata_lock_info.so
usr/lib/mysql/plugin/query_cache_info.so usr/lib/mysql/plugin/query_cache_info.so
usr/lib/mysql/plugin/query_response_time.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/server_audit.so
usr/lib/mysql/plugin/simple_password_check.so usr/lib/mysql/plugin/simple_password_check.so
usr/lib/mysql/plugin/sql_errlog.so usr/lib/mysql/plugin/sql_errlog.so

View File

@ -1061,11 +1061,13 @@ struct my_option xb_server_options[] =
(G_PTR*) &defaults_group, (G_PTR*) &defaults_group, (G_PTR*) &defaults_group, (G_PTR*) &defaults_group,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"plugin-dir", OPT_PLUGIN_DIR, "Server plugin directory", {"plugin-dir", OPT_PLUGIN_DIR,
"Server plugin directory. Used to load encryption plugin during 'prepare' phase."
"Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)",
&xb_plugin_dir, &xb_plugin_dir, &xb_plugin_dir, &xb_plugin_dir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load", { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load during 'prepare' phase.",
&xb_plugin_load, &xb_plugin_load, &xb_plugin_load, &xb_plugin_load,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
@ -3624,7 +3626,6 @@ fail:
/* Reset the system variables in the recovery module. */ /* Reset the system variables in the recovery module. */
recv_sys_var_init(); recv_sys_var_init();
trx_pool_init(); trx_pool_init();
row_mysql_init();
ut_crc32_init(); ut_crc32_init();
crc_init(); crc_init();

View File

@ -152,6 +152,8 @@ typedef struct my_aio_result {
/* Extra length needed for filename if one calls my_create_backup_name */ /* Extra length needed for filename if one calls my_create_backup_name */
#define MY_BACKUP_NAME_EXTRA_LENGTH 17 #define MY_BACKUP_NAME_EXTRA_LENGTH 17
char *guess_malloc_library();
/* If we have our own safemalloc (for debugging) */ /* If we have our own safemalloc (for debugging) */
#if defined(SAFEMALLOC) #if defined(SAFEMALLOC)
void sf_report_leaked_memory(my_thread_id id); void sf_report_leaked_memory(my_thread_id id);

View File

@ -90,7 +90,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/scheduler.cc ../sql/sql_audit.cc ../sql/scheduler.cc ../sql/sql_audit.cc
../sql/sql_alter.cc ../sql/sql_partition_admin.cc ../sql/sql_alter.cc ../sql/sql_partition_admin.cc
../sql/event_parse_data.cc ../sql/event_parse_data.cc
../sql/sql_signal.cc ../sql/rpl_handler.cc ../sql/sql_signal.cc
../sql/sys_vars.cc ../sql/sys_vars.cc
${CMAKE_BINARY_DIR}/sql/sql_builtin.cc ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc
../sql/mdl.cc ../sql/transaction.cc ../sql/mdl.cc ../sql/transaction.cc

View File

@ -4,7 +4,6 @@
# Please check all dependent tests after modifying it # Please check all dependent tests after modifying it
# #
source include/have_semisync.inc;
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_innodb.inc; source include/have_innodb.inc;
source include/master-slave.inc; source include/master-slave.inc;
@ -17,6 +16,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");

View File

@ -82,7 +82,10 @@ call mtr.check_testcase();
let $datadir=`select @@datadir`; let $datadir=`select @@datadir`;
list_files $datadir mysql_upgrade_info; list_files $datadir mysql_upgrade_info;
list_files $datadir/test #sql*; list_files_write_file $datadir.tempfiles.txt $datadir/test #sql*;
--replace_regex /#sql-ib[0-9a-f]+-[0-9a-f]+\.ibd\n//
cat_file $datadir.tempfiles.txt;
remove_file $datadir.tempfiles.txt;
list_files $datadir/mysql #sql*; list_files $datadir/mysql #sql*;
--enable_query_log --enable_query_log

View File

@ -1 +1 @@
--plugin-load-add=$AUTH_TEST_PLUGIN_SO --plugin-maturity=unknown --plugin-load-add=$AUTH_TEST_PLUGIN_SO

View File

@ -1,4 +0,0 @@
if (`select count(*) < 2 from information_schema.plugins where plugin_name like 'rpl_semi_sync_%'`)
{
--skip Test requires semisync plugins
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -330,6 +330,8 @@ my %mysqld_logs;
my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions. my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
my $warn_seconds = 60; my $warn_seconds = 60;
my $rebootstrap_re= '--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)|data[-_]file[-_]path';
sub testcase_timeout ($) { sub testcase_timeout ($) {
my ($tinfo)= @_; my ($tinfo)= @_;
if (exists $tinfo->{'case-timeout'}) { if (exists $tinfo->{'case-timeout'}) {
@ -2793,10 +2795,12 @@ sub mysql_server_start($) {
{ {
# Some InnoDB options are incompatible with the default bootstrap. # Some InnoDB options are incompatible with the default bootstrap.
# If they are used, re-bootstrap # If they are used, re-bootstrap
if ( $extra_opts and my @rebootstrap_opts;
"@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)|data[-_]file[-_]path/ ) @rebootstrap_opts = grep {/$rebootstrap_re/o} @$extra_opts if $extra_opts;
if (@rebootstrap_opts)
{ {
mysql_install_db($mysqld, undef, $extra_opts); mtr_verbose("Re-bootstrap with @rebootstrap_opts");
mysql_install_db($mysqld, undef, \@rebootstrap_opts);
} }
else { else {
# Copy datadir from installed system db # Copy datadir from installed system db

View File

@ -115,3 +115,7 @@ c9: 0x000000000101000000000000000000F03F000000000000F03F
#Print the table contents in html format #Print the table contents in html format
<TABLE BORDER=1><TR><TH>c1</TH><TH>c2</TH><TH>c3</TH><TH>c4</TH><TH>c5</TH><TH>c6</TH><TH>c7</TH><TH>c8</TH><TH>c9</TH></TR><TR><TD>0x74696E79626C6F622D74657874207265616461626C65</TD><TD>0x626C6F622D74657874207265616461626C65</TD><TD>0x6D656469756D626C6F622D74657874207265616461626C65</TD><TD>0x6C6F6E67626C6F622D74657874207265616461626C65</TD><TD>0x74657874207265616461626C65</TD><TD>0x01</TD><TD>0x63</TD><TD>0x7661726961626C65</TD><TD>0x000000000101000000000000000000F03F000000000000F03F</TD></TR></TABLE><TABLE BORDER=1><TR><TH>id</TH><TH>col1</TH><TH>col2</TH></TR><TR><TD>1</TD><TD>0xAB123400000000000000</TD><TD>0x123ABC</TD></TR><TR><TD>2</TD><TD>0xDE123400000000000000</TD><TD>0x123DEF</TD></TR></TABLE>DROP TABLE t1, t2; <TABLE BORDER=1><TR><TH>c1</TH><TH>c2</TH><TH>c3</TH><TH>c4</TH><TH>c5</TH><TH>c6</TH><TH>c7</TH><TH>c8</TH><TH>c9</TH></TR><TR><TD>0x74696E79626C6F622D74657874207265616461626C65</TD><TD>0x626C6F622D74657874207265616461626C65</TD><TD>0x6D656469756D626C6F622D74657874207265616461626C65</TD><TD>0x6C6F6E67626C6F622D74657874207265616461626C65</TD><TD>0x74657874207265616461626C65</TD><TD>0x01</TD><TD>0x63</TD><TD>0x7661726961626C65</TD><TD>0x000000000101000000000000000000F03F000000000000F03F</TD></TR></TABLE><TABLE BORDER=1><TR><TH>id</TH><TH>col1</TH><TH>col2</TH></TR><TR><TD>1</TD><TD>0xAB123400000000000000</TD><TD>0x123ABC</TD></TR><TR><TD>2</TD><TD>0xDE123400000000000000</TD><TD>0x123DEF</TD></TR></TABLE>DROP TABLE t1, t2;
create table t1 (a int);
formatID gtrid_length bqual_length data
1 3 2 0x7472316271
DROP TABLE t1;

View File

@ -2904,6 +2904,53 @@ n
2 2
3 3
# #
# mdev-14629: a user-defined variable is defined by the recursive CTE
#
set @var=
(
with recursive cte_tab(a) as (
select 1
union
select a+1 from cte_tab
where a<3)
select count(*) from cte_tab
);
select @var;
@var
3
create table t1(a int, b int);
insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
set @var=
(
with recursive summ(a,s) as (
select 1, 0 union
select t1.b, t1.b+summ.s from summ, t1
where summ.a=t1.a)
select s from summ
order by a desc
limit 1
);
select @var;
@var
27
set @var=
(
with recursive
cte_1 as (
select 1
union
select * from cte_2),
cte_2 as (
select * from cte_1
union
select a from t1, cte_2
where t1.a=cte_2.a)
select * from cte_2
limit 1
);
ERROR HY000: Unacceptable mutual recursion with anchored table 'cte_1'
drop table t1;
#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
# #
CREATE TEMPORARY TABLE a_tbl ( CREATE TEMPORARY TABLE a_tbl (

File diff suppressed because it is too large Load Diff

View File

@ -998,6 +998,33 @@ The following options may be given as the first argument:
--rowid-merge-buff-size=# --rowid-merge-buff-size=#
The size of the buffers used [NOT] IN evaluation via The size of the buffers used [NOT] IN evaluation via
partial matching 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-delay-master
Only write master info file when ack is needed.
--rpl-semi-sync-slave-enabled
Enable semi-synchronous replication slave (disabled by
default).
--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.
--rpl-semi-sync-slave-trace-level=#
The tracing level for semi-sync replication.
--safe-mode Skip some optimize stages (for testing). Deprecated. --safe-mode Skip some optimize stages (for testing). Deprecated.
--safe-user-create Don't allow new user creation by the user who has no --safe-user-create Don't allow new user creation by the user who has no
write privileges to the mysql.user table. write privileges to the mysql.user table.
@ -1588,6 +1615,15 @@ report-password (No default value)
report-port 0 report-port 0
report-user (No default value) report-user (No default value)
rowid-merge-buff-size 8388608 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-delay-master FALSE
rpl-semi-sync-slave-enabled FALSE
rpl-semi-sync-slave-kill-conn-timeout 5
rpl-semi-sync-slave-trace-level 32
safe-user-create FALSE safe-user-create FALSE
secure-auth TRUE secure-auth TRUE
secure-file-priv (No default value) secure-file-priv (No default value)

View File

@ -60,6 +60,59 @@ a
20 20
disconnect con1; disconnect con1;
connection default; connection default;
xa start 'tr1';
insert t1 values (40);
xa end 'tr1';
xa prepare 'tr1';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 3 0 'tr1'
xa rollback 'tr1';
xa start 'tr1', 'bq';
insert t1 values (40);
xa end 'tr1', 'bq';
xa prepare 'tr1', 'bq';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 3 2 'tr1','bq'
xa rollback 'tr1', 'bq';
xa start 'tr1', 'bq', 3;
insert t1 values (40);
xa end 'tr1', 'bq', 3;
xa prepare 'tr1', 'bq', 3;
xa recover format='SQL';
formatID gtrid_length bqual_length data
3 3 2 'tr1','bq',3
xa rollback 'tr1', 'bq', 3;
xa start 'tr1#$';
insert t1 values (40);
xa end 'tr1#$';
xa prepare 'tr1#$';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 5 0 X'7472312324'
xa rollback 'tr1#$';
xa start 'tr1#$', 'bq';
insert t1 values (40);
xa end 'tr1#$', 'bq';
xa prepare 'tr1#$', 'bq';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 5 2 X'7472312324',X'6271'
xa rollback 'tr1#$', 'bq';
xa start 'tr1#$', 'bq', 3;
insert t1 values (40);
xa end 'tr1#$', 'bq', 3;
xa prepare 'tr1#$', 'bq', 3;
xa recover format='RAW';
formatID gtrid_length bqual_length data
3 5 2 tr1#$bq
xa recover format='PLAIN';
ERROR HY000: Unknown XA RECOVER format name: 'PLAIN'
xa recover format='SQL';
formatID gtrid_length bqual_length data
3 5 2 X'7472312324',X'6271',3
xa rollback 'tr1#$', 'bq', 3;
drop table t1; drop table t1;
drop table if exists t1; drop table if exists t1;
create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb; create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb;

View File

@ -4,6 +4,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");
@ -176,7 +177,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 14 Rpl_semi_sync_master_yes_tx 14
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value
Rpl_semi_sync_master_clients 1 Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ] [ semi-sync replication of these transactions will fail ]
insert into t1 values (500); insert into t1 values (500);
[ master status should be OFF ] [ master status should be OFF ]
@ -321,7 +322,6 @@ connection slave;
include/stop_slave.inc include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
kill query _tid;
connection slave; connection slave;
include/start_slave.inc include/start_slave.inc
connection master; connection master;
@ -353,7 +353,6 @@ include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
reset master; reset master;
kill query _tid;
set sql_log_bin=0; set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges; flush privileges;
@ -404,7 +403,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value Variable_name Value
Rpl_semi_sync_slave_status OFF Rpl_semi_sync_slave_status OFF
connection master; connection master;
kill query _tid;
[ Semi-sync status on master should be ON ] [ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value

View File

@ -1,3 +1,2 @@
--plugin-load-add=$EXAMPLE_KEY_MANAGEMENT_SO --plugin-load-add=$EXAMPLE_KEY_MANAGEMENT_SO
--loose-example-key-management --loose-example-key-management
--plugin-maturity=unknown

View File

@ -4,7 +4,6 @@
[mysqld] [mysqld]
wsrep-on=1 wsrep-on=1
binlog-format=row binlog-format=row
plugin-maturity=unknown
innodb-autoinc-lock-mode=2 innodb-autoinc-lock-mode=2
default-storage-engine=innodb default-storage-engine=innodb
wsrep-provider=@ENV.WSREP_PROVIDER wsrep-provider=@ENV.WSREP_PROVIDER

View File

@ -1 +0,0 @@
--plugin-maturity=unknown

View File

@ -3,7 +3,6 @@
[mysqld] [mysqld]
binlog-format=row binlog-format=row
plugin-maturity=unknown
innodb-autoinc-lock-mode=2 innodb-autoinc-lock-mode=2
default-storage-engine=innodb default-storage-engine=innodb

View File

@ -44,10 +44,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
ERROR HY000: Lost connection to MySQL server during query ERROR HY000: Lost connection to MySQL server during query
# Restart mysqld after the crash and reconnect. # Restart mysqld after the crash and reconnect.
# Manual *.frm recovery begin. SELECT * FROM information_schema.innodb_sys_tables
# Manual recovery end WHERE table_id = ID;
FLUSH TABLES; TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# Drop the orphaned original table.
# Files in datadir after manual recovery. # Files in datadir after manual recovery.
t1.frm t1.frm
t1.ibd t1.ibd
@ -83,12 +82,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit';
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
ERROR HY000: Lost connection to MySQL server during query ERROR HY000: Lost connection to MySQL server during query
# Startup the server after the crash # Startup the server after the crash
# Read and remember the temporary table name SELECT * FROM information_schema.innodb_sys_tables
# Manual *.frm recovery begin. The dictionary was not updated WHERE name LIKE 'test/#sql-%';
# and the files were not renamed. The rebuilt table TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# was left behind on purpose, to faciliate data recovery.
# Manual recovery end
# Drop the orphaned rebuilt table.
SHOW TABLES; SHOW TABLES;
Tables_in_test Tables_in_test
t2 t2
@ -123,10 +119,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE; ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
ERROR HY000: Lost connection to MySQL server during query ERROR HY000: Lost connection to MySQL server during query
# Restart mysqld after the crash and reconnect. # Restart mysqld after the crash and reconnect.
# Manual *.frm recovery begin. SELECT * FROM information_schema.innodb_sys_tables
# Manual recovery end WHERE table_id = ID;
FLUSH TABLES; TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# Drop the orphaned original table.
# Files in datadir after manual recovery. # Files in datadir after manual recovery.
t1.frm t1.frm
t1.ibd t1.ibd

View File

@ -3,7 +3,22 @@ KEY(c1), KEY(c2), KEY(c2,c1),
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1), KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1), KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB; KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
INSERT INTO t (c1) VALUES (1),(2),(1);
SET DEBUG_DBUG='+d,row_drop_table_add_to_background'; SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from target;
ERROR 42S02: Table 'test.target' doesn't exist
DROP TABLE t; DROP TABLE t;
CREATE TABLE t (a INT) ENGINE=InnoDB; CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t; DROP TABLE t;
DROP TABLE target;
ERROR 42S02: Unknown table 'test.target'
CREATE TABLE target (a INT) ENGINE=InnoDB;
DROP TABLE target;
SELECT * FROM `#mysql50##sql-ib-foo`;
ERROR 42S02: Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine
DROP TABLE `#mysql50##sql-ib-foo`;
Warnings:
Warning 1932 Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine

View File

@ -1351,3 +1351,15 @@ t CREATE TABLE `t` (
KEY `i` (`i`) KEY `i` (`i`)
) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1
DROP TABLE t; DROP TABLE t;
#
# MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())
#
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 (
c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000;
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
c1
1e19
DROP TABLE t1;

View File

@ -395,6 +395,6 @@ NAME CREATE_FILE CREATE_LINE OS_WAITS
Warnings: Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_mutexes but the InnoDB storage engine is not installed Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_mutexes but the InnoDB storage engine is not installed
select * from information_schema.innodb_sys_semaphore_waits; select * from information_schema.innodb_sys_semaphore_waits;
THREAD_ID OBJECT_NAME FILE LINE WAIT_TIME WAIT_OBJECT WAIT_TYPE HOLDER_THREAD_ID HOLDER_FILE HOLDER_LINE CREATED_FILE CREATED_LINE WRITER_THREAD RESERVATION_MODE READERS WAITERS_FLAG LOCK_WORD LAST_READER_FILE LAST_READER_LINE LAST_WRITER_FILE LAST_WRITER_LINE OS_WAIT_COUNT THREAD_ID OBJECT_NAME FILE LINE WAIT_TIME WAIT_OBJECT WAIT_TYPE HOLDER_THREAD_ID HOLDER_FILE HOLDER_LINE CREATED_FILE CREATED_LINE WRITER_THREAD RESERVATION_MODE READERS WAITERS_FLAG LOCK_WORD LAST_WRITER_FILE LAST_WRITER_LINE OS_WAIT_COUNT
Warnings: Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_sys_semaphore_waits but the InnoDB storage engine is not installed Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_sys_semaphore_waits but the InnoDB storage engine is not installed

View File

@ -353,6 +353,22 @@ id c2 c4 c5 c6 c8 phrase b
3 3 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 3 3 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog
4 0 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 😱 4 0 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 😱
5 9 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 ääH binary line of business 5 9 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 ääH binary line of business
CREATE TABLE t4
(id INT, foo INT DEFAULT 0, c1 VARCHAR(4000),
p GEOMETRY NOT NULL DEFAULT ST_GeomFromText('LINESTRING(0 0,0 1,1 1)'),
PRIMARY KEY(id,foo))
ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000)), (2, REPEAT('a', 4000));
ALTER TABLE t4 ADD COLUMN d1 INT;
BEGIN;
UPDATE t4 SET c1 = repeat('1', 4000), foo=1 WHERE id=1;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000));
UPDATE t4 SET c1 = repeat('2', 4000), foo=1 WHERE id=2;
ROLLBACK;
BEGIN;
UPDATE t4 SET d1 = 1,foo=2 WHERE id=1;
INSERT INTO t4 (id,foo,c1) VALUES (1, 1, REPEAT('1', 4000));
COMMIT;
CREATE TABLE big CREATE TABLE big
(id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000), (id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000),
p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p)) p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p))
@ -413,7 +429,7 @@ clust_index_size
3 3
connection default; connection default;
InnoDB 0 transactions not purged InnoDB 0 transactions not purged
DROP TABLE t1,t2,t3,big; DROP TABLE t1,t2,t3,t4,big;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
@ -713,6 +729,22 @@ id c2 c4 c5 c6 c8 phrase b
3 3 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 3 3 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog
4 0 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 😱 4 0 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 😱
5 9 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 ääH binary line of business 5 9 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 ääH binary line of business
CREATE TABLE t4
(id INT, foo INT DEFAULT 0, c1 VARCHAR(4000),
p GEOMETRY NOT NULL DEFAULT ST_GeomFromText('LINESTRING(0 0,0 1,1 1)'),
PRIMARY KEY(id,foo))
ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000)), (2, REPEAT('a', 4000));
ALTER TABLE t4 ADD COLUMN d1 INT;
BEGIN;
UPDATE t4 SET c1 = repeat('1', 4000), foo=1 WHERE id=1;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000));
UPDATE t4 SET c1 = repeat('2', 4000), foo=1 WHERE id=2;
ROLLBACK;
BEGIN;
UPDATE t4 SET d1 = 1,foo=2 WHERE id=1;
INSERT INTO t4 (id,foo,c1) VALUES (1, 1, REPEAT('1', 4000));
COMMIT;
CREATE TABLE big CREATE TABLE big
(id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000), (id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000),
p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p)) p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p))
@ -773,7 +805,7 @@ clust_index_size
3 3
connection default; connection default;
InnoDB 0 transactions not purged InnoDB 0 transactions not purged
DROP TABLE t1,t2,t3,big; DROP TABLE t1,t2,t3,t4,big;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
@ -1073,6 +1105,22 @@ id c2 c4 c5 c6 c8 phrase b
3 3 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 3 3 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog
4 0 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 😱 4 0 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog 😱
5 9 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 ääH binary line of business 5 9 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 ääH binary line of business
CREATE TABLE t4
(id INT, foo INT DEFAULT 0, c1 VARCHAR(4000),
p GEOMETRY NOT NULL DEFAULT ST_GeomFromText('LINESTRING(0 0,0 1,1 1)'),
PRIMARY KEY(id,foo))
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000)), (2, REPEAT('a', 4000));
ALTER TABLE t4 ADD COLUMN d1 INT;
BEGIN;
UPDATE t4 SET c1 = repeat('1', 4000), foo=1 WHERE id=1;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000));
UPDATE t4 SET c1 = repeat('2', 4000), foo=1 WHERE id=2;
ROLLBACK;
BEGIN;
UPDATE t4 SET d1 = 1,foo=2 WHERE id=1;
INSERT INTO t4 (id,foo,c1) VALUES (1, 1, REPEAT('1', 4000));
COMMIT;
CREATE TABLE big CREATE TABLE big
(id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000), (id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000),
p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p)) p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p))
@ -1133,11 +1181,11 @@ clust_index_size
3 3
connection default; connection default;
InnoDB 0 transactions not purged InnoDB 0 transactions not purged
DROP TABLE t1,t2,t3,big; DROP TABLE t1,t2,t3,t4,big;
disconnect analyze; disconnect analyze;
SELECT variable_value-@old_instant instants SELECT variable_value-@old_instant instants
FROM information_schema.global_status FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column'; WHERE variable_name = 'innodb_instant_alter_column';
instants instants
30 33
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;

View File

@ -0,0 +1,12 @@
CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES(42);
connect con1,localhost,root,,test;
SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
RENAME TABLE t1 TO t2;
connection default;
SET DEBUG_SYNC='now WAIT_FOR renamed';
disconnect con1;
SELECT * FROM t1;
a
42
DROP TABLE t1;

View File

@ -1 +0,0 @@
--plugin-maturity=unknown

View File

@ -72,31 +72,25 @@ let $orig_table_id = `SELECT table_id
--error 2013 --error 2013
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
perl;
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
print OUT 'let $tablename=', $frm_file[0], ';';
close OUT or die;
EOF
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
move_file $datadir/test/$tablename.frm $datadir/test/t1.frm;
--echo # Restart mysqld after the crash and reconnect. --echo # Restart mysqld after the crash and reconnect.
--source include/start_mysqld.inc --source include/start_mysqld.inc
let $temp_table_name = `SELECT SUBSTR(name, 6) --replace_result $orig_table_id ID
FROM information_schema.innodb_sys_tables eval SELECT * FROM information_schema.innodb_sys_tables
WHERE table_id = $orig_table_id`; WHERE table_id = $orig_table_id;
--echo # Manual *.frm recovery begin.
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
perl;
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
rename($frm_file[0], $t1_frm);
EOF
--echo # Manual recovery end
FLUSH TABLES;
--echo # Drop the orphaned original table.
--disable_query_log
eval DROP TABLE `$temp_table_name`;
--enable_query_log
--echo # Files in datadir after manual recovery. --echo # Files in datadir after manual recovery.
--list_files $MYSQLD_DATADIR/test --list_files $MYSQLD_DATADIR/test
@ -131,35 +125,13 @@ let $orig_table_id = `SELECT table_id
--error 2013 --error 2013
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
remove_files_wildcard $datadir/test #sql-*.frm;
--echo # Startup the server after the crash --echo # Startup the server after the crash
--source include/start_mysqld.inc --source include/start_mysqld.inc
--echo # Read and remember the temporary table name SELECT * FROM information_schema.innodb_sys_tables
let $temp_table_name = `SELECT SUBSTRING(name,6) WHERE name LIKE 'test/#sql-%';
FROM information_schema.innodb_sys_tables
WHERE name LIKE "test/#sql-ib$orig_table_id%"`;
--echo # Manual *.frm recovery begin. The dictionary was not updated
--echo # and the files were not renamed. The rebuilt table
--echo # was left behind on purpose, to faciliate data recovery.
let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
perl;
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
print OUT 'let $tablename=', $frm_file[0], ';';
close OUT or die;
EOF
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
--echo # Manual recovery end
--echo # Drop the orphaned rebuilt table.
--disable_query_log
eval DROP TABLE `#mysql50#$tablename`;
--enable_query_log
SHOW TABLES; SHOW TABLES;
INSERT INTO t2 VALUES (5,6),(7,8); INSERT INTO t2 VALUES (5,6),(7,8);
@ -195,30 +167,24 @@ let $orig_table_id = `select table_id from
--error 2013 --error 2013
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE; ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
perl;
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
print OUT 'let $tablename=', $frm_file[0], ';';
close OUT or die;
EOF
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
move_file $datadir/test/$tablename.frm $datadir/test/t1.frm;
--echo # Restart mysqld after the crash and reconnect. --echo # Restart mysqld after the crash and reconnect.
--source include/start_mysqld.inc --source include/start_mysqld.inc
let $temp_table_name = `SELECT SUBSTR(name, 6) --replace_result $orig_table_id ID
FROM information_schema.innodb_sys_tables eval SELECT * FROM information_schema.innodb_sys_tables
WHERE table_id = $orig_table_id`; WHERE table_id = $orig_table_id;
--echo # Manual *.frm recovery begin.
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
perl;
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
rename($frm_file[0], $t1_frm);
EOF
--echo # Manual recovery end
FLUSH TABLES;
--echo # Drop the orphaned original table.
--disable_query_log
eval DROP TABLE `#mysql50#$temp_table_name`;
--enable_query_log
--echo # Files in datadir after manual recovery. --echo # Files in datadir after manual recovery.
--list_files $MYSQLD_DATADIR/test --list_files $MYSQLD_DATADIR/test

View File

@ -9,6 +9,9 @@ KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1), KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB; KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
INSERT INTO t (c1) VALUES (1),(2),(1);
let $n= 10; let $n= 10;
SET DEBUG_DBUG='+d,row_drop_table_add_to_background'; SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
@ -24,7 +27,18 @@ while ($i) {
dec $i; dec $i;
} }
--enable_query_log --enable_query_log
--error ER_DUP_ENTRY
CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
--error ER_NO_SUCH_TABLE
SELECT * from target;
DROP TABLE t; DROP TABLE t;
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
CREATE TABLE t (a INT) ENGINE=InnoDB; CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t; DROP TABLE t;
--error ER_BAD_TABLE_ERROR
DROP TABLE target;
CREATE TABLE target (a INT) ENGINE=InnoDB;
DROP TABLE target;
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM `#mysql50##sql-ib-foo`;
DROP TABLE `#mysql50##sql-ib-foo`;

View File

@ -32,24 +32,12 @@ SET debug_dbug='+d,innodb_alter_commit_crash_before_commit';
--error 2013 --error 2013
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc; remove_files_wildcard $datadir/test #sql-*.frm;
perl;
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
print OUT 'let $temp_table_name=', $frm_file[0], ';';
close OUT or die;
EOF
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
--source include/start_mysqld.inc --source include/start_mysqld.inc
show create table t1; show create table t1;
--echo # Consecutive Alter table does not create same temporary file name --echo # Consecutive Alter table does not create same temporary file name
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
--disable_query_log
eval DROP TABLE `#mysql50#$temp_table_name`;
--enable_query_log
show create table t1; show create table t1;
drop table t1; drop table t1;

View File

@ -683,3 +683,15 @@ INSERT INTO t VALUES (NULL);
SELECT * FROM t; SELECT * FROM t;
SHOW CREATE TABLE t; SHOW CREATE TABLE t;
DROP TABLE t; DROP TABLE t;
--echo #
--echo # MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())
--echo #
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 (
c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000;
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
DROP TABLE t1;

View File

@ -236,6 +236,26 @@ ALTER TABLE t3 DROP c3, DROP c7;
--disable_info --disable_info
SELECT * FROM t3; SELECT * FROM t3;
eval CREATE TABLE t4
(id INT, foo INT DEFAULT 0, c1 VARCHAR(4000),
p GEOMETRY NOT NULL DEFAULT ST_GeomFromText('LINESTRING(0 0,0 1,1 1)'),
PRIMARY KEY(id,foo))
$engine;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000)), (2, REPEAT('a', 4000));
ALTER TABLE t4 ADD COLUMN d1 INT;
BEGIN;
UPDATE t4 SET c1 = repeat('1', 4000), foo=1 WHERE id=1;
INSERT INTO t4 (id,c1) VALUES (1, REPEAT('a', 4000));
UPDATE t4 SET c1 = repeat('2', 4000), foo=1 WHERE id=2;
ROLLBACK;
BEGIN;
UPDATE t4 SET d1 = 1,foo=2 WHERE id=1;
INSERT INTO t4 (id,foo,c1) VALUES (1, 1, REPEAT('1', 4000));
COMMIT;
eval CREATE TABLE big eval CREATE TABLE big
(id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000), (id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000),
p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p)) p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p))
@ -279,7 +299,7 @@ WHERE name = 'test/big';
connection default; connection default;
--source include/wait_all_purged.inc --source include/wait_all_purged.inc
DROP TABLE t1,t2,t3,big; DROP TABLE t1,t2,t3,t4,big;
dec $format; dec $format;
} }

View File

@ -0,0 +1,19 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/not_embedded.inc
CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES(42);
--connect (con1,localhost,root,,test)
SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
--send
RENAME TABLE t1 TO t2;
--connection default
SET DEBUG_SYNC='now WAIT_FOR renamed';
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
--disconnect con1
SELECT * FROM t1;
DROP TABLE t1;

View File

@ -0,0 +1,10 @@
CREATE TABLE t1 (i INT) ENGINE=MYISAM
PARTITION BY LIST(i) (
PARTITION p0 VALUES IN (1),
PARTITION p1 VALUES IN (2)
);
ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
ALTER TABLE t1 DROP PARTITION p1;
SELECT * FROM t1;
i
DROP TABLE t1;

View File

@ -0,0 +1,17 @@
#
# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
#
--source include/have_partition.inc
CREATE TABLE t1 (i INT) ENGINE=MYISAM
PARTITION BY LIST(i) (
PARTITION p0 VALUES IN (1),
PARTITION p1 VALUES IN (2)
);
ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
ALTER TABLE t1 DROP PARTITION p1;
SELECT * FROM t1;
# Cleanup
DROP TABLE t1;

View File

@ -4,6 +4,7 @@ where name like 'Wait/Synch/Mutex/sql/%'
and name not in ('wait/synch/mutex/sql/DEBUG_SYNC::mutex') and name not in ('wait/synch/mutex/sql/DEBUG_SYNC::mutex')
order by name limit 10; order by name limit 10;
NAME ENABLED TIMED NAME ENABLED TIMED
wait/synch/mutex/sql/Ack_receiver::mutex YES YES
wait/synch/mutex/sql/Cversion_lock YES YES wait/synch/mutex/sql/Cversion_lock YES YES
wait/synch/mutex/sql/Delayed_insert::mutex YES YES wait/synch/mutex/sql/Delayed_insert::mutex YES YES
wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state YES YES wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state YES YES
@ -13,7 +14,6 @@ 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_active_mi YES YES
wait/synch/mutex/sql/LOCK_after_binlog_sync 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_audit_mask YES YES
wait/synch/mutex/sql/LOCK_binlog_state YES YES
select * from performance_schema.setup_instruments select * from performance_schema.setup_instruments
where name like 'Wait/Synch/Rwlock/sql/%' where name like 'Wait/Synch/Rwlock/sql/%'
and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock') and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock')
@ -36,6 +36,8 @@ where name like 'Wait/Synch/Cond/sql/%'
'wait/synch/cond/sql/DEBUG_SYNC::cond') 'wait/synch/cond/sql/DEBUG_SYNC::cond')
order by name limit 10; order by name limit 10;
NAME ENABLED TIMED NAME ENABLED TIMED
wait/synch/cond/sql/Ack_receiver::cond YES YES
wait/synch/cond/sql/COND_binlog_send YES YES
wait/synch/cond/sql/COND_flush_thread_cache 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_group_commit_orderer YES YES
wait/synch/cond/sql/COND_gtid_ignore_duplicates YES YES wait/synch/cond/sql/COND_gtid_ignore_duplicates YES YES
@ -44,8 +46,6 @@ wait/synch/cond/sql/COND_parallel_entry YES YES
wait/synch/cond/sql/COND_prepare_ordered YES YES wait/synch/cond/sql/COND_prepare_ordered YES YES
wait/synch/cond/sql/COND_queue_state 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 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 select * from performance_schema.setup_instruments
where name='Wait'; where name='Wait';
select * from performance_schema.setup_instruments select * from performance_schema.setup_instruments

View File

@ -118,3 +118,19 @@ B
select count(*) from events_statements_history where sql_text like "%..."; select count(*) from events_statements_history where sql_text like "%...";
count(*) count(*)
2 2
use test;
create table t1 (id int);
insert into t1 values (1), (2), (3);
truncate performance_schema.events_statements_history;
select * from t1;
id
1
2
3
insert into t1 select RAND()*10000 from t1;
select sql_text, rows_examined from performance_schema.events_statements_history;
sql_text rows_examined
truncate performance_schema.events_statements_history 0
select * from t1 3
insert into t1 select RAND()*10000 from t1 6
drop table t1;

View File

@ -62,7 +62,9 @@ where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::COND_xid_list" and event_name not like "%MYSQL_BIN_LOG::COND_xid_list"
order by event_name; order by event_name;
EVENT_NAME COUNT_STAR EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated MANY
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
@ -81,7 +83,10 @@ where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond" and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name; order by event_name;
EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated 0 0 0 0 0
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy 0 0 0 0 0 wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy 0 0 0 0 0
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated 0 0 0 0 0
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_binlog_end_pos 0 0 0 0 0
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index 0 0 0 0 0 wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index 0 0 0 0 0
connection slave; connection slave;
"============ Performance schema on slave ============" "============ Performance schema on slave ============"
@ -142,7 +147,9 @@ where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::COND_xid_list" and event_name not like "%MYSQL_BIN_LOG::COND_xid_list"
order by event_name; order by event_name;
EVENT_NAME COUNT_STAR EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
@ -184,6 +191,9 @@ where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond" and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name; order by event_name;
EVENT_NAME COUNT_STAR EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated NONE
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy NONE wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy NONE
wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated MANY
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_binlog_end_pos NONE
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index MANY wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index MANY
include/stop_slave.inc include/stop_slave.inc

View File

@ -207,3 +207,18 @@ select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
select _utf8mb4 'васÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑ' as B; select _utf8mb4 'васÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑ' as B;
select count(*) from events_statements_history where sql_text like "%..."; select count(*) from events_statements_history where sql_text like "%...";
#
# MDEV-10486 MariaDB 10.x does not update rows_examined in performance_schema tables
# Verify that the rows_examined counter is set properly.
use test;
create table t1 (id int);
insert into t1 values (1), (2), (3);
truncate performance_schema.events_statements_history;
select * from t1;
insert into t1 select RAND()*10000 from t1;
select sql_text, rows_examined from performance_schema.events_statements_history;
drop table t1;

View File

@ -0,0 +1,353 @@
include/master-slave.inc
[connection master]
CALL mtr.add_suppression("Failed to start semi-sync ACK receiver thread.*");
CALL mtr.add_suppression("Failed to register slave to semi-sync ACK receiver thread.*");
CALL mtr.add_suppression("Failed to stop ack receiver thread on pthread_join.*");
CALL mtr.add_suppression("Got an error reading communication packets:*");
CALL mtr.add_suppression("Timeout waiting for reply of binlog*");
CALL mtr.add_suppression("slave_read_sync_header*");
CALL mtr.add_suppression("Missing magic number for semi-sync*");
CALL mtr.add_suppression("Got timeout reading communication packets*");
CALL mtr.add_suppression("Failed to call*");
CALL mtr.add_suppression("Execution failed on master*");
CALL mtr.add_suppression("Failed on request_dump()*");
CALL mtr.add_suppression("Semi-sync master failed on*");
CALL mtr.add_suppression("Master command COM_BINLOG_DUMP failed*");
CALL mtr.add_suppression("on master failed*");
CALL mtr.add_suppression("Master server does not support semi-sync*");
CALL mtr.add_suppression("Semi-sync slave net_flush*");
CALL mtr.add_suppression("Failed to flush master info*");
CALL mtr.add_suppression("Request to stop slave SQL Thread received while apply*");
connection master;
[ enable semi-sync on master ]
set global rpl_semi_sync_master_enabled = 1;
show variables like 'rpl_semi_sync_master_enabled';
Variable_name Value
rpl_semi_sync_master_enabled ON
connection slave;
[ enable semi-sync on slave ]
stop slave;
set global rpl_semi_sync_slave_enabled = 1;
start slave;
show status like 'rpl_semi_sync_slave%';
Variable_name Value
Rpl_semi_sync_slave_send_ack 0
Rpl_semi_sync_slave_status ON
connection master;
CREATE TABLE t1(a INT) ENGINE=InnoDB;
connection slave;
connection master;
connect con1,localhost,root,,;
connect con2,localhost,root,,;
connect con3,localhost,root,,;
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
show status like "rpl_semi_sync_master_yes_tx";
Variable_name Value
Rpl_semi_sync_master_yes_tx 1
#########################################
# Test rpl_semi_sync_master_wait_point #
#########################################
# Test after_sync and after_commit first.
#Test after_sync
connection con1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_SYNC';
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL after_sync_done WAIT_FOR end";
INSERT into t1 values (1);;
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR after_sync_done";
connection slave;
#slave can see record (1) after sync slave with master
select * from t1;
a
1
connection con2;
#con2 shouldn't see record (1)
select * from t1;
a
SET DEBUG_SYNC= "now SIGNAL end";
connection con1;
connection con1;
select * from t1;
a
1
truncate table t1;
connection slave;
connection con1;
SET DEBUG_SYNC= 'reset';
SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR more_queue";
INSERT into t1 VALUES (1);;
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
SET DEBUG_SYNC= "after_semisync_queue SIGNAL more_queue";
INSERT INTO t1 VALUES (2);
connection con1;
connection con1;
SET DEBUG_SYNC= 'reset';
SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR disable_semisync";
INSERT into t1 VALUES (3);;
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
SET GLOBAL rpl_semi_sync_master_enabled= 0;
SET DEBUG_SYNC= "now SIGNAL disable_semisync";
connection con1;
SET GLOBAL rpl_semi_sync_master_enabled = 1;
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
#Test after_commit
connection con1;
SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_COMMIT';
SET DEBUG_SYNC= "after_group_after_commit SIGNAL after_commit_done WAIT_FOR end";
INSERT into t1 values (4);;
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR after_commit_done";
connection slave;
select * from t1;
a
1
2
3
4
connection con2;
select * from t1;
a
1
2
3
4
SET DEBUG_SYNC= "now SIGNAL end";
connection con1;
connection con1;
select * from t1;
a
1
2
3
4
truncate table t1;
#######################################################
# Test some other options in order to cover the patch #
#######################################################
connection slave;
# Test rpl_semi_sync_slave_trace_level
SET GLOBAL rpl_semi_sync_slave_trace_level= 1;
SET GLOBAL rpl_semi_sync_slave_trace_level= 16;
SET GLOBAL rpl_semi_sync_slave_trace_level= 64;
SET GLOBAL rpl_semi_sync_slave_trace_level= 128;
SET GLOBAL rpl_semi_sync_slave_trace_level= 32;
connection master;
# Test rpl_semi_sync_master_trace_level
SET GLOBAL rpl_semi_sync_master_trace_level= 1;
SET GLOBAL rpl_semi_sync_master_trace_level= 16;
SET GLOBAL rpl_semi_sync_master_trace_level= 64;
SET GLOBAL rpl_semi_sync_master_trace_level= 128;
SET GLOBAL rpl_semi_sync_master_trace_level= 32;
# Test rpl_semi_sync_master_timeout
SET GLOBAL rpl_semi_sync_master_timeout= 1000;
SET GLOBAL rpl_semi_sync_master_timeout= 10000;
SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
# Test rpl_semi_sync_slave_kill_conn_timeout
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 10;
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 20;
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 60;
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 5;
############################################
# Test rpl_semi_sync_master_wait_no_slave #
############################################
SET GLOBAL rpl_semi_sync_master_wait_no_slave = 1;
connection slave;
STOP SLAVE IO_THREAD;
include/wait_for_slave_io_to_stop.inc
connection con1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;
INSERT INTO t1 values (1);;
connection con1;
# Rpl_semi_sync_master_no_tx should be non-zero
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'
connection slave;
START SLAVE IO_THREAD;
include/wait_for_slave_io_to_start.inc
connection con1;
INSERT INTO t1 values (2);
connection slave;
connection con1;
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status ON
connection slave;
STOP SLAVE IO_THREAD;
include/wait_for_slave_io_to_stop.inc
connection con1;
SET GLOBAL rpl_semi_sync_master_wait_no_slave= 0;
SET GLOBAL rpl_semi_sync_master_timeout= 1000000000;
INSERT INTO t1 values (3);
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 0
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status OFF
connection slave;
START SLAVE IO_THREAD;
include/wait_for_slave_io_to_start.inc
connection con1;
SET GLOBAL rpl_semi_sync_master_timeout= 10000000;
SET GLOBAL rpl_semi_sync_master_wait_no_slave= 1;
INSERT INTO t1 values (4);
connection slave;
connection con1;
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
##########################################
# Test rpl_semi_sync_slave_delay_master #
##########################################
connection slave;
SET GLOBAL rpl_semi_sync_slave_delay_master= 1;
START SLAVE IO_THREAD;
Warnings:
Note 1254 Slave is already running
include/wait_for_slave_io_to_start.inc
connection con1;
INSERT INTO t1 values (3);
include/sync_slave_io_with_master.inc
connection con1;
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
show status like 'Rpl_semi_sync_master_status';
Variable_name Value
Rpl_semi_sync_master_status ON
connection slave;
connection slave;
select * from t1 order by a;
a
1
2
3
3
4
connection con1;
select * from t1 order by a;
a
1
2
3
3
4
connection slave;
SET GLOBAL rpl_semi_sync_slave_delay_master = 0;
STOP SLAVE IO_THREAD;
include/wait_for_slave_io_to_stop.inc
START SLAVE IO_THREAD;
include/wait_for_slave_io_to_start.inc
##########################################################
# Test rpl_semi_sync_master_enabled and new ACK thread #
#########################################################
connection con1;
SET GLOBAL rpl_semi_sync_master_enabled = 0;
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
INSERT INTO t1 VALUES (1);
SET GLOBAL rpl_semi_sync_master_enabled = 1;
INSERT INTO t1 VALUES (2);
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
# Test failure of select error .
SET GLOBAL debug = 'd,rpl_semisync_simulate_select_error';
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
INSERT INTO t1 VALUES(3);
connection slave;
connection con1;
# Test failure of pthread_create
SET GLOBAL rpl_semi_sync_master_enabled = 0;
SET GLOBAL debug = 'd,rpl_semisync_simulate_create_thread_failure';
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
SET GLOBAL rpl_semi_sync_master_enabled= ON;
# Test failure of pthread_join
SET GLOBAL rpl_semi_sync_master_enabled= OFF;
#
# Failure on registering semisync slave
#
SET GLOBAL debug= 'd,rpl_semisync_simulate_add_slave_failure';
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
SET GLOBAL rpl_semi_sync_master_enabled= ON;
connection slave;
STOP SLAVE IO_THREAD;
include/wait_for_slave_io_to_stop.inc
START SLAVE IO_THREAD;
include/wait_for_slave_io_to_start.inc
connection con1;
SET GLOBAL debug='';
Warnings:
Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
connection slave;
START SLAVE IO_THREAD;
include/wait_for_slave_io_to_start.inc
connection con1;
connection slave;
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 0
##################################################################
# Test fixing of BUG#70669 #
#SLAVE CAN'T CONTINUE REPLICATION AFTER MASTER'S CRASH RECOVERY #
#################################################################
connection con1;
SET GLOBAL sync_binlog = 1;
CREATE TABLE t2 (c1 INT);
connection slave;
connection con1;
INSERT INTO t2 values (1);
connection slave;
connection con2;
connection con1;
connection slave;
show tables like 't2';
Tables_in_test (t2)
t2
select * from t2;
c1
1
connection con1;
INSERT INTO t2 VALUES (2);
connection con2;
INSERT INTO t2 VALUES (3);
connection con1;
connection con2;
connection con1;
SET GLOBAL sync_binlog = 0;
DROP TABLE t2;
connection con2;
connection slave;
show tables like 't2';
Tables_in_test (t2)
connection con2;
#cleanup
connection master;
SET DEBUG_SYNC= 'reset';
disconnect con1;
disconnect con2;
disconnect con3;
SET GLOBAL rpl_semi_sync_master_timeout= 10000;
SET GLOBAL rpl_semi_sync_master_enabled = 0;
DROP TABLE t1;
connection slave;
SET GLOBAL rpl_semi_sync_slave_enabled = 0;
stop slave;
start slave;
include/rpl_end.inc

View File

@ -4,6 +4,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");
@ -176,7 +177,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 14 Rpl_semi_sync_master_yes_tx 14
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value
Rpl_semi_sync_master_clients 1 Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ] [ semi-sync replication of these transactions will fail ]
insert into t1 values (500); insert into t1 values (500);
[ master status should be OFF ] [ master status should be OFF ]
@ -321,7 +322,6 @@ connection slave;
include/stop_slave.inc include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
kill query _tid;
connection slave; connection slave;
include/start_slave.inc include/start_slave.inc
connection master; connection master;
@ -353,7 +353,6 @@ include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
reset master; reset master;
kill query _tid;
set sql_log_bin=0; set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges; flush privileges;
@ -404,7 +403,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value Variable_name Value
Rpl_semi_sync_slave_status OFF Rpl_semi_sync_slave_status OFF
connection master; connection master;
kill query _tid;
[ Semi-sync status on master should be ON ] [ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value

View File

@ -5,6 +5,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");
@ -177,7 +178,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 16 Rpl_semi_sync_master_yes_tx 16
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value
Rpl_semi_sync_master_clients 1 Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ] [ semi-sync replication of these transactions will fail ]
insert into t1 values (500); insert into t1 values (500);
[ master status should be OFF ] [ master status should be OFF ]
@ -322,7 +323,6 @@ connection slave;
include/stop_slave.inc include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
kill query _tid;
connection slave; connection slave;
include/start_slave.inc include/start_slave.inc
connection master; connection master;
@ -354,7 +354,6 @@ include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
reset master; reset master;
kill query _tid;
set sql_log_bin=0; set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges; flush privileges;
@ -405,7 +404,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value Variable_name Value
Rpl_semi_sync_slave_status OFF Rpl_semi_sync_slave_status OFF
connection master; connection master;
kill query _tid;
[ Semi-sync status on master should be ON ] [ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value

View File

@ -5,6 +5,7 @@ connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");
@ -177,7 +178,7 @@ Variable_name Value
Rpl_semi_sync_master_yes_tx 14 Rpl_semi_sync_master_yes_tx 14
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value
Rpl_semi_sync_master_clients 1 Rpl_semi_sync_master_clients 0
[ semi-sync replication of these transactions will fail ] [ semi-sync replication of these transactions will fail ]
insert into t1 values (500); insert into t1 values (500);
[ master status should be OFF ] [ master status should be OFF ]
@ -322,7 +323,6 @@ connection slave;
include/stop_slave.inc include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
kill query _tid;
connection slave; connection slave;
include/start_slave.inc include/start_slave.inc
connection master; connection master;
@ -354,7 +354,6 @@ include/stop_slave.inc
reset slave; reset slave;
connection master; connection master;
reset master; reset master;
kill query _tid;
set sql_log_bin=0; set sql_log_bin=0;
grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password';
flush privileges; flush privileges;
@ -405,7 +404,6 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
Variable_name Value Variable_name Value
Rpl_semi_sync_slave_status OFF Rpl_semi_sync_slave_status OFF
connection master; connection master;
kill query _tid;
[ Semi-sync status on master should be ON ] [ Semi-sync status on master should be ON ]
show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_clients';
Variable_name Value Variable_name Value

View File

@ -5,6 +5,7 @@ call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); call mtr.add_suppression("Semi-sync master .* waiting for slave reply");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");

View File

@ -6,6 +6,7 @@ call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); call mtr.add_suppression("Semi-sync master .* waiting for slave reply");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");

View File

@ -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

View File

@ -1 +0,0 @@
--plugin-maturity=unknown

View File

@ -0,0 +1 @@
--binlog_format=row

View File

@ -0,0 +1 @@
--binlog_format=row

View File

@ -0,0 +1,406 @@
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/master-slave.inc
CALL mtr.add_suppression("Failed to start semi-sync ACK receiver thread.*");
CALL mtr.add_suppression("Failed to register slave to semi-sync ACK receiver thread.*");
CALL mtr.add_suppression("Failed to stop ack receiver thread on pthread_join.*");
CALL mtr.add_suppression("Got an error reading communication packets:*");
CALL mtr.add_suppression("Timeout waiting for reply of binlog*");
CALL mtr.add_suppression("slave_read_sync_header*");
CALL mtr.add_suppression("Missing magic number for semi-sync*");
CALL mtr.add_suppression("Got timeout reading communication packets*");
CALL mtr.add_suppression("Failed to call*");
CALL mtr.add_suppression("Execution failed on master*");
CALL mtr.add_suppression("Failed on request_dump()*");
CALL mtr.add_suppression("Semi-sync master failed on*");
CALL mtr.add_suppression("Master command COM_BINLOG_DUMP failed*");
CALL mtr.add_suppression("on master failed*");
CALL mtr.add_suppression("Master server does not support semi-sync*");
CALL mtr.add_suppression("Semi-sync slave net_flush*");
CALL mtr.add_suppression("Failed to flush master info*");
CALL mtr.add_suppression("Request to stop slave SQL Thread received while apply*");
connection master;
echo [ enable semi-sync on master ];
set global rpl_semi_sync_master_enabled = 1;
show variables like 'rpl_semi_sync_master_enabled';
connection slave;
echo [ enable semi-sync on slave ];
stop slave;
set global rpl_semi_sync_slave_enabled = 1;
start slave;
show status like 'rpl_semi_sync_slave%';
connection master;
CREATE TABLE t1(a INT) ENGINE=InnoDB;
sync_slave_with_master;
connection master;
connect(con1,localhost,root,,);
connect(con2,localhost,root,,);
connect(con3,localhost,root,,);
show status like 'Rpl_semi_sync_master_clients';
show status like "rpl_semi_sync_master_yes_tx";
--echo #########################################
--echo # Test rpl_semi_sync_master_wait_point #
--echo #########################################
--echo # Test after_sync and after_commit first.
--echo #Test after_sync
connection con1;
# Let's set a very large timeout value for testing purpose.
SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_SYNC';
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL after_sync_done WAIT_FOR end";
--send INSERT into t1 values (1);
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR after_sync_done";
sync_slave_with_master;
--echo #slave can see record (1) after sync slave with master
select * from t1;
connection con2;
--echo #con2 shouldn't see record (1)
select * from t1;
SET DEBUG_SYNC= "now SIGNAL end";
connection con1;
reap;
connection con1;
select * from t1;
truncate table t1;
sync_slave_with_master;
# Test more threads in one semisync queue
connection con1;
SET DEBUG_SYNC= 'reset';
SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR more_queue";
#SET DEBUG_SYNC= "before_semisync_fetch SIGNAL before_fetch_done WAIT_FOR more_queue";
--send INSERT into t1 VALUES (1);
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
SET DEBUG_SYNC= "after_semisync_queue SIGNAL more_queue";
INSERT INTO t1 VALUES (2);
connection con1;
reap;
# Test more threads in one semisync queue, but disable semisync before
# waiting.
connection con1;
SET DEBUG_SYNC= 'reset';
SET DEBUG_SYNC= "commit_before_get_LOCK_log SIGNAL before_fetch_done WAIT_FOR disable_semisync";
#SET DEBUG_SYNC= "before_semisync_fetch SIGNAL before_fetch_done WAIT_FOR more_queue";
#SET DEBUG_SYNC= "before_semisync_fetch SIGNAL before_fetch_done WAIT_FOR disable_semisync";
--send INSERT into t1 VALUES (3);
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR before_fetch_done";
SET GLOBAL rpl_semi_sync_master_enabled= 0;
SET DEBUG_SYNC= "now SIGNAL disable_semisync";
connection con1;
reap;
SET GLOBAL rpl_semi_sync_master_enabled = 1;
show status like 'Rpl_semi_sync_master_clients';
--echo #Test after_commit
connection con1;
SET GLOBAL rpl_semi_sync_master_wait_point= 'AFTER_COMMIT';
SET DEBUG_SYNC= "after_group_after_commit SIGNAL after_commit_done WAIT_FOR end";
--send INSERT into t1 values (4);
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR after_commit_done";
sync_slave_with_master;
select * from t1;
connection con2;
select * from t1;
SET DEBUG_SYNC= "now SIGNAL end";
connection con1;
reap;
connection con1;
select * from t1;
truncate table t1;
--echo #######################################################
--echo # Test some other options in order to cover the patch #
--echo #######################################################
connection slave;
--echo # Test rpl_semi_sync_slave_trace_level
SET GLOBAL rpl_semi_sync_slave_trace_level= 1;
SET GLOBAL rpl_semi_sync_slave_trace_level= 16;
SET GLOBAL rpl_semi_sync_slave_trace_level= 64;
SET GLOBAL rpl_semi_sync_slave_trace_level= 128;
SET GLOBAL rpl_semi_sync_slave_trace_level= 32;
connection master;
--echo # Test rpl_semi_sync_master_trace_level
SET GLOBAL rpl_semi_sync_master_trace_level= 1;
SET GLOBAL rpl_semi_sync_master_trace_level= 16;
SET GLOBAL rpl_semi_sync_master_trace_level= 64;
SET GLOBAL rpl_semi_sync_master_trace_level= 128;
SET GLOBAL rpl_semi_sync_master_trace_level= 32;
--echo # Test rpl_semi_sync_master_timeout
SET GLOBAL rpl_semi_sync_master_timeout= 1000;
SET GLOBAL rpl_semi_sync_master_timeout= 10000;
SET GLOBAL rpl_semi_sync_master_timeout = 1000000;
--echo # Test rpl_semi_sync_slave_kill_conn_timeout
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 10;
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 20;
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 60;
SET GLOBAL rpl_semi_sync_slave_kill_conn_timeout= 5;
--echo ############################################
--echo # Test rpl_semi_sync_master_wait_no_slave #
--echo ############################################
SET GLOBAL rpl_semi_sync_master_wait_no_slave = 1;
connection slave;
STOP SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_stop.inc
connection con1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;
--send INSERT INTO t1 values (1);
connection con1;
reap;
echo # Rpl_semi_sync_master_no_tx should be non-zero
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';
# test rpl_semi_sync_master_wait_no_slave = 0
connection slave;
START SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_start.inc
connection con1;
INSERT INTO t1 values (2);
sync_slave_with_master;
connection con1;
show status like 'Rpl_semi_sync_master_clients';
show status like 'Rpl_semi_sync_master_status';
connection slave;
STOP SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_stop.inc
connection con1;
SET GLOBAL rpl_semi_sync_master_wait_no_slave= 0;
SET GLOBAL rpl_semi_sync_master_timeout= 1000000000;
INSERT INTO t1 values (3);
show status like 'Rpl_semi_sync_master_clients';
show status like 'Rpl_semi_sync_master_status';
connection slave;
START SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_start.inc
connection con1;
SET GLOBAL rpl_semi_sync_master_timeout= 10000000;
SET GLOBAL rpl_semi_sync_master_wait_no_slave= 1;
INSERT INTO t1 values (4);
sync_slave_with_master;
connection con1;
show status like 'Rpl_semi_sync_master_status';
show status like 'Rpl_semi_sync_master_clients';
--echo ##########################################
--echo # Test rpl_semi_sync_slave_delay_master #
--echo ##########################################
connection slave;
SET GLOBAL rpl_semi_sync_slave_delay_master= 1;
START SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_start.inc
connection con1;
INSERT INTO t1 values (3);
--source include/sync_slave_io_with_master.inc
connection con1;
show status like 'Rpl_semi_sync_master_clients';
show status like 'Rpl_semi_sync_master_status';
sync_slave_with_master;
connection slave;
select * from t1 order by a;
connection con1;
select * from t1 order by a;
connection slave;
SET GLOBAL rpl_semi_sync_slave_delay_master = 0;
STOP SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_stop.inc
START SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_start.inc
--echo ##########################################################
--echo # Test rpl_semi_sync_master_enabled and new ACK thread #
--echo #########################################################
connection con1;
SET GLOBAL rpl_semi_sync_master_enabled = 0;
show status like 'Rpl_semi_sync_master_clients';
INSERT INTO t1 VALUES (1);
SET GLOBAL rpl_semi_sync_master_enabled = 1;
INSERT INTO t1 VALUES (2);
show status like 'Rpl_semi_sync_master_clients';
--echo # Test failure of select error .
SET GLOBAL debug = 'd,rpl_semisync_simulate_select_error';
# It can still receive ACK from semi-sync slave
INSERT INTO t1 VALUES(3);
sync_slave_with_master;
connection con1;
--echo # Test failure of pthread_create
SET GLOBAL rpl_semi_sync_master_enabled = 0;
SET GLOBAL debug = 'd,rpl_semisync_simulate_create_thread_failure';
SET GLOBAL rpl_semi_sync_master_enabled= ON;
--let $wait_condition= SELECT @@global.rpl_semi_sync_master_enabled = 0
--source include/wait_condition.inc
# Todo: implement the thread join failure simulation
--echo # Test failure of pthread_join
#SET GLOBAL DEBUG = 'd,rpl_semisync_simulate_thread_join_failure';
#SET GLOBAL rpl_semi_sync_master_enabled= ON;
#
#--let $wait_condition= SELECT @@global.rpl_semi_sync_master_enabled = 0
#--source include/wait_condition.inc
SET GLOBAL rpl_semi_sync_master_enabled= OFF;
--echo #
--echo # Failure on registering semisync slave
--echo #
SET GLOBAL debug= 'd,rpl_semisync_simulate_add_slave_failure';
SET GLOBAL rpl_semi_sync_master_enabled= ON;
connection slave;
STOP SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_stop.inc
START SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_start.inc
connection con1;
#--echo # Should be Zero.
# Todo: implement the add_slave_failure simulation. Meanwhile
# the status will be 1.
# show status like 'Rpl_semi_sync_master_clients';
SET GLOBAL debug='';
--let $status_var= Rpl_semi_sync_master_clients
--let $status_var_value= 1
--let $status_type= GLOBAL
--source include/wait_for_status_var.inc
connection slave;
--disable_warnings
START SLAVE IO_THREAD;
--source include/wait_for_slave_io_to_start.inc
--enable_warnings
connection con1;
sync_slave_with_master;
show status like 'Rpl_semi_sync_master_clients';
--echo ##################################################################
--echo # Test fixing of BUG#70669 #
--echo #SLAVE CAN'T CONTINUE REPLICATION AFTER MASTER'S CRASH RECOVERY #
--echo #################################################################
connection con1;
SET GLOBAL sync_binlog = 1;
CREATE TABLE t2 (c1 INT);
sync_slave_with_master;
connection con1;
# Block the session before its events are synced to disk
#SET DEBUG_SYNC = 'before_sync_binlog_file SIGNAL before_sync_done WAIT_FOR continue';
send INSERT INTO t2 values (1);
connection slave;
--let $table= t2
--let $count= 1
--source include/wait_until_rows_count.inc
connection con2;
#SET DEBUG_SYNC= "now WAIT_FOR before_sync_done";
#SET DEBUG_SYNC = "now SIGNAL continue";
connection con1;
reap;
sync_slave_with_master;
show tables like 't2';
select * from t2;
connection con1;
#SET DEBUG_SYNC= "before_update_pos SIGNAL leader_ready WAIT_FOR follower_ready";
send INSERT INTO t2 VALUES (2);
connection con2;
#SET DEBUG_SYNC= "now WAIT_FOR leader_ready";
#SET DEBUG_SYNC= "after_sync_queue SIGNAL follower_ready";
send INSERT INTO t2 VALUES (3);
connection con1;
reap;
connection con2;
reap;
connection con1;
#SET DEBUG_SYNC = 'before_sync_binlog_file SIGNAL before_sync_done WAIT_FOR continue';
SET GLOBAL sync_binlog = 0;
# Todo: fix this simulation and implement the intended sync protocol.
# As a workaround the DROP sender explicitly okays
# which naturally increments the binlog position.
#send DROP TABLE t2;
DROP TABLE t2;
connection con2;
#SET DEBUG_SYNC= "now WAIT_FOR before_sync_done";
sync_slave_with_master;
# t2 should be dropped
show tables like 't2';
connection con2;
#SET DEBUG_SYNC = "now SIGNAL continue";
# This block is commented out on purpose. See the todo/workaround above.
#connection con1;
#reap;
--echo #cleanup
connection master;
SET DEBUG_SYNC= 'reset';
disconnect con1;
disconnect con2;
disconnect con3;
SET GLOBAL rpl_semi_sync_master_timeout= 10000;
SET GLOBAL rpl_semi_sync_master_enabled = 0;
DROP TABLE t1;
connection slave;
SET GLOBAL rpl_semi_sync_slave_enabled = 0;
stop slave;start slave;
--source include/rpl_end.inc

View File

@ -1,4 +1,3 @@
--source include/have_semisync.inc
--source include/not_embedded.inc --source include/not_embedded.inc
--source include/have_debug_sync.inc --source include/have_debug_sync.inc
--source include/have_binlog_format_mixed_or_statement.inc --source include/have_binlog_format_mixed_or_statement.inc

View File

@ -1,4 +1,3 @@
source include/have_semisync.inc;
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_innodb.inc; source include/have_innodb.inc;
source include/master-slave.inc; source include/master-slave.inc;
@ -11,6 +10,8 @@ call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); call mtr.add_suppression("Semi-sync master .* waiting for slave reply");
call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
call mtr.add_suppression("mysqld: Got an error reading communication packets");
connection slave; connection slave;
call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Semi-sync slave .* reply");

View File

@ -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;

View File

@ -1,4 +1,3 @@
source include/have_semisync.inc;
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_innodb.inc; source include/have_innodb.inc;

View File

@ -1,4 +1,3 @@
--source include/have_semisync.inc
--source include/master-slave.inc --source include/master-slave.inc
call mtr.add_suppression("Timeout waiting for reply of binlog*"); call mtr.add_suppression("Timeout waiting for reply of binlog*");

View File

@ -1,7 +1,6 @@
# #
# MDEV-4066 semisync_master + temporary tables causes memory leaks # MDEV-4066 semisync_master + temporary tables causes memory leaks
# #
source include/have_semisync.inc;
source include/have_binlog_format_row.inc; source include/have_binlog_format_row.inc;
source include/master-slave.inc; source include/master-slave.inc;

View File

@ -65,6 +65,12 @@ set global rpl_semi_sync_master_enabled=1e1;
ERROR 42000: Incorrect argument type to variable 'rpl_semi_sync_master_enabled' ERROR 42000: Incorrect argument type to variable 'rpl_semi_sync_master_enabled'
set global rpl_semi_sync_master_enabled="some text"; set global rpl_semi_sync_master_enabled="some text";
ERROR 42000: Variable 'rpl_semi_sync_master_enabled' can't be set to the value of 'some text' ERROR 42000: Variable 'rpl_semi_sync_master_enabled' can't be set to the value of 'some text'
connect con1,localhost,root,,;
connect con2,localhost,root,,;
disconnect con1;
disconnect con2;
connection default;
SET @@global.rpl_semi_sync_master_enabled = 1;
SET @@global.rpl_semi_sync_master_enabled = @start_global_value; SET @@global.rpl_semi_sync_master_enabled = @start_global_value;
select @@global.rpl_semi_sync_master_enabled; select @@global.rpl_semi_sync_master_enabled;
@@global.rpl_semi_sync_master_enabled @@global.rpl_semi_sync_master_enabled

View File

@ -1,5 +1,5 @@
--- sysvars_server_notembedded.result 2017-11-17 17:00:22.470630255 +0100 --- sysvars_server_notembedded.result 2017-12-15 20:57:40.174654761 +0200
+++ sysvars_server_notembedded,32bit.reject 2017-11-17 19:12:42.732453556 +0100 +++ sysvars_server_notembedded,32bit.reject 2017-12-15 21:02:20.476044700 +0200
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
GLOBAL_VALUE_ORIGIN CONFIG GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1 DEFAULT_VALUE 1
@ -1116,7 +1116,46 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -4048,7 +4048,7 @@ @@ -4034,10 +4034,10 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10000
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT The timeout value (in ms) for semi-synchronous replication in the master
NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
@@ -4048,10 +4048,10 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT The tracing level for semi-sync replication.
NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
@@ -4132,10 +4132,10 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 32
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT The tracing level for semi-sync replication.
NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
@@ -4174,7 +4174,7 @@
GLOBAL_VALUE_ORIGIN CONFIG GLOBAL_VALUE_ORIGIN CONFIG
DEFAULT_VALUE 1 DEFAULT_VALUE 1
VARIABLE_SCOPE SESSION VARIABLE_SCOPE SESSION
@ -1125,7 +1164,7 @@
VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners
NUMERIC_MIN_VALUE 1 NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 4294967295 NUMERIC_MAX_VALUE 4294967295
@@ -4230,7 +4230,7 @@ @@ -4356,7 +4356,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0 DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1134,7 +1173,7 @@
VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads. VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads.
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383 NUMERIC_MAX_VALUE 16383
@@ -4272,7 +4272,7 @@ @@ -4398,7 +4398,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 1073741824 DEFAULT_VALUE 1073741824
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1143,7 +1182,7 @@
VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave.
NUMERIC_MIN_VALUE 1024 NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 1073741824 NUMERIC_MAX_VALUE 1073741824
@@ -4300,7 +4300,7 @@ @@ -4426,7 +4426,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 131072 DEFAULT_VALUE 131072
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1152,7 +1191,7 @@
VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0. VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0.
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 2147483647 NUMERIC_MAX_VALUE 2147483647
@@ -4328,7 +4328,7 @@ @@ -4454,7 +4454,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0 DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1161,7 +1200,7 @@
VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383 NUMERIC_MAX_VALUE 16383
@@ -4342,7 +4342,7 @@ @@ -4468,7 +4468,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0 DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1170,7 +1209,7 @@
VARIABLE_COMMENT Alias for slave_parallel_threads VARIABLE_COMMENT Alias for slave_parallel_threads
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16383 NUMERIC_MAX_VALUE 16383
@@ -4398,7 +4398,7 @@ @@ -4524,7 +4524,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10 DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1179,7 +1218,7 @@
VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295 NUMERIC_MAX_VALUE 4294967295
@@ -4426,7 +4426,7 @@ @@ -4552,7 +4552,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 0 DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1188,7 +1227,7 @@
VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 3600 NUMERIC_MAX_VALUE 3600
@@ -4257,7 +4257,7 @@ @@ -4580,7 +4580,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2 DEFAULT_VALUE 2
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1197,7 +1236,7 @@
VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 31536000 NUMERIC_MAX_VALUE 31536000
@@ -4316,7 +4316,7 @@ @@ -4639,7 +4639,7 @@
VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size
NUMERIC_MIN_VALUE 1024 NUMERIC_MIN_VALUE 1024
@ -1206,7 +1245,7 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -4621,7 +4621,7 @@ @@ -4944,7 +4944,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 256 DEFAULT_VALUE 256
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1215,7 +1254,7 @@
VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection.
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 524288 NUMERIC_MAX_VALUE 524288
@@ -4719,7 +4719,7 @@ @@ -5042,7 +5042,7 @@
GLOBAL_VALUE_ORIGIN AUTO GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 400 DEFAULT_VALUE 400
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1224,7 +1263,7 @@
VARIABLE_COMMENT The number of cached table definitions VARIABLE_COMMENT The number of cached table definitions
NUMERIC_MIN_VALUE 400 NUMERIC_MIN_VALUE 400
NUMERIC_MAX_VALUE 524288 NUMERIC_MAX_VALUE 524288
@@ -4733,7 +4733,7 @@ @@ -5056,7 +5056,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 2000 DEFAULT_VALUE 2000
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1233,7 +1272,7 @@
VARIABLE_COMMENT The number of cached open tables VARIABLE_COMMENT The number of cached open tables
NUMERIC_MIN_VALUE 1 NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1048576 NUMERIC_MAX_VALUE 1048576
@@ -4761,7 +4761,7 @@ @@ -5126,7 +5126,7 @@
GLOBAL_VALUE_ORIGIN AUTO GLOBAL_VALUE_ORIGIN AUTO
DEFAULT_VALUE 256 DEFAULT_VALUE 256
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1242,7 +1281,7 @@
VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16384 NUMERIC_MAX_VALUE 16384
@@ -4775,7 +4775,7 @@ @@ -5140,7 +5140,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 10 DEFAULT_VALUE 10
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1251,7 +1290,7 @@
VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release. VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release.
NUMERIC_MIN_VALUE 1 NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 512 NUMERIC_MAX_VALUE 512
@@ -4980,15 +4980,15 @@ @@ -5345,15 +5345,15 @@
READ_ONLY YES READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME TMP_DISK_TABLE_SIZE VARIABLE_NAME TMP_DISK_TABLE_SIZE
@ -1271,7 +1310,7 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -5002,7 +5002,7 @@ @@ -5367,7 +5367,7 @@
VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size. VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
NUMERIC_MIN_VALUE 1024 NUMERIC_MIN_VALUE 1024
@ -1280,7 +1319,7 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -5016,7 +5016,7 @@ @@ -5381,7 +5381,7 @@
VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table.
NUMERIC_MIN_VALUE 1024 NUMERIC_MIN_VALUE 1024
@ -1289,7 +1328,7 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -5027,7 +5027,7 @@ @@ -5392,7 +5392,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 8192 DEFAULT_VALUE 8192
VARIABLE_SCOPE SESSION VARIABLE_SCOPE SESSION
@ -1298,7 +1337,7 @@
VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024 NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728 NUMERIC_MAX_VALUE 134217728
@@ -5041,7 +5041,7 @@ @@ -5406,7 +5406,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 4096 DEFAULT_VALUE 4096
VARIABLE_SCOPE SESSION VARIABLE_SCOPE SESSION
@ -1307,7 +1346,7 @@
VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log
NUMERIC_MIN_VALUE 1024 NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 134217728 NUMERIC_MAX_VALUE 134217728
@@ -5139,7 +5139,7 @@ @@ -5504,7 +5504,7 @@
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 28800 DEFAULT_VALUE 28800
VARIABLE_SCOPE SESSION VARIABLE_SCOPE SESSION
@ -1316,7 +1355,7 @@
VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it
NUMERIC_MIN_VALUE 1 NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 31536000 NUMERIC_MAX_VALUE 31536000
@@ -5243,7 +5243,7 @@ @@ -5609,7 +5609,7 @@
COMMAND_LINE_ARGUMENT OPTIONAL COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME OPEN_FILES_LIMIT VARIABLE_NAME OPEN_FILES_LIMIT
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
@ -1325,7 +1364,7 @@
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295 NUMERIC_MAX_VALUE 4294967295
@@ -5256,7 +5256,7 @@ @@ -5622,7 +5622,7 @@
VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
@ -1334,7 +1373,7 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -5266,7 +5266,7 @@ @@ -5632,7 +5632,7 @@
VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes
NUMERIC_MIN_VALUE 0 NUMERIC_MIN_VALUE 0
@ -1343,7 +1382,7 @@
NUMERIC_BLOCK_SIZE 1 NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
@@ -5351,7 +5351,7 @@ @@ -5727,7 +5727,7 @@
VARIABLE_NAME LOG_TC_SIZE VARIABLE_NAME LOG_TC_SIZE
GLOBAL_VALUE_ORIGIN AUTO GLOBAL_VALUE_ORIGIN AUTO
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL

View File

@ -4001,6 +4001,132 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED 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_DELAY_MASTER
SESSION_VALUE NULL
GLOBAL_VALUE OFF
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT Only write master info file when ack is needed.
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_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_KILL_CONN_TIMEOUT
SESSION_VALUE NULL
GLOBAL_VALUE 5
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 5
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT 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.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
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 VARIABLE_NAME SECURE_AUTH
SESSION_VALUE NULL SESSION_VALUE NULL
GLOBAL_VALUE ON GLOBAL_VALUE ON

View File

@ -6,7 +6,6 @@
# #
# #
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_enabled; select @@global.rpl_semi_sync_master_enabled;
SET @start_global_value = @@global.rpl_semi_sync_master_enabled; SET @start_global_value = @@global.rpl_semi_sync_master_enabled;
@ -52,6 +51,35 @@ set global rpl_semi_sync_master_enabled=1e1;
--error ER_WRONG_VALUE_FOR_VAR --error ER_WRONG_VALUE_FOR_VAR
set global rpl_semi_sync_master_enabled="some text"; set global rpl_semi_sync_master_enabled="some text";
#
# Test conflicting concurrent setting
#
--let $val_saved= `SELECT @@global.rpl_semi_sync_master_enabled`
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
--let $iter=100
--disable_query_log
while ($iter)
{
--connection con1
--send_eval SET @@global.rpl_semi_sync_master_enabled = $iter % 2
--connection con2
--send_eval SET @@global.rpl_semi_sync_master_enabled = ($iter + 1) % 2
--connection con1
reap;
--connection con2
reap;
--dec $iter
}
--enable_query_log
disconnect con1;
disconnect con2;
--connection default
--eval SET @@global.rpl_semi_sync_master_enabled = $val_saved
# #
# Cleanup # Cleanup

View File

@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added # 2010-01-21 OBN - Added
# #
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_timeout; select @@global.rpl_semi_sync_master_timeout;
SET @start_global_value = @@global.rpl_semi_sync_master_timeout; SET @start_global_value = @@global.rpl_semi_sync_master_timeout;

View File

@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added # 2010-01-21 OBN - Added
# #
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_trace_level; select @@global.rpl_semi_sync_master_trace_level;
SET @start_global_value = @@global.rpl_semi_sync_master_trace_level; SET @start_global_value = @@global.rpl_semi_sync_master_trace_level;

View File

@ -6,7 +6,6 @@
# #
# #
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_wait_no_slave; select @@global.rpl_semi_sync_master_wait_no_slave;
SET @start_global_value = @@global.rpl_semi_sync_master_wait_no_slave; SET @start_global_value = @@global.rpl_semi_sync_master_wait_no_slave;

View File

@ -1,5 +1,4 @@
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_master_wait_point; select @@global.rpl_semi_sync_master_wait_point;
SET @start_global_value = @@global.rpl_semi_sync_master_wait_point; SET @start_global_value = @@global.rpl_semi_sync_master_wait_point;

View File

@ -6,7 +6,6 @@
# #
# #
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_slave_enabled; select @@global.rpl_semi_sync_slave_enabled;
SET @start_global_value = @@global.rpl_semi_sync_slave_enabled; SET @start_global_value = @@global.rpl_semi_sync_slave_enabled;

View File

@ -5,7 +5,6 @@
# 2010-01-21 OBN - Added # 2010-01-21 OBN - Added
# #
source include/not_embedded.inc; source include/not_embedded.inc;
source include/have_semisync.inc;
select @@global.rpl_semi_sync_slave_trace_level; select @@global.rpl_semi_sync_slave_trace_level;
SET @start_global_value = @@global.rpl_semi_sync_slave_trace_level; SET @start_global_value = @@global.rpl_semi_sync_slave_trace_level;

View File

@ -72,5 +72,25 @@ SELECT * FROM t2;
#Cleanup #Cleanup
DROP TABLE t1, t2; DROP TABLE t1, t2;
# MDEV-14593 human-readable XA RECOVER
create table t1 (a int);
--write_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql
DELIMITER /
XA START 'tr1', 'bq'/
INSERT INTO t1 VALUES (0)/
XA END 'tr1', 'bq'/
XA PREPARE 'tr1', 'bq'/
XA RECOVER/
XA ROLLBACK 'tr1', 'bq'/
EOF
--exec $MYSQL test --binary-as-hex < $MYSQLTEST_VARDIR/tmp/mdev-14593.sql 2>&1
remove_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql;
#Cleanup
DROP TABLE t1;
# Wait till all disconnects are completed # Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc

View File

@ -1948,6 +1948,57 @@ cte2 as (
SELECT * SELECT *
FROM cte1; FROM cte1;
--echo #
--echo # mdev-14629: a user-defined variable is defined by the recursive CTE
--echo #
set @var=
(
with recursive cte_tab(a) as (
select 1
union
select a+1 from cte_tab
where a<3)
select count(*) from cte_tab
);
select @var;
create table t1(a int, b int);
insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
set @var=
(
with recursive summ(a,s) as (
select 1, 0 union
select t1.b, t1.b+summ.s from summ, t1
where summ.a=t1.a)
select s from summ
order by a desc
limit 1
);
select @var;
--ERROR ER_UNACCEPTABLE_MUTUAL_RECURSION
set @var=
(
with recursive
cte_1 as (
select 1
union
select * from cte_2),
cte_2 as (
select * from cte_1
union
select a from t1, cte_2
where t1.a=cte_2.a)
select * from cte_2
limit 1
);
drop table t1;
--echo # --echo #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field --echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
--echo # --echo #
@ -1975,4 +2026,3 @@ DROP TABLE a_tbl;
--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT --error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x; WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;

View File

@ -873,11 +873,585 @@ eval $no_pushdown $query;
eval $query; eval $query;
eval explain $query; eval explain $query;
eval explain format=json $query; eval explain format=json $query;
drop view v1,v2,v3,v4; drop view v1,v2,v3,v4;
drop view v_union,v2_union,v3_union,v4_union; drop view v_union,v2_union,v3_union,v4_union;
drop view v_double,v_char,v_decimal; drop view v_double,v_char,v_decimal;
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal; drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
--echo #
--echo # MDEV-14579: pushdown conditions into materialized views/derived tables
--echo # that are defined with EXIST or/and INTERSECT
--echo #
create table t1 (a int, b int, c int);
create table t2 (a int, b int, c int);
insert into t1 values
(1,21,345), (1,33,7), (8,33,114), (1,21,500), (1,19,117), (5,14,787),
(8,33,123), (9,10,211), (5,16,207), (1,33,988), (5,27,132), (1,21,104),
(6,20,309), (6,20,315), (1,21,101), (4,33,404), (9,10,800), (1,21,123);
insert into t2 values
(2,3,207), (1,16,909), (5,14,312),
(5,33,207), (6,20,211), (1,19,132),
(8,33,117), (3,21,231), (6,23,303);
create view v1 as
select a, b, min(c) as c from t1
where t1.a<9 group by a,b having c < 300
intersect
select a, b, min(c) as c from t1
where t1.b>10 group by a,b having c > 100;
--echo # using intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE
--echo # pushing equalities
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a=8);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE using equalities
let $query= select * from v1,t2 where (v1.a=t2.a) and (t2.a=8);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # conjunctive subformulas : pushing into HAVING
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.c>200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE
--echo # conjunctive subformulas : pushing into HAVING
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # extracted or formula : pushing into WHERE
let $query=
select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # extracted or formula : pushing into HAVING
let $query=
select * from v1,t2 where
(v1.a=t2.a) and ((v1.c>200) or (v1.c<105));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # extracted or formula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING using equalities
--echo # pushing equalities
let $query=
select * from v1,t2 where
((v1.a>3) and (t2.c>110) and (v1.c=t2.c)) or
((v1.a=1) and (v1.c<110));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using intersect in view definition
--echo # prepare of a query
--echo # conjunctive subformulas : pushing into WHERE
--echo # conjunctive subformulas : pushing into HAVING
prepare stmt from "select * from v1,t2
where (v1.a=t2.a) and (v1.a<5) and (v1.c>110);";
execute stmt;
execute stmt;
deallocate prepare stmt;
--echo # using intersect in derived table definition
--echo # extracted or formula : pushing into WHERE using equalities
--echo # extracted or formula : pushing into HAVING
--echo # pushing equalities
let $query=
select *
from t2,
(select a, b, min(c) as c from t1
where t1.a<9 group by a,b having c < 300
intersect
select a, b, min(c) as c from t1
where t1.b>10 group by a,b having c > 100) as d1
where
(d1.b=t2.b) and
(((t2.b>13) and (t2.c=909)) or
((d1.a<4) and (d1.c<200)));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
create view v1 as
select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 200
except
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300;
--echo # using except in view definition
--echo # conjunctive subformulas : pushing into WHERE
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # conjunctive subformulas : pushing into WHERE
--echo # pushing equalities
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a=6);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # conjunctive subformulas : pushing into WHERE using equalities
let $query= select * from v1,t2 where (v1.a=t2.a) and (t2.a=6);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # conjunctive subformulas : pushing into HAVING
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.c>500);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # conjunctive subformulas : pushing into WHERE
--echo # conjunctive subformulas : pushing into HAVING
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # extracted or formula : pushing into WHERE
let $query=
select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # extracted or formula : pushing into HAVING
let $query=
select * from v1,t2 where
(v1.a=t2.a) and ((v1.c<400) or (v1.c>800));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # extracted or formula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING using equalities
--echo # pushing equalities
let $query=
select * from v1,t2 where
(v1.c=t2.c) and
((v1.a>1) and (t2.c<500)) or
((v1.a=1) and (v1.c>500));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
--echo # using except in view definition
--echo # prepare of a query
--echo # conjunctive subformulas : pushing into WHERE
--echo # conjunctive subformulas : pushing into HAVING
prepare stmt from "select * from v1,t2
where (v1.a=t2.a) and (v1.a<5) and (v1.c>500);";
execute stmt;
execute stmt;
deallocate prepare stmt;
--echo # using except in view definition
--echo # extracted or formula : pushing into WHERE using equalities
--echo # extracted or formula : pushing into HAVING
--echo # pushing equalities
let $query=
select *
from t2,
(select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 200
except
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300) as d1
where
(d1.b=t2.b) and
(((t2.b>13) and (t2.c=988)) or
((d1.a>4) and (d1.c>500)));
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union and intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, min(c) as c from t1
where t1.a<9 group by a,b having c > 200
union
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
intersect
select a, b, max(c) as c from t1
where t1.a>3 group by a,b having c < 530;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union and intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, min(c) as c from t1
where t1.a<9 group by a,b having c > 200
intersect
select a, b, max(c) as c from t1
where t1.a>3 group by a,b having c < 500
union
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union and except in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, min(c) as c from t1
where t1.a<9 group by a,b having c > 200
union
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
except
select a, b, max(c) as c from t1
where t1.a>3 group by a,b having c < 530;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union and except in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, min(c) as c from t1
where t1.a<9 group by a,b having c > 200
except
select a, b, max(c) as c from t1
where t1.a>3 group by a,b having c < 500
union
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using except and intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
intersect
select a, b, max(c) as c from t1
where t1.a<7 group by a,b having c < 500
except
select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 150;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using except and intersect in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
except
select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 150
intersect
select a, b, max(c) as c from t1
where t1.a<7 group by a,b having c < 500;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using except, intersect and union in view definition
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
except
select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 150
intersect
select a, b, max(c) as c from t1
where t1.a<7 group by a,b having c < 500
union
select a, b, max(c) as c from t1
where t1.a<7 group by a,b having c < 120;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using intersect in view definition
--echo # using embedded view
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
intersect
select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 120;
create view v2 as
select a, b, max(c) as c from v1
where v1.a<7 group by a,b;
let $query= select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1,v2;
--echo # using except in view definition
--echo # using embedded view
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c < 300
except
select a, b, max(c) as c from t1
where t1.a<9 group by a,b having c > 150;
create view v2 as
select a, b, max(c) as c from v1
where v1.a<7 group by a,b;
let $query= select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1,v2;
--echo # using intersect in view definition
--echo # conditions are pushed in different parts of selects
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.a<9 group by a having c > 300
intersect
select a, b, max(c) as c from t1
where t1.b<21 group by b having c > 200;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using except in view definition
--echo # conditions are pushed in different parts of selects
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>20 group by a having c > 300
except
select a, b, max(c) as c from t1
where t1.a<7 group by b having c > 150;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using except and union in view definition
--echo # conditions are pushed in different parts of selects
--echo # conjunctive subformulas : pushing into HAVING
--echo # extracted or formula : pushing into WHERE
--echo # extracted or formula : pushing into HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.b>20 group by a having c > 300
except
select a, b, max(c) as c from t1
where t1.a<7 group by b having c > 150;
let $query= select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union and intersect in view definition
--echo # conditions are pushed in different parts of selects
--echo # conjunctive subformulas : pushing into WHERE and HAVING
create view v1 as
select a, b, max(c) as c from t1
where t1.a<9 group by a having c > 100
intersect
select a, b, max(c) as c from t1
where t1.a>3 group by b having c < 800
union
select a, b, max(c) as c from t1
where t1.b>10 group by a,b having c > 300;
let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) and (v1.c>400);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
create table t3 (a int, b int, c int);
insert into t3 values
(1,21,345), (2,33,7), (8,33,114), (3,21,500), (1,19,107), (5,14,787),
(4,33,123), (9,10,211), (11,16,207), (10,33,988), (5,27,132), (12,21,104),
(6,20,309), (16,20,315), (16,21,101), (18,33,404), (19,10,800), (10,21,123),
(17,11,708), (6,20,214);
create index i1 on t3(a);
--echo # conjunctive subformulas : pushing into WHERE
--echo # pushed condition gives range access
create view v1 as
select a, b, max(c) as max_c from t3
where a>0 group by a;
let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<5);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union in view definition
--echo # conjunctive subformulas : pushing into WHERE
--echo # pushed condition gives range access
create view v1 as
select a, b, max(c) as c from t3
where t3.a>1 group by a
union
select a, b, max(c) as c from t3
where t3.a>2 group by a;
let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<4);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
--echo # using union in view definition
--echo # conjunctive subformulas : pushing into WHERE
--echo # pushed condition gives range access in one of the selects
create view v1 as
select a, b, max(c) as c from t3
where t3.a>1 group by a
union
select a, b, max(c) as c from t3
where t3.b<21 group by b;
let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<3);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
drop view v1;
alter table t3 drop index i1;
drop table t1,t2,t3;
--echo # --echo #
--echo # MDEV-10782: condition extracted from a multiple equality --echo # MDEV-10782: condition extracted from a multiple equality

View File

@ -30,7 +30,7 @@ perl;
feedback debug temp-pool ssl des-key-file xtradb sequence feedback debug temp-pool ssl des-key-file xtradb sequence
thread-concurrency super-large-pages mutex-deadlock-detector thread-concurrency super-large-pages mutex-deadlock-detector
connect null-audit aria oqgraph sphinx thread-handling 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 query-response-time metadata-lock-info locales unix-socket
wsrep file-key-management cracklib-password-check user-variables/; wsrep file-key-management cracklib-password-check user-variables/;

View File

@ -80,9 +80,57 @@ xa rollback 'testa','testb';
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
select * from t1; select * from t1;
disconnect con1; disconnect con1;
--source include/wait_until_count_sessions.inc
connection default; connection default;
# MDEV-14593 human-readable XA RECOVER
xa start 'tr1';
insert t1 values (40);
xa end 'tr1';
xa prepare 'tr1';
xa recover format='SQL';
xa rollback 'tr1';
xa start 'tr1', 'bq';
insert t1 values (40);
xa end 'tr1', 'bq';
xa prepare 'tr1', 'bq';
xa recover format='SQL';
xa rollback 'tr1', 'bq';
xa start 'tr1', 'bq', 3;
insert t1 values (40);
xa end 'tr1', 'bq', 3;
xa prepare 'tr1', 'bq', 3;
xa recover format='SQL';
xa rollback 'tr1', 'bq', 3;
xa start 'tr1#$';
insert t1 values (40);
xa end 'tr1#$';
xa prepare 'tr1#$';
xa recover format='SQL';
xa rollback 'tr1#$';
xa start 'tr1#$', 'bq';
insert t1 values (40);
xa end 'tr1#$', 'bq';
xa prepare 'tr1#$', 'bq';
xa recover format='SQL';
xa rollback 'tr1#$', 'bq';
xa start 'tr1#$', 'bq', 3;
insert t1 values (40);
xa end 'tr1#$', 'bq', 3;
xa prepare 'tr1#$', 'bq', 3;
xa recover format='RAW';
--error ER_UNKNOWN_EXPLAIN_FORMAT
xa recover format='PLAIN';
xa recover format='SQL';
xa rollback 'tr1#$', 'bq', 3;
drop table t1; drop table t1;
# #
@ -379,7 +427,6 @@ connection default;
DROP TABLE t1, t2; DROP TABLE t1, t2;
disconnect con2; disconnect con2;
# Wait till all disconnects are completed # Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc

View File

@ -36,7 +36,8 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c my_default.c
string.c thr_alarm.c thr_lock.c thr_mutex.c string.c thr_alarm.c thr_lock.c thr_mutex.c
thr_rwlock.c thr_timer.c thr_rwlock.c thr_timer.c
tree.c typelib.c base64.c my_memmem.c tree.c typelib.c base64.c my_memmem.c
my_getpagesize.c my_getpagesize.c
guess_malloc_library.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c lf_alloc-pin.c lf_dynarray.c lf_hash.c
safemalloc.c my_new.cc safemalloc.c my_new.cc
my_getncpus.c my_safehash.c my_chmod.c my_rnd.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c

View File

@ -0,0 +1,64 @@
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
Copyright (c) 2012, 2017, MariaDB Corporation.
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 */
/* guess_malloc_library() deduces, to the best of its ability,
the currently used malloc library and its version */
#include <stddef.h>
#include "my_global.h"
#include <m_string.h>
char *guess_malloc_library()
{
#ifndef HAVE_DLOPEN
return (char*) MALLOC_LIBRARY;
#else
static char buf[128];
if (strcmp(MALLOC_LIBRARY, "system") != 0)
{
return (char*) MALLOC_LIBRARY;
}
/* tcmalloc */
typedef const char* (*tc_version_type)(int*, int*, const char**);
tc_version_type tc_version_func =
(tc_version_type) dlsym(RTLD_DEFAULT, "tc_version");
if (tc_version_func)
{
int major, minor;
const char* ver_str = tc_version_func(&major, &minor, NULL);
strxnmov(buf, sizeof(buf)-1, "tcmalloc ", ver_str, NULL);
return buf;
}
/* jemalloc */
typedef int (*mallctl_type)(const char*, void*, size_t*, void*, size_t);
mallctl_type mallctl_func =
(mallctl_type) dlsym(RTLD_DEFAULT, "mallctl");
if (mallctl_func)
{
char *ver;
size_t len = sizeof(ver);
mallctl_func("version", &ver, &len, NULL, 0);
strxnmov(buf, sizeof(buf)-1, "jemalloc ", ver, NULL);
return buf;
}
return (char*) MALLOC_LIBRARY;
#endif
}

View File

@ -161,7 +161,7 @@ LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox)
pinstack_top_ver is 32 bits; 16 low bits are the index in the pinstack_top_ver is 32 bits; 16 low bits are the index in the
array, to the first element of the list. 16 high bits are a version array, to the first element of the list. 16 high bits are a version
(every time the 16 low bits are updated, the 16 high bits are (every time the 16 low bits are updated, the 16 high bits are
incremented). Versioniong prevents the ABA problem. incremented). Versioning prevents the ABA problem.
*/ */
top_ver= pinbox->pinstack_top_ver; top_ver= pinbox->pinstack_top_ver;
do do

View File

@ -969,31 +969,43 @@ my_bool getopt_compare_strings(register const char *s, register const char *t,
/* /*
function: eval_num_suffix function: eval_num_suffix
Transforms suffix like k/m/g to their real value. Transforms suffix like k/m/g/t/p/e to their real value.
*/ */
static inline long eval_num_suffix(char *suffix, int *error) static inline ulonglong eval_num_suffix(char *suffix, int *error)
{ {
long num= 1; switch (*suffix) {
if (*suffix == 'k' || *suffix == 'K') case '\0':
num*= 1024L; return 1ULL;
else if (*suffix == 'm' || *suffix == 'M') case 'k':
num*= 1024L * 1024L; case 'K':
else if (*suffix == 'g' || *suffix == 'G') return 1ULL << 10;
num*= 1024L * 1024L * 1024L; case 'm':
else if (*suffix) case 'M':
{ return 1ULL << 20;
case 'g':
case 'G':
return 1ULL << 30;
case 't':
case 'T':
return 1ULL << 40;
case 'p':
case 'P':
return 1ULL << 50;
case 'e':
case 'E':
return 1ULL << 60;
default:
*error= 1; *error= 1;
return 0; return 0ULL;
} }
return num;
} }
/* /*
function: eval_num_suffix_ll function: eval_num_suffix_ll
Transforms a number with a suffix to real number. Suffix can Transforms a number with a suffix to real number. Suffix can
be k|K for kilo, m|M for mega or g|G for giga. be k|K for kilo, m|M for mega, etc.
*/ */
static longlong eval_num_suffix_ll(char *argument, static longlong eval_num_suffix_ll(char *argument,
@ -1026,7 +1038,7 @@ static longlong eval_num_suffix_ll(char *argument,
function: eval_num_suffix_ull function: eval_num_suffix_ull
Transforms a number with a suffix to positive Integer. Suffix can Transforms a number with a suffix to positive Integer. Suffix can
be k|K for kilo, m|M for mega or g|G for giga. be k|K for kilo, m|M for mega, etc.
*/ */
static ulonglong eval_num_suffix_ull(char *argument, static ulonglong eval_num_suffix_ull(char *argument,

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -1,140 +0,0 @@
/* Copyright (c) 2008 MySQL AB, 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_slave.h"
char rpl_semi_sync_slave_enabled;
char rpl_semi_sync_slave_status= 0;
unsigned long rpl_semi_sync_slave_trace_level;
int ReplSemiSyncSlave::initObject()
{
int result= 0;
const char *kWho = "ReplSemiSyncSlave::initObject";
if (init_done_)
{
fprintf(stderr, "%s called twice\n", kWho);
return 1;
}
init_done_ = true;
/* References to the parameter works after set_options(). */
setSlaveEnabled(rpl_semi_sync_slave_enabled);
setTraceLevel(rpl_semi_sync_slave_trace_level);
return result;
}
int ReplSemiSyncSlave::slaveReadSyncHeader(const char *header,
unsigned long total_len,
bool *need_reply,
const char **payload,
unsigned long *payload_len)
{
const char *kWho = "ReplSemiSyncSlave::slaveReadSyncHeader";
int read_res = 0;
function_enter(kWho);
if ((unsigned char)(header[0]) == kPacketMagicNum)
{
*need_reply = (header[1] & kPacketFlagSync);
*payload_len = total_len - 2;
*payload = header + 2;
if (trace_level_ & kTraceDetail)
sql_print_information("%s: reply - %d", kWho, *need_reply);
}
else
{
sql_print_error("Missing magic number for semi-sync packet, packet "
"len: %lu", total_len);
read_res = -1;
}
return function_exit(kWho, read_res);
}
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",
param->user, param->host, param->port,
param->master_log_name[0] ? param->master_log_name : "FIRST",
(unsigned long)param->master_log_pos);
if (semi_sync && !rpl_semi_sync_slave_status)
rpl_semi_sync_slave_status= 1;
return 0;
}
int ReplSemiSyncSlave::slaveStop(Binlog_relay_IO_param *param)
{
if (rpl_semi_sync_slave_status)
rpl_semi_sync_slave_status= 0;
if (mysql_reply)
mysql_close(mysql_reply);
mysql_reply= 0;
return 0;
}
int ReplSemiSyncSlave::slaveReply(MYSQL *mysql,
const char *binlog_filename,
my_off_t binlog_filepos)
{
const char *kWho = "ReplSemiSyncSlave::slaveReply";
NET *net= &mysql->net;
uchar reply_buffer[REPLY_MAGIC_NUM_LEN
+ REPLY_BINLOG_POS_LEN
+ REPLY_BINLOG_NAME_LEN];
int reply_res, name_len = strlen(binlog_filename);
function_enter(kWho);
/* Prepare the buffer of the reply. */
reply_buffer[REPLY_MAGIC_NUM_OFFSET] = kPacketMagicNum;
int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos);
memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET,
binlog_filename,
name_len + 1 /* including trailing '\0' */);
if (trace_level_ & kTraceDetail)
sql_print_information("%s: reply (%s, %lu)", kWho,
binlog_filename, (ulong)binlog_filepos);
net_clear(net, 0);
/* Send the reply. */
reply_res = my_net_write(net, reply_buffer,
name_len + REPLY_BINLOG_NAME_OFFSET);
if (!reply_res)
{
reply_res = net_flush(net);
if (reply_res)
sql_print_error("Semi-sync slave net_flush() reply failed");
}
else
{
sql_print_error("Semi-sync slave send reply failed: %s (%d)",
net->last_error, net->last_errno);
}
return function_exit(kWho, reply_res);
}

View File

@ -1,97 +0,0 @@
/* Copyright (c) 2006 MySQL AB, 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 */
#ifndef SEMISYNC_SLAVE_H
#define SEMISYNC_SLAVE_H
#include "semisync.h"
/**
The extension class for the slave of semi-synchronous replication
*/
class ReplSemiSyncSlave
:public ReplSemiSyncBase {
public:
ReplSemiSyncSlave()
:slave_enabled_(false)
{}
~ReplSemiSyncSlave() {}
void setTraceLevel(unsigned long trace_level) {
trace_level_ = trace_level;
}
/* Initialize this class after MySQL parameters are initialized. this
* function should be called once at bootstrap time.
*/
int initObject();
bool getSlaveEnabled() {
return slave_enabled_;
}
void setSlaveEnabled(bool enabled) {
slave_enabled_ = enabled;
}
/* A slave reads the semi-sync packet header and separate the metadata
* from the payload data.
*
* Input:
* header - (IN) packet header pointer
* total_len - (IN) total packet length: metadata + payload
* need_reply - (IN) whether the master is waiting for the reply
* payload - (IN) payload: the replication event
* payload_len - (IN) payload length
*
* Return:
* 0: success; non-zero: error
*/
int slaveReadSyncHeader(const char *header, unsigned long total_len, bool *need_reply,
const char **payload, unsigned long *payload_len);
/* A slave replies to the master indicating its replication process. It
* indicates that the slave has received all events before the specified
* binlog position.
*
* Input:
* mysql - (IN) the mysql network connection
* binlog_filename - (IN) the reply point's binlog file name
* binlog_filepos - (IN) the reply point's binlog file offset
*
* Return:
* 0: success; non-zero: error
*/
int slaveReply(MYSQL *mysql, const char *binlog_filename,
my_off_t binlog_filepos);
int slaveStart(Binlog_relay_IO_param *param);
int slaveStop(Binlog_relay_IO_param *param);
private:
/* True when initObject has been called */
bool init_done_;
bool slave_enabled_; /* semi-sycn is enabled on the slave */
MYSQL *mysql_reply; /* connection to send reply */
};
/* 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;
#endif /* SEMISYNC_SLAVE_H */

View File

@ -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;

View File

@ -36,7 +36,7 @@ ELSE()
ENDIF() ENDIF()
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/sql
${PCRE_INCLUDES} ${PCRE_INCLUDES}
${ZLIB_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}
@ -122,7 +122,7 @@ SET (SQL_SOURCE
rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc
sql_connect.cc scheduler.cc sql_partition_admin.cc sql_connect.cc scheduler.cc sql_partition_admin.cc
sql_profile.cc event_parse_data.cc sql_alter.cc sql_profile.cc event_parse_data.cc sql_alter.cc
sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc sql_signal.cc mdl.cc sql_admin.cc
transaction.cc sys_vars.cc sql_truncate.cc datadict.cc transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
sql_reload.cc item_inetfunc.cc sql_reload.cc item_inetfunc.cc
@ -138,6 +138,8 @@ SET (SQL_SOURCE
my_apc.cc mf_iocache_encr.cc item_jsonfunc.cc my_apc.cc mf_iocache_encr.cc item_jsonfunc.cc
my_json_writer.cc my_json_writer.cc
rpl_gtid.cc rpl_parallel.cc rpl_gtid.cc rpl_parallel.cc
semisync.cc semisync_master.cc semisync_slave.cc
semisync_master_ack_receiver.cc
sql_type.cc sql_type.cc
item_windowfunc.cc sql_window.cc item_windowfunc.cc sql_window.cc
sql_cte.cc sql_cte.cc

View File

@ -421,7 +421,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data)
DBUG_RETURN(ret); DBUG_RETURN(ret);
#ifdef WITH_WSREP #ifdef WITH_WSREP
error: error:
DBUG_RETURN(TRUE); DBUG_RETURN(true);
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
} }

View File

@ -4741,6 +4741,15 @@ double Field_double::val_real(void)
} }
longlong Field_double::val_int_from_real(bool want_unsigned_result)
{
Converter_double_to_longlong conv(val_real(), want_unsigned_result);
if (!want_unsigned_result && conv.error())
conv.push_warning(get_thd(), Field_double::val_real(), false);
return conv.result();
}
my_decimal *Field_real::val_decimal(my_decimal *decimal_value) my_decimal *Field_real::val_decimal(my_decimal *decimal_value)
{ {
ASSERT_COLUMN_MARKED_FOR_READ; ASSERT_COLUMN_MARKED_FOR_READ;

View File

@ -850,6 +850,10 @@ public:
} }
virtual double val_real(void)=0; virtual double val_real(void)=0;
virtual longlong val_int(void)=0; virtual longlong val_int(void)=0;
virtual ulonglong val_uint(void)
{
return (ulonglong) val_int();
}
virtual bool val_bool(void)= 0; virtual bool val_bool(void)= 0;
virtual my_decimal *val_decimal(my_decimal *); virtual my_decimal *val_decimal(my_decimal *);
inline String *val_str(String *str) { return val_str(str, str); } inline String *val_str(String *str) { return val_str(str, str); }
@ -2278,6 +2282,7 @@ private:
class Field_double :public Field_real { class Field_double :public Field_real {
longlong val_int_from_real(bool want_unsigned_result);
public: public:
Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, uchar null_bit_arg,
@ -2315,13 +2320,8 @@ public:
int store(longlong nr, bool unsigned_val); int store(longlong nr, bool unsigned_val);
int reset(void) { bzero(ptr,sizeof(double)); return 0; } int reset(void) { bzero(ptr,sizeof(double)); return 0; }
double val_real(void); double val_real(void);
longlong val_int(void) longlong val_int(void) { return val_int_from_real(false); }
{ ulonglong val_uint(void) { return (ulonglong) val_int_from_real(true); }
Converter_double_to_longlong conv(Field_double::val_real(), false);
if (conv.error())
conv.push_warning(get_thd(), Field_double::val_real(), false);
return conv.result();
}
String *val_str(String*,String *); String *val_str(String*,String *);
bool send_binary(Protocol *protocol); bool send_binary(Protocol *protocol);
int cmp(const uchar *,const uchar *); int cmp(const uchar *,const uchar *);

View File

@ -23,7 +23,7 @@
#include "mariadb.h" #include "mariadb.h"
#include "sql_priv.h" #include "sql_priv.h"
#include "unireg.h" #include "unireg.h"
#include "rpl_handler.h" #include "rpl_rli.h"
#include "sql_cache.h" // query_cache, query_cache_* #include "sql_cache.h" // query_cache, query_cache_*
#include "sql_connect.h" // global_table_stats #include "sql_connect.h" // global_table_stats
#include "key.h" // key_copy, key_unpack, key_cmp_if_same, key_cmp #include "key.h" // key_copy, key_unpack, key_cmp_if_same, key_cmp
@ -50,6 +50,7 @@
#ifdef WITH_ARIA_STORAGE_ENGINE #ifdef WITH_ARIA_STORAGE_ENGINE
#include "../storage/maria/ha_maria.h" #include "../storage/maria/ha_maria.h"
#endif #endif
#include "semisync_master.h"
#include "wsrep_mysqld.h" #include "wsrep_mysqld.h"
#include "wsrep.h" #include "wsrep.h"
@ -1518,7 +1519,10 @@ done:
mysql_mutex_assert_not_owner(mysql_bin_log.get_log_lock()); mysql_mutex_assert_not_owner(mysql_bin_log.get_log_lock());
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync); mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered); mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
RUN_HOOK(transaction, after_commit, (thd, FALSE)); #ifdef HAVE_REPLICATION
repl_semisync_master.wait_after_commit(thd, all);
DEBUG_SYNC(thd, "after_group_after_commit");
#endif
goto end; goto end;
/* Come here if error and we need to rollback. */ /* Come here if error and we need to rollback. */
@ -1763,7 +1767,9 @@ int ha_rollback_trans(THD *thd, bool all)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK, ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER_THD(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK)); ER_THD(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK));
(void) RUN_HOOK(transaction, after_rollback, (thd, FALSE)); #ifdef HAVE_REPLICATION
repl_semisync_master.wait_after_rollback(thd, all);
#endif
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -2020,6 +2026,97 @@ int ha_recover(HASH *commit_list)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/**
return the XID as it appears in the SQL function's arguments.
So this string can be passed to XA START, XA PREPARE etc...
@note
the 'buf' has to have space for at least SQL_XIDSIZE bytes.
*/
/*
'a'..'z' 'A'..'Z', '0'..'9'
and '-' '_' ' ' symbols don't have to be
converted.
*/
static const char xid_needs_conv[128]=
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
};
uint get_sql_xid(XID *xid, char *buf)
{
int tot_len= xid->gtrid_length + xid->bqual_length;
int i;
const char *orig_buf= buf;
for (i=0; i<tot_len; i++)
{
uchar c= ((uchar *) xid->data)[i];
if (c >= 128 || xid_needs_conv[c])
break;
}
if (i >= tot_len)
{
/* No need to convert characters to hexadecimals. */
*buf++= '\'';
memcpy(buf, xid->data, xid->gtrid_length);
buf+= xid->gtrid_length;
*buf++= '\'';
if (xid->bqual_length > 0 || xid->formatID != 1)
{
*buf++= ',';
*buf++= '\'';
memcpy(buf, xid->data+xid->gtrid_length, xid->bqual_length);
buf+= xid->bqual_length;
*buf++= '\'';
}
}
else
{
*buf++= 'X';
*buf++= '\'';
for (i= 0; i < xid->gtrid_length; i++)
{
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] >> 4];
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] & 0x0f];
}
*buf++= '\'';
if (xid->bqual_length > 0 || xid->formatID != 1)
{
*buf++= ',';
*buf++= 'X';
*buf++= '\'';
for (; i < tot_len; i++)
{
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] >> 4];
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] & 0x0f];
}
*buf++= '\'';
}
}
if (xid->formatID != 1)
{
*buf++= ',';
buf+= my_longlong10_to_str_8bit(&my_charset_bin, buf,
MY_INT64_NUM_DECIMAL_DIGITS, -10, xid->formatID);
}
return buf - orig_buf;
}
/** /**
return the list of XID's to a client, the same way SHOW commands do. return the list of XID's to a client, the same way SHOW commands do.
@ -2029,7 +2126,8 @@ int ha_recover(HASH *commit_list)
It can be easily fixed later, if necessary. It can be easily fixed later, if necessary.
*/ */
static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol) static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol,
char *data, uint data_len, CHARSET_INFO *data_cs)
{ {
if (xs->xa_state == XA_PREPARED) if (xs->xa_state == XA_PREPARED)
{ {
@ -2037,8 +2135,7 @@ static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
protocol->store_longlong((longlong) xs->xid.formatID, FALSE); protocol->store_longlong((longlong) xs->xid.formatID, FALSE);
protocol->store_longlong((longlong) xs->xid.gtrid_length, FALSE); protocol->store_longlong((longlong) xs->xid.gtrid_length, FALSE);
protocol->store_longlong((longlong) xs->xid.bqual_length, FALSE); protocol->store_longlong((longlong) xs->xid.bqual_length, FALSE);
protocol->store(xs->xid.data, xs->xid.gtrid_length + xs->xid.bqual_length, protocol->store(data, data_len, data_cs);
&my_charset_bin);
if (protocol->write()) if (protocol->write())
return TRUE; return TRUE;
} }
@ -2046,11 +2143,28 @@ static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
} }
static my_bool xa_recover_callback_short(XID_STATE *xs, Protocol *protocol)
{
return xa_recover_callback(xs, protocol, xs->xid.data,
xs->xid.gtrid_length + xs->xid.bqual_length, &my_charset_bin);
}
static my_bool xa_recover_callback_verbose(XID_STATE *xs, Protocol *protocol)
{
char buf[SQL_XIDSIZE];
uint len= get_sql_xid(&xs->xid, buf);
return xa_recover_callback(xs, protocol, buf, len,
&my_charset_utf8_general_ci);
}
bool mysql_xa_recover(THD *thd) bool mysql_xa_recover(THD *thd)
{ {
List<Item> field_list; List<Item> field_list;
Protocol *protocol= thd->protocol; Protocol *protocol= thd->protocol;
MEM_ROOT *mem_root= thd->mem_root; MEM_ROOT *mem_root= thd->mem_root;
my_hash_walk_action action;
DBUG_ENTER("mysql_xa_recover"); DBUG_ENTER("mysql_xa_recover");
field_list.push_back(new (mem_root) field_list.push_back(new (mem_root)
@ -2062,16 +2176,32 @@ bool mysql_xa_recover(THD *thd)
field_list.push_back(new (mem_root) field_list.push_back(new (mem_root)
Item_int(thd, "bqual_length", 0, Item_int(thd, "bqual_length", 0,
MY_INT32_NUM_DECIMAL_DIGITS), mem_root); MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
field_list.push_back(new (mem_root) {
Item_empty_string(thd, "data", uint len;
XIDDATASIZE), mem_root); CHARSET_INFO *cs;
if (thd->lex->verbose)
{
len= SQL_XIDSIZE;
cs= &my_charset_utf8_general_ci;
action= (my_hash_walk_action) xa_recover_callback_verbose;
}
else
{
len= XIDDATASIZE;
cs= &my_charset_bin;
action= (my_hash_walk_action) xa_recover_callback_short;
}
field_list.push_back(new (mem_root)
Item_empty_string(thd, "data", len, cs), mem_root);
}
if (protocol->send_result_set_metadata(&field_list, if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(1); DBUG_RETURN(1);
if (xid_cache_iterate(thd, (my_hash_walk_action) xa_recover_callback, if (xid_cache_iterate(thd, action, protocol))
protocol))
DBUG_RETURN(1); DBUG_RETURN(1);
my_eof(thd); my_eof(thd);
DBUG_RETURN(0); DBUG_RETURN(0);

View File

@ -672,6 +672,15 @@ struct xid_t {
}; };
typedef struct xid_t XID; typedef struct xid_t XID;
/*
The size of XID string representation in the form
'gtrid', 'bqual', formatID
see xid_t::get_sql_string() for details.
*/
#define SQL_XIDSIZE (XIDDATASIZE * 2 + 8 + MY_INT64_NUM_DECIMAL_DIGITS)
/* The 'buf' has to have space for at least SQL_XIDSIZE bytes. */
uint get_sql_xid(XID *xid, char *buf);
/* for recover() handlerton call */ /* for recover() handlerton call */
#define MIN_XID_LIST_SIZE 128 #define MIN_XID_LIST_SIZE 128
#define MAX_XID_LIST_SIZE (1024*128) #define MAX_XID_LIST_SIZE (1024*128)
@ -1929,6 +1938,13 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET); used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
return false; return false;
} }
ulong table_options_with_row_type()
{
if (row_type == ROW_TYPE_DYNAMIC || row_type == ROW_TYPE_PAGE)
return table_options | HA_OPTION_PACK_RECORD;
else
return table_options;
}
}; };

View File

@ -49,10 +49,10 @@
#endif #endif
#include "sql_plugin.h" #include "sql_plugin.h"
#include "rpl_handler.h"
#include "debug_sync.h" #include "debug_sync.h"
#include "sql_show.h" #include "sql_show.h"
#include "my_pthread.h" #include "my_pthread.h"
#include "semisync_master.h"
#include "wsrep_mysqld.h" #include "wsrep_mysqld.h"
#include "sp_rcontext.h" #include "sp_rcontext.h"
#include "sp_head.h" #include "sp_head.h"
@ -3211,7 +3211,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
group_commit_trigger_lock_wait(0), group_commit_trigger_lock_wait(0),
sync_period_ptr(sync_period), sync_counter(0), sync_period_ptr(sync_period), sync_counter(0),
state_file_deleted(false), binlog_state_recover_done(false), state_file_deleted(false), binlog_state_recover_done(false),
is_relay_log(0), signal_cnt(0), is_relay_log(0), relay_signal_cnt(0),
checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF), checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF), relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
description_event_for_exec(0), description_event_for_queue(0), description_event_for_exec(0), description_event_for_queue(0),
@ -3281,7 +3281,8 @@ void MYSQL_BIN_LOG::cleanup()
mysql_mutex_destroy(&LOCK_xid_list); mysql_mutex_destroy(&LOCK_xid_list);
mysql_mutex_destroy(&LOCK_binlog_background_thread); mysql_mutex_destroy(&LOCK_binlog_background_thread);
mysql_mutex_destroy(&LOCK_binlog_end_pos); mysql_mutex_destroy(&LOCK_binlog_end_pos);
mysql_cond_destroy(&update_cond); mysql_cond_destroy(&COND_relay_log_updated);
mysql_cond_destroy(&COND_bin_log_updated);
mysql_cond_destroy(&COND_queue_busy); mysql_cond_destroy(&COND_queue_busy);
mysql_cond_destroy(&COND_xid_list); mysql_cond_destroy(&COND_xid_list);
mysql_cond_destroy(&COND_binlog_background_thread); mysql_cond_destroy(&COND_binlog_background_thread);
@ -3316,7 +3317,8 @@ void MYSQL_BIN_LOG::init_pthread_objects()
mysql_mutex_setflags(&LOCK_index, MYF_NO_DEADLOCK_DETECTION); mysql_mutex_setflags(&LOCK_index, MYF_NO_DEADLOCK_DETECTION);
mysql_mutex_init(key_BINLOG_LOCK_xid_list, mysql_mutex_init(key_BINLOG_LOCK_xid_list,
&LOCK_xid_list, MY_MUTEX_INIT_FAST); &LOCK_xid_list, MY_MUTEX_INIT_FAST);
mysql_cond_init(m_key_update_cond, &update_cond, 0); mysql_cond_init(m_key_relay_log_update, &COND_relay_log_updated, 0);
mysql_cond_init(m_key_bin_log_update, &COND_bin_log_updated, 0);
mysql_cond_init(m_key_COND_queue_busy, &COND_queue_busy, 0); mysql_cond_init(m_key_COND_queue_busy, &COND_queue_busy, 0);
mysql_cond_init(key_BINLOG_COND_xid_list, &COND_xid_list, 0); mysql_cond_init(key_BINLOG_COND_xid_list, &COND_xid_list, 0);
@ -3802,6 +3804,11 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
close_purge_index_file(); close_purge_index_file();
#endif #endif
/* Notify the io thread that binlog is rotated to a new file */
if (is_relay_log)
signal_relay_log_update();
else
update_binlog_end_pos();
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
@ -5112,7 +5119,12 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
new file name in the current binary log file. new file name in the current binary log file.
*/ */
if ((error= generate_new_name(new_name, name, 0))) if ((error= generate_new_name(new_name, name, 0)))
{
#ifdef ENABLE_AND_FIX_HANG
close_on_error= TRUE;
#endif
goto end; goto end;
}
new_name_ptr=new_name; new_name_ptr=new_name;
if (log_type == LOG_BIN) if (log_type == LOG_BIN)
@ -5143,13 +5155,20 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
} }
bytes_written += r.data_written; bytes_written += r.data_written;
} }
/*
Update needs to be signalled even if there is no rotate event
log rotation should give the waiting thread a signal to
discover EOF and move on to the next log.
*/
signal_update();
} }
/*
Update needs to be signalled even if there is no rotate event
log rotation should give the waiting thread a signal to
discover EOF and move on to the next log.
*/
if ((error= flush_io_cache(&log_file)))
{
close_on_error= TRUE;
goto end;
}
update_binlog_end_pos();
old_name=name; old_name=name;
name=0; // Don't free name name=0; // Don't free name
close_flag= LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX; close_flag= LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX;
@ -5280,7 +5299,7 @@ bool MYSQL_BIN_LOG::append_no_lock(Log_event* ev)
if (my_b_append_tell(&log_file) > max_size) if (my_b_append_tell(&log_file) > max_size)
error= new_file_without_locking(); error= new_file_without_locking();
err: err:
signal_update(); // Safe as we don't call close update_binlog_end_pos();
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -5341,7 +5360,7 @@ bool MYSQL_BIN_LOG::write_event_buffer(uchar* buf, uint len)
err: err:
my_safe_afree(ebuf, len); my_safe_afree(ebuf, len);
if (!error) if (!error)
signal_update(); update_binlog_end_pos();
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -6341,6 +6360,7 @@ err:
{ {
my_off_t offset= my_b_tell(file); my_off_t offset= my_b_tell(file);
bool check_purge= false; bool check_purge= false;
DBUG_ASSERT(!is_relay_log);
if (!error) if (!error)
{ {
@ -6355,25 +6375,23 @@ err:
mysql_mutex_assert_owner(&LOCK_log); mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync); mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered); mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
bool first= true; #ifdef HAVE_REPLICATION
bool last= true; if (repl_semisync_master.report_binlog_update(thd, log_file_name,
if ((error= RUN_HOOK(binlog_storage, after_flush, file->pos_in_file))
(thd, log_file_name, file->pos_in_file,
synced, first, last))))
{ {
sql_print_error("Failed to run 'after_flush' hooks"); sql_print_error("Failed to run 'after_flush' hooks");
error= 1; error= 1;
} }
else else
#endif
{ {
/* update binlog_end_pos so it can be read by dump thread /*
* update binlog_end_pos so it can be read by dump thread
* note: must be _after_ the RUN_HOOK(after_flush) or else note: must be _after_ the RUN_HOOK(after_flush) or else
* semi-sync-plugin might not have put the transaction into semi-sync might not have put the transaction into
* it's list before dump-thread tries to send it it's list before dump-thread tries to send it
*/ */
update_binlog_end_pos(offset); update_binlog_end_pos(offset);
if ((error= rotate(false, &check_purge))) if ((error= rotate(false, &check_purge)))
check_purge= false; check_purge= false;
} }
@ -6390,15 +6408,14 @@ err:
mysql_mutex_assert_not_owner(&LOCK_log); mysql_mutex_assert_not_owner(&LOCK_log);
mysql_mutex_assert_owner(&LOCK_after_binlog_sync); mysql_mutex_assert_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered); mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
bool first= true; #ifdef HAVE_REPLICATION
bool last= true; if (repl_semisync_master.wait_after_sync(log_file_name,
if (RUN_HOOK(binlog_storage, after_sync, file->pos_in_file))
(thd, log_file_name, file->pos_in_file,
first, last)))
{ {
error=1; error=1;
/* error is already printed inside hook */ /* error is already printed inside hook */
} }
#endif
/* /*
Take mutex to protect against a reader seeing partial writes of 64-bit Take mutex to protect against a reader seeing partial writes of 64-bit
@ -7099,7 +7116,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
if (!(error= write_incident_already_locked(thd)) && if (!(error= write_incident_already_locked(thd)) &&
!(error= flush_and_sync(0))) !(error= flush_and_sync(0)))
{ {
signal_update(); update_binlog_end_pos();
if ((error= rotate(false, &check_purge))) if ((error= rotate(false, &check_purge)))
check_purge= false; check_purge= false;
} }
@ -7140,7 +7157,7 @@ MYSQL_BIN_LOG::write_binlog_checkpoint_event_already_locked(const char *name_arg
*/ */
if (!write_event(&ev) && !flush_and_sync(0)) if (!write_event(&ev) && !flush_and_sync(0))
{ {
signal_update(); update_binlog_end_pos();
} }
else else
{ {
@ -7575,7 +7592,11 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
else if (is_leader) else if (is_leader)
trx_group_commit_leader(entry); trx_group_commit_leader(entry);
else if (!entry->queued_by_other) else if (!entry->queued_by_other)
{
DEBUG_SYNC(entry->thd, "after_semisync_queue");
entry->thd->wait_for_wakeup_ready(); entry->thd->wait_for_wakeup_ready();
}
else else
{ {
/* /*
@ -7820,31 +7841,31 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
mysql_mutex_assert_owner(&LOCK_log); mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync); mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered); mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
bool first= true, last;
for (current= queue; current != NULL; current= current->next) for (current= queue; current != NULL; current= current->next)
{ {
last= current->next == NULL; #ifdef HAVE_REPLICATION
if (!current->error && if (!current->error &&
RUN_HOOK(binlog_storage, after_flush, repl_semisync_master.
(current->thd, report_binlog_update(current->thd,
current->cache_mngr->last_commit_pos_file, current->cache_mngr->last_commit_pos_file,
current->cache_mngr->last_commit_pos_offset, synced, current->cache_mngr->
first, last))) last_commit_pos_offset))
{ {
current->error= ER_ERROR_ON_WRITE; current->error= ER_ERROR_ON_WRITE;
current->commit_errno= -1; current->commit_errno= -1;
current->error_cache= NULL; current->error_cache= NULL;
any_error= true; any_error= true;
} }
first= false; #endif
} }
/* update binlog_end_pos so it can be read by dump thread /*
* update binlog_end_pos so it can be read by dump thread
* note: must be _after_ the RUN_HOOK(after_flush) or else Note: must be _after_ the RUN_HOOK(after_flush) or else
* semi-sync-plugin might not have put the transaction into semi-sync might not have put the transaction into
* it's list before dump-thread tries to send it it's list before dump-thread tries to send it
*/ */
update_binlog_end_pos(commit_offset); update_binlog_end_pos(commit_offset);
if (any_error) if (any_error)
@ -7906,18 +7927,19 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
mysql_mutex_assert_owner(&LOCK_after_binlog_sync); mysql_mutex_assert_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered); mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
bool first= true, last; bool first __attribute__((unused))= true;
bool last __attribute__((unused));
for (current= queue; current != NULL; current= current->next) for (current= queue; current != NULL; current= current->next)
{ {
last= current->next == NULL; last= current->next == NULL;
if (!current->error && #ifdef HAVE_REPLICATION
RUN_HOOK(binlog_storage, after_sync, if (!current->error)
(current->thd, current->cache_mngr->last_commit_pos_file, current->error=
current->cache_mngr->last_commit_pos_offset, repl_semisync_master.wait_after_sync(current->cache_mngr->
first, last))) last_commit_pos_file,
{ current->cache_mngr->
/* error is already printed inside hook */ last_commit_pos_offset);
} #endif
first= false; first= false;
} }
} }
@ -8228,10 +8250,10 @@ void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
DBUG_ENTER("wait_for_update_relay_log"); DBUG_ENTER("wait_for_update_relay_log");
mysql_mutex_assert_owner(&LOCK_log); mysql_mutex_assert_owner(&LOCK_log);
thd->ENTER_COND(&update_cond, &LOCK_log, thd->ENTER_COND(&COND_relay_log_updated, &LOCK_log,
&stage_slave_has_read_all_relay_log, &stage_slave_has_read_all_relay_log,
&old_stage); &old_stage);
mysql_cond_wait(&update_cond, &LOCK_log); mysql_cond_wait(&COND_relay_log_updated, &LOCK_log);
thd->EXIT_COND(&old_stage); thd->EXIT_COND(&old_stage);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -8261,9 +8283,9 @@ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd,
thd_wait_begin(thd, THD_WAIT_BINLOG); thd_wait_begin(thd, THD_WAIT_BINLOG);
mysql_mutex_assert_owner(get_binlog_end_pos_lock()); mysql_mutex_assert_owner(get_binlog_end_pos_lock());
if (!timeout) if (!timeout)
mysql_cond_wait(&update_cond, get_binlog_end_pos_lock()); mysql_cond_wait(&COND_bin_log_updated, get_binlog_end_pos_lock());
else else
ret= mysql_cond_timedwait(&update_cond, get_binlog_end_pos_lock(), ret= mysql_cond_timedwait(&COND_bin_log_updated, get_binlog_end_pos_lock(),
timeout); timeout);
thd_wait_end(thd); thd_wait_end(thd);
DBUG_RETURN(ret); DBUG_RETURN(ret);
@ -8308,7 +8330,8 @@ void MYSQL_BIN_LOG::close(uint exiting)
relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF); relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
write_event(&s); write_event(&s);
bytes_written+= s.data_written; bytes_written+= s.data_written;
signal_update(); flush_io_cache(&log_file);
update_binlog_end_pos();
/* /*
When we shut down server, write out the binlog state to a separate When we shut down server, write out the binlog state to a separate
@ -8527,14 +8550,6 @@ bool flush_error_log()
return result; return result;
} }
void MYSQL_BIN_LOG::signal_update()
{
DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
signal_cnt++;
mysql_cond_broadcast(&update_cond);
DBUG_VOID_RETURN;
}
#ifdef _WIN32 #ifdef _WIN32
static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
size_t length, size_t buffLen) size_t length, size_t buffLen)
@ -9918,7 +9933,7 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
for (;;) for (;;)
{ {
while ((ev= Log_event::read_log_event(first_round ? first_log : &log, while ((ev= Log_event::read_log_event(first_round ? first_log : &log,
0, fdle, opt_master_verify_checksum)) fdle, opt_master_verify_checksum))
&& ev->is_valid()) && ev->is_valid())
{ {
enum Log_event_type typ= ev->get_type_code(); enum Log_event_type typ= ev->get_type_code();
@ -10159,7 +10174,7 @@ MYSQL_BIN_LOG::do_binlog_recovery(const char *opt_name, bool do_xa_recovery)
return 1; return 1;
} }
if ((ev= Log_event::read_log_event(&log, 0, &fdle, if ((ev= Log_event::read_log_event(&log, &fdle,
opt_master_verify_checksum)) && opt_master_verify_checksum)) &&
ev->get_type_code() == FORMAT_DESCRIPTION_EVENT) ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
{ {
@ -10400,7 +10415,7 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
*out_gtid_list= NULL; *out_gtid_list= NULL;
if (!(ev= Log_event::read_log_event(cache, 0, &init_fdle, if (!(ev= Log_event::read_log_event(cache, &init_fdle,
opt_master_verify_checksum)) || opt_master_verify_checksum)) ||
ev->get_type_code() != FORMAT_DESCRIPTION_EVENT) ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
{ {
@ -10416,7 +10431,7 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
{ {
Log_event_type typ; Log_event_type typ;
ev= Log_event::read_log_event(cache, 0, fdle, opt_master_verify_checksum); ev= Log_event::read_log_event(cache, fdle, opt_master_verify_checksum);
if (!ev) if (!ev)
{ {
errormsg= "Could not read GTID list event while looking for GTID " errormsg= "Could not read GTID list event while looking for GTID "
@ -10446,6 +10461,7 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
return errormsg; return errormsg;
} }
struct st_mysql_storage_engine binlog_storage_engine= struct st_mysql_storage_engine binlog_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION }; { MYSQL_HANDLERTON_INTERFACE_VERSION };

View File

@ -349,6 +349,11 @@ public:
/* for documentation of mutexes held in various places in code */ /* for documentation of mutexes held in various places in code */
}; };
/* Tell the io thread if we can delay the master info sync. */
#define SEMI_SYNC_SLAVE_DELAY_SYNC 1
/* Tell the io thread if the current event needs a ack. */
#define SEMI_SYNC_NEED_ACK 2
class MYSQL_QUERY_LOG: public MYSQL_LOG class MYSQL_QUERY_LOG: public MYSQL_LOG
{ {
public: public:
@ -425,14 +430,18 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
/** The instrumentation key to use for @ LOCK_index. */ /** The instrumentation key to use for @ LOCK_index. */
PSI_mutex_key m_key_LOCK_index; PSI_mutex_key m_key_LOCK_index;
/** The instrumentation key to use for @ update_cond. */ /** The instrumentation key to use for @ COND_relay_log_updated */
PSI_cond_key m_key_update_cond; PSI_cond_key m_key_relay_log_update;
/** The instrumentation key to use for @ COND_bin_log_updated */
PSI_cond_key m_key_bin_log_update;
/** The instrumentation key to use for opening the log file. */ /** The instrumentation key to use for opening the log file. */
PSI_file_key m_key_file_log; PSI_file_key m_key_file_log;
/** The instrumentation key to use for opening the log index file. */ /** The instrumentation key to use for opening the log index file. */
PSI_file_key m_key_file_log_index; PSI_file_key m_key_file_log_index;
PSI_file_key m_key_COND_queue_busy; PSI_file_key m_key_COND_queue_busy;
/** The instrumentation key to use for LOCK_binlog_end_pos. */
PSI_mutex_key m_key_LOCK_binlog_end_pos;
#endif #endif
struct group_commit_entry struct group_commit_entry
@ -488,7 +497,7 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
mysql_mutex_t LOCK_binlog_end_pos; mysql_mutex_t LOCK_binlog_end_pos;
mysql_mutex_t LOCK_xid_list; mysql_mutex_t LOCK_xid_list;
mysql_cond_t COND_xid_list; mysql_cond_t COND_xid_list;
mysql_cond_t update_cond; mysql_cond_t COND_relay_log_updated, COND_bin_log_updated;
ulonglong bytes_written; ulonglong bytes_written;
IO_CACHE index_file; IO_CACHE index_file;
char index_file_name[FN_REFLEN]; char index_file_name[FN_REFLEN];
@ -598,7 +607,7 @@ public:
/* This is relay log */ /* This is relay log */
bool is_relay_log; bool is_relay_log;
ulong signal_cnt; // update of the counter is checked by heartbeat ulong relay_signal_cnt; // update of the counter is checked by heartbeat
enum enum_binlog_checksum_alg checksum_alg_reset; // to contain a new value when binlog is rotated enum enum_binlog_checksum_alg checksum_alg_reset; // to contain a new value when binlog is rotated
/* /*
Holds the last seen in Relay-Log FD's checksum alg value. Holds the last seen in Relay-Log FD's checksum alg value.
@ -661,16 +670,20 @@ public:
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
void set_psi_keys(PSI_mutex_key key_LOCK_index, void set_psi_keys(PSI_mutex_key key_LOCK_index,
PSI_cond_key key_update_cond, PSI_cond_key key_relay_log_update,
PSI_cond_key key_bin_log_update,
PSI_file_key key_file_log, PSI_file_key key_file_log,
PSI_file_key key_file_log_index, PSI_file_key key_file_log_index,
PSI_file_key key_COND_queue_busy) PSI_file_key key_COND_queue_busy,
PSI_mutex_key key_LOCK_binlog_end_pos)
{ {
m_key_LOCK_index= key_LOCK_index; m_key_LOCK_index= key_LOCK_index;
m_key_update_cond= key_update_cond; m_key_relay_log_update= key_relay_log_update;
m_key_bin_log_update= key_bin_log_update;
m_key_file_log= key_file_log; m_key_file_log= key_file_log;
m_key_file_log_index= key_file_log_index; m_key_file_log_index= key_file_log_index;
m_key_COND_queue_busy= key_COND_queue_busy; m_key_COND_queue_busy= key_COND_queue_busy;
m_key_LOCK_binlog_end_pos= key_LOCK_binlog_end_pos;
} }
#endif #endif
@ -707,7 +720,53 @@ public:
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void set_max_size(ulong max_size_arg); void set_max_size(ulong max_size_arg);
void signal_update();
/* Handle signaling that relay has been updated */
void signal_relay_log_update()
{
mysql_mutex_assert_owner(&LOCK_log);
DBUG_ASSERT(is_relay_log);
DBUG_ENTER("MYSQL_BIN_LOG::signal_relay_log_update");
relay_signal_cnt++;
mysql_cond_broadcast(&COND_relay_log_updated);
DBUG_VOID_RETURN;
}
void signal_bin_log_update()
{
mysql_mutex_assert_owner(&LOCK_binlog_end_pos);
DBUG_ASSERT(!is_relay_log);
DBUG_ENTER("MYSQL_BIN_LOG::signal_bin_log_update");
mysql_cond_broadcast(&COND_bin_log_updated);
DBUG_VOID_RETURN;
}
void update_binlog_end_pos()
{
if (is_relay_log)
signal_relay_log_update();
else
{
lock_binlog_end_pos();
binlog_end_pos= my_b_safe_tell(&log_file);
signal_bin_log_update();
unlock_binlog_end_pos();
}
}
void update_binlog_end_pos(my_off_t pos)
{
mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_not_owner(&LOCK_binlog_end_pos);
lock_binlog_end_pos();
/*
Note: it would make more sense to assert(pos > binlog_end_pos)
but there are two places triggered by mtr that has pos == binlog_end_pos
i didn't investigate but accepted as it should do no harm
*/
DBUG_ASSERT(pos >= binlog_end_pos);
binlog_end_pos= pos;
signal_bin_log_update();
unlock_binlog_end_pos();
}
void wait_for_sufficient_commits(); void wait_for_sufficient_commits();
void binlog_trigger_immediate_group_commit(); void binlog_trigger_immediate_group_commit();
void wait_for_update_relay_log(THD* thd); void wait_for_update_relay_log(THD* thd);
@ -807,7 +866,7 @@ public:
inline char* get_log_fname() { return log_file_name; } inline char* get_log_fname() { return log_file_name; }
inline char* get_name() { return name; } inline char* get_name() { return name; }
inline mysql_mutex_t* get_log_lock() { return &LOCK_log; } inline mysql_mutex_t* get_log_lock() { return &LOCK_log; }
inline mysql_cond_t* get_log_cond() { return &update_cond; } inline mysql_cond_t* get_bin_log_cond() { return &COND_bin_log_updated; }
inline IO_CACHE* get_log_file() { return &log_file; } inline IO_CACHE* get_log_file() { return &log_file; }
inline void lock_index() { mysql_mutex_lock(&LOCK_index);} inline void lock_index() { mysql_mutex_lock(&LOCK_index);}
@ -831,23 +890,6 @@ public:
bool check_strict_gtid_sequence(uint32 domain_id, uint32 server_id, bool check_strict_gtid_sequence(uint32 domain_id, uint32 server_id,
uint64 seq_no); uint64 seq_no);
void update_binlog_end_pos(my_off_t pos)
{
mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_not_owner(&LOCK_binlog_end_pos);
lock_binlog_end_pos();
/**
* note: it would make more sense to assert(pos > binlog_end_pos)
* but there are two places triggered by mtr that has pos == binlog_end_pos
* i didn't investigate but accepted as it should do no harm
*/
DBUG_ASSERT(pos >= binlog_end_pos);
binlog_end_pos= pos;
signal_update();
unlock_binlog_end_pos();
}
/** /**
* used when opening new file, and binlog_end_pos moves backwards * used when opening new file, and binlog_end_pos moves backwards
*/ */
@ -858,7 +900,7 @@ public:
lock_binlog_end_pos(); lock_binlog_end_pos();
binlog_end_pos= pos; binlog_end_pos= pos;
strcpy(binlog_end_pos_file, file_name); strcpy(binlog_end_pos_file, file_name);
signal_update(); signal_bin_log_update();
unlock_binlog_end_pos(); unlock_binlog_end_pos();
} }

View File

@ -1855,7 +1855,7 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock, Log_event* Log_event::read_log_event(IO_CACHE* file,
const Format_description_log_event *fdle, const Format_description_log_event *fdle,
my_bool crc_check) my_bool crc_check)
{ {
@ -1865,9 +1865,6 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
const char *error= 0; const char *error= 0;
Log_event *res= 0; Log_event *res= 0;
if (log_lock)
mysql_mutex_lock(log_lock);
switch (read_log_event(file, &event, fdle, BINLOG_CHECKSUM_ALG_OFF)) switch (read_log_event(file, &event, fdle, BINLOG_CHECKSUM_ALG_OFF))
{ {
case 0: case 0:
@ -1904,8 +1901,6 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
res->register_temp_buf(event.release(), true); res->register_temp_buf(event.release(), true);
err: err:
if (log_lock)
mysql_mutex_unlock(log_lock);
if (error) if (error)
{ {
DBUG_ASSERT(!res); DBUG_ASSERT(!res);
@ -9736,7 +9731,6 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi)
} }
if (!(lev= (Load_log_event*) if (!(lev= (Load_log_event*)
Log_event::read_log_event(&file, Log_event::read_log_event(&file,
(mysql_mutex_t*)0,
rli->relay_log.description_event_for_exec, rli->relay_log.description_event_for_exec,
opt_slave_sql_verify_checksum)) || opt_slave_sql_verify_checksum)) ||
lev->get_type_code() != NEW_LOAD_EVENT) lev->get_type_code() != NEW_LOAD_EVENT)

View File

@ -1300,7 +1300,6 @@ public:
constructor and pass description_event as an argument. constructor and pass description_event as an argument.
*/ */
static Log_event* read_log_event(IO_CACHE* file, static Log_event* read_log_event(IO_CACHE* file,
mysql_mutex_t* log_lock,
const Format_description_log_event const Format_description_log_event
*description_event, *description_event,
my_bool crc_check); my_bool crc_check);

View File

@ -97,8 +97,8 @@
#include "set_var.h" #include "set_var.h"
#include "rpl_injector.h" #include "rpl_injector.h"
#include "semisync_master.h"
#include "rpl_handler.h" #include "semisync_slave.h"
#include "transaction.h" #include "transaction.h"
@ -914,7 +914,7 @@ PSI_mutex_key key_LOCK_des_key_file;
PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_BINLOG_LOCK_binlog_background_thread, key_BINLOG_LOCK_binlog_background_thread,
m_key_LOCK_binlog_end_pos, key_LOCK_binlog_end_pos,
key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
@ -936,8 +936,10 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_thread_count, key_LOCK_thread_cache, key_LOCK_thread_count, key_LOCK_thread_cache,
key_PARTITION_LOCK_auto_inc; key_PARTITION_LOCK_auto_inc;
PSI_mutex_key key_RELAYLOG_LOCK_index; PSI_mutex_key key_RELAYLOG_LOCK_index;
PSI_mutex_key key_LOCK_relaylog_end_pos;
PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state, PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry; 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, PSI_mutex_key key_LOCK_stats,
key_LOCK_global_user_client_stats, key_LOCK_global_table_stats, key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
@ -949,6 +951,7 @@ PSI_mutex_key key_LOCK_after_binlog_sync;
PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered, PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
key_LOCK_slave_background; key_LOCK_slave_background;
PSI_mutex_key key_TABLE_SHARE_LOCK_share; PSI_mutex_key key_TABLE_SHARE_LOCK_share;
PSI_mutex_key key_LOCK_ack_receiver;
PSI_mutex_key key_TABLE_SHARE_LOCK_rotation; PSI_mutex_key key_TABLE_SHARE_LOCK_rotation;
PSI_cond_key key_TABLE_SHARE_COND_rotation; PSI_cond_key key_TABLE_SHARE_COND_rotation;
@ -970,8 +973,9 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0}, { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0},
{ &key_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0}, { &key_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0},
{ &key_BINLOG_LOCK_binlog_background_thread, "MYSQL_BIN_LOG::LOCK_binlog_background_thread", 0}, { &key_BINLOG_LOCK_binlog_background_thread, "MYSQL_BIN_LOG::LOCK_binlog_background_thread", 0},
{ &m_key_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0 }, { &key_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0 },
{ &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0}, { &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0},
{ &key_LOCK_relaylog_end_pos, "MYSQL_RELAY_LOG::LOCK_binlog_end_pos", 0},
{ &key_delayed_insert_mutex, "Delayed_insert::mutex", 0}, { &key_delayed_insert_mutex, "Delayed_insert::mutex", 0},
{ &key_hash_filo_lock, "hash_filo::lock", 0}, { &key_hash_filo_lock, "hash_filo::lock", 0},
{ &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL}, { &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL},
@ -1029,7 +1033,9 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_binlog_state, "LOCK_binlog_state", 0}, { &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
{ &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0}, { &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
{ &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 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_ack_receiver, "Ack_receiver::mutex", 0},
{ &key_LOCK_binlog, "LOCK_binlog", 0}
}; };
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger, PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
@ -1058,7 +1064,8 @@ static PSI_rwlock_info all_server_rwlocks[]=
PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool; PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
#endif /* HAVE_MMAP */ #endif /* HAVE_MMAP */
PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond, PSI_cond_key key_BINLOG_COND_xid_list,
key_BINLOG_COND_bin_log_updated, key_BINLOG_COND_relay_log_updated,
key_BINLOG_COND_binlog_background_thread, key_BINLOG_COND_binlog_background_thread,
key_BINLOG_COND_binlog_background_thread_end, key_BINLOG_COND_binlog_background_thread_end,
key_COND_cache_status_changed, key_COND_manager, key_COND_cache_status_changed, key_COND_manager,
@ -1072,9 +1079,10 @@ PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
key_rpl_group_info_sleep_cond, key_rpl_group_info_sleep_cond,
key_TABLE_SHARE_cond, key_user_level_lock_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_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; key_BINLOG_COND_queue_busy;
PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready, PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
key_COND_wait_commit; key_COND_wait_commit;
PSI_cond_key key_RELAYLOG_COND_queue_busy; PSI_cond_key key_RELAYLOG_COND_queue_busy;
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy; PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
@ -1083,6 +1091,7 @@ PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
key_COND_parallel_entry, key_COND_group_commit_orderer, key_COND_parallel_entry, key_COND_group_commit_orderer,
key_COND_prepare_ordered, key_COND_slave_background; key_COND_prepare_ordered, key_COND_slave_background;
PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates; PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
PSI_cond_key key_COND_ack_receiver;
static PSI_cond_info all_server_conds[]= static PSI_cond_info all_server_conds[]=
{ {
@ -1095,12 +1104,13 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0}, { &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0},
{ &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0}, { &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
#endif /* HAVE_MMAP */ #endif /* HAVE_MMAP */
{ &key_BINLOG_COND_bin_log_updated, "MYSQL_BIN_LOG::COND_bin_log_updated", 0}, { &key_BINLOG_COND_relay_log_updated, "MYSQL_BIN_LOG::COND_relay_log_updated", 0},
{ &key_BINLOG_COND_xid_list, "MYSQL_BIN_LOG::COND_xid_list", 0}, { &key_BINLOG_COND_xid_list, "MYSQL_BIN_LOG::COND_xid_list", 0},
{ &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0},
{ &key_BINLOG_COND_binlog_background_thread, "MYSQL_BIN_LOG::COND_binlog_background_thread", 0}, { &key_BINLOG_COND_binlog_background_thread, "MYSQL_BIN_LOG::COND_binlog_background_thread", 0},
{ &key_BINLOG_COND_binlog_background_thread_end, "MYSQL_BIN_LOG::COND_binlog_background_thread_end", 0}, { &key_BINLOG_COND_binlog_background_thread_end, "MYSQL_BIN_LOG::COND_binlog_background_thread_end", 0},
{ &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0}, { &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
{ &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0}, { &key_RELAYLOG_COND_relay_log_updated, "MYSQL_RELAY_LOG::COND_relay_log_updated", 0},
{ &key_RELAYLOG_COND_bin_log_updated, "MYSQL_RELAY_LOG::COND_bin_log_updated", 0},
{ &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0}, { &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
{ &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0}, { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
{ &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 0}, { &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 0},
@ -1135,6 +1145,8 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL}, { &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL},
{ &key_COND_wait_gtid, "COND_wait_gtid", 0}, { &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_ack_receiver, "Ack_receiver::cond", 0},
{ &key_COND_binlog_send, "COND_binlog_send", 0},
{ &key_TABLE_SHARE_COND_rotation, "TABLE_SHARE::COND_rotation", 0} { &key_TABLE_SHARE_COND_rotation, "TABLE_SHARE::COND_rotation", 0}
}; };
@ -1142,6 +1154,7 @@ PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
key_thread_handle_manager, key_thread_main, key_thread_handle_manager, key_thread_main,
key_thread_one_connection, key_thread_signal_hand, key_thread_one_connection, key_thread_signal_hand,
key_thread_slave_background, key_rpl_parallel_thread; key_thread_slave_background, key_rpl_parallel_thread;
PSI_thread_key key_thread_ack_receiver;
static PSI_thread_info all_server_threads[]= static PSI_thread_info all_server_threads[]=
{ {
@ -1168,6 +1181,7 @@ static PSI_thread_info all_server_threads[]=
{ &key_thread_one_connection, "one_connection", 0}, { &key_thread_one_connection, "one_connection", 0},
{ &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL}, { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
{ &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL}, { &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL},
{ &key_thread_ack_receiver, "Ack_receiver", PSI_FLAG_GLOBAL},
{ &key_rpl_parallel_thread, "rpl_parallel_thread", 0} { &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
}; };
@ -1747,6 +1761,7 @@ static void close_connections(void)
Events::deinit(); Events::deinit();
slave_prepare_for_shutdown(); slave_prepare_for_shutdown();
mysql_bin_log.stop_background_thread(); mysql_bin_log.stop_background_thread();
ack_receiver.stop();
/* /*
Give threads time to die. Give threads time to die.
@ -2228,7 +2243,9 @@ void clean_up(bool print_message)
ha_end(); ha_end();
if (tc_log) if (tc_log)
tc_log->close(); tc_log->close();
delegates_destroy(); #ifdef HAVE_REPLICATION
semi_sync_master_deinit();
#endif
xid_cache_free(); xid_cache_free();
tdc_deinit(); tdc_deinit();
mdl_destroy(); mdl_destroy();
@ -4247,10 +4264,12 @@ static int init_common_variables()
constructor (called before main()). constructor (called before main()).
*/ */
mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index, mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
key_BINLOG_update_cond, key_BINLOG_COND_relay_log_updated,
key_BINLOG_COND_bin_log_updated,
key_file_binlog, key_file_binlog,
key_file_binlog_index, key_file_binlog_index,
key_BINLOG_COND_queue_busy); key_BINLOG_COND_queue_busy,
key_LOCK_binlog_end_pos);
#endif #endif
/* /*
@ -5143,13 +5162,6 @@ static int init_server_components()
xid_cache_init(); xid_cache_init();
/*
initialize delegates for extension observers, errors have already
been reported in the function
*/
if (delegates_init())
unireg_abort(1);
/* need to configure logging before initializing storage engines */ /* need to configure logging before initializing storage engines */
if (!opt_bin_log_used && !WSREP_ON) if (!opt_bin_log_used && !WSREP_ON)
{ {
@ -5181,6 +5193,13 @@ static int init_server_components()
"this server. However this will be ignored as the " "this server. However this will be ignored as the "
"--log-bin option is not defined."); "--log-bin option is not defined.");
} }
if (repl_semisync_master.init_object() ||
repl_semisync_slave.init_object())
{
sql_print_error("Could not initialize semisync.");
unireg_abort(1);
}
#endif #endif
if (opt_bin_log) if (opt_bin_log)
@ -8271,6 +8290,27 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff,
return 0; 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.set_export_stats(); \
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 #ifdef HAVE_YASSL
@ -8589,6 +8629,26 @@ SHOW_VAR status_vars[]= {
{"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
{"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), 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}, {"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},
{"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},
{"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL},
{"Rpl_semi_sync_slave_send_ack", (char*) &rpl_semi_sync_slave_send_ack, SHOW_LONGLONG},
#endif /* HAVE_REPLICATION */
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH}, {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH}, {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@ -10329,6 +10389,10 @@ 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_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_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_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_semi_sync_slave={ 0, "Waiting for semi-sync slave connection", 0};
PSI_stage_info stage_reading_semi_sync_ack={ 0, "Reading 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_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_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}; PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
@ -10489,6 +10553,9 @@ PSI_stage_info *all_server_stages[]=
& stage_gtid_wait_other_connection, & stage_gtid_wait_other_connection,
& stage_slave_background_process_request, & stage_slave_background_process_request,
& stage_slave_background_wait_request, & stage_slave_background_wait_request,
& stage_waiting_for_semi_sync_ack_from_slave,
& stage_waiting_for_semi_sync_slave,
& stage_reading_semi_sync_ack,
& stage_waiting_for_deadlock_kill & stage_waiting_for_deadlock_kill
}; };

View File

@ -329,7 +329,7 @@ extern PSI_mutex_key key_LOCK_des_key_file;
extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_BINLOG_LOCK_binlog_background_thread, key_BINLOG_LOCK_binlog_background_thread,
m_key_LOCK_binlog_end_pos, key_LOCK_binlog_end_pos,
key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
@ -349,6 +349,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_start_thread, key_LOCK_start_thread,
key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc;
extern PSI_mutex_key key_RELAYLOG_LOCK_index; extern PSI_mutex_key key_RELAYLOG_LOCK_index;
extern PSI_mutex_key key_LOCK_relaylog_end_pos;
extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state, extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry; key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
@ -383,7 +384,8 @@ extern PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
key_TABLE_SHARE_cond, key_user_level_lock_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond,
key_COND_start_thread, key_COND_start_thread,
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;
extern PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready, extern PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
key_COND_wait_commit; key_COND_wait_commit;
extern PSI_cond_key key_RELAYLOG_COND_queue_busy; extern PSI_cond_key key_RELAYLOG_COND_queue_busy;
extern PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy; extern PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;

View File

@ -18,16 +18,14 @@
/*************************************************************************** /***************************************************************************
NOTE: plugin locking. 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 The plugin is locked on Binlog_transmit_observer::transmit_start and is
is locked on Binlog_transmit_observer::transmit_start and is unlocked after unlocked after Binlog_transmit_observer::transmit_stop. All other
Binlog_transmit_observer::transmit_stop. All other master observable events master observable events happen between these two and don't lock the
happen between these two and don't lock the plugin at all. This works well plugin at all.
for the semisync_master plugin.
Also a plugin is locked on Binlog_relay_IO_observer::thread_start 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 and unlocked after Binlog_relay_IO_observer::thread_stop.
the semisync_slave plugin.
***************************************************************************/ ***************************************************************************/
#include <mysql.h> #include <mysql.h>

View File

@ -1,553 +0,0 @@
/* Copyright (c) 2008, 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 */
#include "mariadb.h"
#include "sql_priv.h"
#include "unireg.h"
#include "rpl_mi.h"
#include "sql_repl.h"
#include "log_event.h"
#include "rpl_filter.h"
#include <my_dir.h>
#include "rpl_handler.h"
Trans_delegate *transaction_delegate;
Binlog_storage_delegate *binlog_storage_delegate;
#ifdef HAVE_REPLICATION
Binlog_transmit_delegate *binlog_transmit_delegate;
Binlog_relay_IO_delegate *binlog_relay_io_delegate;
#endif /* HAVE_REPLICATION */
/*
structure to save transaction log filename and position
*/
typedef struct Trans_binlog_info {
my_off_t log_pos;
char log_file[FN_REFLEN];
} Trans_binlog_info;
int get_user_var_int(const char *name,
long long int *value, int *null_value)
{
bool null_val;
user_var_entry *entry=
(user_var_entry*) my_hash_search(&current_thd->user_vars,
(uchar*) name, strlen(name));
if (!entry)
return 1;
*value= entry->val_int(&null_val);
if (null_value)
*null_value= null_val;
return 0;
}
int get_user_var_real(const char *name,
double *value, int *null_value)
{
bool null_val;
user_var_entry *entry=
(user_var_entry*) my_hash_search(&current_thd->user_vars,
(uchar*) name, strlen(name));
if (!entry)
return 1;
*value= entry->val_real(&null_val);
if (null_value)
*null_value= null_val;
return 0;
}
int get_user_var_str(const char *name, char *value,
size_t len, unsigned int precision, int *null_value)
{
String str;
bool null_val;
user_var_entry *entry=
(user_var_entry*) my_hash_search(&current_thd->user_vars,
(uchar*) name, strlen(name));
if (!entry)
return 1;
entry->val_str(&null_val, &str, precision);
strncpy(value, str.c_ptr(), len);
if (null_value)
*null_value= null_val;
return 0;
}
int delegates_init()
{
static my_aligned_storage<sizeof(Trans_delegate), MY_ALIGNOF(long)> trans_mem;
static my_aligned_storage<sizeof(Binlog_storage_delegate),
MY_ALIGNOF(long)> storage_mem;
#ifdef HAVE_REPLICATION
static my_aligned_storage<sizeof(Binlog_transmit_delegate),
MY_ALIGNOF(long)> transmit_mem;
static my_aligned_storage<sizeof(Binlog_relay_IO_delegate),
MY_ALIGNOF(long)> relay_io_mem;
#endif
void *place_trans_mem= trans_mem.data;
void *place_storage_mem= storage_mem.data;
transaction_delegate= new (place_trans_mem) Trans_delegate;
if (!transaction_delegate->is_inited())
{
sql_print_error("Initialization of transaction delegates failed. "
"Please report a bug.");
return 1;
}
binlog_storage_delegate= new (place_storage_mem) Binlog_storage_delegate;
if (!binlog_storage_delegate->is_inited())
{
sql_print_error("Initialization binlog storage delegates failed. "
"Please report a bug.");
return 1;
}
#ifdef HAVE_REPLICATION
void *place_transmit_mem= transmit_mem.data;
void *place_relay_io_mem= relay_io_mem.data;
binlog_transmit_delegate= new (place_transmit_mem) Binlog_transmit_delegate;
if (!binlog_transmit_delegate->is_inited())
{
sql_print_error("Initialization of binlog transmit delegates failed. "
"Please report a bug.");
return 1;
}
binlog_relay_io_delegate= new (place_relay_io_mem) Binlog_relay_IO_delegate;
if (!binlog_relay_io_delegate->is_inited())
{
sql_print_error("Initialization binlog relay IO delegates failed. "
"Please report a bug.");
return 1;
}
#endif
return 0;
}
void delegates_destroy()
{
if (transaction_delegate)
transaction_delegate->~Trans_delegate();
if (binlog_storage_delegate)
binlog_storage_delegate->~Binlog_storage_delegate();
#ifdef HAVE_REPLICATION
if (binlog_transmit_delegate)
binlog_transmit_delegate->~Binlog_transmit_delegate();
if (binlog_relay_io_delegate)
binlog_relay_io_delegate->~Binlog_relay_IO_delegate();
#endif /* HAVE_REPLICATION */
}
/*
This macro is used by almost all the Delegate methods to iterate
over all the observers running given callback function of the
delegate.
*/
#define FOREACH_OBSERVER(r, f, do_lock, args) \
param.server_id= thd->variables.server_id; \
read_lock(); \
Observer_info_iterator iter= observer_info_iter(); \
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); \
break; \
} \
} \
unlock();
int Trans_delegate::after_commit(THD *thd, bool all)
{
Trans_param param;
Trans_binlog_info *log_info;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
int ret= 0;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
log_info= thd->semisync_info;
param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
param.log_pos= log_info ? log_info->log_pos : 0;
FOREACH_OBSERVER(ret, after_commit, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
can mark the memory unused.
*/
if (is_real_trans && log_info)
{
log_info->log_file[0]= 0;
log_info->log_pos= 0;
}
return ret;
}
int Trans_delegate::after_rollback(THD *thd, bool all)
{
Trans_param param;
Trans_binlog_info *log_info;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
int ret= 0;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
log_info= thd->semisync_info;
param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
param.log_pos= log_info ? log_info->log_pos : 0;
FOREACH_OBSERVER(ret, after_rollback, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
can mark the memory unused.
*/
if (is_real_trans && log_info)
{
log_info->log_file[0]= 0;
log_info->log_pos= 0;
}
return ret;
}
int Binlog_storage_delegate::after_flush(THD *thd,
const char *log_file,
my_off_t log_pos,
bool synced,
bool first_in_group,
bool last_in_group)
{
Binlog_storage_param param;
Trans_binlog_info *log_info;
uint32 flags=0;
int ret= 0;
if (synced)
flags |= BINLOG_STORAGE_IS_SYNCED;
if (first_in_group)
flags|= BINLOG_GROUP_COMMIT_LEADER;
if (last_in_group)
flags|= BINLOG_GROUP_COMMIT_TRAILER;
if (!(log_info= thd->semisync_info))
{
if(!(log_info=
(Trans_binlog_info*) my_malloc(sizeof(Trans_binlog_info), MYF(0))))
return 1;
thd->semisync_info= log_info;
}
strmake_buf(log_info->log_file, log_file+dirname_length(log_file));
log_info->log_pos = log_pos;
FOREACH_OBSERVER(ret, after_flush, false,
(&param, log_info->log_file, log_info->log_pos, flags));
return ret;
}
int Binlog_storage_delegate::after_sync(THD *thd,
const char *log_file,
my_off_t log_pos,
bool first_in_group,
bool last_in_group)
{
Binlog_storage_param param;
uint32 flags=0;
if (first_in_group)
flags|= BINLOG_GROUP_COMMIT_LEADER;
if (last_in_group)
flags|= BINLOG_GROUP_COMMIT_TRAILER;
int ret= 0;
FOREACH_OBSERVER(ret, after_sync, false,
(&param, log_file+dirname_length(log_file), log_pos, flags));
return ret;
}
#ifdef HAVE_REPLICATION
int Binlog_transmit_delegate::transmit_start(THD *thd, ushort flags,
const char *log_file,
my_off_t log_pos)
{
Binlog_transmit_param param;
param.flags= flags;
int ret= 0;
FOREACH_OBSERVER(ret, transmit_start, true, (&param, log_file, log_pos));
return ret;
}
int Binlog_transmit_delegate::transmit_stop(THD *thd, ushort flags)
{
Binlog_transmit_param param;
param.flags= flags;
int ret= 0;
FOREACH_OBSERVER(ret, transmit_stop, false, (&param));
return ret;
}
int Binlog_transmit_delegate::reserve_header(THD *thd, ushort flags,
String *packet)
{
/* NOTE2ME: Maximum extra header size for each observer, I hope 32
bytes should be enough for each Observer to reserve their extra
header. If later found this is not enough, we can increase this
/HEZX
*/
#define RESERVE_HEADER_SIZE 32
unsigned char header[RESERVE_HEADER_SIZE];
ulong hlen;
Binlog_transmit_param param;
param.flags= flags;
param.server_id= thd->variables.server_id;
int ret= 0;
read_lock();
Observer_info_iterator iter= observer_info_iter();
Observer_info *info= iter++;
for (; info; info= iter++)
{
hlen= 0;
if (((Observer *)info->observer)->reserve_header
&& ((Observer *)info->observer)->reserve_header(&param,
header,
RESERVE_HEADER_SIZE,
&hlen))
{
ret= 1;
break;
}
if (hlen == 0)
continue;
if (hlen > RESERVE_HEADER_SIZE || packet->append((char *)header, hlen))
{
ret= 1;
break;
}
}
unlock();
return ret;
}
int Binlog_transmit_delegate::before_send_event(THD *thd, ushort flags,
String *packet,
const char *log_file,
my_off_t log_pos)
{
Binlog_transmit_param param;
param.flags= flags;
int ret= 0;
FOREACH_OBSERVER(ret, before_send_event, false,
(&param, (uchar *)packet->c_ptr(),
packet->length(),
log_file+dirname_length(log_file), log_pos));
return ret;
}
int Binlog_transmit_delegate::after_send_event(THD *thd, ushort flags,
String *packet)
{
Binlog_transmit_param param;
param.flags= flags;
int ret= 0;
FOREACH_OBSERVER(ret, after_send_event, false,
(&param, packet->c_ptr(), packet->length()));
return ret;
}
int Binlog_transmit_delegate::after_reset_master(THD *thd, ushort flags)
{
Binlog_transmit_param param;
param.flags= flags;
int ret= 0;
FOREACH_OBSERVER(ret, after_reset_master, false, (&param));
return ret;
}
void Binlog_relay_IO_delegate::init_param(Binlog_relay_IO_param *param,
Master_info *mi)
{
param->mysql= mi->mysql;
param->user= mi->user;
param->host= mi->host;
param->port= mi->port;
param->master_log_name= mi->master_log_name;
param->master_log_pos= mi->master_log_pos;
}
int Binlog_relay_IO_delegate::thread_start(THD *thd, Master_info *mi)
{
Binlog_relay_IO_param param;
init_param(&param, mi);
int ret= 0;
FOREACH_OBSERVER(ret, thread_start, true, (&param));
return ret;
}
int Binlog_relay_IO_delegate::thread_stop(THD *thd, Master_info *mi)
{
Binlog_relay_IO_param param;
init_param(&param, mi);
int ret= 0;
FOREACH_OBSERVER(ret, thread_stop, false, (&param));
return ret;
}
int Binlog_relay_IO_delegate::before_request_transmit(THD *thd,
Master_info *mi,
ushort flags)
{
Binlog_relay_IO_param param;
init_param(&param, mi);
int ret= 0;
FOREACH_OBSERVER(ret, before_request_transmit, false, (&param, (uint32)flags));
return ret;
}
int Binlog_relay_IO_delegate::after_read_event(THD *thd, Master_info *mi,
const char *packet, ulong len,
const char **event_buf,
ulong *event_len)
{
Binlog_relay_IO_param param;
init_param(&param, mi);
int ret= 0;
FOREACH_OBSERVER(ret, after_read_event, false,
(&param, packet, len, event_buf, event_len));
return ret;
}
int Binlog_relay_IO_delegate::after_queue_event(THD *thd, Master_info *mi,
const char *event_buf,
ulong event_len,
bool synced)
{
Binlog_relay_IO_param param;
init_param(&param, mi);
uint32 flags=0;
if (synced)
flags |= BINLOG_STORAGE_IS_SYNCED;
int ret= 0;
FOREACH_OBSERVER(ret, after_queue_event, false,
(&param, event_buf, event_len, flags));
return ret;
}
int Binlog_relay_IO_delegate::after_reset_slave(THD *thd, Master_info *mi)
{
Binlog_relay_IO_param param;
init_param(&param, mi);
int ret= 0;
FOREACH_OBSERVER(ret, after_reset_slave, false, (&param));
return ret;
}
#endif /* HAVE_REPLICATION */
int register_trans_observer(Trans_observer *observer, void *p)
{
return transaction_delegate->add_observer(observer, (st_plugin_int *)p);
}
int unregister_trans_observer(Trans_observer *observer, void *p)
{
return transaction_delegate->remove_observer(observer, (st_plugin_int *)p);
}
int register_binlog_storage_observer(Binlog_storage_observer *observer, void *p)
{
return binlog_storage_delegate->add_observer(observer, (st_plugin_int *)p);
}
int unregister_binlog_storage_observer(Binlog_storage_observer *observer, void *p)
{
return binlog_storage_delegate->remove_observer(observer, (st_plugin_int *)p);
}
#ifdef HAVE_REPLICATION
int register_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
{
return binlog_transmit_delegate->add_observer(observer, (st_plugin_int *)p);
}
int unregister_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
{
return binlog_transmit_delegate->remove_observer(observer, (st_plugin_int *)p);
}
int register_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
{
return binlog_relay_io_delegate->add_observer(observer, (st_plugin_int *)p);
}
int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
{
return binlog_relay_io_delegate->remove_observer(observer, (st_plugin_int *)p);
}
#else
int register_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
{
return 0;
}
int unregister_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p)
{
return 0;
}
int register_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
{
return 0;
}
int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p)
{
return 0;
}
#endif /* HAVE_REPLICATION */

View File

@ -1,216 +0,0 @@
/* Copyright (c) 2008, 2011, 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 */
#ifndef RPL_HANDLER_H
#define RPL_HANDLER_H
#include "sql_priv.h"
#include "rpl_mi.h"
#include "rpl_rli.h"
#include "sql_plugin.h"
#include "replication.h"
class Observer_info {
public:
void *observer;
st_plugin_int *plugin_int;
Observer_info(void *ob, st_plugin_int *p)
:observer(ob), plugin_int(p)
{ }
};
class Delegate {
public:
typedef List<Observer_info> Observer_info_list;
typedef List_iterator<Observer_info> Observer_info_iterator;
int add_observer(void *observer, st_plugin_int *plugin)
{
int ret= FALSE;
if (!inited)
return TRUE;
write_lock();
Observer_info_iterator iter(observer_info_list);
Observer_info *info= iter++;
while (info && info->observer != observer)
info= iter++;
if (!info)
{
info= new Observer_info(observer, plugin);
if (!info || observer_info_list.push_back(info, &memroot))
ret= TRUE;
}
else
ret= TRUE;
unlock();
return ret;
}
int remove_observer(void *observer, st_plugin_int *plugin)
{
int ret= FALSE;
if (!inited)
return TRUE;
write_lock();
Observer_info_iterator iter(observer_info_list);
Observer_info *info= iter++;
while (info && info->observer != observer)
info= iter++;
if (info)
{
iter.remove();
delete info;
}
else
ret= TRUE;
unlock();
return ret;
}
inline Observer_info_iterator observer_info_iter()
{
return Observer_info_iterator(observer_info_list);
}
inline bool is_empty()
{
return observer_info_list.is_empty();
}
inline int read_lock()
{
if (!inited)
return TRUE;
return rw_rdlock(&lock);
}
inline int write_lock()
{
if (!inited)
return TRUE;
return rw_wrlock(&lock);
}
inline int unlock()
{
if (!inited)
return TRUE;
return rw_unlock(&lock);
}
inline bool is_inited()
{
return inited;
}
Delegate()
{
inited= FALSE;
if (my_rwlock_init(&lock, NULL))
return;
init_sql_alloc(&memroot, 1024, 0, MYF(0));
inited= TRUE;
}
~Delegate()
{
inited= FALSE;
rwlock_destroy(&lock);
free_root(&memroot, MYF(0));
}
private:
Observer_info_list observer_info_list;
rw_lock_t lock;
MEM_ROOT memroot;
bool inited;
};
class Trans_delegate
:public Delegate {
public:
typedef Trans_observer Observer;
int before_commit(THD *thd, bool all);
int before_rollback(THD *thd, bool all);
int after_commit(THD *thd, bool all);
int after_rollback(THD *thd, bool all);
};
class Binlog_storage_delegate
:public Delegate {
public:
typedef Binlog_storage_observer Observer;
int after_flush(THD *thd, const char *log_file,
my_off_t log_pos, bool synced,
bool first_in_group, bool last_in_group);
int after_sync(THD *thd, const char *log_file, my_off_t log_pos,
bool first_in_group, bool last_in_group);
};
#ifdef HAVE_REPLICATION
class Binlog_transmit_delegate
:public Delegate {
public:
typedef Binlog_transmit_observer Observer;
int transmit_start(THD *thd, ushort flags,
const char *log_file, my_off_t log_pos);
int transmit_stop(THD *thd, ushort flags);
int reserve_header(THD *thd, ushort flags, String *packet);
int before_send_event(THD *thd, ushort flags,
String *packet, const
char *log_file, my_off_t log_pos );
int after_send_event(THD *thd, ushort flags,
String *packet);
int after_reset_master(THD *thd, ushort flags);
};
class Binlog_relay_IO_delegate
:public Delegate {
public:
typedef Binlog_relay_IO_observer Observer;
int thread_start(THD *thd, Master_info *mi);
int thread_stop(THD *thd, Master_info *mi);
int before_request_transmit(THD *thd, Master_info *mi, ushort flags);
int after_read_event(THD *thd, Master_info *mi,
const char *packet, ulong len,
const char **event_buf, ulong *event_len);
int after_queue_event(THD *thd, Master_info *mi,
const char *event_buf, ulong event_len,
bool synced);
int after_reset_slave(THD *thd, Master_info *mi);
private:
void init_param(Binlog_relay_IO_param *param, Master_info *mi);
};
#endif /* HAVE_REPLICATION */
int delegates_init();
void delegates_destroy();
extern Trans_delegate *transaction_delegate;
extern Binlog_storage_delegate *binlog_storage_delegate;
#ifdef HAVE_REPLICATION
extern Binlog_transmit_delegate *binlog_transmit_delegate;
extern Binlog_relay_IO_delegate *binlog_relay_io_delegate;
#endif /* HAVE_REPLICATION */
/*
if there is no observers in the delegate, we can return 0
immediately.
*/
#define RUN_HOOK(group, hook, args) \
(group ##_delegate->is_empty() ? \
0 : group ##_delegate->hook args)
#endif /* RPL_HANDLER_H */

View File

@ -311,6 +311,11 @@ class Master_info : public Slave_reporting_capability
/* The parallel replication mode. */ /* The parallel replication mode. */
enum_slave_parallel_mode parallel_mode; enum_slave_parallel_mode parallel_mode;
/*
semi_ack is used to identify if the current binlog event needs an
ACK from slave, or if delay_master is enabled.
*/
int semi_ack;
}; };
int init_master_info(Master_info* mi, const char* master_info_fname, int init_master_info(Master_info* mi, const char* master_info_fname,

Some files were not shown because too many files have changed in this diff Show More