summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-10-05 20:30:57 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-10-05 20:30:57 +0300
commit65d0c57c1a2036c8a8c065d3e3bd4f85d0cc5d57 (patch)
tree9165f331634b0725bcf628390fcfd8a3381f7147
parentdf97eb1432f91ad13e562111bda393b3650719d0 (diff)
parentc0eda62aec1de8b74ca51791df5ad142dee2ef08 (diff)
downloadmariadb-git-65d0c57c1a2036c8a8c065d3e3bd4f85d0cc5d57.tar.gz
Merge 10.3 into 10.4
-rw-r--r--mysql-test/include/ipv6.inc1
-rw-r--r--mysql-test/include/master-slave.inc2
-rw-r--r--mysql-test/main/log_slow.test2
-rw-r--r--mysql-test/main/plugin_auth.test1
-rwxr-xr-xmysql-test/std_data/wsrep_notify.sh126
-rwxr-xr-xmysql-test/std_data/wsrep_notify_ssl.sh195
-rw-r--r--mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result11
-rw-r--r--mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt1
-rw-r--r--mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf20
-rw-r--r--mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test20
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result3
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test3
-rw-r--r--mysql-test/suite/innodb/r/purge_secondary.result15
-rw-r--r--mysql-test/suite/innodb/t/alter_missing_tablespace.test1
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.test1
-rw-r--r--mysql-test/suite/innodb/t/innodb-get-fk.test2
-rw-r--r--mysql-test/suite/innodb/t/missing_tablespaces.test1
-rw-r--r--mysql-test/suite/innodb/t/purge_secondary.test32
-rw-r--r--mysql-test/suite/innodb/t/table_flags.test6
-rw-r--r--mysql-test/suite/innodb/t/xa_recovery.test1
-rw-r--r--mysql-test/suite/mariabackup/log_page_corruption.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_stop_start.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev12179.test1
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_at_shutdown_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_flush_method_func.test2
-rw-r--r--storage/innobase/btr/btr0btr.cc6
-rw-r--r--storage/innobase/btr/btr0cur.cc86
-rw-r--r--storage/innobase/btr/btr0pcur.cc6
-rw-r--r--storage/innobase/btr/btr0sea.cc59
-rw-r--r--storage/innobase/buf/buf0buf.cc22
-rw-r--r--storage/innobase/dict/dict0dict.cc4
-rw-r--r--storage/innobase/fts/fts0fts.cc4
-rw-r--r--storage/innobase/gis/gis0sea.cc8
-rw-r--r--storage/innobase/include/btr0cur.h77
-rw-r--r--storage/innobase/include/btr0pcur.h55
-rw-r--r--storage/innobase/include/btr0pcur.inl58
-rw-r--r--storage/innobase/include/btr0sea.h1
-rw-r--r--storage/innobase/include/trx0rec.h26
-rw-r--r--storage/innobase/row/row0ins.cc10
-rw-r--r--storage/innobase/row/row0log.cc6
-rw-r--r--storage/innobase/row/row0merge.cc7
-rw-r--r--storage/innobase/row/row0purge.cc142
-rw-r--r--storage/innobase/row/row0sel.cc18
-rw-r--r--storage/innobase/trx/trx0rec.cc179
-rw-r--r--storage/innobase/trx/trx0trx.cc2
-rwxr-xr-x[-rw-r--r--]support-files/wsrep_notify.sh123
46 files changed, 838 insertions, 511 deletions
diff --git a/mysql-test/include/ipv6.inc b/mysql-test/include/ipv6.inc
index 3d8fdcfbc3c..05c65d7817a 100644
--- a/mysql-test/include/ipv6.inc
+++ b/mysql-test/include/ipv6.inc
@@ -22,4 +22,3 @@ eval SET PASSWORD FOR testuser1@'$IPv6' = PASSWORD ('9876');
--replace_result ::1 localhost
SELECT USER();
eval DROP USER testuser1@'$IPv6';
-
diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc
index 9ed206b2c22..5b603fbfdb3 100644
--- a/mysql-test/include/master-slave.inc
+++ b/mysql-test/include/master-slave.inc
@@ -1,3 +1,5 @@
+--source include/no_valgrind_without_big.inc
+
# ==== Purpose ====
#
# Configure two servers to be replication master and slave.
diff --git a/mysql-test/main/log_slow.test b/mysql-test/main/log_slow.test
index 64fd8202985..b51777d859e 100644
--- a/mysql-test/main/log_slow.test
+++ b/mysql-test/main/log_slow.test
@@ -1,3 +1,5 @@
+--source include/no_valgrind_without_big.inc
+
#
# Testing of slow log query options
#
diff --git a/mysql-test/main/plugin_auth.test b/mysql-test/main/plugin_auth.test
index 30e4fa6e0ad..6912462066c 100644
--- a/mysql-test/main/plugin_auth.test
+++ b/mysql-test/main/plugin_auth.test
@@ -2,6 +2,7 @@
--source include/not_embedded.inc
--source include/mysql_upgrade_preparation.inc
--source include/have_innodb.inc
+--source include/no_valgrind_without_big.inc
SET GLOBAL SQL_MODE="";
SET LOCAL SQL_MODE="";
diff --git a/mysql-test/std_data/wsrep_notify.sh b/mysql-test/std_data/wsrep_notify.sh
index 48edad4306f..5050ff9bc3e 100755
--- a/mysql-test/std_data/wsrep_notify.sh
+++ b/mysql-test/std_data/wsrep_notify.sh
@@ -4,11 +4,31 @@
# It will create 'wsrep' schema and two tables in it: 'membeship' and 'status'
# and fill them on every membership or node status change.
#
-# Edit parameters below to specify the address and login to server.
-
+# Edit parameters below to specify the address and login to server:
+#
USER=root
+PSWD=
+#
+# If these parameters are not set, then the values
+# passed by the server are taken:
+#
HOST=127.0.0.1
PORT=$NODE_MYPORT_1
+#
+# Edit parameters below to specify SSL parameters:
+#
+ssl_key=
+ssl_cert=
+ssl_ca=
+ssl_capath=
+ssl_cipher=
+ssl_crl=
+ssl_crlpath=
+ssl_verify_server_cert=0
+#
+# Client executable path:
+#
+CLIENT="$EXE_MYSQL"
SCHEMA="mtr_wsrep_notify"
MEMB_TABLE="$SCHEMA.membership"
@@ -19,7 +39,7 @@ SET wsrep_on=0;
CREATE SCHEMA IF NOT EXISTS $SCHEMA;
CREATE TABLE IF NOT EXISTS $MEMB_TABLE (
idx INT,
- uuid CHAR(40), /* node UUID */
+ uuid CHAR(40), /* node UUID */
name VARCHAR(32), /* node name */
addr VARCHAR(256) /* node address */
) ENGINE=MEMORY;
@@ -40,7 +60,7 @@ configuration_change()
local idx=0
- for NODE in $(echo $MEMBERS | sed s/,/\ /g)
+ for NODE in $(echo "$MEMBERS" | sed s/,/\ /g)
do
echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, "
# Don't forget to properly quote string values
@@ -59,17 +79,44 @@ status_update()
echo "$BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;"
}
+trim_string()
+{
+ if [ -n "${BASH_VERSION:-}" ]; then
+ local pattern="[![:space:]${2:-}]"
+ local x="${1#*$pattern}"
+ local z=${#1}
+ x=${#x}
+ if [ $x -ne $z ]; then
+ local y="${1%$pattern*}"
+ y=${#y}
+ x=$(( z-x-1 ))
+ y=$(( y-x+1 ))
+ printf '%s' "${1:$x:$y}"
+ else
+ printf ''
+ fi
+ else
+ local pattern="[[:space:]${2:-}]"
+ echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
+ fi
+}
+
COM=status_update # not a configuration change by default
-while [ $# -gt 0 ]
-do
+STATUS=""
+CLUSTER_UUID=""
+PRIMARY="0"
+INDEX=""
+MEMBERS=""
+
+while [ $# -gt 0 ]; do
case $1 in
--status)
- STATUS=$2
+ STATUS=$(trim_string "$2")
shift
;;
--uuid)
- CLUSTER_UUID=$2
+ CLUSTER_UUID=$(trim_string "$2")
shift
;;
--primary)
@@ -78,22 +125,75 @@ do
shift
;;
--index)
- INDEX=$2
+ INDEX=$(trim_string "$2")
shift
;;
--members)
- MEMBERS=$2
+ MEMBERS=$(trim_string "$2")
shift
;;
esac
shift
done
+USER=$(trim_string "$USER")
+PSWD=$(trim_string "$PSWD")
+
+HOST=$(trim_string "$HOST")
+PORT=$(trim_string "$PORT")
+
+case "$HOST" in
+\[*)
+ HOST="${HOST##\[}"
+ HOST=$(trim_string "${HOST%%\]}")
+ ;;
+esac
+
+if [ -z "$HOST" ]; then
+ HOST="${NOTIFY_HOST:-}"
+fi
+if [ -z "$PORT" ]; then
+ PORT="${NOTIFY_PORT:-}"
+fi
+
+ssl_key=$(trim_string "$ssl_key");
+ssl_cert=$(trim_string "$ssl_cert");
+ssl_ca=$(trim_string "$ssl_ca");
+ssl_capath=$(trim_string "$ssl_capath");
+ssl_cipher=$(trim_string "$ssl_cipher");
+ssl_crl=$(trim_string "$ssl_crl");
+ssl_crlpath=$(trim_string "$ssl_crlpath");
+ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert");
+
+SSL_PARAM=""
+
+if [ -n "$ssl_key" -o -n "$ssl_cert" -o \
+ -n "$ssl_ca" -o -n "$ssl_capath" -o \
+ -n "$ssl_cipher" ]
+then
+ SSL_PARAM=' --ssl'
+ [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'"
+ [ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'"
+ [ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'"
+ [ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'"
+ [ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'"
+ [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'"
+ [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'"
+ if [ -n "$ssl_verify_server_cert" ]; then
+ if [ $ssl_verify_server_cert -ne 0 ]; then
+ SSL_PARAM+=' --ssl-verify-server-cert'
+ fi
+ fi
+fi
+
case $STATUS in
"joined" | "donor" | "synced")
- $COM | mysql -B -u$USER -h$HOST -P$PORT
+ "$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\
+ "-h'$HOST'" "-P$PORT"$SSL_PARAM
;;
- *)
- exit 0
+ *)
+ # The node might be shutting down
;;
esac
+
+exit 0
diff --git a/mysql-test/std_data/wsrep_notify_ssl.sh b/mysql-test/std_data/wsrep_notify_ssl.sh
new file mode 100755
index 00000000000..0e416a2f448
--- /dev/null
+++ b/mysql-test/std_data/wsrep_notify_ssl.sh
@@ -0,0 +1,195 @@
+#!/bin/sh -eu
+
+# This is a simple example of wsrep notification script (wsrep_notify_cmd).
+# It will create 'wsrep' schema and two tables in it: 'membeship' and 'status'
+# and fill them on every membership or node status change.
+#
+# Edit parameters below to specify the address and login to server:
+#
+USER=root
+PSWD=
+#
+# If these parameters are not set, then the values
+# passed by the server are taken:
+#
+HOST=127.0.0.1
+PORT=$NODE_MYPORT_1
+#
+# Edit parameters below to specify SSL parameters:
+#
+ssl_cert="$MYSQL_TEST_DIR/std_data/client-cert.pem"
+ssl_key="$MYSQL_TEST_DIR/std_data/client-key.pem"
+ssl_ca="$MYSQL_TEST_DIR/std_data/cacert.pem"
+ssl_capath=
+ssl_cipher=
+ssl_crl=
+ssl_crlpath=
+ssl_verify_server_cert=0
+#
+# Client executable path:
+#
+CLIENT="$EXE_MYSQL"
+
+SCHEMA="mtr_wsrep_notify"
+MEMB_TABLE="$SCHEMA.membership"
+STATUS_TABLE="$SCHEMA.status"
+
+BEGIN="
+SET wsrep_on=0;
+CREATE SCHEMA IF NOT EXISTS $SCHEMA;
+CREATE TABLE IF NOT EXISTS $MEMB_TABLE (
+ idx INT,
+ uuid CHAR(40), /* node UUID */
+ name VARCHAR(32), /* node name */
+ addr VARCHAR(256) /* node address */
+) ENGINE=MEMORY;
+CREATE TABLE IF NOT EXISTS $STATUS_TABLE (
+ size INT, /* component size */
+ idx INT, /* this node index */
+ status CHAR(16), /* this node status */
+ uuid CHAR(40), /* cluster UUID */
+ prim BOOLEAN /* if component is primary */
+) ENGINE=MEMORY;
+BEGIN;
+"
+END="COMMIT;"
+
+configuration_change()
+{
+ echo "$BEGIN;"
+
+ local idx=0
+
+ for NODE in $(echo "$MEMBERS" | sed s/,/\ /g)
+ do
+ echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, "
+ # Don't forget to properly quote string values
+ echo "'$NODE'" | sed s/\\//\',\'/g
+ echo ");"
+ idx=$(( $idx + 1 ))
+ done
+
+ echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);"
+
+ echo "$END"
+}
+
+status_update()
+{
+ echo "SET wsrep_on=0; BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; COMMIT;"
+}
+
+trim_string()
+{
+ if [ -n "${BASH_VERSION:-}" ]; then
+ local pattern="[![:space:]${2:-}]"
+ local x="${1#*$pattern}"
+ local z=${#1}
+ x=${#x}
+ if [ $x -ne $z ]; then
+ local y="${1%$pattern*}"
+ y=${#y}
+ x=$(( z-x-1 ))
+ y=$(( y-x+1 ))
+ printf '%s' "${1:$x:$y}"
+ else
+ printf ''
+ fi
+ else
+ local pattern="[[:space:]${2:-}]"
+ echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
+ fi
+}
+
+COM=status_update # not a configuration change by default
+
+STATUS=""
+CLUSTER_UUID=""
+PRIMARY="0"
+INDEX=""
+MEMBERS=""
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ --status)
+ STATUS=$(trim_string "$2")
+ shift
+ ;;
+ --uuid)
+ CLUSTER_UUID=$(trim_string "$2")
+ shift
+ ;;
+ --primary)
+ [ "$2" = "yes" ] && PRIMARY="1" || PRIMARY="0"
+ COM=configuration_change
+ shift
+ ;;
+ --index)
+ INDEX=$(trim_string "$2")
+ shift
+ ;;
+ --members)
+ MEMBERS=$(trim_string "$2")
+ shift
+ ;;
+ esac
+ shift
+done
+
+USER=$(trim_string "$USER")
+PSWD=$(trim_string "$PSWD")
+
+HOST=$(trim_string "$HOST")
+PORT=$(trim_string "$PORT")
+
+case "$HOST" in
+\[*)
+ HOST="${HOST##\[}"
+ HOST=$(trim_string "${HOST%%\]}")
+ ;;
+esac
+
+if [ -z "$HOST" ]; then
+ HOST="${NOTIFY_HOST:-}"
+fi
+if [ -z "$PORT" ]; then
+ PORT="${NOTIFY_PORT:-}"
+fi
+
+ssl_key=$(trim_string "$ssl_key");
+ssl_cert=$(trim_string "$ssl_cert");
+ssl_ca=$(trim_string "$ssl_ca");
+ssl_capath=$(trim_string "$ssl_capath");
+ssl_cipher=$(trim_string "$ssl_cipher");
+ssl_crl=$(trim_string "$ssl_crl");
+ssl_crlpath=$(trim_string "$ssl_crlpath");
+ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert");
+
+SSL_PARAM=""
+
+if [ -n "$ssl_key" -o -n "$ssl_cert" -o \
+ -n "$ssl_ca" -o -n "$ssl_capath" -o \
+ -n "$ssl_cipher" ]
+then
+ SSL_PARAM=' --ssl'
+ [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'"
+ [ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'"
+ [ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'"
+ [ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'"
+ [ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'"
+ [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'"
+ [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'"
+ if [ -n "$ssl_verify_server_cert" ]; then
+ if [ $ssl_verify_server_cert -ne 0 ]; then
+ SSL_PARAM+=' --ssl-verify-server-cert'
+ fi
+ fi
+fi
+
+# Undefined means node is shutting down
+if [ "$STATUS" != 'Undefined' ]; then
+ "$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\
+ "-h'$HOST'" "-P$PORT"$SSL_PARAM
+fi
+
+exit 0
diff --git a/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result b/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result
new file mode 100644
index 00000000000..823407fbba7
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result
@@ -0,0 +1,11 @@
+connection node_1;
+SELECT COUNT(DISTINCT uuid) AS EXPECT_2 FROM mtr_wsrep_notify.membership;
+EXPECT_2
+2
+SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status;
+EXPECT_2
+2
+SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status;
+EXPECT_2
+2
+DROP SCHEMA mtr_wsrep_notify;
diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt
new file mode 100644
index 00000000000..99c5889916b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt
@@ -0,0 +1 @@
+--wsrep_notify_cmd=$MYSQL_TEST_DIR/std_data/wsrep_notify_ssl.sh --wsrep-sync-wait=0
diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf
new file mode 100644
index 00000000000..ce121d20e03
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf
@@ -0,0 +1,20 @@
+!include ../galera_2nodes.cnf
+
+[mysqld]
+ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem
+ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem
+ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem
+bind-address=::
+
+[mysqld.1]
+wsrep_provider_options='base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port;gcache.size=1;pc.ignore_sb=true'
+wsrep_node_incoming_address='[::1]:@mysqld.1.port'
+wsrep_node_address=::1
+wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port'
+
+[mysqld.2]
+wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
+wsrep_provider_options='base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port;gcache.size=1;pc.ignore_sb=true'
+wsrep_node_address=::1
+wsrep_node_incoming_address='[::1]:@mysqld.2.port'
+wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port'
diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test
new file mode 100644
index 00000000000..2c2b106c2ae
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test
@@ -0,0 +1,20 @@
+#
+# Test wsrep_notify_cmd. We use a version of the support-files/wsrep_notify.sh script that writes
+# notifications into a table.
+#
+
+--source include/galera_cluster.inc
+--source include/have_ssl_communication.inc
+--source include/check_ipv6.inc
+--source include/force_restart.inc
+
+--connection node_1
+--let $wait_condition = SELECT COUNT(DISTINCT uuid) = 2 FROM mtr_wsrep_notify.membership;
+--source include/wait_condition.inc
+
+SELECT COUNT(DISTINCT uuid) AS EXPECT_2 FROM mtr_wsrep_notify.membership;
+SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status;
+SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status;
+
+# CLEANUP
+DROP SCHEMA mtr_wsrep_notify;
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
index bb0fb7bbf0b..7d938f3ef81 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
@@ -148,10 +148,7 @@ lock table t write;
connection prevent_purge;
commit;
connection default;
-InnoDB 0 transactions not purged
disconnect lock_table;
-start transaction with consistent snapshot;
-commit;
InnoDB 0 transactions not purged
set global debug_dbug=@old_dbug;
drop table t;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
index 9549c2f0f10..253ad4095f7 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
@@ -189,10 +189,7 @@ lock table t write;
connection prevent_purge;
commit;
connection default;
---source ../../innodb/include/wait_all_purged.inc
disconnect lock_table;
-start transaction with consistent snapshot;
-commit;
--source ../../innodb/include/wait_all_purged.inc
set global debug_dbug=@old_dbug;
drop table t;
diff --git a/mysql-test/suite/innodb/r/purge_secondary.result b/mysql-test/suite/innodb/r/purge_secondary.result
index 1b5f2896887..1a3b241580c 100644
--- a/mysql-test/suite/innodb/r/purge_secondary.result
+++ b/mysql-test/suite/innodb/r/purge_secondary.result
@@ -167,4 +167,19 @@ buffer_LRU_batch_evict_total_pages buffer
# FLUSH TABLES t1 FOR EXPORT;
# UNLOCK TABLES;
DROP TABLE t1;
+#
+# MDEV-29666 InnoDB fails to purge secondary index records
+# when indexed virtual columns exist
+#
+CREATE TABLE t1 (a INT, b INT, a1 INT AS(a) VIRTUAL,
+INDEX(a1),INDEX(b)) ENGINE=InnoDB;
+INSERT INTO t1 SET a=1, b=1;
+UPDATE t1 SET a=2, b=3;
+InnoDB 0 transactions not purged
+FLUSH TABLE t1 FOR EXPORT;
+page 4: N_RECS=0x0001
+page 5: N_RECS=0x0001
+UNLOCK TABLES;
+DROP TABLE t1;
+# End of 10.3 tests
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb/t/alter_missing_tablespace.test b/mysql-test/suite/innodb/t/alter_missing_tablespace.test
index c1cfc0fa092..20088ef9dd3 100644
--- a/mysql-test/suite/innodb/t/alter_missing_tablespace.test
+++ b/mysql-test/suite/innodb/t/alter_missing_tablespace.test
@@ -1,5 +1,6 @@
--source include/not_embedded.inc
--source include/innodb_page_size.inc
+--source include/no_valgrind_without_big.inc
--echo #
--echo # Bug#13955083 ALLOW IN-PLACE DDL OPERATIONS ON MISSING
diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test
index a3f4ad9ac5c..b61d2ca8b6c 100644
--- a/mysql-test/suite/innodb/t/ibuf_not_empty.test
+++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test
@@ -5,6 +5,7 @@
--source include/not_embedded.inc
# The test is not big enough to use change buffering with larger page size.
--source include/have_innodb_max_16k.inc
+--source include/no_valgrind_without_big.inc
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
--disable_query_log
diff --git a/mysql-test/suite/innodb/t/innodb-get-fk.test b/mysql-test/suite/innodb/t/innodb-get-fk.test
index 47db92a0c6d..b4b170b89f9 100644
--- a/mysql-test/suite/innodb/t/innodb-get-fk.test
+++ b/mysql-test/suite/innodb/t/innodb-get-fk.test
@@ -2,6 +2,8 @@
--source include/default_charset.inc
# need to restart server
--source include/not_embedded.inc
+--source include/no_valgrind_without_big.inc
+
CREATE SCHEMA `repro`;
CREATE TABLE `repro`.`crew` (
diff --git a/mysql-test/suite/innodb/t/missing_tablespaces.test b/mysql-test/suite/innodb/t/missing_tablespaces.test
index b4da9745ba4..996b77aa6c1 100644
--- a/mysql-test/suite/innodb/t/missing_tablespaces.test
+++ b/mysql-test/suite/innodb/t/missing_tablespaces.test
@@ -4,6 +4,7 @@
--source include/not_embedded.inc
#Windows has trouble creating files/directories with long names
--source include/not_windows.inc
+--source include/no_valgrind_without_big.inc
--echo #
--echo # Bug#19419026 WHEN A TABLESPACE IS NOT FOUND, DO NOT REPORT "TABLE NOT FOUND"
diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test
index bf702b6b737..530da2c33d9 100644
--- a/mysql-test/suite/innodb/t/purge_secondary.test
+++ b/mysql-test/suite/innodb/t/purge_secondary.test
@@ -149,4 +149,36 @@ WHERE NAME="buffer_LRU_batch_evict_total_pages" AND COUNT > 0;
DROP TABLE t1;
+--echo #
+--echo # MDEV-29666 InnoDB fails to purge secondary index records
+--echo # when indexed virtual columns exist
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, a1 INT AS(a) VIRTUAL,
+INDEX(a1),INDEX(b)) ENGINE=InnoDB;
+INSERT INTO t1 SET a=1, b=1;
+
+UPDATE t1 SET a=2, b=3;
+let DATADIR=`select @@datadir`;
+let PAGE_SIZE=`select @@innodb_page_size`;
+
+source include/wait_all_purged.inc;
+FLUSH TABLE t1 FOR EXPORT;
+
+perl;
+my $ps = $ENV{PAGE_SIZE};
+my $file = "$ENV{DATADIR}/test/t1.ibd";
+open(FILE, "<", $file) or die "Unable to open $file\n";
+die "Unable to read $file\n" unless
+ sysread(FILE, $_, 6*$ps) == 6*$ps;
+close(FILE);
+print "page 4: N_RECS=0x", unpack("H*", substr($_, 4 * $ps + 54, 2)), "\n";
+print "page 5: N_RECS=0x", unpack("H*", substr($_, 5 * $ps + 54, 2)), "\n";
+EOF
+
+UNLOCK TABLES;
+DROP TABLE t1;
+
+--echo # End of 10.3 tests
+
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test
index 79b2c3dd77a..92ebdda442a 100644
--- a/mysql-test/suite/innodb/t/table_flags.test
+++ b/mysql-test/suite/innodb/t/table_flags.test
@@ -2,6 +2,12 @@
# Embedded server tests do not support restarting
--source include/not_embedded.inc
--source include/maybe_debug.inc
+# Slow shutdown may take more than 120 seconds under Valgrind,
+# causing the server to be (silently) killed.
+# Due to that, crash recovery could "heal" the damage that our
+# Perl code is inflicting, and the SELECT statements could succeed
+# instead of failing with ER_NO_SUCH_TABLE_IN_ENGINE.
+--source include/not_valgrind.inc
--disable_query_log
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test
index bb8e3316860..f0fbb1a94c3 100644
--- a/mysql-test/suite/innodb/t/xa_recovery.test
+++ b/mysql-test/suite/innodb/t/xa_recovery.test
@@ -1,6 +1,7 @@
--source include/have_innodb.inc
# Embedded server does not support restarting.
--source include/not_embedded.inc
+--source include/no_valgrind_without_big.inc
# MDEV-8841 - close tables opened by previous tests,
# so they don't get marked crashed when the server gets crashed
diff --git a/mysql-test/suite/mariabackup/log_page_corruption.test b/mysql-test/suite/mariabackup/log_page_corruption.test
index 0151afb96b4..e14735fd024 100644
--- a/mysql-test/suite/mariabackup/log_page_corruption.test
+++ b/mysql-test/suite/mariabackup/log_page_corruption.test
@@ -1,4 +1,5 @@
--source include/have_debug.inc
+--source include/no_valgrind_without_big.inc
--echo ########
--echo # Test for generating "innodb_corrupted_pages" file during full and
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
index fd4cdf71f6f..5d0d39cadce 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
@@ -1,6 +1,7 @@
--let $rpl_topology=1->2
--source include/rpl_init.inc
--source include/have_innodb.inc
+--source include/no_valgrind_without_big.inc
--echo *** Test normal shutdown/restart of slave server configured as a GTID slave. ***
diff --git a/mysql-test/suite/rpl/t/rpl_mdev12179.test b/mysql-test/suite/rpl/t/rpl_mdev12179.test
index e3caccde6b4..962ce3f0135 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev12179.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev12179.test
@@ -1,6 +1,7 @@
--source include/have_innodb.inc
--let $rpl_topology=1->2
--source include/rpl_init.inc
+--source include/no_valgrind_without_big.inc
--connection server_2
call mtr.add_suppression("The automatically created table.*name may not be entirely in lowercase");
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_at_shutdown_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_at_shutdown_basic.test
index feb7bf05638..072d1cec1a4 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_at_shutdown_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_at_shutdown_basic.test
@@ -5,6 +5,7 @@
-- source include/have_innodb.inc
# include/restart_mysqld.inc does not work in embedded mode
-- source include/not_embedded.inc
+-- source include/no_valgrind_without_big.inc
# Check the default value
SET @orig = @@global.innodb_buffer_pool_dump_at_shutdown;
diff --git a/mysql-test/suite/sys_vars/t/innodb_flush_method_func.test b/mysql-test/suite/sys_vars/t/innodb_flush_method_func.test
index aad91d0f4a3..7293a99db41 100644
--- a/mysql-test/suite/sys_vars/t/innodb_flush_method_func.test
+++ b/mysql-test/suite/sys_vars/t/innodb_flush_method_func.test
@@ -1,6 +1,8 @@
--source include/have_innodb.inc
# Embedded server tests do not support restarting.
--source include/not_embedded.inc
+# InnoDB: Cannot read first page of './ibdata1' I/O error
+--source include/not_valgrind.inc
call mtr.add_suppression("InnoDB: Failed to set .*DIRECT");
--replace_result unbuffered fsync
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index e5f94bb42a3..d597520c3d8 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -884,7 +884,7 @@ btr_page_get_father_node_ptr_func(
err = btr_cur_search_to_nth_level(
index, level + 1, tuple,
- PAGE_CUR_LE, latch_mode, cursor, 0,
+ PAGE_CUR_LE, latch_mode, cursor,
file, line, mtr);
if (err != DB_SUCCESS) {
@@ -2450,7 +2450,7 @@ btr_insert_on_non_leaf_level_func(
dberr_t err = btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_LE,
BTR_CONT_MODIFY_TREE,
- &cursor, 0, file, line, mtr);
+ &cursor, file, line, mtr);
if (err != DB_SUCCESS) {
ib::warn() << " Error code: " << err
@@ -2471,7 +2471,7 @@ btr_insert_on_non_leaf_level_func(
btr_cur_search_to_nth_level(index, level, tuple,
PAGE_CUR_RTREE_INSERT,
BTR_CONT_MODIFY_TREE,
- &cursor, 0, file, line, mtr);
+ &cursor, file, line, mtr);
}
ut_ad(cursor.flag == BTR_CUR_BINARY);
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index abb633b51b4..3164352892e 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -1237,38 +1237,36 @@ If mode is PAGE_CUR_GE, then up_match will a have a sensible value.
If mode is PAGE_CUR_LE , cursor is left at the place where an insert of the
search tuple should be performed in the B-tree. InnoDB does an insert
immediately after the cursor. Thus, the cursor may end up on a user record,
-or on a page infimum record. */
-dberr_t
-btr_cur_search_to_nth_level_func(
- dict_index_t* index, /*!< in: index */
- ulint level, /*!< in: the tree level of search */
- const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
- tuple must be set so that it cannot get
- compared to the node ptr page number field! */
- page_cur_mode_t mode, /*!< in: PAGE_CUR_L, ...;
- Inserts should always be made using
- PAGE_CUR_LE to search the position! */
- ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
- at most one of BTR_INSERT, BTR_DELETE_MARK,
- BTR_DELETE, or BTR_ESTIMATE;
- cursor->left_block is used to store a pointer
- to the left neighbor page, in the cases
- BTR_SEARCH_PREV and BTR_MODIFY_PREV;
- NOTE that if ahi_latch, we might not have a
- cursor page latch, we assume that ahi_latch
- protects the record! */
- btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
- s- or x-latched, but see also above! */
-#ifdef BTR_CUR_HASH_ADAPT
- rw_lock_t* ahi_latch,
- /*!< in: currently held btr_search_latch
- (in RW_S_LATCH mode), or NULL */
-#endif /* BTR_CUR_HASH_ADAPT */
- const char* file, /*!< in: file name */
- unsigned line, /*!< in: line where called */
- mtr_t* mtr, /*!< in: mtr */
- ib_uint64_t autoinc)/*!< in: PAGE_ROOT_AUTO_INC to be written
- (0 if none) */
+or on a page infimum record.
+@param index index
+@param level the tree level of search
+@param tuple data tuple; NOTE: n_fields_cmp in tuple must be set so that
+ it cannot get compared to the node ptr page number field!
+@param mode PAGE_CUR_L, NOTE that if the search is made using a unique
+ prefix of a record, mode should be PAGE_CUR_LE, not
+ PAGE_CUR_GE, as the latter may end up on the previous page of
+ the record! Inserts should always be made using PAGE_CUR_LE
+ to search the position!
+@param latch_mode BTR_SEARCH_LEAF, ..., ORed with at most one of BTR_INSERT,
+ BTR_DELETE_MARK, BTR_DELETE, or BTR_ESTIMATE;
+ cursor->left_block is used to store a pointer to the left
+ neighbor page, in the cases BTR_SEARCH_PREV and
+ BTR_MODIFY_PREV; NOTE that if ahi_latch, we might not have a
+ cursor page latch, we assume that ahi_latch protects the
+ record!
+@param cursor tree cursor; the cursor page is s- or x-latched, but see also
+ above!
+@param file file name
+@param line line where called
+@param mtr mini-transaction
+@param autoinc PAGE_ROOT_AUTO_INC to be written (0 if none)
+@return DB_SUCCESS on success or error code otherwise */
+dberr_t btr_cur_search_to_nth_level(dict_index_t *index, ulint level,
+ const dtuple_t *tuple,
+ page_cur_mode_t mode, ulint latch_mode,
+ btr_cur_t *cursor, const char *file,
+ unsigned line, mtr_t *mtr,
+ ib_uint64_t autoinc)
{
page_t* page = NULL; /* remove warning */
buf_block_t* block;
@@ -1436,15 +1434,14 @@ btr_cur_search_to_nth_level_func(
&& mode != PAGE_CUR_LE_OR_EXTENDS
# endif /* PAGE_CUR_LE_OR_EXTENDS */
&& !dict_index_is_spatial(index)
- /* If !ahi_latch, we do a dirty read of
+ /* We do a dirty read of
btr_search_enabled below, and btr_search_guess_on_hash()
will have to check it again. */
&& btr_search_enabled
&& !modify_external
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
&& btr_search_guess_on_hash(index, info, tuple, mode,
- latch_mode, cursor,
- ahi_latch, mtr)) {
+ latch_mode, cursor, mtr)) {
/* Search using the hash index succeeded */
@@ -1465,13 +1462,6 @@ btr_cur_search_to_nth_level_func(
/* If the hash search did not succeed, do binary search down the
tree */
-#ifdef BTR_CUR_HASH_ADAPT
- if (ahi_latch) {
- /* Release possible search latch to obey latching order */
- rw_lock_s_unlock(ahi_latch);
- }
-#endif /* BTR_CUR_HASH_ADAPT */
-
/* Store the position of the tree latch we push to mtr so that we
know how to release it when we have latched leaf node(s) */
@@ -2527,12 +2517,6 @@ func_exit:
cursor->rtr_info->mbr_adj = true;
}
-#ifdef BTR_CUR_HASH_ADAPT
- if (ahi_latch) {
- rw_lock_s_lock(ahi_latch);
- }
-#endif /* BTR_CUR_HASH_ADAPT */
-
DBUG_RETURN(err);
}
@@ -6510,8 +6494,7 @@ btr_estimate_n_rows_in_range_low(
btr_cur_search_to_nth_level(index, 0, tuple1, mode1,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
- &cursor, 0,
- __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
ut_ad(!page_rec_is_infimum(btr_cur_get_rec(&cursor)));
@@ -6564,8 +6547,7 @@ btr_estimate_n_rows_in_range_low(
btr_cur_search_to_nth_level(index, 0, tuple2, mode2,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
- &cursor, 0,
- __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
const rec_t* rec = btr_cur_get_rec(&cursor);
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index c31db34186c..90084ef4379 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -421,11 +421,7 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, const char *file,
}
btr_pcur_open_with_no_init_func(index, tuple, mode, restore_latch_mode,
- this,
-#ifdef BTR_CUR_HASH_ADAPT
- NULL,
-#endif /* BTR_CUR_HASH_ADAPT */
- file, line, mtr);
+ this, file, line, mtr);
/* Restore the old search mode */
search_mode = old_mode;
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 131f8c13c27..5e2684822e7 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -888,8 +888,6 @@ both have sensible values.
we assume the caller uses his search latch
to protect the record!
@param[out] cursor tree cursor
-@param[in] ahi_latch the adaptive hash index latch being held,
- or NULL
@param[in] mtr mini transaction
@return whether the search succeeded */
bool
@@ -900,7 +898,6 @@ btr_search_guess_on_hash(
ulint mode,
ulint latch_mode,
btr_cur_t* cursor,
- rw_lock_t* ahi_latch,
mtr_t* mtr)
{
ulint fold;
@@ -909,8 +906,6 @@ btr_search_guess_on_hash(
btr_cur_t cursor2;
btr_pcur_t pcur;
#endif
- ut_ad(!ahi_latch || rw_lock_own_flagged(
- ahi_latch, RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
if (!btr_search_enabled) {
return false;
@@ -918,7 +913,6 @@ btr_search_guess_on_hash(
ut_ad(index && info && tuple && cursor && mtr);
ut_ad(!dict_index_is_ibuf(index));
- ut_ad(!ahi_latch || ahi_latch == btr_get_search_latch(index));
ut_ad((latch_mode == BTR_SEARCH_LEAF)
|| (latch_mode == BTR_MODIFY_LEAF));
@@ -949,28 +943,21 @@ btr_search_guess_on_hash(
cursor->fold = fold;
cursor->flag = BTR_CUR_HASH;
- rw_lock_t* use_latch = ahi_latch ? NULL : btr_get_search_latch(index);
+ rw_lock_t* ahi_latch = btr_get_search_latch(index);
const rec_t* rec;
- if (use_latch) {
- rw_lock_s_lock(use_latch);
+ rw_lock_s_lock(ahi_latch);
- if (!btr_search_enabled) {
- goto fail;
- }
- } else {
- ut_ad(btr_search_enabled);
- ut_ad(rw_lock_own(ahi_latch, RW_LOCK_S));
+ if (!btr_search_enabled) {
+ goto fail;
}
rec = static_cast<const rec_t*>(
ha_search_and_get_data(btr_get_search_table(index), fold));
if (!rec) {
- if (use_latch) {
fail:
- rw_lock_s_unlock(use_latch);
- }
+ rw_lock_s_unlock(ahi_latch);
btr_search_failure(info, cursor);
return false;
@@ -978,25 +965,19 @@ fail:
buf_block_t* block = buf_block_from_ahi(rec);
- if (use_latch) {
- if (!buf_page_get_known_nowait(
- latch_mode, block, BUF_MAKE_YOUNG,
- __FILE__, __LINE__, mtr)) {
- goto fail;
- }
+ if (!buf_page_get_known_nowait(latch_mode, block, BUF_MAKE_YOUNG,
+ __FILE__, __LINE__, mtr)) {
+ goto fail;
+ }
- const bool fail = index != block->index
- && index_id == block->index->id;
- ut_a(!fail || block->index->freed());
- rw_lock_s_unlock(use_latch);
+ const bool fail = index != block->index
+ && index_id == block->index->id;
+ ut_a(!fail || block->index->freed());
+ ut_ad(fail || !block->page.file_page_was_freed);
+ rw_lock_s_unlock(ahi_latch);
- buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
- if (UNIV_UNLIKELY(fail)) {
- goto fail_and_release_page;
- }
- } else if (UNIV_UNLIKELY(index != block->index
- && index_id == block->index->id)) {
- ut_a(block->index->freed());
+ buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
+ if (UNIV_UNLIKELY(fail)) {
goto fail_and_release_page;
}
@@ -1005,9 +986,7 @@ fail:
ut_ad(buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH);
fail_and_release_page:
- if (!ahi_latch) {
- btr_leaf_page_release(block, latch_mode, mtr);
- }
+ btr_leaf_page_release(block, latch_mode, mtr);
btr_search_failure(info, cursor);
return false;
@@ -1025,7 +1004,7 @@ fail_and_release_page:
record to determine if our guess for the cursor position is
right. */
if (index_id != btr_page_get_index_id(block->frame)
- || !btr_search_check_guess(cursor, !!ahi_latch, tuple, mode)) {
+ || !btr_search_check_guess(cursor, 0, tuple, mode)) {
goto fail_and_release_page;
}
@@ -1074,7 +1053,7 @@ fail_and_release_page:
#ifdef UNIV_SEARCH_PERF_STAT
btr_search_n_succ++;
#endif
- if (!ahi_latch && buf_page_peek_if_too_old(&block->page)) {
+ if (buf_page_peek_if_too_old(&block->page)) {
buf_page_make_young(&block->page);
}
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 72a9764bf3f..8b3c1568a60 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -4798,6 +4798,10 @@ buf_page_get_known_nowait(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
+ /* The check for the page was not freed would already have been
+ performed when the block descriptor was acquired by the thread for the
+ first time.*/
+
buf_block_buf_fix_inc(block, file, line);
buf_page_set_accessed(&block->page);
@@ -4844,24 +4848,6 @@ buf_page_get_known_nowait(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-#ifdef UNIV_DEBUG
- if (mode != BUF_KEEP_OLD) {
- /* If mode == BUF_KEEP_OLD, we are executing an I/O
- completion routine. Avoid a bogus assertion failure
- when ibuf_merge_or_delete_for_page() is processing a
- page that was just freed due to DROP INDEX, or
- deleting a record from SYS_INDEXES. This check will be
- skipped in recv_recover_page() as well. */
-
-# ifdef BTR_CUR_HASH_ADAPT
- ut_ad(!block->page.file_page_was_freed
- || btr_search_check_marked_free_index(block));
-# else /* BTR_CUR_HASH_ADAPT */
- ut_ad(!block->page.file_page_was_freed);
-# endif /* BTR_CUR_HASH_ADAPT */
- }
-#endif /* UNIV_DEBUG */
-
buf_pool->stat.n_page_gets++;
return(TRUE);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 178b7899af8..c91d8c0110d 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -5253,7 +5253,7 @@ dict_set_corrupted(
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_LE,
BTR_MODIFY_LEAF,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
if (cursor.low_match == dtuple_get_n_fields(tuple)) {
/* UPDATE SYS_INDEXES SET TYPE=index->type
@@ -5355,7 +5355,7 @@ dict_index_set_merge_threshold(
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
if (cursor.up_match == dtuple_get_n_fields(tuple)
&& rec_get_n_fields_old(btr_cur_get_rec(&cursor))
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 16766627505..64d662ca9b6 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -3415,7 +3415,7 @@ fts_add_doc_by_id(
btr_pcur_open_with_no_init(
fts_id_index, tuple, PAGE_CUR_LE, BTR_SEARCH_LEAF,
- &pcur, 0, &mtr);
+ &pcur, &mtr);
/* If we have a match, add the data to doc structure */
if (btr_pcur_get_low_match(&pcur) == 1) {
@@ -3453,7 +3453,7 @@ fts_add_doc_by_id(
btr_pcur_open_with_no_init(
clust_index, clust_ref, PAGE_CUR_LE,
- BTR_SEARCH_LEAF, &clust_pcur, 0, &mtr);
+ BTR_SEARCH_LEAF, &clust_pcur, &mtr);
doc_pcur = &clust_pcur;
clust_rec = btr_pcur_get_rec(&clust_pcur);
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 18f75e3d139..339dee00c91 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -588,7 +588,7 @@ rtr_pcur_open_low(
}
btr_cur_search_to_nth_level(index, level, tuple, mode, latch_mode,
- btr_cursor, 0, file, line, mtr);
+ btr_cursor, file, line, mtr);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->trx_if_known = NULL;
@@ -756,8 +756,7 @@ static void rtr_get_father_node(
/* root split, and search the new root */
btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_RTREE_LOCATE,
- BTR_CONT_MODIFY_TREE, btr_cur, 0,
- __FILE__, __LINE__, mtr);
+ BTR_CONT_MODIFY_TREE, btr_cur, __FILE__, __LINE__, mtr);
} else {
/* btr_validate */
@@ -766,8 +765,7 @@ static void rtr_get_father_node(
btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_RTREE_LOCATE,
- BTR_CONT_MODIFY_TREE, btr_cur, 0,
- __FILE__, __LINE__, mtr);
+ BTR_CONT_MODIFY_TREE, btr_cur, __FILE__, __LINE__, mtr);
rec = btr_cur_get_rec(btr_cur);
n_fields = dtuple_get_n_fields_cmp(tuple);
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 0eb06a3bc99..168fd974b86 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -170,56 +170,41 @@ btr_cur_optimistic_latch_leaves(
unsigned line,
mtr_t* mtr);
-/********************************************************************//**
-Searches an index tree and positions a tree cursor on a given level.
+/** Searches an index tree and positions a tree cursor on a given level.
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
to node pointer page number fields on the upper levels of the tree!
Note that if mode is PAGE_CUR_LE, which is used in inserts, then
cursor->up_match and cursor->low_match both will have sensible values.
-If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
-dberr_t
-btr_cur_search_to_nth_level_func(
- dict_index_t* index, /*!< in: index */
- ulint level, /*!< in: the tree level of search */
- const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
- tuple must be set so that it cannot get
- compared to the node ptr page number field! */
- page_cur_mode_t mode, /*!< in: PAGE_CUR_L, ...;
- NOTE that if the search is made using a unique
- prefix of a record, mode should be PAGE_CUR_LE,
- not PAGE_CUR_GE, as the latter may end up on
- the previous page of the record! Inserts
- should always be made using PAGE_CUR_LE to
- search the position! */
- ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
- at most one of BTR_INSERT, BTR_DELETE_MARK,
- BTR_DELETE, or BTR_ESTIMATE;
- cursor->left_block is used to store a pointer
- to the left neighbor page, in the cases
- BTR_SEARCH_PREV and BTR_MODIFY_PREV;
- NOTE that if ahi_latch, we might not have a
- cursor page latch, we assume that ahi_latch
- protects the record! */
- btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
- s- or x-latched, but see also above! */
-#ifdef BTR_CUR_HASH_ADAPT
- rw_lock_t* ahi_latch,
- /*!< in: currently held btr_search_latch
- (in RW_S_LATCH mode), or NULL */
-#endif /* BTR_CUR_HASH_ADAPT */
- const char* file, /*!< in: file name */
- unsigned line, /*!< in: line where called */
- mtr_t* mtr, /*!< in/out: mini-transaction */
- ib_uint64_t autoinc = 0);
- /*!< in: PAGE_ROOT_AUTO_INC to be written
- (0 if none) */
-#ifdef BTR_CUR_HASH_ADAPT
-# define btr_cur_search_to_nth_level(i,l,t,m,lm,c,a,fi,li,mtr) \
- btr_cur_search_to_nth_level_func(i,l,t,m,lm,c,a,fi,li,mtr)
-#else /* BTR_CUR_HASH_ADAPT */
-# define btr_cur_search_to_nth_level(i,l,t,m,lm,c,a,fi,li,mtr) \
- btr_cur_search_to_nth_level_func(i,l,t,m,lm,c,fi,li,mtr)
-#endif /* BTR_CUR_HASH_ADAPT */
+If mode is PAGE_CUR_GE, then up_match will a have a sensible value.
+@param index index
+@param level the tree level of search
+@param tuple data tuple; NOTE: n_fields_cmp in tuple must be set so that
+ it cannot get compared to the node ptr page number field!
+@param mode PAGE_CUR_L, NOTE that if the search is made using a unique
+ prefix of a record, mode should be PAGE_CUR_LE, not
+ PAGE_CUR_GE, as the latter may end up on the previous page of
+ the record! Inserts should always be made using PAGE_CUR_LE
+ to search the position!
+@param latch_mode BTR_SEARCH_LEAF, ..., ORed with at most one of BTR_INSERT,
+ BTR_DELETE_MARK, BTR_DELETE, or BTR_ESTIMATE;
+ cursor->left_block is used to store a pointer to the left
+ neighbor page, in the cases BTR_SEARCH_PREV and
+ BTR_MODIFY_PREV; NOTE that if ahi_latch, we might not have a
+ cursor page latch, we assume that ahi_latch protects the
+ record!
+@param cursor tree cursor; the cursor page is s- or x-latched, but see also
+ above!
+@param file file name
+@param line line where called
+@param mtr mini-transaction
+@param autoinc PAGE_ROOT_AUTO_INC to be written (0 if none)
+@return DB_SUCCESS on success or error code otherwise */
+dberr_t btr_cur_search_to_nth_level(dict_index_t *index, ulint level,
+ const dtuple_t *tuple,
+ page_cur_mode_t mode, ulint latch_mode,
+ btr_cur_t *cursor, const char *file,
+ unsigned line, mtr_t *mtr,
+ ib_uint64_t autoinc= 0);
/*****************************************************************//**
Opens a cursor at either end of an index.
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index bbb9831ae93..ca17dd95aa7 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -116,41 +116,30 @@ btr_pcur_open_low(
mtr_t* mtr); /*!< in: mtr */
#define btr_pcur_open(i,t,md,l,c,m) \
btr_pcur_open_low(i,0,t,md,l,c,__FILE__,__LINE__,0,m)
-/**************************************************************//**
-Opens an persistent cursor to an index tree without initializing the
-cursor. */
+/** Opens an persistent cursor to an index tree without initializing the
+cursor.
+@param index index
+@param tuple tuple on which search done
+@param mode PAGE_CUR_L, ...; NOTE that if the search is made using a
+ unique prefix of a record, mode should be PAGE_CUR_LE, not
+ PAGE_CUR_GE, as the latter may end up on the previous page of
+ the record!
+@param latch_mode BTR_SEARCH_LEAF, ...; NOTE that if ahi_latch then we might
+ not acquire a cursor page latch, but assume that the
+ ahi_latch protects the record!
+@param cursor memory buffer for persistent cursor
+@param file file name
+@param line line where called
+@param mtr mtr
+@return DB_SUCCESS on success or error code otherwise. */
UNIV_INLINE
-dberr_t
-btr_pcur_open_with_no_init_func(
-/*============================*/
- dict_index_t* index, /*!< in: index */
- const dtuple_t* tuple, /*!< in: tuple on which search done */
- page_cur_mode_t mode, /*!< in: PAGE_CUR_L, ...;
- NOTE that if the search is made using a unique
- prefix of a record, mode should be
- PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
- may end up on the previous page of the
- record! */
- ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
- NOTE that if ahi_latch then we might not
- acquire a cursor page latch, but assume
- that the ahi_latch protects the record! */
- btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
-#ifdef BTR_CUR_HASH_ADAPT
- rw_lock_t* ahi_latch,
- /*!< in: adaptive hash index latch held
- by the caller, or NULL if none */
-#endif /* BTR_CUR_HASH_ADAPT */
- const char* file, /*!< in: file name */
- unsigned line, /*!< in: line where called */
- mtr_t* mtr); /*!< in: mtr */
-#ifdef BTR_CUR_HASH_ADAPT
-# define btr_pcur_open_with_no_init(ix,t,md,l,cur,ahi,m) \
- btr_pcur_open_with_no_init_func(ix,t,md,l,cur,ahi,__FILE__,__LINE__,m)
-#else /* BTR_CUR_HASH_ADAPT */
-# define btr_pcur_open_with_no_init(ix,t,md,l,cur,ahi,m) \
+dberr_t btr_pcur_open_with_no_init_func(dict_index_t *index,
+ const dtuple_t *tuple,
+ page_cur_mode_t mode, ulint latch_mode,
+ btr_pcur_t *cursor, const char *file,
+ unsigned line, mtr_t *mtr);
+# define btr_pcur_open_with_no_init(ix,t,md,l,cur,m) \
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,__FILE__,__LINE__,m)
-#endif /* BTR_CUR_HASH_ADAPT */
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
diff --git a/storage/innobase/include/btr0pcur.inl b/storage/innobase/include/btr0pcur.inl
index d93da475a1f..05f61b903ff 100644
--- a/storage/innobase/include/btr0pcur.inl
+++ b/storage/innobase/include/btr0pcur.inl
@@ -438,11 +438,8 @@ btr_pcur_open_low(
ut_ad(!dict_index_is_spatial(index));
- err = btr_cur_search_to_nth_level_func(
+ err = btr_cur_search_to_nth_level(
index, level, tuple, mode, latch_mode, btr_cursor,
-#ifdef BTR_CUR_HASH_ADAPT
- NULL,
-#endif /* BTR_CUR_HASH_ADAPT */
file, line, mtr, autoinc);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
@@ -462,34 +459,28 @@ btr_pcur_open_low(
return(err);
}
-/**************************************************************//**
-Opens an persistent cursor to an index tree without initializing the
-cursor. */
+/** Opens an persistent cursor to an index tree without initializing the
+cursor.
+@param index index
+@param tuple tuple on which search done
+@param mode PAGE_CUR_L, ...; NOTE that if the search is made using a
+ unique prefix of a record, mode should be PAGE_CUR_LE, not
+ PAGE_CUR_GE, as the latter may end up on the previous page of
+ the record!
+@param latch_mode BTR_SEARCH_LEAF, ...; NOTE that if ahi_latch then we might
+ not acquire a cursor page latch, but assume that the
+ ahi_latch protects the record!
+@param cursor memory buffer for persistent cursor
+@param file file name
+@param line line where called
+@param mtr mtr
+@return DB_SUCCESS on success or error code otherwise. */
UNIV_INLINE
-dberr_t
-btr_pcur_open_with_no_init_func(
-/*============================*/
- dict_index_t* index, /*!< in: index */
- const dtuple_t* tuple, /*!< in: tuple on which search done */
- page_cur_mode_t mode, /*!< in: PAGE_CUR_L, ...;
- NOTE that if the search is made using a unique
- prefix of a record, mode should be
- PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
- may end up on the previous page of the
- record! */
- ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
- NOTE that if ahi_latch then we might not
- acquire a cursor page latch, but assume
- that the ahi_latch protects the record! */
- btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
-#ifdef BTR_CUR_HASH_ADAPT
- rw_lock_t* ahi_latch,
- /*!< in: adaptive hash index latch held
- by the caller, or NULL if none */
-#endif /* BTR_CUR_HASH_ADAPT */
- const char* file, /*!< in: file name */
- unsigned line, /*!< in: line where called */
- mtr_t* mtr) /*!< in: mtr */
+dberr_t btr_pcur_open_with_no_init_func(dict_index_t *index,
+ const dtuple_t *tuple,
+ page_cur_mode_t mode, ulint latch_mode,
+ btr_pcur_t *cursor, const char *file,
+ unsigned line, mtr_t *mtr)
{
btr_cur_t* btr_cursor;
dberr_t err = DB_SUCCESS;
@@ -501,11 +492,8 @@ btr_pcur_open_with_no_init_func(
btr_cursor = btr_pcur_get_btr_cur(cursor);
- err = btr_cur_search_to_nth_level_func(
+ err = btr_cur_search_to_nth_level(
index, 0, tuple, mode, latch_mode, btr_cursor,
-#ifdef BTR_CUR_HASH_ADAPT
- ahi_latch,
-#endif /* BTR_CUR_HASH_ADAPT */
file, line, mtr);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index 8277be8ac14..f217f8213f8 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -80,7 +80,6 @@ btr_search_guess_on_hash(
ulint mode,
ulint latch_mode,
btr_cur_t* cursor,
- rw_lock_t* ahi_latch,
mtr_t* mtr);
/** Move or delete hash entries for moved records, usually in a page split.
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index fa084ff274c..992e7645bc7 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2022, 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
@@ -136,30 +136,6 @@ trx_undo_update_rec_get_update(
mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
upd_t** upd); /*!< out, own: update vector */
-/*******************************************************************//**
-Builds a partial row from an update undo log record, for purge.
-It contains the columns which occur as ordering in any index of the table.
-Any missing columns are indicated by col->mtype == DATA_MISSING.
-@return pointer to remaining part of undo record */
-byte*
-trx_undo_rec_get_partial_row(
-/*=========================*/
- const byte* ptr, /*!< in: remaining part in update undo log
- record of a suitable type, at the start of
- the stored index columns;
- NOTE that this copy of the undo log record must
- be preserved as long as the partial row is
- used, as we do NOT copy the data in the
- record! */
- dict_index_t* index, /*!< in: clustered index */
- const upd_t* update, /*!< in: updated columns */
- dtuple_t** row, /*!< out, own: partial row */
- ibool ignore_prefix, /*!< in: flag to indicate if we
- expect blob prefixes in undo. Used
- only in the assertion. */
- mem_heap_t* heap) /*!< in: memory heap from which the memory
- needed is allocated */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Report a RENAME TABLE operation.
@param[in,out] trx transaction
@param[in] table table that is being renamed
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index eab4925c875..594a13e3740 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1137,7 +1137,7 @@ row_ins_foreign_check_on_constraint(
tmp_heap);
btr_pcur_open_with_no_init(clust_index, ref,
PAGE_CUR_LE, BTR_SEARCH_LEAF,
- cascade->pcur, 0, mtr);
+ cascade->pcur, mtr);
clust_rec = btr_pcur_get_rec(cascade->pcur);
clust_block = btr_pcur_get_block(cascade->pcur);
@@ -2947,7 +2947,7 @@ row_ins_sec_index_entry_low(
err = btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_RTREE_INSERT,
search_mode,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
if (mode == BTR_MODIFY_LEAF && rtr_info.mbr_adj) {
mtr_commit(&mtr);
@@ -2966,7 +2966,7 @@ row_ins_sec_index_entry_low(
err = btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_RTREE_INSERT,
search_mode,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
mode = BTR_MODIFY_TREE;
}
@@ -2978,7 +2978,7 @@ row_ins_sec_index_entry_low(
err = btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_LE,
search_mode,
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
}
if (err != DB_SUCCESS) {
@@ -3072,7 +3072,7 @@ row_ins_sec_index_entry_low(
index, 0, entry, PAGE_CUR_LE,
(search_mode
& ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)),
- &cursor, 0, __FILE__, __LINE__, &mtr);
+ &cursor, __FILE__, __LINE__, &mtr);
}
if (row_ins_must_modify_rec(&cursor)) {
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 54b427ef8b4..2ab49962cd8 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -3359,7 +3359,7 @@ row_log_apply_op_low(
has_index_lock
? BTR_MODIFY_TREE
: BTR_MODIFY_LEAF,
- &cursor, 0, __FILE__, __LINE__,
+ &cursor, __FILE__, __LINE__,
&mtr);
ut_ad(dict_index_get_n_unique(index) > 0);
@@ -3408,7 +3408,7 @@ row_log_apply_op_low(
index->set_modified(mtr);
btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_LE,
- BTR_MODIFY_TREE, &cursor, 0,
+ BTR_MODIFY_TREE, &cursor,
__FILE__, __LINE__, &mtr);
/* No other thread than the current one
@@ -3511,7 +3511,7 @@ insert_the_rec:
index->set_modified(mtr);
btr_cur_search_to_nth_level(
index, 0, entry, PAGE_CUR_LE,
- BTR_MODIFY_TREE, &cursor, 0,
+ BTR_MODIFY_TREE, &cursor,
__FILE__, __LINE__, &mtr);
}
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 7661994394c..cfe0463ca61 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -163,7 +163,7 @@ public:
btr_cur_search_to_nth_level(m_index, 0, dtuple,
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_LEAF, &ins_cur,
- 0, __FILE__, __LINE__,
+ __FILE__, __LINE__,
&mtr);
/* It need to update MBR in parent entry,
@@ -179,7 +179,7 @@ public:
btr_cur_search_to_nth_level(
m_index, 0, dtuple,
PAGE_CUR_RTREE_INSERT,
- BTR_MODIFY_TREE, &ins_cur, 0,
+ BTR_MODIFY_TREE, &ins_cur,
__FILE__, __LINE__, &mtr);
}
@@ -202,8 +202,7 @@ public:
m_index, 0, dtuple,
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_TREE,
- &ins_cur, 0,
- __FILE__, __LINE__, &mtr);
+ &ins_cur, __FILE__, __LINE__, &mtr);
error = btr_cur_pessimistic_insert(
flag, &ins_cur, &ins_offsets,
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 8ee7639f095..6ed03f0eabb 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, 2021, MariaDB Corporation.
+Copyright (c) 2017, 2022, 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
@@ -1009,6 +1009,141 @@ skip_secondaries:
row_purge_upd_exist_or_extern_func(node,undo_rec)
#endif /* UNIV_DEBUG */
+/** Build a partial row from an update undo log record for purge.
+Any columns which occur as ordering in any index of the table are present.
+Any missing columns are indicated by col->mtype == DATA_MISSING.
+
+@param ptr remaining part of the undo log record
+@param index clustered index
+@param node purge node
+@return pointer to remaining part of undo record */
+static byte *row_purge_get_partial(const byte *ptr, const dict_index_t &index,
+ purge_node_t *node)
+{
+ bool first_v_col= true;
+ bool is_undo_log= true;
+
+ ut_ad(index.is_primary());
+ ut_ad(index.n_uniq == node->ref->n_fields);
+
+ node->row= dtuple_create_with_vcol(node->heap, index.table->n_cols,
+ index.table->n_v_cols);
+
+ /* Mark all columns in the row uninitialized, so that
+ we can distinguish missing fields from fields that are SQL NULL. */
+ for (ulint i= 0; i < index.table->n_cols; i++)
+ node->row->fields[i].type.mtype= DATA_MISSING;
+
+ dtuple_init_v_fld(node->row);
+
+ for (const upd_field_t *uf= node->update->fields, *const ue=
+ node->update->fields + node->update->n_fields; uf != ue; uf++)
+ {
+ if (!uf->old_v_val)
+ {
+ const dict_col_t &c= *dict_index_get_nth_col(&index, uf->field_no);
+ if (!c.is_dropped())
+ node->row->fields[c.ind]= uf->new_val;
+ }
+ }
+
+ const byte *end_ptr= ptr + mach_read_from_2(ptr);
+ ptr+= 2;
+
+ while (ptr != end_ptr)
+ {
+ dfield_t *dfield;
+ const byte *field;
+ const dict_col_t *col;
+ ulint len;
+ ulint orig_len;
+
+ ulint field_no= mach_read_next_compressed(&ptr);
+
+ if (field_no >= REC_MAX_N_FIELDS)
+ {
+ ptr= trx_undo_read_v_idx(index.table, ptr, first_v_col, &is_undo_log,
+ &field_no);
+ first_v_col= false;
+
+ ptr= trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
+
+ if (field_no == ULINT_UNDEFINED)
+ continue; /* there no longer is an index on the virtual column */
+
+ dict_v_col_t *vcol= dict_table_get_nth_v_col(index.table, field_no);
+ col =&vcol->m_col;
+ dfield= dtuple_get_nth_v_field(node->row, vcol->v_pos);
+ dict_col_copy_type(&vcol->m_col, &dfield->type);
+ }
+ else
+ {
+ ptr= trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
+ col= dict_index_get_nth_col(&index, field_no);
+ if (col->is_dropped())
+ continue;
+ dfield= dtuple_get_nth_field(node->row, col->ind);
+ ut_ad(dfield->type.mtype == DATA_MISSING ||
+ dict_col_type_assert_equal(col, &dfield->type));
+ ut_ad(dfield->type.mtype == DATA_MISSING ||
+ dfield->len == len ||
+ (len != UNIV_SQL_NULL && len >= UNIV_EXTERN_STORAGE_FIELD));
+ dict_col_copy_type(dict_table_get_nth_col(index.table, col->ind),
+ &dfield->type);
+ }
+
+ dfield_set_data(dfield, field, len);
+
+ if (len == UNIV_SQL_NULL || len < UNIV_EXTERN_STORAGE_FIELD)
+ continue;
+
+ spatial_status_t spatial_status= static_cast<spatial_status_t>
+ ((len & SPATIAL_STATUS_MASK) >> SPATIAL_STATUS_SHIFT);
+ len&= ~SPATIAL_STATUS_MASK;
+
+ /* Keep compatible with 5.7.9 format. */
+ if (spatial_status == SPATIAL_UNKNOWN)
+ spatial_status= dict_col_get_spatial_status(col);
+
+ switch (UNIV_EXPECT(spatial_status, SPATIAL_NONE)) {
+ case SPATIAL_ONLY:
+ ut_ad(len - UNIV_EXTERN_STORAGE_FIELD == DATA_MBR_LEN);
+ dfield_set_len(dfield, len - UNIV_EXTERN_STORAGE_FIELD);
+ break;
+
+ case SPATIAL_MIXED:
+ dfield_set_len(dfield, len - UNIV_EXTERN_STORAGE_FIELD - DATA_MBR_LEN);
+ break;
+
+ default:
+ dfield_set_len(dfield, len - UNIV_EXTERN_STORAGE_FIELD);
+ break;
+ }
+
+ dfield_set_ext(dfield);
+ dfield_set_spatial_status(dfield, spatial_status);
+
+ if (!col->ord_part || spatial_status == SPATIAL_ONLY ||
+ node->rec_type == TRX_UNDO_UPD_DEL_REC)
+ continue;
+ /* If the prefix of this BLOB column is indexed, ensure that enough
+ prefix is stored in the undo log record. */
+ ut_a(dfield_get_len(dfield) >= BTR_EXTERN_FIELD_REF_SIZE);
+ ut_a(dict_table_has_atomic_blobs(index.table) ||
+ dfield_get_len(dfield) >=
+ REC_ANTELOPE_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE);
+ }
+
+ for (ulint i= 0; i < index.n_uniq; i++)
+ {
+ dfield_t &field= node->row->fields[index.fields[i].col->ind];
+ if (field.type.mtype == DATA_MISSING)
+ field= node->ref->fields[i];
+ }
+
+ return const_cast<byte*>(ptr);
+}
+
/***********************************************************//**
Parses the row reference and other info in a modify undo log record.
@return true if purge operation required */
@@ -1158,10 +1293,7 @@ err_exit:
if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
ut_ad(!(node->update->info_bits & REC_INFO_MIN_REC_FLAG));
- ptr = trx_undo_rec_get_partial_row(
- ptr, clust_index, node->update, &node->row,
- type == TRX_UNDO_UPD_DEL_REC,
- node->heap);
+ ptr = row_purge_get_partial(ptr, *clust_index, node);
} else if (node->update->info_bits & REC_INFO_MIN_REC_FLAG) {
node->ref = &trx_undo_metadata;
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 781769dbf04..95342ac11d2 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -988,8 +988,7 @@ row_sel_get_clust_rec(
index = dict_table_get_first_index(plan->table);
btr_pcur_open_with_no_init(index, plan->clust_ref, PAGE_CUR_LE,
- BTR_SEARCH_LEAF, &plan->clust_pcur,
- 0, mtr);
+ BTR_SEARCH_LEAF, &plan->clust_pcur, mtr);
clust_rec = btr_pcur_get_rec(&(plan->clust_pcur));
@@ -1397,8 +1396,7 @@ row_sel_open_pcur(
/* Open pcur to the index */
btr_pcur_open_with_no_init(index, plan->tuple, plan->mode,
- BTR_SEARCH_LEAF, &plan->pcur,
- NULL, mtr);
+ BTR_SEARCH_LEAF, &plan->pcur, mtr);
} else {
/* Open the cursor to the start or the end of the index
(FALSE: no init) */
@@ -3329,7 +3327,7 @@ Row_sel_get_clust_rec_for_mysql::operator()(
btr_pcur_open_with_no_init(clust_index, prebuilt->clust_ref,
PAGE_CUR_LE, BTR_SEARCH_LEAF,
- prebuilt->clust_pcur, 0, mtr);
+ prebuilt->clust_pcur, mtr);
clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur);
@@ -3912,15 +3910,12 @@ row_sel_try_search_shortcut_for_mysql(
ut_ad(dict_index_is_clust(index));
ut_ad(!prebuilt->templ_contains_blob);
- rw_lock_t* ahi_latch = btr_get_search_latch(index);
- rw_lock_s_lock(ahi_latch);
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
- BTR_SEARCH_LEAF, pcur, ahi_latch, mtr);
+ BTR_SEARCH_LEAF, pcur, mtr);
rec = btr_pcur_get_rec(pcur);
if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, *index)) {
retry:
- rw_lock_s_unlock(ahi_latch);
return(SEL_RETRY);
}
@@ -3930,7 +3925,6 @@ retry:
if (btr_pcur_get_up_match(pcur) < dtuple_get_n_fields(search_tuple)) {
exhausted:
- rw_lock_s_unlock(ahi_latch);
return(SEL_EXHAUSTED);
}
@@ -3954,7 +3948,6 @@ exhausted:
*out_rec = rec;
- rw_lock_s_unlock(ahi_latch);
return(SEL_FOUND);
}
#endif /* BTR_CUR_HASH_ADAPT */
@@ -4727,8 +4720,7 @@ wait_table_again:
}
err = btr_pcur_open_with_no_init(index, search_tuple, mode,
- BTR_SEARCH_LEAF,
- pcur, 0, &mtr);
+ BTR_SEARCH_LEAF, pcur, &mtr);
if (err != DB_SUCCESS) {
rec = NULL;
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 4ef7a043104..22d8915f582 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -1762,185 +1762,6 @@ trx_undo_update_rec_get_update(
return(const_cast<byte*>(ptr));
}
-/*******************************************************************//**
-Builds a partial row from an update undo log record, for purge.
-It contains the columns which occur as ordering in any index of the table.
-Any missing columns are indicated by col->mtype == DATA_MISSING.
-@return pointer to remaining part of undo record */
-byte*
-trx_undo_rec_get_partial_row(
-/*=========================*/
- const byte* ptr, /*!< in: remaining part in update undo log
- record of a suitable type, at the start of
- the stored index columns;
- NOTE that this copy of the undo log record must
- be preserved as long as the partial row is
- used, as we do NOT copy the data in the
- record! */
- dict_index_t* index, /*!< in: clustered index */
- const upd_t* update, /*!< in: updated columns */
- dtuple_t** row, /*!< out, own: partial row */
- ibool ignore_prefix, /*!< in: flag to indicate if we
- expect blob prefixes in undo. Used
- only in the assertion. */
- mem_heap_t* heap) /*!< in: memory heap from which the memory
- needed is allocated */
-{
- const byte* end_ptr;
- bool first_v_col = true;
- bool is_undo_log = true;
-
- ut_ad(index->is_primary());
-
- *row = dtuple_create_with_vcol(
- heap, dict_table_get_n_cols(index->table),
- dict_table_get_n_v_cols(index->table));
-
- /* Mark all columns in the row uninitialized, so that
- we can distinguish missing fields from fields that are SQL NULL. */
- for (ulint i = 0; i < dict_table_get_n_cols(index->table); i++) {
- dfield_get_type(dtuple_get_nth_field(*row, i))
- ->mtype = DATA_MISSING;
- }
-
- dtuple_init_v_fld(*row);
-
- for (const upd_field_t* uf = update->fields, * const ue
- = update->fields + update->n_fields;
- uf != ue; uf++) {
- if (uf->old_v_val) {
- continue;
- }
- const dict_col_t& c = *dict_index_get_nth_col(index,
- uf->field_no);
- if (!c.is_dropped()) {
- *dtuple_get_nth_field(*row, c.ind) = uf->new_val;
- }
- }
-
- end_ptr = ptr + mach_read_from_2(ptr);
- ptr += 2;
-
- while (ptr != end_ptr) {
- dfield_t* dfield;
- const byte* field;
- ulint field_no;
- const dict_col_t* col;
- ulint len;
- ulint orig_len;
- bool is_virtual;
-
- field_no = mach_read_next_compressed(&ptr);
-
- is_virtual = (field_no >= REC_MAX_N_FIELDS);
-
- if (is_virtual) {
- ptr = trx_undo_read_v_idx(
- index->table, ptr, first_v_col, &is_undo_log,
- &field_no);
- first_v_col = false;
- }
-
- ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
-
- /* This column could be dropped or no longer indexed */
- if (field_no == ULINT_UNDEFINED) {
- ut_ad(is_virtual);
- continue;
- }
-
- if (is_virtual) {
- dict_v_col_t* vcol = dict_table_get_nth_v_col(
- index->table, field_no);
- col = &vcol->m_col;
- dfield = dtuple_get_nth_v_field(*row, vcol->v_pos);
- dict_col_copy_type(
- &vcol->m_col,
- dfield_get_type(dfield));
- } else {
- col = dict_index_get_nth_col(index, field_no);
-
- if (col->is_dropped()) {
- continue;
- }
-
- dfield = dtuple_get_nth_field(*row, col->ind);
- ut_ad(dfield->type.mtype == DATA_MISSING
- || dict_col_type_assert_equal(col,
- &dfield->type));
- ut_ad(dfield->type.mtype == DATA_MISSING
- || dfield->len == len
- || (len != UNIV_SQL_NULL
- && len >= UNIV_EXTERN_STORAGE_FIELD));
- dict_col_copy_type(col, dfield_get_type(dfield));
- }
-
- dfield_set_data(dfield, field, len);
-
- if (len != UNIV_SQL_NULL
- && len >= UNIV_EXTERN_STORAGE_FIELD) {
- spatial_status_t spatial_status;
-
- /* Decode spatial status. */
- spatial_status = static_cast<spatial_status_t>(
- (len & SPATIAL_STATUS_MASK)
- >> SPATIAL_STATUS_SHIFT);
- len &= ~SPATIAL_STATUS_MASK;
-
- /* Keep compatible with 5.7.9 format. */
- if (spatial_status == SPATIAL_UNKNOWN) {
- spatial_status =
- dict_col_get_spatial_status(col);
- }
-
- switch (spatial_status) {
- case SPATIAL_ONLY:
- ut_ad(len - UNIV_EXTERN_STORAGE_FIELD
- == DATA_MBR_LEN);
- dfield_set_len(
- dfield,
- len - UNIV_EXTERN_STORAGE_FIELD);
- break;
-
- case SPATIAL_MIXED:
- dfield_set_len(
- dfield,
- len - UNIV_EXTERN_STORAGE_FIELD
- - DATA_MBR_LEN);
- break;
-
- case SPATIAL_NONE:
- dfield_set_len(
- dfield,
- len - UNIV_EXTERN_STORAGE_FIELD);
- break;
-
- case SPATIAL_UNKNOWN:
- ut_ad(0);
- break;
- }
-
- dfield_set_ext(dfield);
- dfield_set_spatial_status(dfield, spatial_status);
-
- /* If the prefix of this column is indexed,
- ensure that enough prefix is stored in the
- undo log record. */
- if (!ignore_prefix && col->ord_part
- && spatial_status != SPATIAL_ONLY) {
- ut_a(dfield_get_len(dfield)
- >= BTR_EXTERN_FIELD_REF_SIZE);
- ut_a(dict_table_has_atomic_blobs(index->table)
- || dfield_get_len(dfield)
- >= REC_ANTELOPE_MAX_INDEX_COL_LEN
- + BTR_EXTERN_FIELD_REF_SIZE);
- }
- }
- }
-
- return(const_cast<byte*>(ptr));
-}
-
/** Erase the unused undo log page end.
@param[in,out] undo_page undo log page
@return whether the page contained something */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 038cf9be825..770bbd961f2 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -568,8 +568,10 @@ void trx_disconnect_prepared(trx_t *trx)
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
ut_ad(trx->mysql_thd);
trx->read_view.close();
+ mutex_enter(&trx_sys.mutex);
trx->is_recovered= true;
trx->mysql_thd= NULL;
+ mutex_exit(&trx_sys.mutex);
/* todo/fixme: suggest to do it at innodb prepare */
trx->will_lock= false;
}
diff --git a/support-files/wsrep_notify.sh b/support-files/wsrep_notify.sh
index bdbe3d12a39..87ba11342c5 100644..100755
--- a/support-files/wsrep_notify.sh
+++ b/support-files/wsrep_notify.sh
@@ -4,12 +4,31 @@
# It will create 'wsrep' schema and two tables in it: 'membeship' and 'status'
# and fill them on every membership or node status change.
#
-# Edit parameters below to specify the address and login to server.
-
+# Edit parameters below to specify the address and login to server:
+#
USER=root
PSWD=rootpass
+#
+# If these parameters are not set, then the values
+# passed by the server are taken:
+#
HOST=127.0.0.1
PORT=3306
+#
+# Edit parameters below to specify SSL parameters:
+#
+ssl_key=
+ssl_cert=
+ssl_ca=
+ssl_capath=
+ssl_cipher=
+ssl_crl=
+ssl_crlpath=
+ssl_verify_server_cert=0
+#
+# Client executable path:
+#
+CLIENT="mysql"
SCHEMA="wsrep"
MEMB_TABLE="$SCHEMA.membership"
@@ -32,8 +51,6 @@ CREATE TABLE $STATUS_TABLE (
prim BOOLEAN /* if component is primary */
) ENGINE=MEMORY;
BEGIN;
-DELETE FROM $MEMB_TABLE;
-DELETE FROM $STATUS_TABLE;
"
END="COMMIT;"
@@ -43,7 +60,7 @@ configuration_change()
local idx=0
- for NODE in $(echo $MEMBERS | sed s/,/\ /g)
+ for NODE in $(echo "$MEMBERS" | sed s/,/\ /g)
do
echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, "
# Don't forget to properly quote string values
@@ -62,17 +79,44 @@ status_update()
echo "SET wsrep_on=0; BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; COMMIT;"
}
+trim_string()
+{
+ if [ -n "${BASH_VERSION:-}" ]; then
+ local pattern="[![:space:]${2:-}]"
+ local x="${1#*$pattern}"
+ local z=${#1}
+ x=${#x}
+ if [ $x -ne $z ]; then
+ local y="${1%$pattern*}"
+ y=${#y}
+ x=$(( z-x-1 ))
+ y=$(( y-x+1 ))
+ printf '%s' "${1:$x:$y}"
+ else
+ printf ''
+ fi
+ else
+ local pattern="[[:space:]${2:-}]"
+ echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
+ fi
+}
+
COM=status_update # not a configuration change by default
-while [ $# -gt 0 ]
-do
+STATUS=""
+CLUSTER_UUID=""
+PRIMARY="0"
+INDEX=""
+MEMBERS=""
+
+while [ $# -gt 0 ]; do
case $1 in
--status)
- STATUS=$2
+ STATUS=$(trim_string "$2")
shift
;;
--uuid)
- CLUSTER_UUID=$2
+ CLUSTER_UUID=$(trim_string "$2")
shift
;;
--primary)
@@ -81,22 +125,71 @@ do
shift
;;
--index)
- INDEX=$2
+ INDEX=$(trim_string "$2")
shift
;;
--members)
- MEMBERS=$2
+ MEMBERS=$(trim_string "$2")
shift
;;
esac
shift
done
-# Undefined means node is shutting down
-if [ "$STATUS" != "Undefined" ]
+USER=$(trim_string "$USER")
+PSWD=$(trim_string "$PSWD")
+
+HOST=$(trim_string "$HOST")
+PORT=$(trim_string "$PORT")
+
+case "$HOST" in
+\[*)
+ HOST="${HOST##\[}"
+ HOST=$(trim_string "${HOST%%\]}")
+ ;;
+esac
+
+if [ -z "$HOST" ]; then
+ HOST="${NOTIFY_HOST:-}"
+fi
+if [ -z "$PORT" ]; then
+ PORT="${NOTIFY_PORT:-}"
+fi
+
+ssl_key=$(trim_string "$ssl_key");
+ssl_cert=$(trim_string "$ssl_cert");
+ssl_ca=$(trim_string "$ssl_ca");
+ssl_capath=$(trim_string "$ssl_capath");
+ssl_cipher=$(trim_string "$ssl_cipher");
+ssl_crl=$(trim_string "$ssl_crl");
+ssl_crlpath=$(trim_string "$ssl_crlpath");
+ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert");
+
+SSL_PARAM=""
+
+if [ -n "$ssl_key" -o -n "$ssl_cert" -o \
+ -n "$ssl_ca" -o -n "$ssl_capath" -o \
+ -n "$ssl_cipher" ]
then
- $COM | mysql -B -u$USER -p$PSWD -h$HOST -P$PORT
+ SSL_PARAM=' --ssl'
+ [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'"
+ [ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'"
+ [ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'"
+ [ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'"
+ [ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'"
+ [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'"
+ [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'"
+ if [ -n "$ssl_verify_server_cert" ]; then
+ if [ $ssl_verify_server_cert -ne 0 ]; then
+ SSL_PARAM+=' --ssl-verify-server-cert'
+ fi
+ fi
+fi
+
+# Undefined means node is shutting down
+if [ "$STATUS" != 'Undefined' ]; then
+ "$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\
+ "-h'$HOST'" "-P$PORT"$SSL_PARAM
fi
exit 0
-#