1
0
mirror of https://github.com/MariaDB/server.git synced 2025-04-18 21:44:20 +03:00

Merge 10.6 into 10.11

This commit is contained in:
Marko Mäkelä 2025-02-25 10:23:24 +02:00
commit 0c204bfb87
25 changed files with 360 additions and 380 deletions

View File

@ -1,16 +1,15 @@
***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts ***
include/master-slave.inc
[connection master]
connection server_2;
SET sql_log_bin=0;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CALL mtr.add_suppression("InnoDB: Transaction was aborted due to ");
CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
SET sql_log_bin=1;
connection server_2;
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
CHANGE MASTER TO master_use_gtid=slave_pos;
connection server_1;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB;
INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6);
connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,;

View File

@ -31,3 +31,6 @@ test.t1 repair note The storage engine for the table doesn't support repair
test.t2 repair note The storage engine for the table doesn't support repair
DROP TABLE t1;
DROP TABLE t2;
connection node_1;
disconnect node_2a;
disconnect node_2b;

View File

@ -1,5 +0,0 @@
!include ../galera_2nodes.cnf
[mysqld.1]
wsrep-debug=1
loose-galera-bf-abort-lock-table=1

View File

@ -1,6 +1,5 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/force_restart.inc
#
# Test that a local LOCK TABLE will NOT be broken by an incoming remote transaction against that table
@ -18,15 +17,15 @@ INSERT INTO t1 VALUES (2);
--connection node_2
SET SESSION wsrep_sync_wait = 0;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'Waiting for table metadata lock'
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE LIKE 'Waiting for table metadata lock%' OR STATE LIKE 'Waiting to execute in isolation%');
--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
--source include/wait_condition_with_debug_and_kill.inc
--source include/wait_condition_with_debug.inc
UNLOCK TABLES;
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'Waiting for table metadata lock'
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE LIKE 'Waiting for table metadata lock%' OR STATE LIKE 'Waiting to execute in isolation%');
--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
--source include/wait_condition_with_debug_and_kill.inc
--source include/wait_condition_with_debug.inc
COMMIT;
SELECT COUNT(*) = 1 FROM t1;

View File

@ -2,5 +2,3 @@
[mysqld]
log-bin
wsrep-debug=1
loose-mysql-wsrep198=1

View File

@ -1,6 +1,5 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/force_restart.inc
CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t2 (id INT PRIMARY KEY) ENGINE=InnoDB;
@ -21,7 +20,7 @@ LOCK TABLE t2 WRITE;
--connection node_2
SET SESSION wsrep_sync_wait = 0;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'Waiting for table metadata lock'
--let $wait_condition = SELECT COUNT(*) BETWEEN 1 AND 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for table metadata lock%' OR STATE LIKE 'Waiting to execute in isolation%';
--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
--source include/wait_condition_with_debug_and_kill.inc
@ -39,3 +38,8 @@ UNLOCK TABLES;
DROP TABLE t1;
DROP TABLE t2;
--connection node_1
--disconnect node_2a
--disconnect node_2b

View File

@ -1,4 +1,6 @@
@@ -13,212 +13,212 @@
--- autoinc_persist.result
+++ autoinc_persist.result,desc
@@ -13,224 +13,224 @@
#
# Pre-create several tables
SET SQL_MODE='STRICT_ALL_TABLES';
@ -296,8 +298,7 @@
+2
+1
+CREATE TABLE t11(a FLOAT AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB;
INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0),
(20), (30), (31);
INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
SELECT * FROM t11;
a
--10
@ -310,7 +311,7 @@
-20
-30
31
-CREATE TABLE t12(a DOUBLE AUTO_INCREMENT KEY) ENGINE = InnoDB;
-CREATE TABLE t11u(a FLOAT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB;
+30
+20
+5
@ -320,9 +321,30 @@
+1
+-1
+-10
+CREATE TABLE t11u(a FLOAT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB;
INSERT INTO t11u VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
ERROR 22003: Out of range value for column 'a' at row 5
INSERT INTO t11u VALUES(0), (0), (0), (0), (0), (20), (30), (31);
SELECT * FROM t11u;
a
-11
-12
-13
-14
-15
-20
-30
31
-CREATE TABLE t12(a DOUBLE AUTO_INCREMENT KEY) ENGINE = InnoDB;
+30
+20
+15
+14
+13
+12
+11
+CREATE TABLE t12(a DOUBLE AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB;
INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0),
(20), (30), (31);
INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
SELECT * FROM t12;
a
--10
@ -344,10 +366,10 @@
+1
+-1
+-10
# Scenario 1: Normal restart, to test if the counters are persisted
# Scenario 2: Delete some values, to test the counters should not be the
# one which is the largest in current table
@@ -242,14 +242,14 @@
CREATE TABLE t12u(a DOUBLE UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB;
INSERT INTO t12u VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
ERROR 22003: Out of range value for column 'a' at row 5
@@ -268,14 +268,14 @@
SELECT MAX(a) AS `Expect 100000000000` FROM t9;
Expect 100000000000
100000000000
@ -364,7 +386,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=1234 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t13 VALUES(0);
SELECT a AS `Expect 1234` FROM t13;
@@ -464,28 +464,28 @@
@@ -490,28 +490,28 @@
INSERT INTO t1 VALUES(0), (0);
SELECT * FROM t1;
a
@ -398,7 +420,7 @@
# Ensure that all changes before the server is killed are persisted.
set global innodb_flush_log_at_trx_commit=1;
TRUNCATE TABLE t1;
@@ -498,63 +498,63 @@
@@ -524,63 +524,63 @@
INSERT INTO t19 VALUES(0), (0);
SELECT * FROM t19;
a
@ -481,7 +503,7 @@
DELETE FROM t3 WHERE a > 300;
SELECT MAX(a) AS `Expect 200` FROM t3;
Expect 200
@@ -566,7 +566,7 @@
@@ -592,7 +592,7 @@
Table Create Table
t3 CREATE TABLE `t3` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -490,7 +512,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t3 VALUES(0);
SELECT MAX(a) AS `Expect 201` FROM t3;
@@ -579,7 +579,7 @@
@@ -605,7 +605,7 @@
Table Create Table
t3 CREATE TABLE `t3` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -499,7 +521,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t3 VALUES(0);
SELECT MAX(a) AS `Expect 500` FROM t3;
@@ -591,13 +591,13 @@
@@ -617,13 +617,13 @@
Table Create Table
t3 CREATE TABLE `t3` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -515,7 +537,7 @@
INSERT INTO t3 VALUES(150), (180);
UPDATE t3 SET a = 200 WHERE a = 150;
INSERT INTO t3 VALUES(220);
@@ -607,7 +607,7 @@
@@ -633,7 +633,7 @@
Table Create Table
t3 CREATE TABLE `t3` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -524,7 +546,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=221 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t3 VALUES(0);
SELECT MAX(a) AS `Expect 221` FROM t3;
@@ -619,7 +619,7 @@
@@ -645,7 +645,7 @@
Table Create Table
t3 CREATE TABLE `t3` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -533,7 +555,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# MDEV-6076: Test adding an AUTO_INCREMENT COLUMN
CREATE TABLE mdev6076a (b INT) ENGINE=InnoDB;
@@ -669,18 +669,18 @@
@@ -695,18 +695,18 @@
INSERT INTO t_inplace SELECT * FROM t3;
SELECT * FROM t_inplace;
a
@ -559,7 +581,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=211 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# This will keep the autoinc counter
ALTER TABLE t_inplace AUTO_INCREMENT = 250, ALGORITHM = INPLACE;
@@ -689,7 +689,7 @@
@@ -715,7 +715,7 @@
Table Create Table
t_inplace CREATE TABLE `t_inplace` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -568,7 +590,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# This should keep the autoinc counter as well
ALTER TABLE t_inplace ADD COLUMN b INT, ALGORITHM = INPLACE;
@@ -699,16 +699,16 @@
@@ -725,16 +725,16 @@
t_inplace CREATE TABLE `t_inplace` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
@ -590,7 +612,7 @@
# This should reset the autoinc counter to the one specified
# Since it's smaller than current one but bigger than existing
# biggest counter in the table
@@ -719,7 +719,7 @@
@@ -745,7 +745,7 @@
t_inplace CREATE TABLE `t_inplace` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
@ -599,7 +621,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=180 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# This should reset the autoinc counter to the next value of
# current max counter in the table, since the specified value
@@ -730,7 +730,7 @@
@@ -756,7 +756,7 @@
Table Create Table
t_inplace CREATE TABLE `t_inplace` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -608,7 +630,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=123 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t_inplace VALUES(0), (0);
SELECT MAX(a) AS `Expect 124` FROM t_inplace;
@@ -757,18 +757,18 @@
@@ -783,18 +783,18 @@
INSERT INTO t_copy SELECT * FROM t3;
SELECT * FROM t_copy;
a
@ -634,7 +656,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=211 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# This will keep the autoinc counter
ALTER TABLE t_copy AUTO_INCREMENT = 250, ALGORITHM = COPY;
@@ -777,7 +777,7 @@
@@ -803,7 +803,7 @@
Table Create Table
t_copy CREATE TABLE `t_copy` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -643,7 +665,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# This should keep the autoinc counter as well
ALTER TABLE t_copy ADD COLUMN b INT, ALGORITHM = COPY;
@@ -787,16 +787,16 @@
@@ -813,16 +813,16 @@
t_copy CREATE TABLE `t_copy` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
@ -665,7 +687,7 @@
# This should reset the autoinc counter to the one specified
# Since it's smaller than current one but bigger than existing
# biggest counter in the table
@@ -807,7 +807,7 @@
@@ -833,7 +833,7 @@
t_copy CREATE TABLE `t_copy` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
@ -674,7 +696,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=180 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
# This should reset the autoinc counter to the next value of
# current max counter in the table, since the specified value
@@ -818,7 +818,7 @@
@@ -844,7 +844,7 @@
Table Create Table
t_copy CREATE TABLE `t_copy` (
`a` smallint(6) NOT NULL AUTO_INCREMENT,
@ -683,7 +705,7 @@
) ENGINE=InnoDB AUTO_INCREMENT=123 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
INSERT INTO t_copy VALUES(0), (0);
SELECT MAX(a) AS `Expect 124` FROM t_copy;
@@ -842,7 +842,7 @@
@@ -868,7 +868,7 @@
126
DROP TABLE t_copy, it_copy;
# Scenario 9: Test the sql_mode = NO_AUTO_VALUE_ON_ZERO
@ -692,7 +714,7 @@
set SQL_MODE = NO_AUTO_VALUE_ON_ZERO;
INSERT INTO t30 VALUES(NULL, 1), (200, 2), (0, 3);
INSERT INTO t30(b) VALUES(4), (5), (6), (7);
@@ -869,20 +869,20 @@
@@ -895,20 +895,20 @@
set global innodb_flush_log_at_trx_commit=1;
CREATE TABLE t31 (a INT) ENGINE = InnoDB;
INSERT INTO t31 VALUES(1), (2);
@ -719,7 +741,7 @@
INSERT INTO t32 VALUES(0), (0);
# Ensure that all changes before the server is killed are persisted.
set global innodb_flush_log_at_trx_commit=1;
@@ -897,7 +897,7 @@
@@ -923,7 +923,7 @@
# increasing the counter
CREATE TABLE t33 (
a BIGINT NOT NULL PRIMARY KEY,
@ -728,7 +750,7 @@
INSERT INTO t33 VALUES(1, NULL);
INSERT INTO t33 VALUES(2, NULL);
INSERT INTO t33 VALUES(2, NULL);
@@ -920,13 +920,13 @@
@@ -946,13 +946,13 @@
INSERT INTO t31(a) VALUES(6), (0);
SELECT * FROM t31;
a b
@ -748,7 +770,7 @@
DROP TABLE t31;
set SQL_MODE = NO_AUTO_VALUE_ON_ZERO;
DELETE FROM t30 WHERE a = 0;
@@ -965,7 +965,7 @@
@@ -991,7 +991,7 @@
DROP TABLE t33;
CREATE TABLE t33 (
a BIGINT NOT NULL PRIMARY KEY,
@ -757,7 +779,7 @@
ALTER TABLE t33 DISCARD TABLESPACE;
restore: t33 .ibd and .cfg files
ALTER TABLE t33 IMPORT TABLESPACE;
@@ -975,7 +975,7 @@
@@ -1001,8 +1001,8 @@
4
SELECT * FROM t33;
a b
@ -766,4 +788,5 @@
3 4
+2 2
+10 1
DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t30, t32, t33;
DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t11u, t12u,
t30, t32, t33;

View File

@ -190,8 +190,7 @@ a
100000000000
100000000006
CREATE TABLE t11(a FLOAT AUTO_INCREMENT KEY) ENGINE = InnoDB;
INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0),
(20), (30), (31);
INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
SELECT * FROM t11;
a
-10
@ -204,9 +203,22 @@ a
20
30
31
CREATE TABLE t11u(a FLOAT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB;
INSERT INTO t11u VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
ERROR 22003: Out of range value for column 'a' at row 5
INSERT INTO t11u VALUES(0), (0), (0), (0), (0), (20), (30), (31);
SELECT * FROM t11u;
a
11
12
13
14
15
20
30
31
CREATE TABLE t12(a DOUBLE AUTO_INCREMENT KEY) ENGINE = InnoDB;
INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0),
(20), (30), (31);
INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
SELECT * FROM t12;
a
-10
@ -219,6 +231,20 @@ a
20
30
31
CREATE TABLE t12u(a DOUBLE UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB;
INSERT INTO t12u VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
ERROR 22003: Out of range value for column 'a' at row 5
INSERT INTO t12u VALUES(0), (0), (0), (0), (0), (20), (30), (31);
SELECT * FROM t12u;
a
11
12
13
14
15
20
30
31
# Scenario 1: Normal restart, to test if the counters are persisted
# Scenario 2: Delete some values, to test the counters should not be the
# one which is the largest in current table
@ -978,4 +1004,5 @@ a b
10 1
2 2
3 4
DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t30, t32, t33;
DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t11u, t12u,
t30, t32, t33;

View File

@ -95,15 +95,25 @@ INSERT INTO t10 VALUES(0), (0), (0), (0), (8), (10), (0),
SELECT * FROM t10;
eval CREATE TABLE t11(a FLOAT $AUTO_INCREMENT_KEY_a) ENGINE = InnoDB;
INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0),
(20), (30), (31);
INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
SELECT * FROM t11;
eval CREATE TABLE t11u(a FLOAT UNSIGNED $AUTO_INCREMENT_KEY_a) ENGINE = InnoDB;
--error ER_WARN_DATA_OUT_OF_RANGE
INSERT INTO t11u VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
INSERT INTO t11u VALUES(0), (0), (0), (0), (0), (20), (30), (31);
SELECT * FROM t11u;
eval CREATE TABLE t12(a DOUBLE $AUTO_INCREMENT_KEY_a) ENGINE = InnoDB;
INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0),
(20), (30), (31);
INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
SELECT * FROM t12;
CREATE TABLE t12u(a DOUBLE UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB;
--error ER_WARN_DATA_OUT_OF_RANGE
INSERT INTO t12u VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31);
INSERT INTO t12u VALUES(0), (0), (0), (0), (0), (20), (30), (31);
SELECT * FROM t12u;
--echo # Scenario 1: Normal restart, to test if the counters are persisted
--echo # Scenario 2: Delete some values, to test the counters should not be the
--echo # one which is the largest in current table
@ -566,4 +576,5 @@ INSERT INTO t33 VALUES(3, NULL);
SELECT MAX(b) AS `Expect 4` FROM t33;
SELECT * FROM t33;
DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t30, t32, t33;
DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t11u, t12u,
t30, t32, t33;

View File

@ -5,6 +5,9 @@ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
content TEXT
) ENGINE= InnoDB;
SET STATEMENT debug_dbug='+d,innodb_report_deadlock' FOR
CREATE FULLTEXT INDEX idx ON articles (title, content);
ERROR HY000: Got error 11 "Resource temporarily unavailable" from storage engine InnoDB
CREATE FULLTEXT INDEX idx ON articles (title, content);
INSERT INTO articles (title, content) VALUES
('MySQL Tutorial','DBMS stands for MySQL DataBase ...'),

View File

@ -3,6 +3,9 @@
-- source include/have_innodb.inc
-- source include/have_debug.inc
--disable_query_log
call mtr.add_suppression("InnoDB: \\(Deadlock\\) writing `use_stopword'");
--enable_query_log
SET @optimize=@@GLOBAL.INNODB_OPTIMIZE_FULLTEXT_ONLY;
SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=1;
@ -14,6 +17,9 @@ CREATE TABLE articles (
content TEXT
) ENGINE= InnoDB;
--error ER_GET_ERRNO
SET STATEMENT debug_dbug='+d,innodb_report_deadlock' FOR
CREATE FULLTEXT INDEX idx ON articles (title, content);
CREATE FULLTEXT INDEX idx ON articles (title, content);
INSERT INTO articles (title, content) VALUES

View File

@ -1,16 +1,15 @@
***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts ***
include/master-slave.inc
[connection master]
connection server_2;
SET sql_log_bin=0;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CALL mtr.add_suppression("InnoDB: Transaction was aborted due to ");
CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
SET sql_log_bin=1;
connection server_2;
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
CHANGE MASTER TO master_use_gtid=slave_pos;
connection server_1;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB;
INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6);
connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,;

View File

@ -5,21 +5,19 @@
--source include/have_debug_sync.inc
--source include/master-slave.inc
--disable_query_log
call mtr.add_suppression("InnoDB: Transaction was aborted due to ");
--enable_query_log
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CALL mtr.add_suppression("InnoDB: Transaction was aborted due to ");
CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
--save_master_pos
--connection server_2
SET sql_log_bin=0;
CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
SET sql_log_bin=1;
--sync_with_master
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
CHANGE MASTER TO master_use_gtid=slave_pos;
--connection server_1
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB;
INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6);
--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,)

View File

@ -1870,18 +1870,6 @@ err:
if (non_temp_tables_count)
query_cache_invalidate3(thd, tables, 0);
/*
We are always logging drop of temporary tables.
The reason is to handle the following case:
- Use statement based replication
- CREATE TEMPORARY TABLE foo (logged)
- set row based replication
- DROP TEMPORARY TABLE foo (needs to be logged)
This should be fixed so that we remember if creation of the
temporary table was logged and only log it if the creation was
logged.
*/
if (non_trans_tmp_table_deleted ||
trans_tmp_table_deleted || non_tmp_table_deleted)
{

View File

@ -3242,11 +3242,9 @@ void wsrep_to_isolation_end(THD *thd)
@param requestor_ctx The MDL context of the requestor
@param ticket MDL ticket for the requested lock
@param key The key of the object (data) being protected
@retval TRUE Lock request can be granted
@retval FALSE Lock request cannot be granted
*/
void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
const MDL_ticket *ticket,
const MDL_key *key)
@ -3328,16 +3326,21 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
(granted_thd->system_thread != NON_SYSTEM_THREAD &&
granted_thd->mdl_context.has_explicit_locks()))
{
WSREP_DEBUG("BF thread waiting for FLUSH for %s",
wsrep_thd_query(request_thd));
THD_STAGE_INFO(request_thd, stage_waiting_ddl);
WSREP_DEBUG("BF thread waiting for %s",
granted_thd->lex->sql_command == SQLCOM_FLUSH ? "FLUSH" : "BACKUP");
ticket->wsrep_report(wsrep_debug);
if (granted_thd->current_backup_stage != BACKUP_FINISHED &&
wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP))
{
wsrep_abort_thd(request_thd, granted_thd, 1);
}
}
else if (granted_thd->lex->sql_command == SQLCOM_LOCK_TABLES)
{
WSREP_DEBUG("BF thread waiting for LOCK TABLES");
ticket->wsrep_report(wsrep_debug);
}
else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
{
WSREP_DEBUG("DROP caused BF abort, conf %s for %s",

View File

@ -3487,9 +3487,7 @@ dict_stats_fetch_from_ps(
dict_table_t* table) /*!< in/out: table */
{
index_fetch_t index_fetch_arg;
trx_t* trx;
pars_info_t* pinfo;
dberr_t ret;
char db_utf8[MAX_DB_UTF8_LEN];
char table_utf8[MAX_TABLE_UTF8_LEN];
@ -3503,34 +3501,36 @@ dict_stats_fetch_from_ps(
MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr;
dict_table_t* table_stats = dict_table_open_on_name(
TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE);
if (table_stats) {
dict_sys.freeze(SRW_LOCK_CALL);
table_stats = dict_acquire_mdl_shared<false>(table_stats, thd,
&mdl_table);
dict_sys.unfreeze();
if (!table_stats) {
return DB_STATS_DO_NOT_EXIST;
}
dict_table_t* index_stats = dict_table_open_on_name(
INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE);
if (!index_stats) {
dict_table_close(table_stats);
return DB_STATS_DO_NOT_EXIST;
}
dict_sys.freeze(SRW_LOCK_CALL);
table_stats = dict_acquire_mdl_shared<false>(table_stats, thd,
&mdl_table);
if (!table_stats
|| strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) {
release_and_exit:
if (table_stats) {
dict_table_close(table_stats, false, thd, mdl_table);
dict_table_close(table_stats, true, thd, mdl_table);
}
if (index_stats) {
dict_table_close(index_stats, true, thd, mdl_index);
}
dict_sys.unfreeze();
return DB_STATS_DO_NOT_EXIST;
}
dict_table_t* index_stats = dict_table_open_on_name(
INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE);
if (index_stats) {
dict_sys.freeze(SRW_LOCK_CALL);
index_stats = dict_acquire_mdl_shared<false>(index_stats, thd,
&mdl_index);
dict_sys.unfreeze();
}
if (!index_stats) {
goto release_and_exit;
}
if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) {
dict_table_close(index_stats, false, thd, mdl_index);
index_stats = dict_acquire_mdl_shared<false>(index_stats, thd,
&mdl_index);
if (!index_stats
|| strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) {
goto release_and_exit;
}
@ -3538,10 +3538,6 @@ release_and_exit:
DEBUG_SYNC(thd, "dict_stats_mdl_acquired");
#endif /* ENABLED_DEBUG_SYNC */
trx = trx_create();
trx_start_internal_read_only(trx);
dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8),
table_utf8, sizeof(table_utf8));
@ -3562,76 +3558,85 @@ release_and_exit:
"fetch_index_stats_step",
dict_stats_fetch_index_stats_step,
&index_fetch_arg);
dict_sys.lock(SRW_LOCK_CALL); /* FIXME: remove this */
ret = que_eval_sql(pinfo,
"PROCEDURE FETCH_STATS () IS\n"
"found INT;\n"
"DECLARE FUNCTION fetch_table_stats_step;\n"
"DECLARE FUNCTION fetch_index_stats_step;\n"
"DECLARE CURSOR table_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_table_stats_step() */
" n_rows,\n"
" clustered_index_size,\n"
" sum_of_other_index_sizes\n"
" FROM \"" TABLE_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
"DECLARE CURSOR index_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_index_stats_step() */
" index_name,\n"
" stat_name,\n"
" stat_value,\n"
" sample_size\n"
" FROM \"" INDEX_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
dict_sys.unfreeze();
dict_sys.lock(SRW_LOCK_CALL);
que_t* graph = pars_sql(
pinfo,
"PROCEDURE FETCH_STATS () IS\n"
"found INT;\n"
"DECLARE FUNCTION fetch_table_stats_step;\n"
"DECLARE FUNCTION fetch_index_stats_step;\n"
"DECLARE CURSOR table_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_table_stats_step() */
" n_rows,\n"
" clustered_index_size,\n"
" sum_of_other_index_sizes\n"
" FROM \"" TABLE_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
"DECLARE CURSOR index_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_index_stats_step() */
" index_name,\n"
" stat_name,\n"
" stat_value,\n"
" sample_size\n"
" FROM \"" INDEX_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
"BEGIN\n"
"BEGIN\n"
"OPEN table_stats_cur;\n"
"FETCH table_stats_cur INTO\n"
" fetch_table_stats_step();\n"
"IF (SQL % NOTFOUND) THEN\n"
" CLOSE table_stats_cur;\n"
" RETURN;\n"
"END IF;\n"
"CLOSE table_stats_cur;\n"
"OPEN table_stats_cur;\n"
"FETCH table_stats_cur INTO\n"
" fetch_table_stats_step();\n"
"IF (SQL % NOTFOUND) THEN\n"
" CLOSE table_stats_cur;\n"
" RETURN;\n"
"END IF;\n"
"CLOSE table_stats_cur;\n"
"OPEN index_stats_cur;\n"
"found := 1;\n"
"WHILE found = 1 LOOP\n"
" FETCH index_stats_cur INTO\n"
" fetch_index_stats_step();\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" END IF;\n"
"END LOOP;\n"
"CLOSE index_stats_cur;\n"
"OPEN index_stats_cur;\n"
"found := 1;\n"
"WHILE found = 1 LOOP\n"
" FETCH index_stats_cur INTO\n"
" fetch_index_stats_step();\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" END IF;\n"
"END LOOP;\n"
"CLOSE index_stats_cur;\n"
"END;", trx);
/* pinfo is freed by que_eval_sql() */
"END;");
dict_sys.unlock();
trx_t* trx = trx_create();
trx->graph = nullptr;
graph->trx = trx;
trx_start_internal_read_only(trx);
que_run_threads(que_fork_start_command(graph));
que_graph_free(graph);
dict_table_close(table_stats, false, thd, mdl_table);
dict_table_close(index_stats, false, thd, mdl_index);
trx_commit_for_mysql(trx);
dberr_t ret = trx->error_state;
trx->free();
if (!index_fetch_arg.stats_were_modified) {
return(DB_STATS_DO_NOT_EXIST);
return DB_STATS_DO_NOT_EXIST;
}
return(ret);
return ret;
}
/*********************************************************************//**

View File

@ -231,7 +231,7 @@ fts_config_set_value(
n_rows_updated = trx->undo_no - undo_no;
/* Check if we need to do an insert. */
if (n_rows_updated == 0) {
if (error == DB_SUCCESS && n_rows_updated == 0) {
info = pars_info_create();
pars_info_bind_varchar_literal(

View File

@ -37,6 +37,7 @@ Full Text Search interface
#include "fts0plugin.h"
#include "dict0stats.h"
#include "btr0pcur.h"
#include "log.h"
static const ulint FTS_MAX_ID_LEN = 32;
@ -1870,8 +1871,10 @@ fts_create_one_common_table(
}
}
ib::warn() << "Failed to create FTS common table " << fts_table_name;
trx->error_state = error;
ut_ad(trx->state == TRX_STATE_NOT_STARTED
|| trx->error_state == error);
sql_print_warning("InnoDB: Failed to create FTS common table %s: %s",
fts_table_name, ut_strerr(error));
return NULL;
}
@ -2055,8 +2058,10 @@ fts_create_one_index_table(
}
}
ib::warn() << "Failed to create FTS index table " << table_name;
trx->error_state = error;
ut_ad(trx->state == TRX_STATE_NOT_STARTED
|| trx->error_state == error);
sql_print_warning("InnoDB: Failed to create FTS index table %s: %s",
table_name, ut_strerr(error));
return NULL;
}

View File

@ -328,22 +328,6 @@ row_get_clust_rec(
mtr_t* mtr) /*!< in: mtr */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Parse the integer data from specified data, which could be
DATA_INT, DATA_FLOAT or DATA_DOUBLE. If the value is less than 0
and the type is not unsigned then we reset the value to 0
@param[in] data data to read
@param[in] len length of data
@param[in] mtype mtype of data
@param[in] unsigned_type if the data is unsigned
@return the integer value from the data */
inline
ib_uint64_t
row_parse_int(
const byte* data,
ulint len,
ulint mtype,
bool unsigned_type);
/** Result of row_search_index_entry */
enum row_search_result {
ROW_FOUND = 0, /*!< the record was found */

View File

@ -170,52 +170,3 @@ row_build_row_ref_fast(
}
}
}
/** Parse the integer data from specified data, which could be
DATA_INT, DATA_FLOAT or DATA_DOUBLE. If the value is less than 0
and the type is not unsigned then we reset the value to 0
@param[in] data data to read
@param[in] len length of data
@param[in] mtype mtype of data
@param[in] unsigned_type if the data is unsigned
@return the integer value from the data */
ib_uint64_t
row_parse_int(
const byte* data,
ulint len,
ulint mtype,
bool unsigned_type)
{
ib_uint64_t value = 0;
switch (mtype) {
case DATA_INT:
ut_a(len <= sizeof value);
value = mach_read_int_type(data, len, unsigned_type);
break;
case DATA_FLOAT:
ut_a(len == sizeof(float));
value = static_cast<ib_uint64_t>(mach_float_read(data));
break;
case DATA_DOUBLE:
ut_a(len == sizeof(double));
value = static_cast<ib_uint64_t>(mach_double_read(data));
break;
default:
ut_error;
}
if (!unsigned_type && static_cast<int64_t>(value) < 0) {
value = 0;
}
return(value);
}

View File

@ -182,9 +182,8 @@ dberr_t row_check_index(row_prebuilt_t *prebuilt, ulint *n_rows)
@param[in] index index starting with an AUTO_INCREMENT column
@return the largest AUTO_INCREMENT value
@retval 0 if no records were found */
ib_uint64_t
row_search_max_autoinc(dict_index_t* index)
MY_ATTRIBUTE((nonnull, warn_unused_result));
uint64_t row_search_max_autoinc(dict_index_t *index) noexcept
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** A structure for caching column values for prefetched rows */
struct sel_buf_t{

View File

@ -783,11 +783,6 @@ pars_retrieve_table_list_defs(
{
ulint count = 0;
if (sym_node == NULL) {
return(count);
}
while (sym_node) {
pars_retrieve_table_def(sym_node);

View File

@ -2580,12 +2580,44 @@ static bool thd_sql_is_insert(const THD *thd) noexcept
}
}
#if defined __aarch64__&&defined __GNUC__&&__GNUC__==4&&!defined __clang__
/* Avoid GCC 4.8.5 internal compiler error due to srw_mutex::wr_unlock().
We would only need this for row_ins_clust_index_entry_low(),
but GCC 4.8.5 does not support pop_options. */
# pragma GCC optimize ("O0")
#endif
/** Parse the integer data from specified data, which could be
DATA_INT, DATA_FLOAT or DATA_DOUBLE. If the value is less than 0
and the type is not unsigned then we reset the value to 0
@param data data to read
@param len length of data
@param mtype main type of the column
@param prtype precise type of the column
@return the integer value from the data
@retval 0 if the value is negative or the type or length invalid */
static uint64_t row_parse_int(const byte *data, size_t len,
ulint mtype, ulint prtype) noexcept
{
switch (mtype) {
case DATA_FLOAT:
if (len != sizeof(float))
return 0;
{
float f= mach_float_read(data);
return f <= 0.0 ? 0 : uint64_t(f);
}
case DATA_DOUBLE:
if (len != sizeof(double))
return 0;
{
double d= mach_double_read(data);
return d <= 0.0 ? 0 : uint64_t(d);
}
case DATA_INT:
if (len == 0 || len > 8)
return 0;
const ibool unsigned_type{prtype & DATA_UNSIGNED};
uint64_t value= mach_read_int_type(data, len, unsigned_type);
return !unsigned_type && int64_t(value) < 0 ? 0 : value;
}
ut_ad("invalid type" == 0);
return 0;
}
/***************************************************************//**
Tries to insert an entry into a clustered index, ignoring foreign key
@ -2672,8 +2704,7 @@ row_ins_clust_index_entry_low(
dfield->data),
dfield->len,
dfield->type.mtype,
dfield->type.prtype
& DATA_UNSIGNED);
dfield->type.prtype);
if (auto_inc
&& mode != BTR_MODIFY_TREE) {
mode = btr_latch_mode(
@ -3891,3 +3922,79 @@ error_handling:
return(thr);
}
/** Read the AUTOINC column from an index record
@param index index of the record
@param rec the record
@return value read from the first column
@retval 0 if the value would be NULL or negative */
static uint64_t row_read_autoinc(const dict_index_t &index, const rec_t *rec)
noexcept
{
const dict_field_t &field= index.fields[0];
ut_ad(!DATA_BIG_COL(field.col));
ut_ad(!(rec_get_info_bits(rec, index.table->not_redundant()) &
(REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG)));
mem_heap_t *heap= nullptr;
rec_offs offsets_[REC_OFFS_HEADER_SIZE + 2];
rec_offs_init(offsets_);
rec_offs *offsets= rec_get_offsets(rec, &index, offsets_,
index.n_core_fields, 1, &heap);
ut_ad(!heap);
size_t len;
ut_d(size_t first_offset=) rec_get_nth_field_offs(offsets, 0, &len);
ut_ad(!first_offset);
return row_parse_int(rec, len, field.col->mtype, field.col->prtype);
}
/** Get the maximum and non-delete-marked record in an index.
@param index index B-tree
@param mtr mini-transaction (may be committed and restarted)
@return maximum record, page s-latched in mtr
@retval nullptr if there are no records, or if all of them are delete-marked */
static
const rec_t *row_search_get_max_rec(dict_index_t *index, mtr_t *mtr) noexcept
{
btr_pcur_t pcur;
const bool desc= index->fields[0].descending;
/* Open at the high/right end (false), and init cursor */
if (pcur.open_leaf(desc, index, BTR_SEARCH_LEAF, mtr) != DB_SUCCESS)
return nullptr;
if (desc)
{
const bool comp= index->table->not_redundant();
while (btr_pcur_move_to_next_user_rec(&pcur, mtr))
{
const rec_t *rec= btr_pcur_get_rec(&pcur);
if (!rec_is_metadata(rec, comp) && !rec_get_deleted_flag(rec, comp))
return rec;
}
return nullptr;
}
do
{
const page_t *page= btr_pcur_get_page(&pcur);
const rec_t *rec= page_find_rec_last_not_deleted(page);
if (page_rec_is_user_rec_low(rec - page))
return rec;
btr_pcur_move_before_first_on_page(&pcur);
}
while (btr_pcur_move_to_prev(&pcur, mtr));
return nullptr;
}
uint64_t row_search_max_autoinc(dict_index_t *index) noexcept
{
uint64_t value= 0;
mtr_t mtr;
mtr.start();
if (const rec_t *rec= row_search_get_max_rec(index, &mtr))
value= row_read_autoinc(*index, rec);
mtr.commit();
return value;
}

View File

@ -2159,11 +2159,9 @@ row_create_index_for_mysql(
index = node->index;
ut_ad(!index == (err != DB_SUCCESS));
que_graph_free((que_t*) que_node_get_parent(thr));
if (index && (index->type & DICT_FTS)) {
if (err == DB_SUCCESS && (index->type & DICT_FTS)) {
err = fts_create_index_tables(trx, index, table->id);
}

View File

@ -6852,123 +6852,3 @@ next_rec:
goto rec_loop;
}
/*******************************************************************//**
Read the AUTOINC column from the current row. If the value is less than
0 and the type is not unsigned then we reset the value to 0.
@return value read from the column */
static
ib_uint64_t
row_search_autoinc_read_column(
/*===========================*/
dict_index_t* index, /*!< in: index to read from */
const rec_t* rec, /*!< in: current rec */
ulint col_no, /*!< in: column number */
ulint mtype, /*!< in: column main type */
ibool unsigned_type) /*!< in: signed or unsigned flag */
{
ulint len;
const byte* data;
ib_uint64_t value;
mem_heap_t* heap = NULL;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(page_rec_is_leaf(rec));
offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields,
col_no + 1, &heap);
if (rec_offs_nth_sql_null(offsets, col_no)) {
/* There is no non-NULL value in the auto-increment column. */
value = 0;
goto func_exit;
}
data = rec_get_nth_field(rec, offsets, col_no, &len);
value = row_parse_int(data, len, mtype, unsigned_type);
func_exit:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(value);
}
/** Get the maximum and non-delete-marked record in an index.
@param[in] index index tree
@param[in,out] mtr mini-transaction (may be committed and restarted)
@return maximum record, page s-latched in mtr
@retval NULL if there are no records, or if all of them are delete-marked */
static
const rec_t*
row_search_get_max_rec(
dict_index_t* index,
mtr_t* mtr)
{
btr_pcur_t pcur;
const rec_t* rec;
const bool desc = index->fields[0].descending;
if (pcur.open_leaf(desc, index, BTR_SEARCH_LEAF, mtr) != DB_SUCCESS) {
return nullptr;
}
if (desc) {
const bool comp = index->table->not_redundant();
while (btr_pcur_move_to_next_user_rec(&pcur, mtr)) {
rec = btr_pcur_get_rec(&pcur);
if (rec_is_metadata(rec, *index)) {
continue;
}
if (!rec_get_deleted_flag(rec, comp)) {
goto found;
}
}
} else {
do {
rec = page_find_rec_last_not_deleted(
btr_pcur_get_page(&pcur));
if (page_rec_is_user_rec(rec)) {
goto found;
}
btr_pcur_move_before_first_on_page(&pcur);
} while (btr_pcur_move_to_prev(&pcur, mtr));
}
rec = nullptr;
found:
ut_ad(!rec
|| !(rec_get_info_bits(rec, dict_table_is_comp(index->table))
& (REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG)));
return(rec);
}
/** Read the max AUTOINC value from an index.
@param[in] index index starting with an AUTO_INCREMENT column
@return the largest AUTO_INCREMENT value
@retval 0 if no records were found */
ib_uint64_t
row_search_max_autoinc(dict_index_t* index)
{
const dict_field_t* dfield = dict_index_get_nth_field(index, 0);
ib_uint64_t value = 0;
mtr_t mtr;
mtr.start();
if (const rec_t* rec = row_search_get_max_rec(index, &mtr)) {
value = row_search_autoinc_read_column(
index, rec, 0,
dfield->col->mtype,
dfield->col->prtype & DATA_UNSIGNED);
}
mtr.commit();
return(value);
}