mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-17598: Store DB_TRX_ID in secondary index leaf records
Added innodb_sec_trx_id_debug variable to enable the secondary index which has DB_TRX_ID as a part of the record.
This commit is contained in:
102
mysql-test/suite/innodb/r/sec_index_trx_id_debug.result
Normal file
102
mysql-test/suite/innodb/r/sec_index_trx_id_debug.result
Normal file
@@ -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;
|
||||
204
mysql-test/suite/innodb/r/sec_index_trx_locking.result
Normal file
204
mysql-test/suite/innodb/r/sec_index_trx_locking.result
Normal file
@@ -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;
|
||||
65
mysql-test/suite/innodb/t/sec_index_trx_id_debug.test
Normal file
65
mysql-test/suite/innodb/t/sec_index_trx_id_debug.test
Normal file
@@ -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;
|
||||
170
mysql-test/suite/innodb/t/sec_index_trx_locking.test
Normal file
170
mysql-test/suite/innodb/t/sec_index_trx_locking.test
Normal file
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user