From f4b379d6cac898888950194e8422e13ecdced67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Aug 2017 17:18:55 +0300 Subject: [PATCH] MDEV-13536 DB_TRX_ID is not actually being reset when the history is removed This should have been part of MDEV-12288. trx_undo_t::del_marks: Remove. Purge needs to process all undo log records in order to reset the DB_TRX_ID. Before MDEV-12288, it sufficed to only delete the purgeable delete-marked records, and it ignore other undo log. trx_rseg_t::needs_purge: Renamed from trx_rseg_t::last_del_marks. Indicates whether a rollback segment needs to be processed by purge. TRX_UNDO_NEEDS_PURGE: Renamed from TRX_UNDO_DEL_MARKS. Indicates whether a rollback segment needs to be processed by purge. This will be 1 until trx_purge_free_segment() has been invoked. row_purge_record_func(): Set the is_insert flag for TRX_UNDO_INSERT_REC, so that the DB_ROLL_PTR will match in row_purge_reset_trx_id(). trx_purge_fetch_next_rec(): Add a comment about row_purge_record_func() going to set the is_insert flag. trx_purge_read_undo_rec(): Always attempt to read the undo log record. trx_purge_get_next_rec(): Do not skip any undo log records. Even when no clustered index record is going to be removed, we may want to reset some DB_TRX_ID,DB_ROLL_PTR. trx_undo_rec_get_cmpl_info(), trx_undo_rec_get_extern_storage(): Remove. trx_purge_add_undo_to_history(): Set the TRX_UNDO_NEEDS_PURGE flag so that the resetting will work on undo logs that were originally created before MDEV-12288 (MariaDB 10.3.1). trx_undo_roll_ptr_is_insert(), trx_purge_free_segment(): Cleanup (should be no functional change). --- mysql-test/suite/innodb/r/dml_purge.result | 26 +++ .../suite/innodb/r/table_flags,32k.rdiff | 89 +--------- .../suite/innodb/r/table_flags,4k.rdiff | 92 ---------- .../suite/innodb/r/table_flags,64k.rdiff | 89 +--------- .../suite/innodb/r/table_flags,8k.rdiff | 92 ---------- mysql-test/suite/innodb/r/table_flags.result | 40 ++--- mysql-test/suite/innodb/t/dml_purge.test | 57 +++++++ mysql-test/suite/innodb/t/table_flags.test | 3 + .../suite/innodb_zip/r/cmp_per_index.result | 2 + .../suite/innodb_zip/t/cmp_per_index.test | 4 + storage/innobase/include/trx0rec.h | 16 -- storage/innobase/include/trx0rec.ic | 29 ---- storage/innobase/include/trx0rseg.h | 4 +- storage/innobase/include/trx0undo.h | 33 ++-- storage/innobase/include/trx0undo.ic | 4 +- storage/innobase/row/row0purge.cc | 3 + storage/innobase/trx/trx0purge.cc | 157 +++++++----------- storage/innobase/trx/trx0rec.cc | 14 -- storage/innobase/trx/trx0rseg.cc | 7 +- storage/innobase/trx/trx0undo.cc | 6 +- 20 files changed, 202 insertions(+), 565 deletions(-) create mode 100644 mysql-test/suite/innodb/r/dml_purge.result delete mode 100644 mysql-test/suite/innodb/r/table_flags,4k.rdiff delete mode 100644 mysql-test/suite/innodb/r/table_flags,8k.rdiff create mode 100644 mysql-test/suite/innodb/t/dml_purge.test diff --git a/mysql-test/suite/innodb/r/dml_purge.result b/mysql-test/suite/innodb/r/dml_purge.result new file mode 100644 index 00000000000..e2376f475e0 --- /dev/null +++ b/mysql-test/suite/innodb/r/dml_purge.result @@ -0,0 +1,26 @@ +# +# MDEV-12288 Reset DB_TRX_ID when the history is removed, +# to speed up MVCC +# +CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL) +ROW_FORMAT=REDUNDANT ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,2),(3,4); +UPDATE t1 SET b=-3 WHERE a=3; +SET GLOBAL innodb_fast_shutdown=0; +Clustered index root page contents: +N_RECS=2; LEVEL=0 +header=0x010000030087 (a=0x696e66696d756d00) +header=0x0000100900a6 (a=0x80000001, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, + b=0x80000002) +header=0x000018090074 (a=0x80000003, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, + b=0x7ffffffd) +header=0x030008030000 (a=0x73757072656d756d00) +SELECT * FROM t1; +a b +1 2 +3 -3 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/table_flags,32k.rdiff b/mysql-test/suite/innodb/r/table_flags,32k.rdiff index ea2d7048bb7..ce1ff623d50 100644 --- a/mysql-test/suite/innodb/r/table_flags,32k.rdiff +++ b/mysql-test/suite/innodb/r/table_flags,32k.rdiff @@ -9,93 +9,8 @@ SET innodb_strict_mode=ON; CREATE TABLE tp(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; -@@ -13,7 +15,7 @@ - header=0x01000003016e (NAME=0x696e66696d756d00) - header=0x00002815008d (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320194, -+ DB_ROLL_PTR=0x81000001310194, - ID=0x000000000000000e, - N_COLS=0x00000002, - TYPE=0x00000001, -@@ -23,7 +25,7 @@ - SPACE=0x00000000) - header=0x0000101500d5 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0110, -+ DB_ROLL_PTR=0x800000012c0110, - ID=0x000000000000000b, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -33,7 +35,7 @@ - SPACE=0x00000000) - header=0x000018150122 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0201, -+ DB_ROLL_PTR=0x800000012c0201, - ID=0x000000000000000c, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -43,7 +45,7 @@ - SPACE=0x00000000) - header=0x0400201501b8 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320110, -+ DB_ROLL_PTR=0x81000001310110, - ID=0x000000000000000d, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -53,7 +55,7 @@ - SPACE=0x00000000) - header=0x000030150244 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000304, -- DB_ROLL_PTR=0x82000001350110, -+ DB_ROLL_PTR=0x82000001340110, - ID=0x000000000000000f, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -63,7 +65,7 @@ - SPACE=0x00000000) - header=0x000040150288 (NAME='test/tc', - DB_TRX_ID=0x000000000308, -- DB_ROLL_PTR=0x84000001380110, -+ DB_ROLL_PTR=0x84000001370110, - ID=0x0000000000000011, - N_COLS=0x80000001, - TYPE=0x00000001, -@@ -73,7 +75,7 @@ - SPACE=0x00000002) - header=0x000048150310 (NAME='test/td', - DB_TRX_ID=0x00000000030a, -- DB_ROLL_PTR=0x85000001390110, -+ DB_ROLL_PTR=0x85000001380110, - ID=0x0000000000000012, - N_COLS=0x80000001, - TYPE=0x00000021, -@@ -83,7 +85,7 @@ - SPACE=0x00000003) - header=0x000058150200 (NAME='test/tp', - DB_TRX_ID=0x00000000030e, -- DB_ROLL_PTR=0x870000013b0110, -+ DB_ROLL_PTR=0x870000013a0110, - ID=0x0000000000000014, - N_COLS=0x80000001, - TYPE=0x000009a1, -@@ -93,7 +95,7 @@ - SPACE=0x00000005) - header=0x0000381502cc (NAME='test/tr', - DB_TRX_ID=0x000000000306, -- DB_ROLL_PTR=0x83000001370110, -+ DB_ROLL_PTR=0x83000001360110, - ID=0x0000000000000010, - N_COLS=0x00000001, - TYPE=0x00000001, -@@ -103,10 +105,10 @@ - SPACE=0x00000001) - header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x00000000030c, -- DB_ROLL_PTR=0x860000013a0110, -+ DB_ROLL_PTR=0x86000001390110, +@@ -103,7 +105,7 @@ + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000013, N_COLS=0x80000001, - TYPE=0x00000023, diff --git a/mysql-test/suite/innodb/r/table_flags,4k.rdiff b/mysql-test/suite/innodb/r/table_flags,4k.rdiff deleted file mode 100644 index 0e469ee631b..00000000000 --- a/mysql-test/suite/innodb/r/table_flags,4k.rdiff +++ /dev/null @@ -1,92 +0,0 @@ ---- suite/innodb/r/table_flags.result -+++ suite/innodb/r/table_flags,4k.reject -@@ -13,7 +13,7 @@ - header=0x01000003016e (NAME=0x696e66696d756d00) - header=0x00002815008d (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320194, -+ DB_ROLL_PTR=0x81000003260194, - ID=0x000000000000000e, - N_COLS=0x00000002, - TYPE=0x00000001, -@@ -23,7 +23,7 @@ - SPACE=0x00000000) - header=0x0000101500d5 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0110, -+ DB_ROLL_PTR=0x80000003200110, - ID=0x000000000000000b, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -33,7 +33,7 @@ - SPACE=0x00000000) - header=0x000018150122 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0201, -+ DB_ROLL_PTR=0x80000003200201, - ID=0x000000000000000c, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -43,7 +43,7 @@ - SPACE=0x00000000) - header=0x0400201501b8 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320110, -+ DB_ROLL_PTR=0x81000003260110, - ID=0x000000000000000d, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -53,7 +53,7 @@ - SPACE=0x00000000) - header=0x000030150244 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000304, -- DB_ROLL_PTR=0x82000001350110, -+ DB_ROLL_PTR=0x820000032a0110, - ID=0x000000000000000f, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -63,7 +63,7 @@ - SPACE=0x00000000) - header=0x000040150288 (NAME='test/tc', - DB_TRX_ID=0x000000000308, -- DB_ROLL_PTR=0x84000001380110, -+ DB_ROLL_PTR=0x840000032d0110, - ID=0x0000000000000011, - N_COLS=0x80000001, - TYPE=0x00000001, -@@ -73,7 +73,7 @@ - SPACE=0x00000002) - header=0x000048150310 (NAME='test/td', - DB_TRX_ID=0x00000000030a, -- DB_ROLL_PTR=0x85000001390110, -+ DB_ROLL_PTR=0x850000032f0110, - ID=0x0000000000000012, - N_COLS=0x80000001, - TYPE=0x00000021, -@@ -83,7 +83,7 @@ - SPACE=0x00000003) - header=0x000058150200 (NAME='test/tp', - DB_TRX_ID=0x00000000030e, -- DB_ROLL_PTR=0x870000013b0110, -+ DB_ROLL_PTR=0x87000003310110, - ID=0x0000000000000014, - N_COLS=0x80000001, - TYPE=0x000009a1, -@@ -93,7 +93,7 @@ - SPACE=0x00000005) - header=0x0000381502cc (NAME='test/tr', - DB_TRX_ID=0x000000000306, -- DB_ROLL_PTR=0x83000001370110, -+ DB_ROLL_PTR=0x830000032c0110, - ID=0x0000000000000010, - N_COLS=0x00000001, - TYPE=0x00000001, -@@ -103,7 +103,7 @@ - SPACE=0x00000001) - header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x00000000030c, -- DB_ROLL_PTR=0x860000013a0110, -+ DB_ROLL_PTR=0x86000003300110, - ID=0x0000000000000013, - N_COLS=0x80000001, - TYPE=0x00000023, diff --git a/mysql-test/suite/innodb/r/table_flags,64k.rdiff b/mysql-test/suite/innodb/r/table_flags,64k.rdiff index ce2d7faa925..f2ba1280be3 100644 --- a/mysql-test/suite/innodb/r/table_flags,64k.rdiff +++ b/mysql-test/suite/innodb/r/table_flags,64k.rdiff @@ -9,93 +9,8 @@ SET innodb_strict_mode=ON; CREATE TABLE tp(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; -@@ -13,7 +15,7 @@ - header=0x01000003016e (NAME=0x696e66696d756d00) - header=0x00002815008d (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320194, -+ DB_ROLL_PTR=0x81000001310194, - ID=0x000000000000000e, - N_COLS=0x00000002, - TYPE=0x00000001, -@@ -23,7 +25,7 @@ - SPACE=0x00000000) - header=0x0000101500d5 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0110, -+ DB_ROLL_PTR=0x800000012c0110, - ID=0x000000000000000b, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -33,7 +35,7 @@ - SPACE=0x00000000) - header=0x000018150122 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0201, -+ DB_ROLL_PTR=0x800000012c0201, - ID=0x000000000000000c, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -43,7 +45,7 @@ - SPACE=0x00000000) - header=0x0400201501b8 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320110, -+ DB_ROLL_PTR=0x81000001310110, - ID=0x000000000000000d, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -53,7 +55,7 @@ - SPACE=0x00000000) - header=0x000030150244 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000304, -- DB_ROLL_PTR=0x82000001350110, -+ DB_ROLL_PTR=0x82000001340110, - ID=0x000000000000000f, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -63,7 +65,7 @@ - SPACE=0x00000000) - header=0x000040150288 (NAME='test/tc', - DB_TRX_ID=0x000000000308, -- DB_ROLL_PTR=0x84000001380110, -+ DB_ROLL_PTR=0x84000001370110, - ID=0x0000000000000011, - N_COLS=0x80000001, - TYPE=0x00000001, -@@ -73,7 +75,7 @@ - SPACE=0x00000002) - header=0x000048150310 (NAME='test/td', - DB_TRX_ID=0x00000000030a, -- DB_ROLL_PTR=0x85000001390110, -+ DB_ROLL_PTR=0x85000001380110, - ID=0x0000000000000012, - N_COLS=0x80000001, - TYPE=0x00000021, -@@ -83,7 +85,7 @@ - SPACE=0x00000003) - header=0x000058150200 (NAME='test/tp', - DB_TRX_ID=0x00000000030e, -- DB_ROLL_PTR=0x870000013b0110, -+ DB_ROLL_PTR=0x870000013a0110, - ID=0x0000000000000014, - N_COLS=0x80000001, - TYPE=0x000009a1, -@@ -93,7 +95,7 @@ - SPACE=0x00000005) - header=0x0000381502cc (NAME='test/tr', - DB_TRX_ID=0x000000000306, -- DB_ROLL_PTR=0x83000001370110, -+ DB_ROLL_PTR=0x83000001360110, - ID=0x0000000000000010, - N_COLS=0x00000001, - TYPE=0x00000001, -@@ -103,10 +105,10 @@ - SPACE=0x00000001) - header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x00000000030c, -- DB_ROLL_PTR=0x860000013a0110, -+ DB_ROLL_PTR=0x86000001390110, +@@ -103,7 +105,7 @@ + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000013, N_COLS=0x80000001, - TYPE=0x00000023, diff --git a/mysql-test/suite/innodb/r/table_flags,8k.rdiff b/mysql-test/suite/innodb/r/table_flags,8k.rdiff deleted file mode 100644 index d5b5731b305..00000000000 --- a/mysql-test/suite/innodb/r/table_flags,8k.rdiff +++ /dev/null @@ -1,92 +0,0 @@ ---- suite/innodb/r/table_flags.result -+++ suite/innodb/r/table_flags,8k.reject -@@ -13,7 +13,7 @@ - header=0x01000003016e (NAME=0x696e66696d756d00) - header=0x00002815008d (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320194, -+ DB_ROLL_PTR=0x81000001d70194, - ID=0x000000000000000e, - N_COLS=0x00000002, - TYPE=0x00000001, -@@ -23,7 +23,7 @@ - SPACE=0x00000000) - header=0x0000101500d5 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0110, -+ DB_ROLL_PTR=0x80000001d10110, - ID=0x000000000000000b, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -33,7 +33,7 @@ - SPACE=0x00000000) - header=0x000018150122 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000300, -- DB_ROLL_PTR=0x800000012d0201, -+ DB_ROLL_PTR=0x80000001d10201, - ID=0x000000000000000c, - N_COLS=0x00000004, - TYPE=0x00000001, -@@ -43,7 +43,7 @@ - SPACE=0x00000000) - header=0x0400201501b8 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000302, -- DB_ROLL_PTR=0x81000001320110, -+ DB_ROLL_PTR=0x81000001d70110, - ID=0x000000000000000d, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -53,7 +53,7 @@ - SPACE=0x00000000) - header=0x000030150244 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000304, -- DB_ROLL_PTR=0x82000001350110, -+ DB_ROLL_PTR=0x82000001da0110, - ID=0x000000000000000f, - N_COLS=0x00000003, - TYPE=0x00000001, -@@ -63,7 +63,7 @@ - SPACE=0x00000000) - header=0x000040150288 (NAME='test/tc', - DB_TRX_ID=0x000000000308, -- DB_ROLL_PTR=0x84000001380110, -+ DB_ROLL_PTR=0x84000001dd0110, - ID=0x0000000000000011, - N_COLS=0x80000001, - TYPE=0x00000001, -@@ -73,7 +73,7 @@ - SPACE=0x00000002) - header=0x000048150310 (NAME='test/td', - DB_TRX_ID=0x00000000030a, -- DB_ROLL_PTR=0x85000001390110, -+ DB_ROLL_PTR=0x85000001de0110, - ID=0x0000000000000012, - N_COLS=0x80000001, - TYPE=0x00000021, -@@ -83,7 +83,7 @@ - SPACE=0x00000003) - header=0x000058150200 (NAME='test/tp', - DB_TRX_ID=0x00000000030e, -- DB_ROLL_PTR=0x870000013b0110, -+ DB_ROLL_PTR=0x87000001e00110, - ID=0x0000000000000014, - N_COLS=0x80000001, - TYPE=0x000009a1, -@@ -93,7 +93,7 @@ - SPACE=0x00000005) - header=0x0000381502cc (NAME='test/tr', - DB_TRX_ID=0x000000000306, -- DB_ROLL_PTR=0x83000001370110, -+ DB_ROLL_PTR=0x83000001dc0110, - ID=0x0000000000000010, - N_COLS=0x00000001, - TYPE=0x00000001, -@@ -103,7 +103,7 @@ - SPACE=0x00000001) - header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x00000000030c, -- DB_ROLL_PTR=0x860000013a0110, -+ DB_ROLL_PTR=0x86000001df0110, - ID=0x0000000000000013, - N_COLS=0x80000001, - TYPE=0x00000023, diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result index ac7187cd610..fdb2898dc81 100644 --- a/mysql-test/suite/innodb/r/table_flags.result +++ b/mysql-test/suite/innodb/r/table_flags.result @@ -12,8 +12,8 @@ SYS_TABLES clustered index root page (8): N_RECS=10; LEVEL=0; INDEX_ID=0x0000000000000001 header=0x01000003016e (NAME=0x696e66696d756d00) header=0x00002815008d (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000302, - DB_ROLL_PTR=0x81000001320194, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000e, N_COLS=0x00000002, TYPE=0x00000001, @@ -22,8 +22,8 @@ header=0x00002815008d (NAME='SYS_DATAFILES', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) header=0x0000101500d5 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000300, - DB_ROLL_PTR=0x800000012d0110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000b, N_COLS=0x00000004, TYPE=0x00000001, @@ -32,8 +32,8 @@ header=0x0000101500d5 (NAME='SYS_FOREIGN', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) header=0x000018150122 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000300, - DB_ROLL_PTR=0x800000012d0201, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000c, N_COLS=0x00000004, TYPE=0x00000001, @@ -42,8 +42,8 @@ header=0x000018150122 (NAME='SYS_FOREIGN_COLS', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) header=0x0400201501b8 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000302, - DB_ROLL_PTR=0x81000001320110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000d, N_COLS=0x00000003, TYPE=0x00000001, @@ -52,8 +52,8 @@ header=0x0400201501b8 (NAME='SYS_TABLESPACES', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) header=0x000030150244 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000304, - DB_ROLL_PTR=0x82000001350110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000f, N_COLS=0x00000003, TYPE=0x00000001, @@ -62,8 +62,8 @@ header=0x000030150244 (NAME='SYS_VIRTUAL', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) header=0x000040150288 (NAME='test/tc', - DB_TRX_ID=0x000000000308, - DB_ROLL_PTR=0x84000001380110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000011, N_COLS=0x80000001, TYPE=0x00000001, @@ -72,8 +72,8 @@ header=0x000040150288 (NAME='test/tc', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000002) header=0x000048150310 (NAME='test/td', - DB_TRX_ID=0x00000000030a, - DB_ROLL_PTR=0x85000001390110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000012, N_COLS=0x80000001, TYPE=0x00000021, @@ -82,8 +82,8 @@ header=0x000048150310 (NAME='test/td', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000003) header=0x000058150200 (NAME='test/tp', - DB_TRX_ID=0x00000000030e, - DB_ROLL_PTR=0x870000013b0110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000014, N_COLS=0x80000001, TYPE=0x000009a1, @@ -92,8 +92,8 @@ header=0x000058150200 (NAME='test/tp', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000005) header=0x0000381502cc (NAME='test/tr', - DB_TRX_ID=0x000000000306, - DB_ROLL_PTR=0x83000001370110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000010, N_COLS=0x00000001, TYPE=0x00000001, @@ -102,8 +102,8 @@ header=0x0000381502cc (NAME='test/tr', CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000001) header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x00000000030c, - DB_ROLL_PTR=0x860000013a0110, + DB_TRX_ID=0x000000000000, + DB_ROLL_PTR=0x80000000000000, ID=0x0000000000000013, N_COLS=0x80000001, TYPE=0x00000023, diff --git a/mysql-test/suite/innodb/t/dml_purge.test b/mysql-test/suite/innodb/t/dml_purge.test new file mode 100644 index 00000000000..8e23ad90203 --- /dev/null +++ b/mysql-test/suite/innodb/t/dml_purge.test @@ -0,0 +1,57 @@ +--source include/innodb_page_size.inc +--source include/not_embedded.inc + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +--echo # +--echo # MDEV-12288 Reset DB_TRX_ID when the history is removed, +--echo # to speed up MVCC +--echo # + +CREATE TABLE t1(a INT PRIMARY KEY, b INT NOT NULL) +ROW_FORMAT=REDUNDANT ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,2),(3,4); +UPDATE t1 SET b=-3 WHERE a=3; + +# Initiate a full purge, which should reset all DB_TRX_ID. +SET GLOBAL innodb_fast_shutdown=0; +--source include/shutdown_mysqld.inc +# The following is based on innodb.table_flags: +--perl +use strict; +my $ps= $ENV{INNODB_PAGE_SIZE}; +my $file= "$ENV{MYSQLD_DATADIR}/test/t1.ibd"; +open(FILE, "<", $file) || die "Unable to open $file\n"; +my $page; +print "Clustered index root page contents:\n"; +sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file"; +die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; +print "N_RECS=", unpack("n", substr($page,38+16,2)); +print "; LEVEL=", unpack("n", substr($page,38+26,2)), "\n"; +my @fields=("a","DB_TRX_ID","DB_ROLL_PTR", "b"); +for (my $offset= 0x65; $offset; + $offset= unpack("n", substr($page,$offset-2,2))) +{ + print "header=0x", unpack("H*",substr($page,$offset-6,6)), " ("; + my $n_fields= unpack("n", substr($page,$offset-4,2)) >> 1 & 0x3ff; + my $start= 0; + my $name; + for (my $i= 0; $i < $n_fields; $i++) { + my $end= unpack("C", substr($page, $offset-7-$i, 1)); + print ",\n " if $i; + print "$fields[$i]="; + if ($end & 0x80) { + print "NULL(", ($end & 0x7f) - $start, " bytes)" + } else { + print "0x", unpack("H*", substr($page,$offset+$start,$end-$start)) + } + $start= $end & 0x7f; + } + print ")\n"; +} +close(FILE) || die "Unable to close $file\n"; +EOF +--source include/start_mysqld.inc +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test index 7f47b8254e2..c64ff5ace20 100644 --- a/mysql-test/suite/innodb/t/table_flags.test +++ b/mysql-test/suite/innodb/t/table_flags.test @@ -27,6 +27,9 @@ let bugdir= $MYSQLTEST_VARDIR/tmp/table_flags; --let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir --let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend --let $d=$d --innodb-undo-tablespaces=0 +--let $d=$d --innodb-purge-rseg-truncate-frequency=1 +--let $d=$d --skip-innodb-fast-shutdown + --let $restart_parameters=$d --innodb-stats-persistent=0 --source include/restart_mysqld.inc diff --git a/mysql-test/suite/innodb_zip/r/cmp_per_index.result b/mysql-test/suite/innodb_zip/r/cmp_per_index.result index b380071c623..5b001279b58 100644 --- a/mysql-test/suite/innodb_zip/r/cmp_per_index.result +++ b/mysql-test/suite/innodb_zip/r/cmp_per_index.result @@ -1,3 +1,5 @@ +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET GLOBAL innodb_fast_shutdown=0; SET GLOBAL innodb_cmp_per_index_enabled=ON; SELECT * FROM information_schema.innodb_cmp_per_index; CREATE TABLE t ( diff --git a/mysql-test/suite/innodb_zip/t/cmp_per_index.test b/mysql-test/suite/innodb_zip/t/cmp_per_index.test index 58b7855219b..b26d5a4f243 100644 --- a/mysql-test/suite/innodb_zip/t/cmp_per_index.test +++ b/mysql-test/suite/innodb_zip/t/cmp_per_index.test @@ -19,6 +19,10 @@ if (`SELECT @@innodb_log_compressed_pages = 0`) # include/restart_mysqld.inc does not work in embedded mode -- source include/not_embedded.inc +# ensure that all history gets purged on shutdown +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +SET GLOBAL innodb_fast_shutdown=0; + -- vertical_results SET GLOBAL innodb_cmp_per_index_enabled=ON; diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h index 3b4a195735b..cc211bd42fd 100644 --- a/storage/innobase/include/trx0rec.h +++ b/storage/innobase/include/trx0rec.h @@ -56,22 +56,6 @@ trx_undo_rec_get_type( /*==================*/ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */ /**********************************************************************//** -Reads from an undo log record the record compiler info. -@return compiler info */ -UNIV_INLINE -ulint -trx_undo_rec_get_cmpl_info( -/*=======================*/ - const trx_undo_rec_t* undo_rec); /*!< in: undo log record */ -/**********************************************************************//** -Returns TRUE if an undo log record contains an extern storage field. -@return TRUE if extern */ -UNIV_INLINE -ibool -trx_undo_rec_get_extern_storage( -/*============================*/ - const trx_undo_rec_t* undo_rec); /*!< in: undo log record */ -/**********************************************************************//** Reads the undo log record number. @return undo no */ UNIV_INLINE diff --git a/storage/innobase/include/trx0rec.ic b/storage/innobase/include/trx0rec.ic index c2c756484b2..136e0edb468 100644 --- a/storage/innobase/include/trx0rec.ic +++ b/storage/innobase/include/trx0rec.ic @@ -35,35 +35,6 @@ trx_undo_rec_get_type( return(mach_read_from_1(undo_rec + 2) & (TRX_UNDO_CMPL_INFO_MULT - 1)); } -/**********************************************************************//** -Reads from an undo log record the record compiler info. -@return compiler info */ -UNIV_INLINE -ulint -trx_undo_rec_get_cmpl_info( -/*=======================*/ - const trx_undo_rec_t* undo_rec) /*!< in: undo log record */ -{ - return(mach_read_from_1(undo_rec + 2) / TRX_UNDO_CMPL_INFO_MULT); -} - -/**********************************************************************//** -Returns TRUE if an undo log record contains an extern storage field. -@return TRUE if extern */ -UNIV_INLINE -ibool -trx_undo_rec_get_extern_storage( -/*============================*/ - const trx_undo_rec_t* undo_rec) /*!< in: undo log record */ -{ - if (mach_read_from_1(undo_rec + 2) & TRX_UNDO_UPD_EXTERN) { - - return(TRUE); - } - - return(FALSE); -} - /**********************************************************************//** Reads the undo log record number. @return undo no */ diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index f14dadd7999..3c580e72cf4 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -185,8 +185,8 @@ struct trx_rseg_t { /** Transaction number of the last not yet purged log */ trx_id_t last_trx_no; - /** TRUE if the last not yet purged log needs purging */ - ibool last_del_marks; + /** Whether the log segment needs purge */ + bool needs_purge; /** Reference counter to track rseg allocated transactions. */ ulint trx_ref_count; diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index ba4dc73f73b..e60be7b9da8 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -384,14 +384,6 @@ struct trx_undo_t { rollback segment */ ulint state; /*!< state of the corresponding undo log segment */ - ibool del_marks; /*!< relevant only in an update undo - log: this is TRUE if the transaction may - have delete marked records, because of - a delete of a row or an update of an - indexed field; purge is then - necessary; also TRUE if the transaction - has updated an externally stored - field */ trx_id_t trx_id; /*!< id of the trx assigned to the undo log */ XID xid; /*!< X/Open XA transaction @@ -500,14 +492,23 @@ log segment */ page of an update undo log segment. */ /* @{ */ /*-------------------------------------------------------------*/ -#define TRX_UNDO_TRX_ID 0 /*!< Transaction id */ -#define TRX_UNDO_TRX_NO 8 /*!< Transaction number of the - transaction; defined only if the log - is in a history list */ -#define TRX_UNDO_DEL_MARKS 16 /*!< Defined only in an update undo - log: TRUE if the transaction may have - done delete markings of records, and - thus purge is necessary */ +/** Transaction start identifier, or 0 if the undo log segment has been +completely purged and trx_purge_free_segment() has started freeing it */ +#define TRX_UNDO_TRX_ID 0 +/** Transaction end identifier (if the log is in a history list), +or 0 if the transaction has not been committed */ +#define TRX_UNDO_TRX_NO 8 +/** 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. + +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 +trx_purge_free_segment() has been invoked, so the log is not safe to access. + +Before MariaDB 10.3.1, a log segment may carry the value 0 even before +trx_purge_free_segment() was called, for those undo log records for +which purge would not result in removing delete-marked records. */ +#define TRX_UNDO_NEEDS_PURGE 16 #define TRX_UNDO_LOG_START 18 /*!< Offset of the first undo log record of this log on the header page; purge may remove undo log record from the diff --git a/storage/innobase/include/trx0undo.ic b/storage/innobase/include/trx0undo.ic index 0285c212bdd..6e76ba205ae 100644 --- a/storage/innobase/include/trx0undo.ic +++ b/storage/innobase/include/trx0undo.ic @@ -98,8 +98,8 @@ trx_undo_roll_ptr_is_insert( #if TRUE != 1 # error "TRUE != 1" #endif - ut_ad(roll_ptr < (1ULL << 56)); - return((ibool) (roll_ptr >> 55)); + ut_ad(roll_ptr < (1ULL << (ROLL_PTR_INSERT_FLAG_POS + 1))); + return((ibool) (roll_ptr >> ROLL_PTR_INSERT_FLAG_POS)); } /***********************************************************************//** diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index ac8ae0002e6..4bdb8b34a80 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1035,6 +1035,9 @@ row_purge_record_func( MONITOR_INC(MONITOR_N_DEL_ROW_PURGE); } break; + case TRX_UNDO_INSERT_REC: + node->roll_ptr |= 1ULL << ROLL_PTR_INSERT_FLAG_POS; + /* fall through */ default: if (!updated_extern) { mtr_t mtr; diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index bc7100a6d3a..1d4668e54f8 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -255,6 +255,8 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) undo, mtr); trx_ulogf_t* undo_header = undo_page + undo->hdr_offset; + ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1); + if (undo->state != TRX_UNDO_CACHED) { ulint hist_size; #ifdef UNIV_DEBUG @@ -311,13 +313,12 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) my_atomic_addlint(&trx_sys->rseg_history_len, 1); - /* Write the trx number to the undo log header */ mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); - - /* Write information about delete markings to the undo log header */ - - if (!undo->del_marks) { - mlog_write_ulint(undo_header + TRX_UNDO_DEL_MARKS, FALSE, + /* This is needed for upgrading old undo log pages from + before MariaDB 10.3.1. */ + if (UNIV_UNLIKELY(!mach_read_from_2(undo_header + + TRX_UNDO_NEEDS_PURGE))) { + mlog_write_ulint(undo_header + TRX_UNDO_NEEDS_PURGE, 1, MLOG_2BYTES, mtr); } @@ -325,7 +326,7 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) rseg->last_page_no = undo->hdr_page_no; rseg->last_offset = undo->hdr_offset; rseg->last_trx_no = trx->no; - rseg->last_del_marks = undo->del_marks; + rseg->needs_purge = true; } if (undo->state == TRX_UNDO_CACHED) { @@ -364,16 +365,30 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr) { mtr_t mtr; trx_rsegf_t* rseg_hdr; - trx_ulogf_t* log_hdr; - trx_usegf_t* seg_hdr; - ulint seg_size; - ulint hist_size; - bool marked = false; + page_t* undo_page; - for (;;) { - page_t* undo_page; + mtr.start(); + mutex_enter(&rseg->mutex); - mtr_start(&mtr); + rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr); + undo_page = trx_undo_page_get( + page_id_t(rseg->space, hdr_addr.page), &mtr); + + /* Mark the last undo log totally purged, so that if the + system crashes, the tail of the undo log will not get accessed + again. The list of pages in the undo log tail gets + inconsistent during the freeing of the segment, and therefore + purge should not try to access them again. */ + mlog_write_ulint(undo_page + hdr_addr.boffset + TRX_UNDO_NEEDS_PURGE, + 0, MLOG_2BYTES, &mtr); + + while (!fseg_free_step_not_header( + TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER + + undo_page, false, &mtr)) { + mutex_exit(&rseg->mutex); + + mtr.commit(); + mtr.start(); mutex_enter(&rseg->mutex); @@ -381,46 +396,21 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr) undo_page = trx_undo_page_get( page_id_t(rseg->space, hdr_addr.page), &mtr); - - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - log_hdr = undo_page + hdr_addr.boffset; - - /* Mark the last undo log totally purged, so that if the - system crashes, the tail of the undo log will not get accessed - again. The list of pages in the undo log tail gets inconsistent - during the freeing of the segment, and therefore purge should - not try to access them again. */ - - if (!marked) { - marked = true; - mlog_write_ulint( - log_hdr + TRX_UNDO_DEL_MARKS, FALSE, - MLOG_2BYTES, &mtr); - } - - if (fseg_free_step_not_header( - seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr)) { - - break; - } - - mutex_exit(&rseg->mutex); - - mtr_commit(&mtr); } /* The page list may now be inconsistent, but the length field stored in the list base node tells us how big it was before we started the freeing. */ - seg_size = flst_get_len(seg_hdr + TRX_UNDO_PAGE_LIST); + const ulint seg_size = flst_get_len( + TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + undo_page); /* We may free the undo log segment header page; it must be freed within the same mtr as the undo log header is removed from the history list: otherwise, in case of a database crash, the segment could become inaccessible garbage in the file space. */ - trx_purge_remove_log_hdr(rseg_hdr, log_hdr, &mtr); + trx_purge_remove_log_hdr(rseg_hdr, undo_page + hdr_addr.boffset, &mtr); do { @@ -429,10 +419,11 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr) is not flooded with bufferfixed pages: see the note in fsp0fsp.cc. */ - } while (!fseg_free_step(seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr)); + } while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER + + undo_page, false, &mtr)); - hist_size = mtr_read_ulint(rseg_hdr + TRX_RSEG_HISTORY_SIZE, - MLOG_4BYTES, &mtr); + const ulint hist_size = mach_read_from_4(rseg_hdr + + TRX_RSEG_HISTORY_SIZE); ut_ad(hist_size >= seg_size); mlog_write_ulint(rseg_hdr + TRX_RSEG_HISTORY_SIZE, @@ -1127,7 +1118,6 @@ trx_purge_rseg_get_next_history_log( trx_ulogf_t* log_hdr; fil_addr_t prev_log_addr; trx_id_t trx_no; - ibool del_marks; mtr_t mtr; mutex_enter(&(rseg->mutex)); @@ -1189,7 +1179,7 @@ trx_purge_rseg_get_next_history_log( mtr_commit(&mtr); - /* Read the trx number and del marks from the previous log header */ + /* Read the previous log header. */ mtr_start(&mtr); log_hdr = trx_undo_page_get_s_latched(page_id_t(rseg->space, @@ -1198,8 +1188,8 @@ trx_purge_rseg_get_next_history_log( + prev_log_addr.boffset; trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO); - - del_marks = mach_read_from_2(log_hdr + TRX_UNDO_DEL_MARKS); + unsigned purge = mach_read_from_2(log_hdr + TRX_UNDO_NEEDS_PURGE); + ut_ad(purge <= 1); mtr_commit(&mtr); @@ -1208,7 +1198,7 @@ trx_purge_rseg_get_next_history_log( rseg->last_page_no = prev_log_addr.page; rseg->last_offset = prev_log_addr.boffset; rseg->last_trx_no = trx_no; - rseg->last_del_marks = del_marks; + rseg->needs_purge = purge != 0; TrxUndoRsegs elem(rseg->last_trx_no); elem.push_back(rseg); @@ -1240,18 +1230,13 @@ trx_purge_read_undo_rec() purge_sys->hdr_offset = purge_sys->rseg->last_offset; page_no = purge_sys->hdr_page_no = purge_sys->rseg->last_page_no; - if (purge_sys->rseg->last_del_marks) { + if (purge_sys->rseg->needs_purge) { mtr_t mtr; - trx_undo_rec_t* undo_rec = NULL; + mtr.start(); + if (trx_undo_rec_t* undo_rec = trx_undo_get_first_rec( + purge_sys->rseg->space, purge_sys->hdr_page_no, + purge_sys->hdr_offset, RW_S_LATCH, &mtr)) { - mtr_start(&mtr); - - undo_rec = trx_undo_get_first_rec( - purge_sys->rseg->space, - purge_sys->hdr_page_no, - purge_sys->hdr_offset, RW_S_LATCH, &mtr); - - if (undo_rec != NULL) { offset = page_offset(undo_rec); undo_no = trx_undo_rec_get_undo_no(undo_rec); undo_rseg_space = purge_sys->rseg->space; @@ -1262,7 +1247,7 @@ trx_purge_read_undo_rec() undo_rseg_space = ULINT_UNDEFINED; } - mtr_commit(&mtr); + mtr.commit(); } else { offset = 0; undo_no = 0; @@ -1346,45 +1331,12 @@ trx_purge_get_next_rec( rec = undo_page + offset; - rec2 = rec; + rec2 = trx_undo_page_get_next_rec(rec, purge_sys->hdr_page_no, + purge_sys->hdr_offset); - for (;;) { - ulint type; - trx_undo_rec_t* next_rec; - ulint cmpl_info; - - /* Try first to find the next record which requires a purge - operation from the same page of the same undo log */ - - next_rec = trx_undo_page_get_next_rec( - rec2, purge_sys->hdr_page_no, purge_sys->hdr_offset); - - if (next_rec == NULL) { - rec2 = trx_undo_get_next_rec( - rec2, purge_sys->hdr_page_no, - purge_sys->hdr_offset, &mtr); - break; - } - - rec2 = next_rec; - - type = trx_undo_rec_get_type(rec2); - - if (type == TRX_UNDO_DEL_MARK_REC) { - - break; - } - - cmpl_info = trx_undo_rec_get_cmpl_info(rec2); - - if (trx_undo_rec_get_extern_storage(rec2)) { - break; - } - - if ((type == TRX_UNDO_UPD_EXIST_REC) - && !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { - break; - } + if (rec2 == NULL) { + rec2 = trx_undo_get_next_rec(rec, purge_sys->hdr_page_no, + purge_sys->hdr_offset, &mtr); } if (rec2 == NULL) { @@ -1457,7 +1409,10 @@ trx_purge_fetch_next_rec( os_thread_get_curr_id(), iter->trx_no, iter->undo_no); */ *roll_ptr = trx_undo_build_roll_ptr( - FALSE, purge_sys->rseg->id, + /* row_purge_record_func() will later set + ROLL_PTR_INSERT_FLAG for TRX_UNDO_INSERT_REC */ + false, + purge_sys->rseg->id, purge_sys->page_no, purge_sys->offset); /* The following call will advance the stored values of the diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 0a0be4e9c23..260e79d67f9 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -886,9 +886,6 @@ trx_undo_page_report_modify( ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + undo_page) <= 2); - trx_undo_t* undo = dict_table_is_temporary(table) - ? NULL : trx->rsegs.m_redo.undo; - first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE); ptr = undo_page + first_free; @@ -1112,13 +1109,6 @@ trx_undo_page_report_modify( dict_table_page_size(table), &field, &flen, SPATIAL_UNKNOWN); - /* Notify purge that it eventually has to - free the old externally stored field */ - - if (undo) { - undo->del_marks = TRUE; - } - *type_cmpl_ptr |= TRX_UNDO_UPD_EXTERN; } else { ptr += mach_write_compressed(ptr, flen); @@ -1186,10 +1176,6 @@ trx_undo_page_report_modify( double mbr[SPDIMS * 2]; mem_heap_t* row_heap = NULL; - if (undo) { - undo->del_marks = TRUE; - } - if (trx_undo_left(undo_page, ptr) < 5) { return(0); diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 5470fb4baf4..ad7bcdf2173 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -204,9 +204,10 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, mtr_t* mtr) rseg->last_trx_no = mach_read_from_8( undo_log_hdr + TRX_UNDO_TRX_NO); - - rseg->last_del_marks = mtr_read_ulint( - undo_log_hdr + TRX_UNDO_DEL_MARKS, MLOG_2BYTES, mtr); + unsigned purge = mach_read_from_2( + undo_log_hdr + TRX_UNDO_NEEDS_PURGE); + ut_ad(purge <= 1); + rseg->needs_purge = purge != 0; TrxUndoRsegs elem(rseg->last_trx_no); elem.push_back(rseg); diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 9d1fc009bc2..c4041340fce 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -548,7 +548,7 @@ trx_undo_header_create( log_hdr = undo_page + free; - mach_write_to_2(log_hdr + TRX_UNDO_DEL_MARKS, TRUE); + mach_write_to_2(log_hdr + TRX_UNDO_NEEDS_PURGE, 1); mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id); mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free); @@ -1274,7 +1274,6 @@ trx_undo_mem_create( undo->id = id; undo->state = TRX_UNDO_ACTIVE; - undo->del_marks = FALSE; undo->trx_id = trx_id; undo->xid = *xid; @@ -1313,7 +1312,6 @@ trx_undo_mem_init_for_reuse( ut_a(undo->id < TRX_RSEG_N_SLOTS); undo->state = TRX_UNDO_ACTIVE; - undo->del_marks = FALSE; undo->trx_id = trx_id; undo->xid = *xid; @@ -1795,7 +1793,7 @@ trx_undo_truncate_tablespace( rseg->last_page_no = FIL_NULL; rseg->last_offset = 0; rseg->last_trx_no = 0; - rseg->last_del_marks = FALSE; + rseg->needs_purge = false; } mtr_commit(&mtr);