Commit c3246e4b authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.8 into 10.9

parents 0d55914d 6ac44ac3
--source include/have_utf32.inc
--source include/have_ucs2.inc
--source include/have_sequence.inc
EXECUTE IMMEDIATE SFORMAT('
CREATE VIEW v_bmp AS
SELECT
seq AS codepoint,
LPAD(HEX(seq),4,''0'') AS codepoint_hex4,
CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c
FROM
seq_0_to_65535', @@character_set_connection, @@collation_connection);
SELECT COLLATION(c) FROM v_bmp LIMIT 1;
SELECT
codepoint_hex4,
HEX(CAST(LOWER(c) AS CHAR CHARACTER SET ucs2)),
HEX(CAST(UPPER(c) AS CHAR CHARACTER SET ucs2))
FROM v_bmp
WHERE BINARY(c)<>BINARY(LOWER(c)) OR BINARY(c)<>BINARY(UPPER(c));
DROP VIEW v_bmp;
--source include/have_utf32.inc
--source include/have_sequence.inc
EXECUTE IMMEDIATE SFORMAT('
CREATE VIEW v_supplementary AS
SELECT
seq AS codepoint,
LPAD(HEX(seq),8,''0'') AS codepoint_hex8,
CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c
FROM
seq_65536_to_1114111', @@character_set_connection, @@collation_connection);
SELECT COLLATION(c) FROM v_supplementary LIMIT 1;
SELECT
codepoint_hex8,
HEX(CAST(LOWER(c) AS CHAR CHARACTER SET utf32)),
HEX(CAST(UPPER(c) AS CHAR CHARACTER SET utf32))
FROM v_supplementary
WHERE BINARY(c)<>BINARY(LOWER(c)) OR BINARY(c)<>BINARY(UPPER(c));
DROP VIEW v_supplementary;
--source include/have_utf32.inc
--source include/have_sequence.inc
EXECUTE IMMEDIATE SFORMAT('
CREATE VIEW v_bmp AS
SELECT
seq AS codepoint,
LPAD(HEX(seq),4,''0'') AS codepoint_hex4,
CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c
FROM
seq_0_to_65535', @@character_set_connection, @@collation_connection);
SELECT COLLATION(c) FROM v_bmp LIMIT 1;
SELECT HEX(codepoint) FROM v_bmp WHERE HEX(WEIGHT_STRING(c))='FFFD';
SELECT
SUM(codepoint_hex4=HEX(WEIGHT_STRING(c))) AS count_bmp_weight_is_codepoint,
SUM(codepoint_hex4<>HEX(WEIGHT_STRING(c))) AS count_bmp_weight_is_not_codepoint
FROM v_bmp;
SELECT codepoint_hex4,HEX(WEIGHT_STRING(c))
FROM v_bmp
WHERE codepoint_hex4<>HEX(WEIGHT_STRING(c));
DROP VIEW v_bmp;
--source include/have_utf32.inc
--source include/have_sequence.inc
EXECUTE IMMEDIATE SFORMAT('
CREATE VIEW v_supplementary AS
SELECT
seq AS codepoint,
CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c
FROM
seq_65536_to_1114111', @@character_set_connection, @@collation_connection);
SELECT COLLATION(c) FROM v_supplementary LIMIT 1;
SELECT
SUM(HEX(WEIGHT_STRING(c))<>'FFFD'),
SUM(HEX(WEIGHT_STRING(c))='FFFD')
FROM v_supplementary;
DROP VIEW v_supplementary;
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET collation_connection=ucs2_general_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET @@collation_connection=ucs2_general_ci;
--source include/ctype_unicode_ws_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET @@collation_connection=ucs2_general_mysql500_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET @@collation_connection=ucs2_general_mysql500_ci;
--source include/ctype_unicode_ws_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET @@collation_connection=ucs2_turkish_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET @@collation_connection=ucs2_unicode_520_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb3 COLLATE utf8mb3_general_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb3 COLLATE utf8mb3_general_ci;
--source include/ctype_unicode_ws_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb3 COLLATE utf8mb3_general_mysql500_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb3 COLLATE utf8mb3_general_mysql500_ci;
--source include/ctype_unicode_ws_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb3 COLLATE utf8mb3_turkish_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb3 COLLATE utf8mb3_unicode_520_ci;
--source include/ctype_unicode_casefold_bmp.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
--source include/ctype_unicode_casefold_bmp.inc
--source include/ctype_unicode_casefold_supplementary.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
--source include/ctype_unicode_ws_bmp.inc
--source include/ctype_unicode_ws_supplementary.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb4 COLLATE utf8mb4_turkish_ci;
--source include/ctype_unicode_casefold_bmp.inc
--source include/ctype_unicode_casefold_supplementary.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_520_ci;
--source include/ctype_unicode_casefold_bmp.inc
--source include/ctype_unicode_casefold_supplementary.inc
--echo #
--echo # End of 10.7 tests
--echo #
This diff is collapsed.
--echo #
--echo # Start of 10.7 tests
--echo #
--echo #
--echo # MDEV-30716 Wrong casefolding in xxx_unicode_520_ci for U+0700..U+07FF
--echo #
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
--source include/ctype_unicode_casefold_bmp.inc
--source include/ctype_unicode_casefold_supplementary.inc
--echo #
--echo # End of 10.7 tests
--echo #
SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET @save_dbug=@@GLOBAL.debug_dbug;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t1(f1 INT NOT NULL, f2 int not null, CREATE TABLE t1(f1 INT NOT NULL, f2 int not null,
f3 int generated always as (f2 * 2) VIRTUAL, f3 int generated always as (f2 * 2) VIRTUAL,
primary key(f1), INDEX (f3))ENGINE=InnoDB; primary key(f1), INDEX (f3))ENGINE=InnoDB;
connect con1,localhost,root,,,; connect con1,localhost,root,,,;
InnoDB 0 transactions not purged
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default; connection default;
INSERT INTO t1(f1, f2) VALUES(1,2); INSERT INTO t1(f1, f2) VALUES(1,2);
...@@ -18,5 +22,6 @@ commit; ...@@ -18,5 +22,6 @@ commit;
disconnect con1; disconnect con1;
disconnect con2; disconnect con2;
connection default; connection default;
set global debug_dbug=default; SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
SET GLOBAL debug_dbug=@save_dbug;
DROP TABLE t1; DROP TABLE t1;
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_debug.inc --source include/have_debug.inc
SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET @save_dbug=@@GLOBAL.debug_dbug;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t1(f1 INT NOT NULL, f2 int not null, CREATE TABLE t1(f1 INT NOT NULL, f2 int not null,
f3 int generated always as (f2 * 2) VIRTUAL, f3 int generated always as (f2 * 2) VIRTUAL,
primary key(f1), INDEX (f3))ENGINE=InnoDB; primary key(f1), INDEX (f3))ENGINE=InnoDB;
connect(con1,localhost,root,,,); connect(con1,localhost,root,,,);
--source ../innodb/include/wait_all_purged.inc
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default; connection default;
...@@ -26,5 +31,6 @@ commit; ...@@ -26,5 +31,6 @@ commit;
disconnect con1; disconnect con1;
disconnect con2; disconnect con2;
connection default; connection default;
set global debug_dbug=default; SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
SET GLOBAL debug_dbug=@save_dbug;
DROP TABLE t1; DROP TABLE t1;
SET @save_freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB; CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
InnoDB 0 transactions not purged
connect prevent_purge,localhost,root,,; connect prevent_purge,localhost,root,,;
start transaction with consistent snapshot; start transaction with consistent snapshot;
connect con_del_1,localhost,root,,; connect con_del_1,localhost,root,,;
...@@ -34,3 +37,4 @@ disconnect con_del_2; ...@@ -34,3 +37,4 @@ disconnect con_del_2;
connection default; connection default;
SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'RESET';
DROP TABLE t; DROP TABLE t;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_freq;
...@@ -7,6 +7,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; ...@@ -7,6 +7,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL) CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL)
ROW_FORMAT=REDUNDANT ENGINE=InnoDB; ROW_FORMAT=REDUNDANT ENGINE=InnoDB;
InnoDB 0 transactions not purged
connect prevent_purge,localhost,root; connect prevent_purge,localhost,root;
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default; connection default;
...@@ -19,7 +20,11 @@ UPDATE t1 SET b=4 WHERE a=3; ...@@ -19,7 +20,11 @@ UPDATE t1 SET b=4 WHERE a=3;
disconnect prevent_purge; disconnect prevent_purge;
connection default; connection default;
InnoDB 0 transactions not purged InnoDB 0 transactions not purged
connection con1;
ROLLBACK;
disconnect con1; disconnect con1;
connection default;
InnoDB 0 transactions not purged
FLUSH TABLE t1 FOR EXPORT; FLUSH TABLE t1 FOR EXPORT;
Clustered index root page contents: Clustered index root page contents:
N_RECS=3; LEVEL=0 N_RECS=3; LEVEL=0
......
...@@ -3,6 +3,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency=1; ...@@ -3,6 +3,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB; CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB;
INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023; INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023;
connect con1,localhost,root,,; connect con1,localhost,root,,;
InnoDB 0 transactions not purged
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default; connection default;
DELETE FROM t1 WHERE id=1788; DELETE FROM t1 WHERE id=1788;
......
...@@ -9,12 +9,10 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency= 1; ...@@ -9,12 +9,10 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency= 1;
CREATE PROCEDURE insert_n(start int, end int) CREATE PROCEDURE insert_n(start int, end int)
BEGIN BEGIN
DECLARE i INT DEFAULT start; DECLARE i INT DEFAULT start;
START TRANSACTION;
WHILE i <= end do WHILE i <= end do
INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i; INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i;
SET i = i + 1; SET i = i + 1;
END WHILE; END WHILE;
COMMIT;
END~~ END~~
CREATE FUNCTION num_pages_get() CREATE FUNCTION num_pages_get()
RETURNS INT RETURNS INT
...@@ -30,6 +28,7 @@ END~~ ...@@ -30,6 +28,7 @@ END~~
# #
CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c))
ENGINE=InnoDB STATS_PERSISTENT=0; ENGINE=InnoDB STATS_PERSISTENT=0;
InnoDB 0 transactions not purged
BEGIN; BEGIN;
SELECT * FROM t1; SELECT * FROM t1;
a b c a b c
...@@ -38,20 +37,24 @@ a b c ...@@ -38,20 +37,24 @@ a b c
# #
connect con2, localhost, root,,; connect con2, localhost, root,,;
connection con2; connection con2;
BEGIN;
INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = NULL; INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = NULL;
CALL insert_n(1, 50);; CALL insert_n(1, 50);;
connect con3, localhost, root,,; connect con3, localhost, root,,;
connection con3; connection con3;
BEGIN;
CALL insert_n(51, 100);; CALL insert_n(51, 100);;
connection con2; connection con2;
COMMIT;
connection con3; connection con3;
INSERT INTO t1 VALUES (1, 2, 1) ON DUPLICATE KEY UPDATE c = NULL; INSERT INTO t1 VALUES (1, 2, 1) ON DUPLICATE KEY UPDATE c = NULL;
COMMIT;
connection default; connection default;
# #
# Connect to default and record how many pages were accessed # Connect to default and record how many pages were accessed
# when selecting the record using the secondary key. # when selecting the record using the secondary key.
# #
InnoDB 4 transactions not purged InnoDB 2 transactions not purged
SET @num_pages_1 = num_pages_get(); SET @num_pages_1 = num_pages_get();
SELECT * FROM t1 force index (b); SELECT * FROM t1 force index (b);
a b c a b c
......
CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) ENGINE=InnoDB;
INSERT INTO t VALUES (10, "0123456789");
connection default;
BEGIN;
SELECT * FROM t WHERE c = 10 FOR UPDATE;
pk c
connect trx2, localhost,root,,;
BEGIN;
SET DEBUG_SYNC="lock_wait_start SIGNAL trx2_start_waiting";
SET DEBUG_SYNC="lock_wait_end SIGNAL trx2_wait_end WAIT_FOR trx2_cont_upd";
SET DEBUG_SYNC="lock_rec_store_on_page_infimum_end SIGNAL trx2_moved_locks WAIT_FOR trx2_cont";
UPDATE t SET c = NULL WHERE pk = 10;
connect trx3, localhost,root,,;
SET DEBUG_SYNC="now WAIT_FOR trx2_start_waiting";
SET innodb_lock_wait_timeout=1;
BEGIN;
SET DEBUG_SYNC="lock_wait_start SIGNAL trx3_start_waiting WAIT_FOR trx3_cont_waiting";
SET DEBUG_SYNC="lock_sys_t_cancel_enter SIGNAL trx3_cancel_enter WAIT_FOR trx3_cont_cancel_waiting";
UPDATE t SET c = "abcdefghij" WHERE pk = 10;
connection default;
SET DEBUG_SYNC="now WAIT_FOR trx3_start_waiting";
COMMIT;
SET DEBUG_SYNC="now WAIT_FOR trx2_wait_end";
SET DEBUG_SYNC="now SIGNAL trx3_cont_waiting";
SET DEBUG_SYNC="now WAIT_FOR trx3_cancel_enter";
SET DEBUG_SYNC="now SIGNAL trx2_cont_upd";
SET DEBUG_SYNC="now WAIT_FOR trx2_moved_locks";
SET DEBUG_SYNC="now SIGNAL trx3_cont_cancel_waiting";
SET DEBUG_SYNC="now SIGNAL trx2_cont";
disconnect trx2;
disconnect trx3;
connection default;
SET DEBUG_SYNC="RESET";
DROP TABLE t;
...@@ -3,8 +3,11 @@ ...@@ -3,8 +3,11 @@
source include/have_debug.inc; source include/have_debug.inc;
source include/have_debug_sync.inc; source include/have_debug_sync.inc;
SET @save_freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB; CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
--source include/wait_all_purged.inc
--connect(prevent_purge,localhost,root,,) --connect(prevent_purge,localhost,root,,)
start transaction with consistent snapshot; start transaction with consistent snapshot;
...@@ -80,4 +83,5 @@ INSERT INTO t VALUES(30, 20); ...@@ -80,4 +83,5 @@ INSERT INTO t VALUES(30, 20);
SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'RESET';
DROP TABLE t; DROP TABLE t;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_freq;
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
...@@ -14,6 +14,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; ...@@ -14,6 +14,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL) CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL)
ROW_FORMAT=REDUNDANT ENGINE=InnoDB; ROW_FORMAT=REDUNDANT ENGINE=InnoDB;
--source include/wait_all_purged.inc
--connect (prevent_purge,localhost,root) --connect (prevent_purge,localhost,root)
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
...@@ -33,7 +34,12 @@ UPDATE t1 SET b=4 WHERE a=3; ...@@ -33,7 +34,12 @@ UPDATE t1 SET b=4 WHERE a=3;
# Initiate a full purge, which should reset the DB_TRX_ID except for a=3. # Initiate a full purge, which should reset the DB_TRX_ID except for a=3.
--source include/wait_all_purged.inc --source include/wait_all_purged.inc
# Initiate a ROLLBACK of the update, which should reset the DB_TRX_ID for a=3. # Initiate a ROLLBACK of the update, which should reset the DB_TRX_ID for a=3.
--connection con1
ROLLBACK;
--disconnect con1 --disconnect con1
--connection default
# Reset the DB_TRX_ID for the hidden ADD COLUMN metadata record.
--source include/wait_all_purged.inc
FLUSH TABLE t1 FOR EXPORT; FLUSH TABLE t1 FOR EXPORT;
# The following is based on innodb.table_flags: # The following is based on innodb.table_flags:
......
...@@ -9,6 +9,7 @@ CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB; ...@@ -9,6 +9,7 @@ CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB;
INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023; INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023;
connect(con1,localhost,root,,); connect(con1,localhost,root,,);
source include/wait_all_purged.inc;
# Prevent purge. # Prevent purge.
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default; connection default;
......
...@@ -13,12 +13,10 @@ DELIMITER ~~; ...@@ -13,12 +13,10 @@ DELIMITER ~~;
CREATE PROCEDURE insert_n(start int, end int) CREATE PROCEDURE insert_n(start int, end int)
BEGIN BEGIN
DECLARE i INT DEFAULT start; DECLARE i INT DEFAULT start;
START TRANSACTION;
WHILE i <= end do WHILE i <= end do
INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i; INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i;
SET i = i + 1; SET i = i + 1;
END WHILE; END WHILE;
COMMIT;
END~~ END~~
CREATE FUNCTION num_pages_get() CREATE FUNCTION num_pages_get()
...@@ -37,6 +35,7 @@ DELIMITER ;~~ ...@@ -37,6 +35,7 @@ DELIMITER ;~~
--echo # --echo #
CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c))
ENGINE=InnoDB STATS_PERSISTENT=0; ENGINE=InnoDB STATS_PERSISTENT=0;
--source include/wait_all_purged.inc
BEGIN; BEGIN;
SELECT * FROM t1; SELECT * FROM t1;
...@@ -45,18 +44,22 @@ SELECT * FROM t1; ...@@ -45,18 +44,22 @@ SELECT * FROM t1;
--echo # --echo #
connect (con2, localhost, root,,); connect (con2, localhost, root,,);
connection con2; connection con2;
BEGIN;
INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = NULL; INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = NULL;
--send CALL insert_n(1, 50); --send CALL insert_n(1, 50);
connect (con3, localhost, root,,); connect (con3, localhost, root,,);
connection con3; connection con3;
BEGIN;
--send CALL insert_n(51, 100); --send CALL insert_n(51, 100);
connection con2; connection con2;
reap; reap;
COMMIT;
connection con3; connection con3;
reap; reap;
INSERT INTO t1 VALUES (1, 2, 1) ON DUPLICATE KEY UPDATE c = NULL; INSERT INTO t1 VALUES (1, 2, 1) ON DUPLICATE KEY UPDATE c = NULL;
COMMIT;
connection default; connection default;
...@@ -64,7 +67,7 @@ connection default; ...@@ -64,7 +67,7 @@ connection default;
--echo # Connect to default and record how many pages were accessed --echo # Connect to default and record how many pages were accessed
--echo # when selecting the record using the secondary key. --echo # when selecting the record using the secondary key.
--echo # --echo #
--let $wait_all_purged=4 --let $wait_all_purged=2
--source include/wait_all_purged.inc --source include/wait_all_purged.inc
SET @num_pages_1 = num_pages_get(); SET @num_pages_1 = num_pages_get();
SELECT * FROM t1 force index (b); SELECT * FROM t1 force index (b);
......
--source include/have_innodb.inc
--source include/count_sessions.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) ENGINE=InnoDB;
INSERT INTO t VALUES (10, "0123456789");
--connection default
BEGIN;
SELECT * FROM t WHERE c = 10 FOR UPDATE;
--connect(trx2, localhost,root,,)
BEGIN;
SET DEBUG_SYNC="lock_wait_start SIGNAL trx2_start_waiting";
SET DEBUG_SYNC="lock_wait_end SIGNAL trx2_wait_end WAIT_FOR trx2_cont_upd";
SET DEBUG_SYNC="lock_rec_store_on_page_infimum_end SIGNAL trx2_moved_locks WAIT_FOR trx2_cont";
#################
# We need to update clustered record without changing ordering fields and
# changing the size of non-ordering fields to cause locks moving from deleted
# record to infimum.
###
--send UPDATE t SET c = NULL WHERE pk = 10
--connect(trx3, localhost,root,,)
SET DEBUG_SYNC="now WAIT_FOR trx2_start_waiting";
#################
# The condition wariable waiting in lock_wait() must be finished by timeout
###
SET innodb_lock_wait_timeout=1;
BEGIN;
SET DEBUG_SYNC="lock_wait_start SIGNAL trx3_start_waiting WAIT_FOR trx3_cont_waiting";
SET DEBUG_SYNC="lock_sys_t_cancel_enter SIGNAL trx3_cancel_enter WAIT_FOR trx3_cont_cancel_waiting";
--send UPDATE t SET c = "abcdefghij" WHERE pk = 10
--connection default
SET DEBUG_SYNC="now WAIT_FOR trx3_start_waiting";
COMMIT;
SET DEBUG_SYNC="now WAIT_FOR trx2_wait_end";
SET DEBUG_SYNC="now SIGNAL trx3_cont_waiting";
SET DEBUG_SYNC="now WAIT_FOR trx3_cancel_enter";
SET DEBUG_SYNC="now SIGNAL trx2_cont_upd";
SET DEBUG_SYNC="now WAIT_FOR trx2_moved_locks";
#################
# If the bug is not fixed, there will be assertion failure here, because trx2
# moved trx3 lock from deleted record to infimum when trx3 tried to cancel the
# lock.
###
SET DEBUG_SYNC="now SIGNAL trx3_cont_cancel_waiting";
SET DEBUG_SYNC="now SIGNAL trx2_cont";
--disconnect trx2
--disconnect trx3
--connection default
SET DEBUG_SYNC="RESET";
DROP TABLE t;
--source include/wait_until_count_sessions.inc
...@@ -31,5 +31,33 @@ set DEBUG_SYNC= 'now SIGNAL fts_drop_index'; ...@@ -31,5 +31,33 @@ set DEBUG_SYNC= 'now SIGNAL fts_drop_index';
connection con1; connection con1;
drop table t1, t2; drop table t1, t2;
connection default; connection default;
set DEBUG_SYNC=RESET;
SET @@GLOBAL.debug_dbug = @saved_dbug; SET @@GLOBAL.debug_dbug = @saved_dbug;
disconnect con1;
#
# MDEV-25984 Assertion `max_doc_id > 0' failed in fts_init_doc_id()
#
call mtr.add_suppression("InnoDB: \\(Lock wait timeout\\) while getting next doc id for table `test`.`t1`");
CREATE TABLE t1(f1 CHAR(100), f2 INT, fulltext(f1))ENGINE=InnoDB;
INSERT INTO t1 VALUES("mariadb", 1), ("innodb", 1);
# restart
SET DEBUG_SYNC='innodb_rollback_after_fts_lock SIGNAL insert_dml WAIT_FOR ddl_continue';
ALTER TABLE t1 ADD UNIQUE INDEX(f2);
connect con1,localhost,root,,,;
SET DEBUG_SYNC='now WAIT_FOR insert_dml';
SET DEBUG_SYNC='fts_cmp_set_sync_doc_id_retry SIGNAL ddl_continue WAIT_FOR dml_finish';
INSERT INTO t1 VALUES("index", 2);
connection default;
ERROR 23000: Duplicate entry '1' for key 'f2'
SET DEBUG_SYNC="now SIGNAL dml_finish";
connection con1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` char(100) DEFAULT NULL,
`f2` int(11) DEFAULT NULL,
FULLTEXT KEY `f1` (`f1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
connection default;
disconnect con1;
DROP TABLE t1;
set DEBUG_SYNC=RESET;
...@@ -129,8 +129,9 @@ test ...@@ -129,8 +129,9 @@ test
select * from t1 where a like "te_t"; select * from t1 where a like "te_t";
a a
test test
select * from t1 where match a against ("te*" in boolean mode)+0; select * from t1 where match a against ("te*" in boolean mode);
a a
test
drop table t1; drop table t1;
# #
# Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY # Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY
......
...@@ -48,5 +48,33 @@ connection con1; ...@@ -48,5 +48,33 @@ connection con1;
reap; reap;
drop table t1, t2; drop table t1, t2;
connection default; connection default;
set DEBUG_SYNC=RESET;
SET @@GLOBAL.debug_dbug = @saved_dbug; SET @@GLOBAL.debug_dbug = @saved_dbug;
disconnect con1;
--echo #
--echo # MDEV-25984 Assertion `max_doc_id > 0' failed in fts_init_doc_id()
--echo #
call mtr.add_suppression("InnoDB: \\(Lock wait timeout\\) while getting next doc id for table `test`.`t1`");
CREATE TABLE t1(f1 CHAR(100), f2 INT, fulltext(f1))ENGINE=InnoDB;
INSERT INTO t1 VALUES("mariadb", 1), ("innodb", 1);
--source include/restart_mysqld.inc
SET DEBUG_SYNC='innodb_rollback_after_fts_lock SIGNAL insert_dml WAIT_FOR ddl_continue';
SEND ALTER TABLE t1 ADD UNIQUE INDEX(f2);
connect(con1,localhost,root,,,);
SET DEBUG_SYNC='now WAIT_FOR insert_dml';
SET DEBUG_SYNC='fts_cmp_set_sync_doc_id_retry SIGNAL ddl_continue WAIT_FOR dml_finish';
send INSERT INTO t1 VALUES("index", 2);
connection default;
--error ER_DUP_ENTRY
reap;
SET DEBUG_SYNC="now SIGNAL dml_finish";
connection con1;
reap;
SHOW CREATE TABLE t1;
connection default;
disconnect con1;
DROP TABLE t1;
set DEBUG_SYNC=RESET;
...@@ -152,10 +152,7 @@ insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); ...@@ -152,10 +152,7 @@ insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
select * from t1 where a like "abc%"; select * from t1 where a like "abc%";
select * from t1 where a like "test%"; select * from t1 where a like "test%";
select * from t1 where a like "te_t"; select * from t1 where a like "te_t";
# InnoDB_FTS: we don't support the postfix "+0" select * from t1 where match a against ("te*" in boolean mode);
# Work around MDEV-29871 (FIXME: remove this)
--echo select * from t1 where match a against ("te*" in boolean mode)+0;
--echo a
drop table t1; drop table t1;
......
...@@ -2575,7 +2575,6 @@ fts_cmp_set_sync_doc_id( ...@@ -2575,7 +2575,6 @@ fts_cmp_set_sync_doc_id(
que_t* graph = NULL; que_t* graph = NULL;
fts_cache_t* cache = table->fts->cache; fts_cache_t* cache = table->fts->cache;
char table_name[MAX_FULL_NAME_LEN]; char table_name[MAX_FULL_NAME_LEN];
retry:
ut_a(table->fts->doc_col != ULINT_UNDEFINED); ut_a(table->fts->doc_col != ULINT_UNDEFINED);
fts_table.suffix = "CONFIG"; fts_table.suffix = "CONFIG";
...@@ -2583,7 +2582,8 @@ fts_cmp_set_sync_doc_id( ...@@ -2583,7 +2582,8 @@ fts_cmp_set_sync_doc_id(
fts_table.type = FTS_COMMON_TABLE; fts_table.type = FTS_COMMON_TABLE;
fts_table.table = table; fts_table.table = table;
trx = trx_create(); trx= trx_create();
retry:
trx_start_internal(trx); trx_start_internal(trx);
trx->op_info = "update the next FTS document id"; trx->op_info = "update the next FTS document id";
...@@ -2663,7 +2663,8 @@ fts_cmp_set_sync_doc_id( ...@@ -2663,7 +2663,8 @@ fts_cmp_set_sync_doc_id(
"for table " << table->name; "for table " << table->name;
fts_sql_rollback(trx); fts_sql_rollback(trx);
if (error == DB_DEADLOCK) { if (error == DB_DEADLOCK || error == DB_LOCK_WAIT_TIMEOUT) {
DEBUG_SYNC_C("fts_cmp_set_sync_doc_id_retry");
std::this_thread::sleep_for(FTS_DEADLOCK_RETRY_WAIT); std::this_thread::sleep_for(FTS_DEADLOCK_RETRY_WAIT);
goto retry; goto retry;
} }
......
...@@ -9035,6 +9035,7 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, ...@@ -9035,6 +9035,7 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info,
ut_a(!lock_table_for_trx(dict_sys.sys_fields, ctx->trx, LOCK_X)); ut_a(!lock_table_for_trx(dict_sys.sys_fields, ctx->trx, LOCK_X));
} }
innodb_lock_wait_timeout= save_timeout; innodb_lock_wait_timeout= save_timeout;
DEBUG_SYNC_C("innodb_rollback_after_fts_lock");
row_mysql_lock_data_dictionary(ctx->trx); row_mysql_lock_data_dictionary(ctx->trx);
ctx->rollback_instant(); ctx->rollback_instant();
innobase_rollback_sec_index(ctx->old_table, table, innobase_rollback_sec_index(ctx->old_table, table,
......
...@@ -891,8 +891,8 @@ class lock_sys_t ...@@ -891,8 +891,8 @@ class lock_sys_t
/** Cancel a waiting lock request. /** Cancel a waiting lock request.
@tparam check_victim whether to check for DB_DEADLOCK @tparam check_victim whether to check for DB_DEADLOCK
@param lock waiting lock request
@param trx active transaction @param trx active transaction
@param lock waiting lock request
@retval DB_SUCCESS if no lock existed @retval DB_SUCCESS if no lock existed
@retval DB_DEADLOCK if trx->lock.was_chosen_as_deadlock_victim was set @retval DB_DEADLOCK if trx->lock.was_chosen_as_deadlock_victim was set
@retval DB_LOCK_WAIT if the lock was canceled */ @retval DB_LOCK_WAIT if the lock was canceled */
......
...@@ -65,53 +65,44 @@ struct alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_rseg_t ...@@ -65,53 +65,44 @@ struct alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_rseg_t
/** length of the TRX_RSEG_HISTORY list (number of transactions) */ /** length of the TRX_RSEG_HISTORY list (number of transactions) */
uint32_t history_size; uint32_t history_size;
/** Last known transaction that has not been purged yet,
or 0 if everything has been purged. */
trx_id_t needs_purge;
private: private:
/** Reference counter to track rseg allocated transactions, /** Reference counter to track is_persistent() transactions,
with SKIP and NEEDS_PURGE flags. */ with SKIP flag. */
std::atomic<uint32_t> ref; std::atomic<uint32_t> ref;
/** Whether undo tablespace truncation is pending */ /** Whether undo tablespace truncation is pending */
static constexpr uint32_t SKIP= 1; static constexpr uint32_t SKIP= 1;
/** Whether the log segment needs purge */
static constexpr uint32_t NEEDS_PURGE= 2;
/** Transaction reference count multiplier */ /** Transaction reference count multiplier */
static constexpr uint32_t REF= 4; static constexpr uint32_t REF= 2;
uint32_t ref_load() const { return ref.load(std::memory_order_relaxed); } uint32_t ref_load() const { return ref.load(std::memory_order_relaxed); }
/** Set a bit in ref */ /** Set the SKIP bit */
template<bool needs_purge> void ref_set() void ref_set_skip()
{ {
static_assert(SKIP == 1U << 0, "compatibility"); static_assert(SKIP == 1U, "compatibility");
static_assert(NEEDS_PURGE == 1U << 1, "compatibility");
#if defined __GNUC__ && (defined __i386__ || defined __x86_64__) #if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
if (needs_purge) __asm__ __volatile__("lock btsl $0, %0" : "+m" (ref));
__asm__ __volatile__("lock btsl $1, %0" : "+m" (ref));
else
__asm__ __volatile__("lock btsl $0, %0" : "+m" (ref));
#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) #elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
_interlockedbittestandset(reinterpret_cast<volatile long*>(&ref), _interlockedbittestandset(reinterpret_cast<volatile long*>(&ref), 0);
needs_purge);
#else #else
ref.fetch_or(needs_purge ? NEEDS_PURGE : SKIP, std::memory_order_relaxed); ref.fetch_or(SKIP, std::memory_order_relaxed);
#endif #endif
} }
/** Clear a bit in ref */ /** Clear a bit in ref */
template<bool needs_purge> void ref_reset() void ref_reset_skip()
{ {
static_assert(SKIP == 1U << 0, "compatibility"); static_assert(SKIP == 1U, "compatibility");
static_assert(NEEDS_PURGE == 1U << 1, "compatibility");
#if defined __GNUC__ && (defined __i386__ || defined __x86_64__) #if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
if (needs_purge) __asm__ __volatile__("lock btrl $0, %0" : "+m" (ref));
__asm__ __volatile__("lock btrl $1, %0" : "+m" (ref));
else
__asm__ __volatile__("lock btrl $0, %0" : "+m" (ref));
#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) #elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
_interlockedbittestandreset(reinterpret_cast<volatile long*>(&ref), _interlockedbittestandreset(reinterpret_cast<volatile long*>(&ref), 0);
needs_purge);
#else #else
ref.fetch_and(needs_purge ? ~NEEDS_PURGE : ~SKIP, ref.fetch_and(~SKIP, std::memory_order_relaxed);
std::memory_order_relaxed);
#endif #endif
} }
...@@ -125,26 +116,20 @@ struct alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_rseg_t ...@@ -125,26 +116,20 @@ struct alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_rseg_t
void destroy(); void destroy();
/** Note that undo tablespace truncation was started. */ /** Note that undo tablespace truncation was started. */
void set_skip_allocation() { ut_ad(is_persistent()); ref_set<false>(); } void set_skip_allocation() { ut_ad(is_persistent()); ref_set_skip(); }
/** Note that undo tablespace truncation was completed. */ /** Note that undo tablespace truncation was completed. */
void clear_skip_allocation() void clear_skip_allocation()
{ {
ut_ad(is_persistent()); ut_ad(is_persistent());
#if defined DBUG_OFF #if defined DBUG_OFF
ref_reset<false>(); ref_reset_skip();
#else #else
ut_d(auto r=) ref.fetch_and(~SKIP, std::memory_order_relaxed); ut_d(auto r=) ref.fetch_and(~SKIP, std::memory_order_relaxed);
ut_ad(r == SKIP); ut_ad(r == SKIP);
#endif #endif
} }
/** Note that the rollback segment requires purge. */
void set_needs_purge() { ref_set<true>(); }
/** Note that the rollback segment will not require purge. */
void clear_needs_purge() { ref_reset<true>(); }
/** @return whether the segment is marked for undo truncation */ /** @return whether the segment is marked for undo truncation */
bool skip_allocation() const { return ref_load() & SKIP; } bool skip_allocation() const { return ref_load() & SKIP; }
/** @return whether the segment needs purge */
bool needs_purge() const { return ref_load() & NEEDS_PURGE; }
/** Increment the reference count */ /** Increment the reference count */
void acquire() void acquire()
{ ut_d(auto r=) ref.fetch_add(REF); ut_ad(!(r & SKIP)); } { ut_d(auto r=) ref.fetch_add(REF); ut_ad(!(r & SKIP)); }
......
...@@ -246,12 +246,10 @@ trx_undo_free_at_shutdown(trx_t *trx); ...@@ -246,12 +246,10 @@ trx_undo_free_at_shutdown(trx_t *trx);
@param[in,out] rseg rollback segment @param[in,out] rseg rollback segment
@param[in] id rollback segment slot @param[in] id rollback segment slot
@param[in] page_no undo log segment page number @param[in] page_no undo log segment page number
@param[in,out] max_trx_id the largest observed transaction ID
@return the undo log @return the undo log
@retval nullptr on error */ @retval nullptr on error */
trx_undo_t * trx_undo_t *
trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no, trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no);
trx_id_t &max_trx_id);
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */
...@@ -493,6 +491,8 @@ or 0 if the transaction has not been committed */ ...@@ -493,6 +491,8 @@ or 0 if the transaction has not been committed */
/** Before MariaDB 10.3.1, when purge did not reset DB_TRX_ID of /** Before MariaDB 10.3.1, when purge did not reset DB_TRX_ID of
surviving user records, this used to be called TRX_UNDO_DEL_MARKS. surviving user records, this used to be called TRX_UNDO_DEL_MARKS.
This field is redundant; it is only being read by some debug assertions.
The value 1 indicates that purge needs to process the undo log segment. The value 1 indicates that purge needs to process the undo log segment.
The value 0 indicates that all of it has been processed, and The value 0 indicates that all of it has been processed, and
trx_purge_free_segment() has been invoked, so the log is not safe to access. trx_purge_free_segment() has been invoked, so the log is not safe to access.
......
This diff is collapsed.
This diff is collapsed.
...@@ -399,7 +399,7 @@ void trx_rseg_t::reinit(uint32_t page) ...@@ -399,7 +399,7 @@ void trx_rseg_t::reinit(uint32_t page)
} }
ut_ad(!is_referenced()); ut_ad(!is_referenced());
clear_needs_purge(); needs_purge= 0;
last_commit_and_offset= 0; last_commit_and_offset= 0;
last_page_no= FIL_NULL; last_page_no= FIL_NULL;
curr_size= 1; curr_size= 1;
...@@ -407,10 +407,9 @@ void trx_rseg_t::reinit(uint32_t page) ...@@ -407,10 +407,9 @@ void trx_rseg_t::reinit(uint32_t page)
/** Read the undo log lists. /** Read the undo log lists.
@param[in,out] rseg rollback segment @param[in,out] rseg rollback segment
@param[in,out] max_trx_id maximum observed transaction identifier
@param[in] rseg_header rollback segment header @param[in] rseg_header rollback segment header
@return error code */ @return error code */
static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id, static dberr_t trx_undo_lists_init(trx_rseg_t *rseg,
const buf_block_t *rseg_header) const buf_block_t *rseg_header)
{ {
ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN); ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
...@@ -420,8 +419,8 @@ static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id, ...@@ -420,8 +419,8 @@ static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
uint32_t page_no= trx_rsegf_get_nth_undo(rseg_header, i); uint32_t page_no= trx_rsegf_get_nth_undo(rseg_header, i);
if (page_no != FIL_NULL) if (page_no != FIL_NULL)
{ {
const trx_undo_t *undo= trx_undo_mem_create_at_db_start(rseg, i, page_no, const trx_undo_t *undo=
max_trx_id); trx_undo_mem_create_at_db_start(rseg, i, page_no);
if (!undo) if (!undo)
return DB_CORRUPTION; return DB_CORRUPTION;
rseg->curr_size+= undo->size; rseg->curr_size+= undo->size;
...@@ -434,11 +433,9 @@ static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id, ...@@ -434,11 +433,9 @@ static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
/** Restore the state of a persistent rollback segment. /** Restore the state of a persistent rollback segment.
@param[in,out] rseg persistent rollback segment @param[in,out] rseg persistent rollback segment
@param[in,out] max_trx_id maximum observed transaction identifier
@param[in,out] mtr mini-transaction @param[in,out] mtr mini-transaction
@return error code */ @return error code */
static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id, static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, mtr_t *mtr)
mtr_t *mtr)
{ {
if (!rseg->space) if (!rseg->space)
return DB_TABLESPACE_NOT_FOUND; return DB_TABLESPACE_NOT_FOUND;
...@@ -454,8 +451,8 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id, ...@@ -454,8 +451,8 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
trx_id_t id= mach_read_from_8(TRX_RSEG + TRX_RSEG_MAX_TRX_ID + trx_id_t id= mach_read_from_8(TRX_RSEG + TRX_RSEG_MAX_TRX_ID +
rseg_hdr->page.frame); rseg_hdr->page.frame);
if (id > max_trx_id) if (id > rseg->needs_purge)
max_trx_id= id; rseg->needs_purge= id;
const byte *binlog_name= const byte *binlog_name=
TRX_RSEG + TRX_RSEG_BINLOG_NAME + rseg_hdr->page.frame; TRX_RSEG + TRX_RSEG_BINLOG_NAME + rseg_hdr->page.frame;
...@@ -491,7 +488,7 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id, ...@@ -491,7 +488,7 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
rseg->curr_size = mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE + rseg->curr_size = mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE +
rseg_hdr->page.frame) + 1; rseg_hdr->page.frame) + 1;
err= trx_undo_lists_init(rseg, max_trx_id, rseg_hdr); err= trx_undo_lists_init(rseg, rseg_hdr);
if (err != DB_SUCCESS); if (err != DB_SUCCESS);
else if (auto len= flst_get_len(TRX_RSEG + TRX_RSEG_HISTORY + else if (auto len= flst_get_len(TRX_RSEG + TRX_RSEG_HISTORY +
rseg_hdr->page.frame)) rseg_hdr->page.frame))
...@@ -512,19 +509,16 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id, ...@@ -512,19 +509,16 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
trx_id_t id= mach_read_from_8(block->page.frame + node_addr.boffset + trx_id_t id= mach_read_from_8(block->page.frame + node_addr.boffset +
TRX_UNDO_TRX_ID); TRX_UNDO_TRX_ID);
if (id > max_trx_id) if (id > rseg->needs_purge)
max_trx_id= id; rseg->needs_purge= id;
id= mach_read_from_8(block->page.frame + node_addr.boffset + id= mach_read_from_8(block->page.frame + node_addr.boffset +
TRX_UNDO_TRX_NO); TRX_UNDO_TRX_NO);
if (id > max_trx_id) if (id > rseg->needs_purge)
max_trx_id= id; rseg->needs_purge= id;
rseg->set_last_commit(node_addr.boffset, id); rseg->set_last_commit(node_addr.boffset, id);
unsigned purge= mach_read_from_2(block->page.frame + node_addr.boffset + ut_ad(mach_read_from_2(block->page.frame + node_addr.boffset +
TRX_UNDO_NEEDS_PURGE); TRX_UNDO_NEEDS_PURGE) <= 1);
ut_ad(purge <= 1);
if (purge != 0)
rseg->set_needs_purge();
if (rseg->last_page_no != FIL_NULL) if (rseg->last_page_no != FIL_NULL)
/* There is no need to cover this operation by the purge /* There is no need to cover this operation by the purge
...@@ -597,9 +591,11 @@ dberr_t trx_rseg_array_init() ...@@ -597,9 +591,11 @@ dberr_t trx_rseg_array_init()
sys, rseg_id)), sys, rseg_id)),
page_no); page_no);
ut_ad(rseg.is_persistent()); ut_ad(rseg.is_persistent());
if ((err = trx_rseg_mem_restore( err = trx_rseg_mem_restore(&rseg, &mtr);
&rseg, max_trx_id, &mtr)) if (rseg.needs_purge > max_trx_id) {
!= DB_SUCCESS) { max_trx_id = rseg.needs_purge;
}
if (err != DB_SUCCESS) {
mtr.commit(); mtr.commit();
break; break;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -4595,7 +4595,7 @@ static MY_UNICASE_CHARACTER u520p104[]={ ...@@ -4595,7 +4595,7 @@ static MY_UNICASE_CHARACTER u520p104[]={
MY_UNICASE_CHARACTER *my_unicase_pages_unicode520[4352]= MY_UNICASE_CHARACTER *my_unicase_pages_unicode520[4352]=
{ {
u520p00, u520p01, u520p02, u520p03, u520p04, u520p05, plane06, plane06, u520p00, u520p01, u520p02, u520p03, u520p04, u520p05, plane06, plane07,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
u520p10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, u520p10, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, u520p1D, u520p1E, u520p1F, NULL, NULL, NULL, NULL, NULL, u520p1D, u520p1E, u520p1F,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment