1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
--source include/have_debug.inc
# Currently valgrind has issues with DBUG_SUICIDE()
--source include/not_valgrind.inc
# DEBUG_SYNC must be compiled in.
--source include/have_debug_sync.inc
--disable_query_log
let $debug_test = 0;
let $n_conn = 10;
let $i = $n_conn;
while ($i) {
# If a row is less than half a page long, all of it is stored locally
# within the page. The minimum page size is 4kB, so we should use row
# with size < 2048 bytes.
eval CREATE TABLE t$i (a INT PRIMARY KEY, b VARCHAR(1800)) ENGINE = InnoDB;
eval INSERT INTO t$i (a, b) VALUES (0, '');
dec $i;
}
DELIMITER |;
CREATE PROCEDURE mtr_redo_generate_single(IN tab INT, IN rec_size INT)
BEGIN
DECLARE max_a INT;
SET @t = CONCAT("SELECT MAX(a)+1 FROM t", tab, " INTO @max_a");
PREPARE stmt_1 FROM @t;
EXECUTE stmt_1;
SET @t = CONCAT("INSERT INTO t", tab, " (a, b) "
"VALUES (", @max_a, ", REPEAT('x', ", rec_size, "))");
PREPARE stmt_2 FROM @t;
EXECUTE stmt_2;
DEALLOCATE PREPARE stmt_2;
DEALLOCATE PREPARE stmt_1;
END|
CREATE PROCEDURE mtr_redo_generate_multi(IN tab INT, IN rec_size INT, IN n INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= n DO
CALL mtr_redo_generate_single(tab, rec_size);
SET i = i + 1;
END WHILE;
END|
CREATE PROCEDURE mtr_noredo_generate_single()
BEGIN
DECLARE max_a INT;
SELECT MAX(a)+1 FROM tmp_t INTO @max_a;
INSERT INTO tmp_t (a, b) VALUES (@max_a, REPEAT('y', 1800));
END|
CREATE PROCEDURE mtr_noredo_generate_multi(IN n INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= n DO
CALL mtr_noredo_generate_single();
SET i = i + 1;
END WHILE;
END|
CREATE PROCEDURE mtr_noredo_update_all()
BEGIN
UPDATE tmp_t SET b = REPEAT('z', 1800);
END|
DELIMITER ;|
--echo #
--echo # BUG#27664539 INNODB: ASSERTION FAILURE: BUF0FLU.CC:457:
--echo # (BUF_POOL->FLUSH_LIST).START == __NULL
--echo #
# We need to test two main scenarios in which mini-transaction with
# MTR_LOG_NO_REDO can be involved:
# 1. Pages dirtied without redo pretend to be inserted too quickly,
# when the current lsn is far away in future in comparison to lsn
# up to which we have finished inserting dirty pages to flush lists.
# The interesting case happens when current lsn is greater than
# log.recent_closed.tail() by more than log.recent_closed.capacity().
#
# 2. Pages dirtied without redo pretend to be inserted too late,
# with lsn which is smaller than log.recent_closed.tail().
# This might happen because they are not required to advance
# the log.recent_closed.tail() because they did not generate
# any redo records. However we need to be careful not to insert
# pages dirtied without redo, with oldest_modification smaller
# than checkpoint_lsn.
#
let $freeze_background_mtr = 1;
--echo #
--echo # Scenario 1.1.1 - No-redo dirtied page inserted too quickly.
--echo # Non-empty flush list when it is inserted.
--echo # The page is no-redo dirtied first time.
--echo #
--source ../include/log_flush_order_test_begin.inc
let $noredo_remodify = 0;
--source ../include/log_flush_order_test_too_fast.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 1.1.2 - No-redo dirtied page inserted too quickly.
--echo # Non-empty flush list when it is inserted.
--echo # The page is no-redo dirtied second time.
--echo #
--source ../include/log_flush_order_test_begin.inc
let $noredo_remodify = 1;
--source ../include/log_flush_order_test_too_fast.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 1.2.1 - No-redo dirtied page inserted too quickly.
--echo # Empty flush list when it is inserted.
--echo # The page is no-redo dirtied first time.
--echo #
--source ../include/log_flush_order_test_begin.inc
let $noredo_remodify = 0;
--source ../include/log_flush_order_test_too_fast_empty.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 1.2.2 - No-redo dirtied page inserted too quickly.
--echo # Empty flush list when it is inserted.
--echo # The page is no-redo dirtied second time,
--echo # but it was flushed (empty flush list).
--echo #
--source ../include/log_flush_order_test_begin.inc
let $noredo_remodify = 1;
--source ../include/log_flush_order_test_too_fast_empty.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 2.1.1 - No-redo dirtied page inserted too late.
--echo # Non-empty flush list when it is inserted.
--echo # The page is no-redo dirtied first time.
--echo #
--source ../include/log_flush_order_test_begin.inc
let $empty_flush_list = 0;
let $noredo_remodify = 0;
--source ../include/log_flush_order_test_too_slow.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 2.1.2 - No-redo dirtied page inserted too late.
--echo # Non-empty flush list when it is inserted.
--echo # The page is no-redo dirtied second time.
--echo #
--source ../include/log_flush_order_test_begin.inc
let $empty_flush_list = 0;
let $noredo_remodify = 1;
--source ../include/log_flush_order_test_too_slow.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 2.2.1 - No-redo dirtied page inserted too late.
--echo # Empty flush list when it is inserted.
--echo # The page is no-redo dirtied first time.
--echo #
--source ../include/log_flush_order_test_begin.inc
let $empty_flush_list = 1;
let $noredo_remodify = 0;
--source ../include/log_flush_order_test_too_slow.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 2.2.2 - No-redo dirtied page inserted too late.
--echo # Empty flush list when it is inserted.
--echo # The page is no-redo dirtied second time,
--echo # but it was flushed (empty flush list).
--echo #
--source ../include/log_flush_order_test_begin.inc
let $empty_flush_list = 1;
let $noredo_remodify = 1;
--source ../include/log_flush_order_test_too_slow.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # Scenario 3 - Execute in parallel many redo and no-redo mini-transactions.
--echo # Freeze and unfreeze recent_closed every 1s.
--echo #
let $freeze_background_mtr = 0;
--source ../include/log_flush_order_test_begin.inc
--source ../include/log_flush_order_test_random.inc
--source ../include/log_flush_order_test_end.inc
--echo #
--echo # CLEANUP
--echo #
--disable_query_log
DROP PROCEDURE mtr_redo_generate_single;
DROP PROCEDURE mtr_redo_generate_multi;
DROP PROCEDURE mtr_noredo_generate_single;
DROP PROCEDURE mtr_noredo_generate_multi;
DROP PROCEDURE mtr_noredo_update_all;
let $i = $n_conn;
while ($i) {
eval DROP TABLE t$i;
dec $i;
}
--enable_query_log
|