summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-03-11 17:49:36 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-03-11 17:49:36 +0200
commit814205f306cad8a4b3e55785616ea69a027fef9d (patch)
treef70402682975e8c6a99ea34a7b1ff3dd9ba73b32
parent89b463ee99c22e69fe4adf686e0d61cd20973c49 (diff)
parent28e713dc12881e7f50207d0c642523ca3e630114 (diff)
downloadmariadb-git-814205f306cad8a4b3e55785616ea69a027fef9d.tar.gz
Merge 10.2 into 10.3
-rw-r--r--CMakeLists.txt8
-rw-r--r--cmake/os/Linux.cmake4
-rw-r--r--cmake/plugin.cmake4
-rw-r--r--mysql-test/suite/galera/disabled.def4
-rw-r--r--mysql-test/suite/galera/r/galera_kill_nochanges.result2
-rw-r--r--mysql-test/suite/galera/r/galera_many_rows.result28
-rw-r--r--mysql-test/suite/galera/r/galera_var_dirty_reads.result2
-rw-r--r--mysql-test/suite/galera/r/galera_var_notify_cmd.result1
-rw-r--r--mysql-test/suite/galera/t/galera_autoinc_sst_mariabackup.test10
-rw-r--r--mysql-test/suite/galera/t/galera_kill_nochanges.test9
-rw-r--r--mysql-test/suite/galera/t/galera_many_rows.cnf5
-rw-r--r--mysql-test/suite/galera/t/galera_many_rows.test19
-rw-r--r--mysql-test/suite/galera/t/galera_var_dirty_reads.test5
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup_section.result18
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync_section.result14
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.cnf39
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.opt1
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test69
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.cnf31
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.opt1
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.test32
-rw-r--r--mysql-test/suite/innodb/include/wait_all_purged.inc2
-rwxr-xr-xscripts/wsrep_sst_common.sh2
-rw-r--r--scripts/wsrep_sst_mariabackup.sh24
-rw-r--r--scripts/wsrep_sst_rsync.sh5
-rw-r--r--storage/innobase/include/que0que.h35
-rw-r--r--storage/innobase/include/que0types.h39
-rw-r--r--storage/innobase/include/row0import.h21
-rw-r--r--storage/innobase/include/row0purge.h77
-rw-r--r--storage/innobase/row/row0import.cc30
-rw-r--r--storage/innobase/row/row0mysql.cc2
-rw-r--r--storage/innobase/row/row0purge.cc76
-rw-r--r--storage/innobase/trx/trx0purge.cc21
33 files changed, 428 insertions, 212 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fc30750df99..a8e6307e975 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -213,6 +213,14 @@ IF (WITH_TSAN)
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=thread" DEBUG RELWITHDEBINFO)
ENDIF()
+OPTION(WITH_UBSAN "Enable undefined behavior sanitizer" OFF)
+IF (WITH_UBSAN)
+ IF(SECURITY_HARDENED)
+ MESSAGE(FATAL_ERROR "WITH_UBSAN and SECURITY_HARDENED are mutually exclusive")
+ ENDIF()
+ MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined" DEBUG RELWITHDEBINFO)
+ENDIF()
+
IF(NOT WITH_TSAN)
# enable security hardening features, like most distributions do
# in our benchmarks that costs about ~1% of performance, depending on the load
diff --git a/cmake/os/Linux.cmake b/cmake/os/Linux.cmake
index e3520f3accd..557b276113f 100644
--- a/cmake/os/Linux.cmake
+++ b/cmake/os/Linux.cmake
@@ -34,8 +34,8 @@ ENDFOREACH()
# Ensure we have clean build for shared libraries
# without unresolved symbols
-# Not supported with AddressSanitizer and ThreadSanitizer
-IF(NOT WITH_ASAN AND NOT WITH_TSAN)
+# Not supported with the clang sanitizers
+IF(NOT WITH_ASAN AND NOT WITH_TSAN AND NOT WITH_UBSAN)
SET(LINK_FLAG_NO_UNDEFINED "-Wl,--no-undefined")
ENDIF()
diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake
index 5b3bac773e1..1252a796ba6 100644
--- a/cmake/plugin.cmake
+++ b/cmake/plugin.cmake
@@ -1,5 +1,5 @@
# Copyright (c) 2009, 2018, Oracle and/or its affiliates.
-# Copyright (c) 2011, 2018, MariaDB Corporation
+# Copyright (c) 2011, 2019, 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
@@ -209,7 +209,7 @@ MACRO(MYSQL_ADD_PLUGIN)
ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES (${target} mysqld)
ENDIF()
- ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT WITH_ASAN AND NOT WITH_TSAN)
+ ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT WITH_ASAN AND NOT WITH_TSAN AND NOT WITH_UBSAN)
TARGET_LINK_LIBRARIES (${target} "-Wl,--no-undefined")
ENDIF()
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 863ee1306be..d744e3cb811 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -25,8 +25,10 @@ galera_as_slave_preordered : wsrep-preordered feature not merged to MariaDB
galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event()
galera_binlog_rows_query_log_events: MariaDB does not support binlog_rows_query_log_events
galera_flush : MariaDB does not have global.thread_statistics
+galera_gcache_recover_manytrx : MDEV-18834 Galera test failure
galera_gcs_fc_limit : MDEV-17061 Timeout in wait_condition.inc for PROCESSLIST
-galera_ist_progress: MDEV-15236 galera_ist_progress fails when trying to read transfer status
+galera_ist_mariabackup : MDEV-18829 test leaves port open
+galera_ist_progress: MDEV-15236 fails when trying to read transfer status
galera_kill_applier : race condition at the start of the test
galera_kill_ddl : MDEV-17108 Test failure on galera.galera_kill_ddl
galera_migrate : MariaDB does not support START SLAVE USER
diff --git a/mysql-test/suite/galera/r/galera_kill_nochanges.result b/mysql-test/suite/galera/r/galera_kill_nochanges.result
index 56caf1bd9ea..3ccf73f0d46 100644
--- a/mysql-test/suite/galera/r/galera_kill_nochanges.result
+++ b/mysql-test/suite/galera/r/galera_kill_nochanges.result
@@ -1,4 +1,6 @@
connection node_1;
+connection node_2;
+connection node_1;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connection node_2;
diff --git a/mysql-test/suite/galera/r/galera_many_rows.result b/mysql-test/suite/galera/r/galera_many_rows.result
index b06925fea60..d6669fe6bdf 100644
--- a/mysql-test/suite/galera/r/galera_many_rows.result
+++ b/mysql-test/suite/galera/r/galera_many_rows.result
@@ -1,7 +1,9 @@
connection node_1;
+connection node_2;
+connection node_1;
SET SESSION innodb_lock_wait_timeout=600;
SET SESSION lock_wait_timeout=600;
-CREATE TABLE ten (f1 INTEGER);
+CREATE TABLE ten (f1 INTEGER) engine=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB;
INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
@@ -9,24 +11,24 @@ connection node_2;
SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_sync_wait = 15;
SET GLOBAL wsrep_provider_options = 'repl.causal_read_timeout=PT1H';
-SELECT COUNT(*) = 100000 FROM t1;
-COUNT(*) = 100000
-1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+100000
INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
connection node_1;
-SELECT COUNT(*) = 200000 FROM t1;
-COUNT(*) = 200000
-1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+200000
UPDATE t1 SET f2 = 1;
connection node_2;
-SELECT COUNT(*) = 200000 FROM t1 WHERE f2 = 1;
-COUNT(*) = 200000
-1
+SELECT COUNT(*) FROM t1 WHERE f2 = 1;
+COUNT(*)
+200000
connection node_1;
START TRANSACTION;
-SELECT COUNT(*) = 200000 FROM t1;
-COUNT(*) = 200000
-1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+200000
UPDATE t1 SET f2 = 3;
connection node_2;
START TRANSACTION;
diff --git a/mysql-test/suite/galera/r/galera_var_dirty_reads.result b/mysql-test/suite/galera/r/galera_var_dirty_reads.result
index 049aa5be3cc..020efb7b8f1 100644
--- a/mysql-test/suite/galera/r/galera_var_dirty_reads.result
+++ b/mysql-test/suite/galera/r/galera_var_dirty_reads.result
@@ -1,7 +1,5 @@
connection node_1;
connection node_2;
-connection node_1;
-connection node_2;
connection node_2;
CREATE TABLE t1(i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES(1);
diff --git a/mysql-test/suite/galera/r/galera_var_notify_cmd.result b/mysql-test/suite/galera/r/galera_var_notify_cmd.result
index e9e4605e1bc..bcd9875743a 100644
--- a/mysql-test/suite/galera/r/galera_var_notify_cmd.result
+++ b/mysql-test/suite/galera/r/galera_var_notify_cmd.result
@@ -1,3 +1,4 @@
+connection node_1;
SELECT COUNT(DISTINCT uuid) = 2 FROM mtr_wsrep_notify.membership;
COUNT(DISTINCT uuid) = 2
1
diff --git a/mysql-test/suite/galera/t/galera_autoinc_sst_mariabackup.test b/mysql-test/suite/galera/t/galera_autoinc_sst_mariabackup.test
index 9d5f821a170..6aa8ad2923c 100644
--- a/mysql-test/suite/galera/t/galera_autoinc_sst_mariabackup.test
+++ b/mysql-test/suite/galera/t/galera_autoinc_sst_mariabackup.test
@@ -5,7 +5,6 @@
--source include/big_test.inc
--source include/galera_cluster.inc
---source include/have_innodb.inc
--source include/have_mariabackup.inc
--let $node_1=node_1
@@ -33,11 +32,11 @@ END|
DELIMITER ;|
--send CALL p1();
---sleep 2
+--sleep 1
--connection node_2
--send CALL p1();
---sleep 2
+--sleep 1
# Kill and restart node #2
@@ -45,10 +44,7 @@ DELIMITER ;|
--connection node_2a
--source include/kill_galera.inc
---sleep 10
--source include/start_mysqld.inc
---sleep 25
---source include/wait_until_connected_again.inc
INSERT INTO t1 VALUES (DEFAULT);
@@ -72,8 +68,6 @@ INSERT INTO t1 VALUES (DEFAULT);
--error 2013,2006
--reap
---sleep 10
-
# Confirm that the count is correct and that the cluster is intact
--connection node_1a
diff --git a/mysql-test/suite/galera/t/galera_kill_nochanges.test b/mysql-test/suite/galera/t/galera_kill_nochanges.test
index 4106378885f..9360ad542f6 100644
--- a/mysql-test/suite/galera/t/galera_kill_nochanges.test
+++ b/mysql-test/suite/galera/t/galera_kill_nochanges.test
@@ -3,7 +3,11 @@
#
--source include/galera_cluster.inc
---source include/have_innodb.inc
+
+# Save original auto_increment_offset values.
+--let $node_1=node_1
+--let $node_2=node_2
+--source include/auto_increment_offset_save.inc
--connection node_1
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
@@ -29,4 +33,7 @@ SET SESSION wsrep_sync_wait = DEFAULT;
SELECT COUNT(*) = 1 FROM t1;
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--let $node_2=node_2a
+--source include/auto_increment_offset_restore.inc
+
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/galera_many_rows.cnf b/mysql-test/suite/galera/t/galera_many_rows.cnf
new file mode 100644
index 00000000000..4e1022cf67f
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_many_rows.cnf
@@ -0,0 +1,5 @@
+!include ../galera_2nodes.cnf
+
+[mysqld]
+innodb-status-output=ON
+innodb-status-output-locks=ON
diff --git a/mysql-test/suite/galera/t/galera_many_rows.test b/mysql-test/suite/galera/t/galera_many_rows.test
index 58ba85e1b9e..bc9e99db8da 100644
--- a/mysql-test/suite/galera/t/galera_many_rows.test
+++ b/mysql-test/suite/galera/t/galera_many_rows.test
@@ -1,13 +1,16 @@
-
--source include/big_test.inc
--source include/galera_cluster.inc
---source include/have_innodb.inc
+
+# Save original auto_increment_offset values.
+--let $node_1=node_1
+--let $node_2=node_2
+--source include/auto_increment_offset_save.inc
--connection node_1
SET SESSION innodb_lock_wait_timeout=600;
SET SESSION lock_wait_timeout=600;
-CREATE TABLE ten (f1 INTEGER);
+CREATE TABLE ten (f1 INTEGER) engine=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB;
@@ -20,19 +23,19 @@ SET SESSION wsrep_sync_wait = 15;
SET GLOBAL wsrep_provider_options = 'repl.causal_read_timeout=PT1H';
-SELECT COUNT(*) = 100000 FROM t1;
+SELECT COUNT(*) FROM t1;
INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
--connection node_1
-SELECT COUNT(*) = 200000 FROM t1;
+SELECT COUNT(*) FROM t1;
UPDATE t1 SET f2 = 1;
--connection node_2
-SELECT COUNT(*) = 200000 FROM t1 WHERE f2 = 1;
+SELECT COUNT(*) FROM t1 WHERE f2 = 1;
--connection node_1
START TRANSACTION;
-SELECT COUNT(*) = 200000 FROM t1;
+SELECT COUNT(*) FROM t1;
UPDATE t1 SET f2 = 3;
--connection node_2
@@ -50,5 +53,7 @@ COMMIT;
--eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node2';
--enable_query_log
+--source include/auto_increment_offset_restore.inc
+
DROP TABLE t1;
DROP TABLE ten;
diff --git a/mysql-test/suite/galera/t/galera_var_dirty_reads.test b/mysql-test/suite/galera/t/galera_var_dirty_reads.test
index 1f01c4aac07..3e2108868af 100644
--- a/mysql-test/suite/galera/t/galera_var_dirty_reads.test
+++ b/mysql-test/suite/galera/t/galera_var_dirty_reads.test
@@ -11,11 +11,6 @@
--let $node_2=node_2
--source include/auto_increment_offset_save.inc
-# Save original auto_increment_offset values.
---let $node_1=node_1
---let $node_2=node_2
---source include/auto_increment_offset_save.inc
-
--connection node_2
--let $wsrep_cluster_address_saved = `SELECT @@global.wsrep_cluster_address`
diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup_section.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup_section.result
new file mode 100644
index 00000000000..53e35939a79
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_mariabackup_section.result
@@ -0,0 +1,18 @@
+SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';
+VARIABLE_VALUE LIKE '%[::1]%'
+1
+SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+VARIABLE_VALUE = 3
+1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+DROP TABLE t1;
+include/assert_grep.inc [Streaming the backup to joiner at \[::1\]]
+include/assert_grep.inc [async IST sender starting to serve tcp://\[::1\]:]
+include/assert_grep.inc [IST receiver addr using tcp://\[::1\]]
+include/assert_grep.inc [Prepared IST receiver, listening at: tcp://\[::1\]]
diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync_section.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync_section.result
new file mode 100644
index 00000000000..a2bf5f4d98c
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_ipv6_rsync_section.result
@@ -0,0 +1,14 @@
+SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';
+VARIABLE_VALUE LIKE '%[::1]%'
+1
+SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+VARIABLE_VALUE = 3
+1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.cnf
new file mode 100644
index 00000000000..dc294854056
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.cnf
@@ -0,0 +1,39 @@
+!include ../galera_3nodes.cnf
+
+# decoy value - should not be read by mysqld or sst scripts
+[mysqld]
+innodb-data-home-dir=/tmp
+
+[galera]
+innodb-data-home-dir=
+wsrep_sst_method=mariabackup
+wsrep_sst_auth="root:"
+wsrep_node_address=::1
+
+[galera.1]
+wsrep-cluster-address=gcomm://
+wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port'
+wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port'
+wsrep_node_incoming_address='[::1]:@mysqld.1.port'
+wsrep_node_name=node_1
+
+[galera.2]
+wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
+wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port'
+wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port'
+wsrep_node_incoming_address='[::1]:@mysqld.2.port'
+wsrep_node_name=node_2
+wsrep_sst_donor=node_1
+
+[galera.3]
+wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
+wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port'
+wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
+wsrep_node_incoming_address='[::1]:@mysqld.3.port'
+wsrep_node_name=node_3
+wsrep_sst_donor=node_1
+
+[SST]
+transferfmt=@ENV.MTR_GALERA_TFMT
+streamfmt=xbstream
+sockopt=",pf=ip6"
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.opt
new file mode 100644
index 00000000000..c2bb4d156af
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.opt
@@ -0,0 +1 @@
+--bind-address=::
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test
new file mode 100644
index 00000000000..95cd1a5bea5
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test
@@ -0,0 +1,69 @@
+--source include/galera_cluster.inc
+--source include/check_ipv6.inc
+--source suite/galera/include/have_mariabackup.inc
+
+# Confirm that initial handshake happened over ipv6
+
+SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';
+SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+
+# Force IST
+
+--connection node_2
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+--connection node_2
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+SELECT COUNT(*) = 1 FROM t1;
+
+DROP TABLE t1;
+
+# Confirm that key messages around SST and IST reference IPv6
+
+--connection node_1
+--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
+--let $assert_only_after = CURRENT_TEST
+
+# The SSTs happen when nodes are started first time
+--let $assert_count= 2
+--let $assert_text = Streaming the backup to joiner at \[::1\]
+--let $assert_select = Streaming the backup to joiner at \[::1\]
+--source include/assert_grep.inc
+
+# There will be 1 ISTs donated from node_1 in Galera 3.
+# Two first happen at the initial startup to populate the certification
+# index. The third one is from the IST which happens during the actual test.
+--let $assert_count= 1
+--let $assert_text = async IST sender starting to serve tcp://\[::1\]:
+--let $assert_select = async IST sender starting to serve tcp://\[::1\]:
+--source include/assert_grep.inc
+
+--connection node_2
+--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err
+--let $assert_only_after = CURRENT_TEST
+
+# There is one ISTs on joiner at Galera 3.
+--let $assert_count= 1
+--let $assert_text = IST receiver addr using tcp://\[::1\]
+--let $assert_select = IST receiver addr using tcp://\[::1\]
+--source include/assert_grep.inc
+
+# There will be only one Prepared IST and in Galera 3 segnos are not printed
+--let $assert_count= 1
+--let $assert_text = Prepared IST receiver, listening at: tcp://\[::1\]
+--let $assert_select = Prepared IST receiver, listening at: tcp://\[::1\]
+--source include/assert_grep.inc
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.cnf
new file mode 100644
index 00000000000..7cac8e1451e
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.cnf
@@ -0,0 +1,31 @@
+!include ../galera_3nodes.cnf
+
+# decoy value - should not be read by mysqld or sst scripts
+[mysqld]
+innodb-data-home-dir=/tmp
+
+[mariadb]
+innodb-data-home-dir=
+wsrep_sst_method=rsync
+wsrep_node_address=::1
+
+[mariadb.1]
+wsrep-cluster-address=gcomm://
+wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port'
+wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port'
+wsrep_node_incoming_address='[::1]:@mysqld.1.port'
+
+[mariadb.2]
+wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
+wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port'
+wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port'
+wsrep_node_incoming_address='[::1]:@mysqld.2.port'
+
+[mariadb.3]
+wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
+wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port'
+wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
+wsrep_node_incoming_address='[::1]:@mysqld.3.port'
+
+[SST]
+sockopt=",pf=ip6"
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.opt b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.opt
new file mode 100644
index 00000000000..c2bb4d156af
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.opt
@@ -0,0 +1 @@
+--bind-address=::
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.test
new file mode 100644
index 00000000000..1937eb43e13
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_rsync_section.test
@@ -0,0 +1,32 @@
+--source include/galera_cluster.inc
+--source include/check_ipv6.inc
+
+# Confirm that initial handshake happened over ipv6
+
+SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';
+SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+
+# Force IST
+
+--connection node_2
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+--connection node_2
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+SELECT COUNT(*) = 1 FROM t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/include/wait_all_purged.inc b/mysql-test/suite/innodb/include/wait_all_purged.inc
index c7a16888829..992e14f0843 100644
--- a/mysql-test/suite/innodb/include/wait_all_purged.inc
+++ b/mysql-test/suite/innodb/include/wait_all_purged.inc
@@ -7,7 +7,7 @@ if (!$wait_all_purged)
}
let $remaining_expect= `select concat('InnoDB ',$wait_all_purged)`;
-let $wait_counter= 300;
+let $wait_counter= 600;
while ($wait_counter)
{
--replace_regex /.*History list length ([0-9]+).*/\1/
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index 3e82d379a6d..ee5af2121e0 100755
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -28,7 +28,6 @@ WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-}
WSREP_SST_OPT_DEFAULT=""
WSREP_SST_OPT_EXTRA_DEFAULT=""
WSREP_SST_OPT_SUFFIX_DEFAULT=""
-WSREP_SST_OPT_SUFFIX_VALUE=""
INNODB_DATA_HOME_DIR_ARG=""
while [ $# -gt 0 ]; do
@@ -94,7 +93,6 @@ case "$1" in
;;
'--defaults-group-suffix')
readonly WSREP_SST_OPT_SUFFIX_DEFAULT="$1=$2"
- readonly WSREP_SST_OPT_SUFFIX_VALUE="$2"
shift
;;
'--host')
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index f4ec0d59a29..e2544ccb1c0 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -1,6 +1,6 @@
#!/bin/bash -ue
# Copyright (C) 2013 Percona Inc
-# Copyright (C) 2017 MariaDB
+# Copyright (C) 2017-2019 MariaDB
#
# 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
@@ -667,7 +667,7 @@ monitor_process()
exit 32
fi
- if ! ps -p "${sst_stream_pid}" &>/dev/null; then
+ if ! ps -p "${sst_stream_pid}" &>/dev/null; then
break
fi
@@ -707,10 +707,7 @@ if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
fi
# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
- INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
-fi
-if [ -z "$INNODB_DATA_HOME_DIR" ]; then
- INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir "")
+ INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '')
fi
if [ ! -z "$INNODB_DATA_HOME_DIR" ]; then
INNOEXTRA+=" --innodb-data-home-dir=$INNODB_DATA_HOME_DIR"
@@ -753,8 +750,8 @@ else
if [[ "$sstlogarchive" -eq 1 ]]
then
- ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S")
- newfile=""
+ ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
+ newfile=""
if [[ ! -z "$sstlogarchivedir" ]]
then
@@ -829,7 +826,7 @@ then
exit 93
fi
- if [[ -z $(parse_cnf mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then
+ if [[ -z $(parse_cnf --mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then
xtmpdir=$(mktemp -d)
tmpopts=" --tmpdir=$xtmpdir "
wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory"
@@ -952,8 +949,8 @@ then
[[ -n $SST_PROGRESS_FILE ]] && touch $SST_PROGRESS_FILE
ib_home_dir=$INNODB_DATA_HOME_DIR
- ib_log_dir=$(parse_cnf mysqld innodb-log-group-home-dir "")
- ib_undo_dir=$(parse_cnf mysqld innodb-undo-directory "")
+ ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "")
+ ib_undo_dir=$(parse_cnf --mysqld innodb-undo-directory "")
stagemsg="Joiner-Recv"
@@ -1023,15 +1020,14 @@ then
jpid=$!
wsrep_log_info "Proceeding with SST"
-
wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories"
if [ "${OS}" = "FreeBSD" ]; then
find -E $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+
else
find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+
- fi
+ fi
- tempdir=$(parse_cnf mysqld log-bin "")
+ tempdir=$(parse_cnf --mysqld log-bin "")
if [[ -n ${tempdir:-} ]];then
binlog_dir=$(dirname $tempdir)
binlog_file=$(basename $tempdir)
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index c1d6660f9d2..b5dca7e6c25 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -170,10 +170,7 @@ if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
fi
# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
- INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
-fi
-if [ -z "$INNODB_DATA_HOME_DIR" ]; then
- INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir "")
+ INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '')
fi
if [ -n "$INNODB_DATA_HOME_DIR" ]; then
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index ffca9034b38..9912960e3b4 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -442,39 +442,6 @@ struct que_fork_t{
/* Flag which is ORed to control structure statement node types */
#define QUE_NODE_CONTROL_STAT 1024
-/* Query graph node types */
-#define QUE_NODE_LOCK 1
-#define QUE_NODE_INSERT 2
-#define QUE_NODE_UPDATE 4
-#define QUE_NODE_CURSOR 5
-#define QUE_NODE_SELECT 6
-#define QUE_NODE_AGGREGATE 7
-#define QUE_NODE_FORK 8
-#define QUE_NODE_THR 9
-#define QUE_NODE_UNDO 10
-#define QUE_NODE_COMMIT 11
-#define QUE_NODE_ROLLBACK 12
-#define QUE_NODE_PURGE 13
-#define QUE_NODE_CREATE_TABLE 14
-#define QUE_NODE_CREATE_INDEX 15
-#define QUE_NODE_SYMBOL 16
-#define QUE_NODE_RES_WORD 17
-#define QUE_NODE_FUNC 18
-#define QUE_NODE_ORDER 19
-#define QUE_NODE_PROC (20 + QUE_NODE_CONTROL_STAT)
-#define QUE_NODE_IF (21 + QUE_NODE_CONTROL_STAT)
-#define QUE_NODE_WHILE (22 + QUE_NODE_CONTROL_STAT)
-#define QUE_NODE_ASSIGNMENT 23
-#define QUE_NODE_FETCH 24
-#define QUE_NODE_OPEN 25
-#define QUE_NODE_COL_ASSIGNMENT 26
-#define QUE_NODE_FOR (27 + QUE_NODE_CONTROL_STAT)
-#define QUE_NODE_RETURN 28
-#define QUE_NODE_ROW_PRINTF 29
-#define QUE_NODE_ELSIF 30
-#define QUE_NODE_CALL 31
-#define QUE_NODE_EXIT 32
-
#include "que0que.ic"
#endif
diff --git a/storage/innobase/include/que0types.h b/storage/innobase/include/que0types.h
index 017e5df9a6f..2b5a04811b3 100644
--- a/storage/innobase/include/que0types.h
+++ b/storage/innobase/include/que0types.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2009, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, 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
@@ -36,6 +37,39 @@ typedef struct que_fork_t que_t;
struct que_thr_t;
+/* Query graph node types */
+#define QUE_NODE_LOCK 1
+#define QUE_NODE_INSERT 2
+#define QUE_NODE_UPDATE 4
+#define QUE_NODE_CURSOR 5
+#define QUE_NODE_SELECT 6
+#define QUE_NODE_AGGREGATE 7
+#define QUE_NODE_FORK 8
+#define QUE_NODE_THR 9
+#define QUE_NODE_UNDO 10
+#define QUE_NODE_COMMIT 11
+#define QUE_NODE_ROLLBACK 12
+#define QUE_NODE_PURGE 13
+#define QUE_NODE_CREATE_TABLE 14
+#define QUE_NODE_CREATE_INDEX 15
+#define QUE_NODE_SYMBOL 16
+#define QUE_NODE_RES_WORD 17
+#define QUE_NODE_FUNC 18
+#define QUE_NODE_ORDER 19
+#define QUE_NODE_PROC (20 + QUE_NODE_CONTROL_STAT)
+#define QUE_NODE_IF (21 + QUE_NODE_CONTROL_STAT)
+#define QUE_NODE_WHILE (22 + QUE_NODE_CONTROL_STAT)
+#define QUE_NODE_ASSIGNMENT 23
+#define QUE_NODE_FETCH 24
+#define QUE_NODE_OPEN 25
+#define QUE_NODE_COL_ASSIGNMENT 26
+#define QUE_NODE_FOR (27 + QUE_NODE_CONTROL_STAT)
+#define QUE_NODE_RETURN 28
+#define QUE_NODE_ROW_PRINTF 29
+#define QUE_NODE_ELSIF 30
+#define QUE_NODE_CALL 31
+#define QUE_NODE_EXIT 32
+
/* Common struct at the beginning of each query graph node; the name of this
substruct must be 'common' */
@@ -51,6 +85,11 @@ struct que_common_t{
symbol node or a function node, then we
have to free the data field in val
explicitly */
+
+ /** Constructor */
+ que_common_t(ulint type, que_node_t* parent)
+ : type(type), parent(parent), brother(), val(), val_buf_size()
+ {}
};
#endif
diff --git a/storage/innobase/include/row0import.h b/storage/innobase/include/row0import.h
index 94df1a61341..9c4d3a7f7a5 100644
--- a/storage/innobase/include/row0import.h
+++ b/storage/innobase/include/row0import.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -55,22 +55,13 @@ dberr_t row_import_update_discarded_flag(trx_t* trx, table_id_t table_id,
bool discarded)
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*****************************************************************//**
-Update the (space, root page) of a table's indexes from the values
-in the data dictionary.
+/** Update the root page numbers and tablespace ID of a table.
+@param[in,out] trx dictionary transaction
+@param[in,out] table persistent table
+@param[in] reset whether to reset the fields to FIL_NULL
@return DB_SUCCESS or error code */
dberr_t
-row_import_update_index_root(
-/*=========================*/
- trx_t* trx, /*!< in/out: transaction that
- covers the update */
- const dict_table_t* table, /*!< in: Table for which we want
- to set the root page_no */
- bool reset, /*!< in: if true then set to
- FIL_NUL */
- bool dict_locked) /*!< in: Set to true if the
- caller already owns the
- dict_sys_t:: mutex. */
+row_import_update_index_root(trx_t* trx, dict_table_t* table, bool reset)
MY_ATTRIBUTE((nonnull, warn_unused_result));
#endif /* row0import_h */
diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h
index 25cd43979bf..a1718398a83 100644
--- a/storage/innobase/include/row0purge.h
+++ b/storage/innobase/include/row0purge.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -35,16 +35,6 @@ Created 3/14/1997 Heikki Tuuri
#include "ut0vec.h"
#include "row0mysql.h"
-/** Create a purge node to a query graph.
-@param[in] parent parent node, i.e., a thr node
-@param[in] heap memory heap where created
-@return own: purge node */
-purge_node_t*
-row_purge_node_create(
- que_thr_t* parent,
- mem_heap_t* heap)
- MY_ATTRIBUTE((warn_unused_result));
-
/** Determines if it is possible to remove a secondary index entry.
Removal is possible if the secondary index entry does not refer to any
not delete marked version of a clustered index record where DB_TRX_ID
@@ -102,6 +92,13 @@ struct purge_node_t{
ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC,
... */
+private:
+ /** latest unavailable table ID (do not bother looking up again) */
+ table_id_t unavailable_table_id;
+ /** the latest modification of the table definition identified by
+ unavailable_table_id, or TRX_ID_MAX */
+ trx_id_t def_trx_id;
+public:
dict_table_t* table; /*!< table where purge is done */
ulint cmpl_info;/* compiler analysis info of an update */
@@ -118,19 +115,27 @@ struct purge_node_t{
mem_heap_t* heap; /*!< memory heap used as auxiliary storage for
row; this must be emptied after a successful
purge of a row */
- ibool found_clust;/* TRUE if the clustered index record
+ ibool found_clust;/*!< whether the clustered index record
determined by ref was found in the clustered
index, and we were able to position pcur on
it */
btr_pcur_t pcur; /*!< persistent cursor used in searching the
clustered index record */
- ibool done; /* Debug flag */
+#ifdef UNIV_DEBUG
+ /** whether the operation is in progress */
+ bool in_progress;
+#endif
trx_id_t trx_id; /*!< trx id for this purging record */
/** Virtual column information about opening of MariaDB table.
It resets after processing each undo log record. */
purge_vcol_info_t vcol_info;
+ /** Constructor */
+ explicit purge_node_t(que_thr_t* parent) :
+ common(QUE_NODE_PURGE, parent), heap(mem_heap_create(256))
+ {}
+
#ifdef UNIV_DEBUG
/***********************************************************//**
Validate the persisent cursor. The purge node has two references
@@ -146,6 +151,52 @@ struct purge_node_t{
computation.
@return true if the table failed to open. */
bool vcol_op_failed() const { return !vcol_info.validate(); }
+
+ /** Determine if a table should be skipped in purge.
+ @param[in] table_id table identifier
+ @return whether to skip the table lookup and processing */
+ bool is_skipped(table_id_t id) const
+ {
+ return id == unavailable_table_id && trx_id <= def_trx_id;
+ }
+
+ /** Remember that a table should be skipped in purge.
+ @param[in] id table identifier
+ @param[in] limit last transaction for which to skip */
+ void skip(table_id_t id, trx_id_t limit)
+ {
+ DBUG_ASSERT(limit >= trx_id);
+ unavailable_table_id = id;
+ def_trx_id = limit;
+ }
+
+ /** Start processing an undo log record. */
+ void start()
+ {
+ ut_ad(in_progress);
+ DBUG_ASSERT(common.type == QUE_NODE_PURGE);
+
+ table = NULL;
+ row = NULL;
+ ref = NULL;
+ index = NULL;
+ update = NULL;
+ found_clust = FALSE;
+ rec_type = ULINT_UNDEFINED;
+ cmpl_info = ULINT_UNDEFINED;
+ }
+
+ /** Reset the state at end
+ @return the query graph parent */
+ que_node_t* end()
+ {
+ DBUG_ASSERT(common.type == QUE_NODE_PURGE);
+ undo_recs = NULL;
+ ut_d(in_progress = false);
+ vcol_info.reset();
+ mem_heap_empty(heap);
+ return common.parent;
+ }
};
#endif
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 9cdb4cab764..9174a922cdb 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3066,23 +3066,13 @@ row_import_read_cfg(
return(err);
}
-/*****************************************************************//**
-Update the <space, root page> of a table's indexes from the values
-in the data dictionary.
+/** Update the root page numbers and tablespace ID of a table.
+@param[in,out] trx dictionary transaction
+@param[in,out] table persistent table
+@param[in] reset whether to reset the fields to FIL_NULL
@return DB_SUCCESS or error code */
dberr_t
-row_import_update_index_root(
-/*=========================*/
- trx_t* trx, /*!< in/out: transaction that
- covers the update */
- const dict_table_t* table, /*!< in: Table for which we want
- to set the root page_no */
- bool reset, /*!< in: if true then set to
- FIL_NUL */
- bool dict_locked) /*!< in: Set to true if the
- caller already owns the
- dict_sys_t:: mutex. */
-
+row_import_update_index_root(trx_t* trx, dict_table_t* table, bool reset)
{
const dict_index_t* index;
que_t* graph = 0;
@@ -3100,9 +3090,7 @@ row_import_update_index_root(
"WHERE TABLE_ID = :table_id AND ID = :index_id;\n"
"END;\n"};
- if (!dict_locked) {
- mutex_enter(&dict_sys->mutex);
- }
+ table->def_trx_id = trx->id;
for (index = dict_table_get_first_index(table);
index != 0;
@@ -3177,10 +3165,6 @@ row_import_update_index_root(
que_graph_free(graph);
- if (!dict_locked) {
- mutex_exit(&dict_sys->mutex);
- }
-
return(err);
}
@@ -4115,7 +4099,7 @@ row_import_for_mysql(
row_mysql_lock_data_dictionary(trx);
/* Update the root pages of the table's indexes. */
- err = row_import_update_index_root(trx, table, false, true);
+ err = row_import_update_index_root(trx, table, false);
if (err != DB_SUCCESS) {
return(row_import_error(prebuilt, trx, err));
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index e5bc21c21a7..1d5357f7473 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3028,7 +3028,7 @@ row_discard_tablespace(
}
/* Update the index root pages in the system tables, on disk */
- err = row_import_update_index_root(trx, table, true, true);
+ err = row_import_update_index_root(trx, table, true);
if (err != DB_SUCCESS) {
return(err);
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 5699c8b2f56..7854901cfa8 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -57,31 +57,6 @@ check.
If you make a change in this module make sure that no codepath is
introduced where a call to log_free_check() is bypassed. */
-/** Create a purge node to a query graph.
-@param[in] parent parent node, i.e., a thr node
-@param[in] heap memory heap where created
-@return own: purge node */
-purge_node_t*
-row_purge_node_create(
- que_thr_t* parent,
- mem_heap_t* heap)
-{
- purge_node_t* node;
-
- ut_ad(parent != NULL);
- ut_ad(heap != NULL);
-
- node = static_cast<purge_node_t*>(
- mem_heap_zalloc(heap, sizeof(*node)));
-
- node->common.type = QUE_NODE_PURGE;
- node->common.parent = parent;
- node->done = TRUE;
- node->heap = mem_heap_create(256);
-
- return(node);
-}
-
/***********************************************************//**
Repositions the pcur in the purge node on the clustered index record,
if found. If the record is not found, close pcur.
@@ -1066,6 +1041,10 @@ row_purge_parse_undo_rec(
break;
}
+ if (node->is_skipped(table_id)) {
+ return false;
+ }
+
/* Prevent DROP TABLE etc. from running when we are doing the purge
for this row */
@@ -1075,15 +1054,18 @@ try_again:
node->table = dict_table_open_on_id(
table_id, FALSE, DICT_TABLE_OP_NORMAL);
+ trx_id_t trx_id;
+
if (node->table == NULL) {
/* The table has been dropped: no need to do purge */
+ trx_id = TRX_ID_MAX;
goto err_exit;
}
ut_ad(!node->table->is_temporary());
if (!fil_table_accessible(node->table)) {
- goto close_exit;
+ goto inaccessible;
}
switch (type) {
@@ -1119,11 +1101,20 @@ try_again:
/* The table was corrupt in the data dictionary.
dict_set_corrupted() works on an index, and
we do not have an index to call it with. */
-close_exit:
+inaccessible:
+ DBUG_ASSERT(table_id == node->table->id);
+ trx_id = node->table->def_trx_id;
+ if (!trx_id) {
+ trx_id = TRX_ID_MAX;
+ }
+
dict_table_close(node->table, FALSE, FALSE);
node->table = NULL;
err_exit:
rw_lock_s_unlock(dict_operation_lock);
+ if (table_id) {
+ node->skip(table_id, trx_id);
+ }
return(false);
}
@@ -1283,25 +1274,11 @@ row_purge_end(
/*==========*/
que_thr_t* thr) /*!< in: query thread */
{
- purge_node_t* node;
-
ut_ad(thr);
- node = static_cast<purge_node_t*>(thr->run_node);
-
- ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
-
- thr->run_node = que_node_get_parent(node);
-
- node->undo_recs = NULL;
-
- node->done = TRUE;
-
- node->vcol_info.reset();
+ thr->run_node = static_cast<purge_node_t*>(thr->run_node)->end();
ut_a(thr->run_node != NULL);
-
- mem_heap_empty(node->heap);
}
/***********************************************************//**
@@ -1319,18 +1296,7 @@ row_purge_step(
node = static_cast<purge_node_t*>(thr->run_node);
- node->table = NULL;
- node->row = NULL;
- node->ref = NULL;
- node->index = NULL;
- node->update = NULL;
- node->found_clust = FALSE;
- node->rec_type = ULINT_UNDEFINED;
- node->cmpl_info = ULINT_UNDEFINED;
-
- ut_a(!node->done);
-
- ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
+ node->start();
if (!(node->undo_recs == NULL || ib_vector_is_empty(node->undo_recs))) {
trx_purge_rec_t*purge_rec;
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index a4fa12708ac..980e518daf6 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -148,7 +148,8 @@ purge_graph_build()
for (ulint i = 0; i < srv_n_purge_threads; ++i) {
que_thr_t* thr = que_thr_create(fork, heap, NULL);
- thr->child = row_purge_node_create(thr, heap);
+ thr->child = new(mem_heap_zalloc(heap, sizeof(purge_node_t)))
+ purge_node_t(thr);
}
return(fork);
@@ -1404,7 +1405,7 @@ ulint
trx_purge_attach_undo_recs(ulint n_purge_threads)
{
que_thr_t* thr;
- ulint i = 0;
+ ulint i;
ulint n_pages_handled = 0;
ulint n_thrs = UT_LIST_GET_LEN(purge_sys.query->thrs);
@@ -1412,6 +1413,8 @@ trx_purge_attach_undo_recs(ulint n_purge_threads)
purge_sys.head = purge_sys.tail;
+#ifdef UNIV_DEBUG
+ i = 0;
/* Debug code to validate some pre-requisites and reset done flag. */
for (thr = UT_LIST_GET_FIRST(purge_sys.query->thrs);
thr != NULL && i < n_purge_threads;
@@ -1422,16 +1425,16 @@ trx_purge_attach_undo_recs(ulint n_purge_threads)
/* Get the purge node. */
node = (purge_node_t*) thr->child;
- ut_a(que_node_get_type(node) == QUE_NODE_PURGE);
- ut_a(node->undo_recs == NULL);
- ut_a(node->done);
-
- node->done = FALSE;
+ ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
+ ut_ad(node->undo_recs == NULL);
+ ut_ad(!node->in_progress);
+ ut_d(node->in_progress = true);
}
/* There should never be fewer nodes than threads, the inverse
however is allowed because we only use purge threads as needed. */
- ut_a(i == n_purge_threads);
+ ut_ad(i == n_purge_threads);
+#endif
/* Fetch and parse the UNDO records. The UNDO records are added
to a per purge node vector. */