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 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
# Bug#36511673 MLOG_FILE_EXTEND log record is not redo logged for System
# tablespace
# Change buffer persists in the system tablespace. System tablespace size
# may expand beyond the default size when then change buffer grows. This
# test verifies that System tablespace expansion is redo logged and,
# crash recovery works.
--source include/big_test.inc
--source include/linux.inc
--source include/have_debug.inc
--source include/have_innodb_16k.inc
--source include/count_sessions.inc
let $MYSQLD_DATADIR = $MYSQL_TMP_DIR/test_data_dir;
let $MYSQLD_ERROR_LOG = $MYSQL_TMP_DIR/mysqld_test.err;
# It is pre-requisite of this test to have system tablespace of default size.
# It is possible only if test explicitly creates the new datadir for the
# stability (e.g. runing with --repeat option) reasons.
--echo # Initialize new data directory...
let $MYSQLD_EXTRA_ARGS = --innodb_page_size=16384 --datadir=$MYSQLD_DATADIR --log-error=$MYSQLD_ERROR_LOG;
--source include/initialize_datadir.inc
let restart_parameters = restart: --datadir=$MYSQLD_DATADIR --log-error=$MYSQLD_ERROR_LOG --log_error_verbosity=2;
--echo # Restart on the new data directory...
--replace_result $MYSQLD_ERROR_LOG my_restart.err $MYSQLD_DATADIR tmp/test_data_dir
--source include/restart_mysqld.inc
SET GLOBAL innodb_redo_log_capacity=52428800;
SET GLOBAL innodb_change_buffering=all;
SET GLOBAL innodb_change_buffer_max_size=50;
# The flag that instructs InnoDB to try to evict pages from the
# buffer pool when change buffering is possible, so that the change
# buffer will be used whenever possible.
SET GLOBAL innodb_change_buffering_debug = 1;
# Disable merging the changes from change buffer to the indexes
SET GLOBAL innodb_disable_background_merge=ON;
SET GLOBAL DEBUG='+d,ib_redo_log_system_tablespace_expansion';
let $inital_file_size= `SELECT
ROUND(SUM(TOTAL_EXTENTS * EXTENT_SIZE)/1024/1024) AS tablespace_size_in_MB
FROM
information_schema.FILES
WHERE
TABLESPACE_NAME = 'innodb_system'
GROUP BY
TABLESPACE_NAME, FILE_NAME`;
CREATE DATABASE db1;
--disable_query_log
--DELIMITER //
CREATE PROCEDURE db1.CreateNTables(IN dbName VARCHAR(255),
IN tableNamePrefix VARCHAR(255), IN COUNT INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE fullTableName VARCHAR(255);
WHILE i <= COUNT DO
SET fullTableName := CONCAT(dbName, '.', tableNamePrefix, i);
-- Create table
SET @sql := CONCAT(
'CREATE TABLE ', fullTableName, ' (',
'`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,',
'`k` BIGINT UNSIGNED NOT NULL DEFAULT ''0'',',
'`nk` INT NOT NULL DEFAULT ''0'',',
'`c` VARCHAR(2048),',
'`pad` VARCHAR(2048),',
'PRIMARY KEY (`id`),',
'KEY `idx_k` (`k`),',
'KEY `idx_knk` (`nk`, `k`),',
'KEY `idx_nk` (`nk`),',
'KEY `idx_c` (`c`(512)),',
'KEY `idx_pad` (`pad`(512))',
') ENGINE=InnoDB ',
'DEFAULT CHARSET=ascii COLLATE=ascii_bin;'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET i = i + 1;
END WHILE;
END //
CREATE PROCEDURE db1.InsertIntoRecords (IN schemaName VARCHAR(255),
IN tableName VARCHAR(255), IN two_to_power INT)
BEGIN
DECLARE fullTableName VARCHAR(255);
SET fullTableName := CONCAT(schemaName, '.', tableName);
SET @stm := CONCAT('INSERT INTO ', fullTableName , ' (k, nk, c, pad)',
' SELECT 2000, nk, c, pad FROM db1.t1');
PREPARE stmt FROM @stm;
SET @idx := two_to_power;
WHILE (@idx > 0) DO
EXECUTE stmt;
SET @idx := @idx - 1;
END WHILE;
DEALLOCATE PREPARE stmt;
END //
--DELIMITER ;
--enable_query_log
let $max_connections=2;
--echo # Create $max_connections tables
eval CALL db1.CreateNTables('db1', 't', $max_connections);
--echo
--echo # Create Connection objects
let $counter = 1;
while($counter <= $max_connections){
connect (con_$counter, localhost, root,,);
inc $counter;
}
--echo
--echo # Insert record in each table
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
send_eval INSERT INTO db1.t$counter
VALUES(0, 1000 , 1, REPEAT('a', 2048), REPEAT('b', 2048));
inc $counter;
}
--echo # Wait for inserts to finish
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
reap;
inc $counter;
}
--echo
--echo # Insert total 2^8 records in each table
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
send_eval CALL db1.InsertIntoRecords('db1', 't$counter', 8);
inc $counter;
}
--echo
--echo # Wait for insert into tables to finish
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
reap;
inc $counter;
}
connection default;
--echo # Disable page cleaner to have redo logs for recovery later on
--source suite/innodb/include/log_disable_page_cleaners.inc
# Update the records with id divisible by 2
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
send_eval UPDATE db1.t$counter
SET k = id + k , nk = k + id, c = REPEAT('a2', 512),
pad = REPEAT('b2', 512)
WHERE id % 2 = 0;
inc $counter;
}
--echo
--echo # Wait for Updates to finish
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
reap;
inc $counter;
}
# Update the records with id divisible by 3
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
send_eval UPDATE db1.t$counter
SET k = id + k , nk = k + id, c = REPEAT('a3', 512),
pad = REPEAT('b3', 512)
WHERE id % 3 = 0;
inc $counter;
}
--echo
--echo # Wait for Updates to finish
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
reap;
inc $counter;
}
# Update the records with id divisible by 5
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
send_eval UPDATE db1.t$counter
SET k = id + k , nk = k + id, c = REPEAT('a5', 512),
pad = REPEAT('b5', 512)
WHERE id % 5 = 0;
inc $counter;
}
--echo
--echo # Wait for Updates to finish
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
reap;
inc $counter;
}
--echo
--echo # Delete records
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
send_eval DELETE FROM db1.t$counter WHERE id % 4 = 1 ORDER BY id;
inc $counter;
}
--echo
--echo # Wait for Deletes to finish #1
let $counter = 1;
while($counter <= $max_connections){
connection con_$counter;
reap;
inc $counter;
}
connection default;
--file_exists $MYSQLD_ERROR_LOG
--let SEARCH_FILE=$MYSQLD_ERROR_LOG
--let SEARCH_PATTERN=System tablespace expansion is redo logged
--source include/search_pattern.inc
let $file_size_now = `SELECT
ROUND(SUM(TOTAL_EXTENTS * EXTENT_SIZE)/1024/1024) AS tablespace_size_in_MB
FROM
information_schema.FILES
WHERE
TABLESPACE_NAME = 'innodb_system'
GROUP BY
TABLESPACE_NAME, FILE_NAME`;
if($file_size_now == $inital_file_size ) {
--echo # Current file size=$file_size_now is same as initial file size=$inital_file_size.
--die "Test failed because system tablespace is not expanded"
}
SET GLOBAL DEBUG='-d,ib_redo_log_system_tablespace_expansion';
--echo # Verify no issues observed during crash recovery
--replace_result $MYSQLD_ERROR_LOG my_restart.err $MYSQLD_DATADIR tmp/test_data_dir
--source include/kill_and_restart_mysqld.inc
SELECT id, k FROM db1.t1 ORDER BY id LIMIT 1;
--echo
--echo # Cleanup
--echo
let restart_parameters = restart:;
--source include/kill_and_restart_mysqld.inc
--remove_file $MYSQLD_ERROR_LOG
--force-rmdir $MYSQLD_DATADIR
let $counter = 1;
while($counter <= $max_connections){
disconnect con_$counter;
inc $counter;
}
--source include/wait_until_count_sessions.inc
|