diff --git a/mysql-test/suite/innodb/r/sec_index_trx_id_debug.result b/mysql-test/suite/innodb/r/sec_index_trx_id_debug.result new file mode 100644 index 00000000000..61a987508e0 --- /dev/null +++ b/mysql-test/suite/innodb/r/sec_index_trx_id_debug.result @@ -0,0 +1,102 @@ +# Old format (default) +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(20), KEY(b), UNIQUE KEY(c)) +ENGINE=InnoDB; +SELECT i.NAME, i.TYPE FROM information_schema.INNODB_SYS_INDEXES i +JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) +WHERE t.NAME='test/t1' ORDER BY i.NAME; +NAME TYPE +b 0 +c 2 +PRIMARY 3 +DROP TABLE t1; +# New format +SET GLOBAL innodb_sec_index_trx_id_debug=ON; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(20), KEY(b), UNIQUE KEY(c)) +ENGINE=InnoDB; +SELECT i.NAME, i.TYPE FROM information_schema.INNODB_SYS_INDEXES i +JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) +WHERE t.NAME='test/t1' ORDER BY i.NAME; +NAME TYPE +b 4 +c 6 +PRIMARY 3 +SET GLOBAL innodb_sec_index_trx_id_debug=OFF; +INSERT INTO t1 SELECT seq, seq%10, CONCAT('v',seq) FROM seq_1_to_2000; +SELECT COUNT(*), SUM(b) FROM t1 FORCE INDEX(b) WHERE b>=5; +COUNT(*) SUM(b) +1000 7000 +SELECT COUNT(*) FROM t1 FORCE INDEX(c); +COUNT(*) +2000 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +# UPDATE, DELETE, and rollback +BEGIN; +UPDATE t1 SET b=b+100 WHERE a<=100; +DELETE FROM t1 WHERE a BETWEEN 101 AND 200; +SELECT COUNT(*) FROM t1 FORCE INDEX(b) WHERE b>=100; +COUNT(*) +100 +ROLLBACK; +SELECT COUNT(*) FROM t1 FORCE INDEX(b) WHERE b>=100; +COUNT(*) +0 +SELECT COUNT(*) FROM t1 FORCE INDEX(b); +COUNT(*) +2000 +UPDATE t1 SET b=b+1 WHERE a<=100; +DELETE FROM t1 WHERE a BETWEEN 101 AND 200; +INSERT INTO t1 VALUES (101,1,'v101'); +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +# Consistent read of an old snapshot while another connection modifies +connect con1,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +UPDATE t1 SET b=999 WHERE a BETWEEN 1 AND 50; +DELETE FROM t1 WHERE a BETWEEN 51 AND 100; +connection con1; +SELECT COUNT(*) FROM t1 FORCE INDEX(b) WHERE b=999; +COUNT(*) +0 +SELECT COUNT(*), SUM(b) FROM t1 FORCE INDEX(b) WHERE a<=100; +COUNT(*) SUM(b) +100 550 +COMMIT; +disconnect con1; +connection default; +# Mixed formats in one table: ADD INDEX creates the old format +ALTER TABLE t1 ADD KEY(c, b); +SELECT i.NAME, i.TYPE FROM information_schema.INNODB_SYS_INDEXES i +JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) +WHERE t.NAME='test/t1' ORDER BY i.NAME; +NAME TYPE +b 4 +c 6 +c_2 0 +PRIMARY 3 +SELECT COUNT(*) FROM t1 FORCE INDEX(c_2); +COUNT(*) +1851 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +# Restart keeps both formats +# restart +SELECT i.NAME, i.TYPE FROM information_schema.INNODB_SYS_INDEXES i +JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) +WHERE t.NAME='test/t1' ORDER BY i.NAME; +NAME TYPE +b 4 +c 6 +c_2 0 +PRIMARY 3 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT COUNT(*) FROM t1 FORCE INDEX(b); +COUNT(*) +1851 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/sec_index_trx_locking.result b/mysql-test/suite/innodb/r/sec_index_trx_locking.result new file mode 100644 index 00000000000..3ef9f0a1fa4 --- /dev/null +++ b/mysql-test/suite/innodb/r/sec_index_trx_locking.result @@ -0,0 +1,204 @@ +# +# MDEV-17598: implicit locks, consistent reads and purge on a secondary +# index whose records end with DB_TRX_ID, on an "orders" table. +# +SET GLOBAL innodb_sec_index_trx_id_debug=ON; +CREATE TABLE orders ( +id INT PRIMARY KEY, +customer INT NOT NULL, +status VARCHAR(10) NOT NULL, +amount INT NOT NULL, +KEY(customer) +) ENGINE=InnoDB; +CREATE TABLE events ( +id INT PRIMARY KEY, +a INT NOT NULL, +b INT NOT NULL, +total INT AS (a+b) VIRTUAL, +KEY(total) +) ENGINE=InnoDB; +SET GLOBAL innodb_sec_index_trx_id_debug=OFF; +# Both secondary indexes have the new format (TYPE bit 4) +SELECT t.NAME, i.NAME, (i.TYPE & 4) AS new_format +FROM information_schema.INNODB_SYS_INDEXES i +JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) +WHERE t.NAME IN ('test/orders','test/events') AND i.NAME IN ('customer','total') +ORDER BY t.NAME; +NAME NAME new_format +test/events total 4 +test/orders customer 4 +INSERT INTO orders SELECT seq, seq%5, 'new', seq FROM seq_1_to_100; +connect con1,localhost,root,,; +connect con2,localhost,root,,; +# +# 1. Locks: a transaction moves order 7 from customer 2 to customer 9 +# +connection con1; +BEGIN; +UPDATE orders SET customer=9 WHERE id=7; +connection con2; +SET SESSION innodb_lock_wait_timeout=1; +# (9,7) was inserted by con1 and is locked only implicitly +SELECT id FROM orders WHERE customer=9 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# (2,7) was delete-marked by con1 +SELECT id FROM orders WHERE customer=2 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Other orders are not locked +SELECT id FROM orders WHERE customer=3 AND id<=8 FOR UPDATE; +id +3 +8 +SET SESSION innodb_lock_wait_timeout=50; +# The waiter gets the lock when the holder commits +SELECT id FROM orders WHERE customer=9 FOR UPDATE; +connection default; +connection con1; +COMMIT; +connection con2; +id +7 +# ... and when the holder rolls back +connection con1; +BEGIN; +UPDATE orders SET customer=8 WHERE id=12; +connection con2; +SELECT id FROM orders WHERE customer=8 FOR UPDATE; +connection default; +connection con1; +ROLLBACK; +connection con2; +id +SELECT COUNT(*) AS customer2_orders FROM orders FORCE INDEX(customer) +WHERE customer=2; +customer2_orders +19 +# +# 2. Consistent reads: a report runs while orders change +# +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +customer COUNT(*) +0 20 +1 20 +2 19 +3 20 +4 20 +9 1 +connection default; +# customer 4 -> 0 (10 orders), customer 1 loses 10 orders, 2 new orders +# for customer 5, and a change of a column that is not in the index +UPDATE orders SET customer=0 WHERE customer=4 AND id<=50; +DELETE FROM orders WHERE customer=1 AND id>50; +INSERT INTO orders VALUES (101,5,'new',101), (102,5,'new',102); +UPDATE orders SET status='paid' WHERE customer=3; +connection con1; +# The report still sees the old orders +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +customer COUNT(*) +0 20 +1 20 +2 19 +3 20 +4 20 +9 1 +SELECT SUM(amount) FROM orders FORCE INDEX(customer) WHERE customer=4; +SUM(amount) +1030 +SELECT COUNT(*) FROM orders FORCE INDEX(customer) +WHERE customer=3 AND status='new'; +COUNT(*) +20 +COMMIT; +# A new transaction sees the changes +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +customer COUNT(*) +0 30 +1 10 +2 19 +3 20 +4 10 +5 2 +9 1 +SELECT COUNT(*) FROM orders FORCE INDEX(customer) +WHERE customer=3 AND status='paid'; +COUNT(*) +20 +# +# 3. Purge +# +DELETE FROM orders WHERE customer IN (1,5); +InnoDB 0 transactions not purged +CHECK TABLE orders EXTENDED; +Table Op Msg_type Msg_text +test.orders check status OK +SELECT COUNT(*) FROM orders; +COUNT(*) +80 +# An old read view keeps the deleted orders of customer 4 alive +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE FROM orders WHERE customer=4; +connection con1; +SELECT COUNT(*) AS customer4_in_old_view FROM orders FORCE INDEX(customer) +WHERE customer=4; +customer4_in_old_view +10 +COMMIT; +connection default; +InnoDB 0 transactions not purged +SELECT COUNT(*) AS customer4_now FROM orders FORCE INDEX(customer) +WHERE customer=4; +customer4_now +0 +# An order that is deleted and re-created before purge must survive +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE FROM orders WHERE id=3; +INSERT INTO orders VALUES (3,3,'new',3); +connection con1; +COMMIT; +connection default; +InnoDB 0 transactions not purged +SELECT id, status FROM orders FORCE INDEX(customer) WHERE customer=3 AND id=3; +id status +3 new +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +customer COUNT(*) +0 30 +2 19 +3 20 +9 1 +CHECK TABLE orders EXTENDED; +Table Op Msg_type Msg_text +test.orders check status OK +# +# 4. Purge of an index on a virtual column +# +INSERT INTO events (id,a,b) SELECT seq, seq, 0 FROM seq_1_to_50; +UPDATE events SET b=b+100 WHERE id<=20; +DELETE FROM events WHERE id>40; +InnoDB 0 transactions not purged +CHECK TABLE events EXTENDED; +Table Op Msg_type Msg_text +test.events check status OK +# 20 events with total = id+100, 40 events in all +SELECT COUNT(*), SUM(total) FROM events FORCE INDEX(total) WHERE total>=100; +COUNT(*) SUM(total) +20 2210 +SELECT COUNT(*) FROM events FORCE INDEX(total); +COUNT(*) +40 +connection con1; +disconnect con1; +connection con2; +disconnect con2; +connection default; +DROP TABLE orders, events; diff --git a/mysql-test/suite/innodb/t/sec_index_trx_id_debug.test b/mysql-test/suite/innodb/t/sec_index_trx_id_debug.test new file mode 100644 index 00000000000..90bd929658e --- /dev/null +++ b/mysql-test/suite/innodb/t/sec_index_trx_id_debug.test @@ -0,0 +1,65 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +let $flag_query= + SELECT i.NAME, i.TYPE FROM information_schema.INNODB_SYS_INDEXES i + JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) + WHERE t.NAME='test/t1' ORDER BY i.NAME; + +--echo # Old format (default) +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(20), KEY(b), UNIQUE KEY(c)) +ENGINE=InnoDB; +eval $flag_query; +DROP TABLE t1; + +--echo # New format +SET GLOBAL innodb_sec_index_trx_id_debug=ON; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(20), KEY(b), UNIQUE KEY(c)) +ENGINE=InnoDB; +eval $flag_query; +SET GLOBAL innodb_sec_index_trx_id_debug=OFF; + +INSERT INTO t1 SELECT seq, seq%10, CONCAT('v',seq) FROM seq_1_to_2000; +SELECT COUNT(*), SUM(b) FROM t1 FORCE INDEX(b) WHERE b>=5; +SELECT COUNT(*) FROM t1 FORCE INDEX(c); +CHECK TABLE t1 EXTENDED; + +--echo # UPDATE, DELETE, and rollback +BEGIN; +UPDATE t1 SET b=b+100 WHERE a<=100; +DELETE FROM t1 WHERE a BETWEEN 101 AND 200; +SELECT COUNT(*) FROM t1 FORCE INDEX(b) WHERE b>=100; +ROLLBACK; +SELECT COUNT(*) FROM t1 FORCE INDEX(b) WHERE b>=100; +SELECT COUNT(*) FROM t1 FORCE INDEX(b); +UPDATE t1 SET b=b+1 WHERE a<=100; +DELETE FROM t1 WHERE a BETWEEN 101 AND 200; +INSERT INTO t1 VALUES (101,1,'v101'); +CHECK TABLE t1 EXTENDED; + +--echo # Consistent read of an old snapshot while another connection modifies +connect (con1,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +UPDATE t1 SET b=999 WHERE a BETWEEN 1 AND 50; +DELETE FROM t1 WHERE a BETWEEN 51 AND 100; +connection con1; +SELECT COUNT(*) FROM t1 FORCE INDEX(b) WHERE b=999; +SELECT COUNT(*), SUM(b) FROM t1 FORCE INDEX(b) WHERE a<=100; +COMMIT; +disconnect con1; +connection default; + +--echo # Mixed formats in one table: ADD INDEX creates the old format +ALTER TABLE t1 ADD KEY(c, b); +eval $flag_query; +SELECT COUNT(*) FROM t1 FORCE INDEX(c_2); +CHECK TABLE t1 EXTENDED; + +--echo # Restart keeps both formats +--source include/restart_mysqld.inc +eval $flag_query; +CHECK TABLE t1 EXTENDED; +SELECT COUNT(*) FROM t1 FORCE INDEX(b); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/sec_index_trx_locking.test b/mysql-test/suite/innodb/t/sec_index_trx_locking.test new file mode 100644 index 00000000000..04e7704e185 --- /dev/null +++ b/mysql-test/suite/innodb/t/sec_index_trx_locking.test @@ -0,0 +1,170 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-17598: implicit locks, consistent reads and purge on a secondary +--echo # index whose records end with DB_TRX_ID, on an "orders" table. +--echo # + +SET GLOBAL innodb_sec_index_trx_id_debug=ON; +CREATE TABLE orders ( + id INT PRIMARY KEY, + customer INT NOT NULL, + status VARCHAR(10) NOT NULL, + amount INT NOT NULL, + KEY(customer) +) ENGINE=InnoDB; +CREATE TABLE events ( + id INT PRIMARY KEY, + a INT NOT NULL, + b INT NOT NULL, + total INT AS (a+b) VIRTUAL, + KEY(total) +) ENGINE=InnoDB; +SET GLOBAL innodb_sec_index_trx_id_debug=OFF; + +--echo # Both secondary indexes have the new format (TYPE bit 4) +SELECT t.NAME, i.NAME, (i.TYPE & 4) AS new_format +FROM information_schema.INNODB_SYS_INDEXES i +JOIN information_schema.INNODB_SYS_TABLES t USING (TABLE_ID) +WHERE t.NAME IN ('test/orders','test/events') AND i.NAME IN ('customer','total') +ORDER BY t.NAME; + +# 100 orders, 20 for each of the customers 0..4 +INSERT INTO orders SELECT seq, seq%5, 'new', seq FROM seq_1_to_100; + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +--echo # +--echo # 1. Locks: a transaction moves order 7 from customer 2 to customer 9 +--echo # +connection con1; +BEGIN; +UPDATE orders SET customer=9 WHERE id=7; + +connection con2; +SET SESSION innodb_lock_wait_timeout=1; +--echo # (9,7) was inserted by con1 and is locked only implicitly +--error ER_LOCK_WAIT_TIMEOUT +SELECT id FROM orders WHERE customer=9 FOR UPDATE; +--echo # (2,7) was delete-marked by con1 +--error ER_LOCK_WAIT_TIMEOUT +SELECT id FROM orders WHERE customer=2 FOR UPDATE; +--echo # Other orders are not locked +SELECT id FROM orders WHERE customer=3 AND id<=8 FOR UPDATE; +SET SESSION innodb_lock_wait_timeout=50; + +--echo # The waiter gets the lock when the holder commits +--send SELECT id FROM orders WHERE customer=9 FOR UPDATE +connection default; +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.INNODB_TRX + WHERE trx_state = 'LOCK WAIT'; +--source include/wait_condition.inc +connection con1; +COMMIT; +connection con2; +reap; + +--echo # ... and when the holder rolls back +connection con1; +BEGIN; +UPDATE orders SET customer=8 WHERE id=12; +connection con2; +--send SELECT id FROM orders WHERE customer=8 FOR UPDATE +connection default; +--source include/wait_condition.inc +connection con1; +ROLLBACK; +connection con2; +reap; +SELECT COUNT(*) AS customer2_orders FROM orders FORCE INDEX(customer) +WHERE customer=2; + +--echo # +--echo # 2. Consistent reads: a report runs while orders change +--echo # +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; + +connection default; +--echo # customer 4 -> 0 (10 orders), customer 1 loses 10 orders, 2 new orders +--echo # for customer 5, and a change of a column that is not in the index +UPDATE orders SET customer=0 WHERE customer=4 AND id<=50; +DELETE FROM orders WHERE customer=1 AND id>50; +INSERT INTO orders VALUES (101,5,'new',101), (102,5,'new',102); +UPDATE orders SET status='paid' WHERE customer=3; + +connection con1; +--echo # The report still sees the old orders +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +SELECT SUM(amount) FROM orders FORCE INDEX(customer) WHERE customer=4; +SELECT COUNT(*) FROM orders FORCE INDEX(customer) +WHERE customer=3 AND status='new'; +COMMIT; + +--echo # A new transaction sees the changes +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +SELECT COUNT(*) FROM orders FORCE INDEX(customer) +WHERE customer=3 AND status='paid'; + +--echo # +--echo # 3. Purge +--echo # +DELETE FROM orders WHERE customer IN (1,5); +--source include/wait_all_purged.inc +CHECK TABLE orders EXTENDED; +SELECT COUNT(*) FROM orders; + +--echo # An old read view keeps the deleted orders of customer 4 alive +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE FROM orders WHERE customer=4; +connection con1; +SELECT COUNT(*) AS customer4_in_old_view FROM orders FORCE INDEX(customer) +WHERE customer=4; +COMMIT; +connection default; +--source include/wait_all_purged.inc +SELECT COUNT(*) AS customer4_now FROM orders FORCE INDEX(customer) +WHERE customer=4; + +--echo # An order that is deleted and re-created before purge must survive +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE FROM orders WHERE id=3; +INSERT INTO orders VALUES (3,3,'new',3); +connection con1; +COMMIT; +connection default; +--source include/wait_all_purged.inc +SELECT id, status FROM orders FORCE INDEX(customer) WHERE customer=3 AND id=3; +SELECT customer, COUNT(*) FROM orders FORCE INDEX(customer) +GROUP BY customer ORDER BY customer; +CHECK TABLE orders EXTENDED; + +--echo # +--echo # 4. Purge of an index on a virtual column +--echo # +INSERT INTO events (id,a,b) SELECT seq, seq, 0 FROM seq_1_to_50; +UPDATE events SET b=b+100 WHERE id<=20; +DELETE FROM events WHERE id>40; +--source include/wait_all_purged.inc +CHECK TABLE events EXTENDED; +--echo # 20 events with total = id+100, 40 events in all +SELECT COUNT(*), SUM(total) FROM events FORCE INDEX(total) WHERE total>=100; +SELECT COUNT(*) FROM events FORCE INDEX(total); + +connection con1; +disconnect con1; +connection con2; +disconnect con2; +connection default; +DROP TABLE orders, events; diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 77d96402081..fb2c8588e52 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -1463,6 +1463,18 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME INNODB_SEC_INDEX_TRX_ID_DEBUG +SESSION_VALUE NULL +DEFAULT_VALUE OFF +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT Testing aid: create the secondary indexes of new tables in the format where the leaf page records end with DB_TRX_ID. Not supported for ROW_FORMAT=REDUNDANT or COMPRESSED, temporary or FULLTEXT tables; ALTER TABLE ... ADD INDEX still creates the old format +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY NO +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_SNAPSHOT_ISOLATION SESSION_VALUE ON DEFAULT_VALUE ON diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 30baad5a0b7..f5dd6f5e223 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -206,6 +206,10 @@ extern uint srv_n_fil_crypt_iops; my_bool innodb_evict_tables_on_commit_debug; #endif +/** Create the secondary indexes of new tables in the +DICT_SEC_TRX_ID format. */ +static my_bool innodb_sec_index_trx_id_debug; + #if defined(UNIV_DEBUG) || \ defined(INNODB_ENABLE_XAP_UNLOCK_UNMODIFIED_FOR_PRIMARY) my_bool innodb_enable_xap_unlock_unmodified_for_primary_debug; @@ -11153,6 +11157,17 @@ create_index( ind_type |= DICT_UNIQUE; } + if (innodb_sec_index_trx_id_debug + && !(ind_type & DICT_CLUSTERED) + && table->not_redundant() + && !DICT_TF_GET_ZIP_SSIZE(table->flags) + && !table->is_temporary() + && !DICT_TF2_FLAG_IS_SET( + table, + DICT_TF2_FTS | DICT_TF2_FTS_HAS_DOC_ID)) { + ind_type |= DICT_SEC_TRX_ID; + } + field_lengths = (ulint*) my_malloc(PSI_INSTRUMENT_ME, key->user_defined_key_parts * sizeof * field_lengths, MYF(MY_FAE)); @@ -20467,6 +20482,14 @@ static MYSQL_SYSVAR_BOOL(enable_xap_unlock_unmodified_for_primary_debug, #endif /* defined(UNIV_DEBUG) || defined(INNODB_ENABLE_XAP_UNLOCK_UNMODIFIED_FOR_PRIMARY) */ +static MYSQL_SYSVAR_BOOL(sec_index_trx_id_debug, + innodb_sec_index_trx_id_debug, PLUGIN_VAR_OPCMDARG, + "Testing aid: create the secondary indexes of new tables " + " in the format where the leaf page records end with DB_TRX_ID. " + "Not supported for ROW_FORMAT=REDUNDANT or COMPRESSED, temporary or " + "FULLTEXT tables; ALTER TABLE ... ADD INDEX still creates the old format", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_BOOL(force_primary_key, srv_force_primary_key, PLUGIN_VAR_OPCMDARG, @@ -20736,6 +20759,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(enable_xap_unlock_unmodified_for_primary_debug), #endif /* defined(UNIV_DEBUG) || defined(INNODB_ENABLE_XAP_UNLOCK_UNMODIFIED_FOR_PRIMARY) */ + MYSQL_SYSVAR(sec_index_trx_id_debug), MYSQL_SYSVAR(force_primary_key), MYSQL_SYSVAR(alter_copy_bulk), MYSQL_SYSVAR(fatal_semaphore_wait_threshold),