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

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).
parent 442ac922
#
# 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;
......@@ -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,
......
--- 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,
......@@ -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,
......
--- 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,
......@@ -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,
......
--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;
......@@ -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
......
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 (
......
......@@ -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;
......
......@@ -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
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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
......
......@@ -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));
}
/***********************************************************************//**
......
......@@ -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;
......
......@@ -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,63 +365,52 @@ 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;
for (;;) {
page_t* undo_page;
mtr_start(&mtr);
mtr.start();
mutex_enter(&rseg->mutex);
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);
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);
}
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);
if (fseg_free_step_not_header(
seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr)) {
mtr.commit();
mtr.start();
break;
}
mutex_enter(&rseg->mutex);
mutex_exit(&rseg->mutex);
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
mtr_commit(&mtr);
undo_page = trx_undo_page_get(
page_id_t(rseg->space, hdr_addr.page), &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(&mtr);
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)) {
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,
if (rec2 == NULL) {
rec2 = trx_undo_get_next_rec(rec, 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) {
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
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