summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-16 15:38:37 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-07-26 08:54:14 +0300
commitab192cbe8320c92826aca27920b9604066c5582a (patch)
treef0bc2de5bd7d2ad0b2ecf0c2d65db510b52465f9
parente71365e3bd48cde174ba223609df90b98a94ec3d (diff)
downloadmariadb-git-ab192cbe8320c92826aca27920b9604066c5582a.tar.gz
WIP: Introduce separate ib_logdata file
The file ib_logfile0 used to consist of a 2048-byte header and a fixed-size portion of log records written in circular fashion. We are introducing a separate ib_logdata for the circular log, while ib_logfile0 will (eventually) an append-only file comprising a header (facilitating upgrade/downgrade checks) and records that identify data files and checkpoints. FIXME: Upgrade from earlier version is broken (in addition to crash recovery being broken). create_data_file(): create ib_logdata which should have a size of srv_log_file_size. recv_sys_t::upgrade_file_format_to_10_6_if_needed(): not finished bacause more file format changes are coming. log_t::file::lsn_offset: start from 0 (no header in file) log_t::file::data_fd: this one is ib_logdata
-rw-r--r--extra/mariabackup/xtrabackup.cc38
-rw-r--r--mysql-test/suite/encryption/r/innodb_encrypt_log.result6
-rw-r--r--mysql-test/suite/encryption/t/innodb_encrypt_log.test5
-rw-r--r--mysql-test/suite/innodb/include/log_file_cleanup.inc2
-rw-r--r--mysql-test/suite/innodb/r/log_file.result34
-rw-r--r--mysql-test/suite/innodb/r/row_format_redundant.result1
-rw-r--r--mysql-test/suite/innodb/r/table_flags.result1
-rw-r--r--mysql-test/suite/innodb/t/log_file.test5
-rw-r--r--mysql-test/suite/innodb_fts/disabled.def1
-rw-r--r--mysql-test/suite/mariabackup/disabled.def9
-rw-r--r--storage/innobase/handler/ha_innodb.cc1
-rw-r--r--storage/innobase/include/log0log.h57
-rw-r--r--storage/innobase/include/log0recv.h11
-rw-r--r--storage/innobase/log/log0log.cc148
-rw-r--r--storage/innobase/log/log0recv.cc100
-rw-r--r--storage/innobase/srv/srv0start.cc41
16 files changed, 355 insertions, 105 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index e57454ef19f..bdc2fb5568a 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -4295,9 +4295,9 @@ static bool xtrabackup_backup_low()
if (recv_find_max_checkpoint(&max_cp_field) == DB_SUCCESS
&& log_sys.log.format != 0) {
if (max_cp_field == LOG_CHECKPOINT_1) {
- log_sys.log.read(max_cp_field,
- {log_sys.checkpoint_buf,
- OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.data_read(max_cp_field,
+ {log_sys.checkpoint_buf,
+ OS_FILE_LOG_BLOCK_SIZE});
}
metadata_to_lsn = mach_read_from_8(
log_sys.checkpoint_buf + LOG_CHECKPOINT_LSN);
@@ -4461,7 +4461,7 @@ fail:
log_sys.create();
log_sys.log.create();
- log_sys.log.open_file(get_log_file_path());
+ log_sys.log.open_files(get_log_file_path());
/* create extra LSN dir if it does not exist. */
if (xtrabackup_extra_lsndir
@@ -4519,7 +4519,7 @@ free_and_fail:
checkpoint_lsn_start = log_sys.log.get_lsn();
checkpoint_no_start = log_sys.next_checkpoint_no;
- log_sys.log.read(max_cp_field, {buf, OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.main_read(max_cp_field, {buf, OS_FILE_LOG_BLOCK_SIZE});
if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)
|| checkpoint_lsn_start
@@ -4536,19 +4536,28 @@ free_and_fail:
goto free_and_fail;
}
- /* open the log file */
+ /* open the log data file */
memset(&stat_info, 0, sizeof(MY_STAT));
- dst_log_file = ds_open(ds_redo, LOG_FILE_NAME, &stat_info);
+ dst_log_file = ds_open(ds_redo, LOG_DATA_FILE_NAME, &stat_info);
if (dst_log_file == NULL) {
msg("Error: failed to open the target stream for '%s'.",
+ LOG_DATA_FILE_NAME);
+ goto fail;
+ }
+
+ memset(&stat_info, 0, sizeof(MY_STAT));
+ ds_file_t *dst_log_main_file=
+ ds_open(ds_redo, LOG_FILE_NAME, &stat_info);
+ if (dst_log_main_file == nullptr) {
+ msg("Error: failed to open the target stream for '%s'.",
LOG_FILE_NAME);
goto free_and_fail;
}
/* label it */
byte* log_hdr_buf = static_cast<byte*>(
- aligned_malloc(LOG_FILE_HDR_SIZE, OS_FILE_LOG_BLOCK_SIZE));
- memset(log_hdr_buf, 0, LOG_FILE_HDR_SIZE);
+ aligned_malloc(LOG_MAIN_FILE_SIZE, LOG_MAIN_FILE_SIZE));
+ memset(log_hdr_buf, 0, LOG_MAIN_FILE_SIZE);
byte *log_hdr_field = log_hdr_buf;
mach_write_to_4(LOG_HEADER_FORMAT + log_hdr_field, log_sys.log.format);
@@ -4571,19 +4580,24 @@ free_and_fail:
/* Adjust the checkpoint page. */
memcpy(log_hdr_field, log_sys.checkpoint_buf, OS_FILE_LOG_BLOCK_SIZE);
mach_write_to_8(log_hdr_field + LOG_CHECKPOINT_OFFSET,
- (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1))
- | LOG_FILE_HDR_SIZE);
+ (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1)));
log_block_set_checksum(log_hdr_field,
log_block_calc_checksum_crc32(log_hdr_field));
/* Write log header*/
- if (ds_write(dst_log_file, log_hdr_buf, LOG_FILE_HDR_SIZE)) {
+ if (ds_write(dst_log_file, log_hdr_buf, LOG_MAIN_FILE_SIZE)) {
msg("error: write to logfile failed");
aligned_free(log_hdr_buf);
goto free_and_fail;
}
aligned_free(log_hdr_buf);
+
+ if (int err = ds_close(dst_log_main_file)) {
+ msg("error while closing %s: %d", LOG_FILE_NAME, err);
+ }
+ dst_log_main_file = nullptr;
+
log_copying_running = true;
/* start io throttle */
if(xtrabackup_throttle) {
diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log.result b/mysql-test/suite/encryption/r/innodb_encrypt_log.result
index b436435090b..6bde3174ebd 100644
--- a/mysql-test/suite/encryption/r/innodb_encrypt_log.result
+++ b/mysql-test/suite/encryption/r/innodb_encrypt_log.result
@@ -46,8 +46,10 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip');
# Kill the server
# ib_logfile0 expecting NOT FOUND
NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ib_logfile0
-# ib_logfile0 expecting FOUND
-FOUND 1 /(public|gossip).*/ in ib_logfile0
+# ib_logfile0 expecting NOT FOUND
+NOT FOUND /(public|gossip).*/ in ib_logfile0
+# ib_logdata expecting FOUND
+FOUND 1 /(public|gossip).*/ in ib_logdata
# ibdata1 expecting NOT FOUND
NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip/ in ibdata1
# t0.ibd expecting NOT FOUND
diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_log.test b/mysql-test/suite/encryption/t/innodb_encrypt_log.test
index 1d016be73c8..4fc09621122 100644
--- a/mysql-test/suite/encryption/t/innodb_encrypt_log.test
+++ b/mysql-test/suite/encryption/t/innodb_encrypt_log.test
@@ -73,9 +73,12 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip');
-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0
-- source include/search_pattern_in_file.inc
--let SEARCH_PATTERN=(public|gossip).*
---echo # ib_logfile0 expecting FOUND
+--echo # ib_logfile0 expecting NOT FOUND
-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0
-- source include/search_pattern_in_file.inc
+--echo # ib_logdata expecting FOUND
+-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logdata
+-- source include/search_pattern_in_file.inc
--let SEARCH_PATTERN=private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip
--echo # ibdata1 expecting NOT FOUND
diff --git a/mysql-test/suite/innodb/include/log_file_cleanup.inc b/mysql-test/suite/innodb/include/log_file_cleanup.inc
index 80ce1df0c97..6f3bd8e525b 100644
--- a/mysql-test/suite/innodb/include/log_file_cleanup.inc
+++ b/mysql-test/suite/innodb/include/log_file_cleanup.inc
@@ -5,10 +5,12 @@
--list_files $bugdir
--remove_files_wildcard $bugdir ibdata*
--remove_files_wildcard $bugdir ib_logfile*
+--remove_files_wildcard $bugdir ib_logdata
--remove_files_wildcard $bugdir undo00*
--copy_file $bugdir/bak_ibdata1 $bugdir/ibdata1
--copy_file $bugdir/bak_ibdata2 $bugdir/ibdata2
--copy_file $bugdir/bak_ib_logfile0 $bugdir/ib_logfile0
+--copy_file $bugdir/bak_ib_logdata $bugdir/ib_logdata
--copy_file $bugdir/bak_undo001 $bugdir/undo001
--copy_file $bugdir/bak_undo002 $bugdir/undo002
--copy_file $bugdir/bak_undo003 $bugdir/undo003
diff --git a/mysql-test/suite/innodb/r/log_file.result b/mysql-test/suite/innodb/r/log_file.result
index 10479e5004a..ff0b5b78115 100644
--- a/mysql-test/suite/innodb/r/log_file.result
+++ b/mysql-test/suite/innodb/r/log_file.result
@@ -9,6 +9,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /\[ERROR\] InnoDB: Could not create undo tablespace '.*undo002'/ in mysqld.1.err
# Remove undo001,undo002,ibdata1,ibdata2,ib_logfile101
+ib_logdata
# Start mysqld with non existent innodb_log_group_home_dir
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-directory=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-logs=20 --innodb-undo-tablespaces=3 --innodb-data-file-path=ibdata1:16M;ibdata2:10M:autoextend --innodb_log_group_home_dir=/path/to/non-existent/
SELECT * FROM INFORMATION_SCHEMA.ENGINES
@@ -17,6 +18,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /File .path.to.non-existent.*ib_logfile101: 'create' returned OS error \d+/ in mysqld.1.err
# Remove ibdata1 & ibdata2
+ib_logdata
# Successfully let InnoDB create tablespaces
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-directory=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-logs=20 --innodb-undo-tablespaces=3 --innodb-data-file-path=ibdata1:16M;ibdata2:10M:autoextend
SELECT COUNT(*) `1` FROM INFORMATION_SCHEMA.ENGINES
@@ -32,6 +34,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /The data file '.*ibdata1' was not found but one of the other data files '.*ibdata2' exists/ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -39,6 +42,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata2
undo001
@@ -52,6 +56,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: Tablespace size stored in header is \d+ pages, but the sum of data file sizes is \d+ pages/ in mysqld.1.err
FOUND 1 /InnoDB: Cannot start InnoDB. The tail of the system tablespace is missing/ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -59,6 +64,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
@@ -66,6 +72,7 @@ undo001
undo002
undo003
# 3. Without ibdata1 & ibdata2
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -73,6 +80,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
undo001
undo002
@@ -83,6 +91,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: undo tablespace .*undo001.* exists\. Creating system tablespace with existing undo tablespaces is not supported\. Please delete all undo tablespaces before creating new system tablespace\./ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -90,11 +99,13 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
undo001
undo002
undo003
# 4. Without ibdata*, ib_logfile* and with undo00*
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -110,6 +121,7 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -121,6 +133,7 @@ undo001
undo002
undo003
# 5. Without ibdata*,ib_logfile* files & Without undo002
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -135,6 +148,7 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -145,6 +159,7 @@ ib_buffer_pool
undo001
undo003
# 6. Without ibdata*,ib_logfile* files & Without undo001, undo002
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -159,6 +174,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /undo tablespace .*undo003.* exists\. Creating system tablespace with existing undo tablespaces is not supported\. Please delete all undo tablespaces before creating new system tablespace\./ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -168,6 +184,7 @@ bak_undo003
ib_buffer_pool
undo003
# 7. With ibdata files & Without undo002
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -175,6 +192,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
@@ -186,6 +204,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: Expected to open innodb_undo_tablespaces=3 but was able to find only 1/ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -193,12 +212,14 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
undo001
undo003
# 8. With ibdata files & Without undo001, undo002
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -206,6 +227,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
@@ -216,6 +238,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /InnoDB: Expected to open innodb_undo_tablespaces=3 but was able to find only 0/ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -223,11 +246,13 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
undo003
# 9. Without ibdata*, without undo*
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -235,6 +260,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-directory=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-logs=20 --innodb-undo-tablespaces=3 --innodb-data-file-path=ibdata1:16M;ibdata2:10M:autoextend
SELECT * FROM INFORMATION_SCHEMA.ENGINES
@@ -242,6 +268,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
FOUND 1 /redo log file .*ib_logfile0.* exists\. Creating system tablespace with existing redo log file is not recommended\. Please delete redo log file before creating new system tablespace\./ in mysqld.1.err
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -249,6 +276,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
# 10. With ibdata*, without ib_logfile0
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-directory=MYSQLTEST_VARDIR/tmp/log_file --innodb-undo-logs=20 --innodb-undo-tablespaces=3 --innodb-data-file-path=ibdata1:16M;ibdata2:10M:autoextend
@@ -257,6 +285,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
InnoDB YES Supports transactions, row-level locking, foreign keys and encryption for tables YES YES YES
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -264,6 +293,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
@@ -271,6 +301,7 @@ undo001
undo002
undo003
# 11. With ibdata*
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -278,6 +309,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
@@ -293,6 +325,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
NOT FOUND /Resizing redo log from 1\*\d+ to 3\*\d+ bytes; LSN=\d+/ in mysqld.1.err
# restart
# Cleanup
+bak_ib_logdata
bak_ib_logfile0
bak_ibdata1
bak_ibdata2
@@ -300,6 +333,7 @@ bak_undo001
bak_undo002
bak_undo003
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
ibdata2
diff --git a/mysql-test/suite/innodb/r/row_format_redundant.result b/mysql-test/suite/innodb/r/row_format_redundant.result
index f354666f645..bccd81d3164 100644
--- a/mysql-test/suite/innodb/r/row_format_redundant.result
+++ b/mysql-test/suite/innodb/r/row_format_redundant.result
@@ -78,6 +78,7 @@ DROP TABLE t2,t3;
FOUND 5 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
# restart
ib_buffer_pool
+ib_logdata
ib_logfile0
ibdata1
db.opt
diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result
index ce71d9b022d..7f5b91588c8 100644
--- a/mysql-test/suite/innodb/r/table_flags.result
+++ b/mysql-test/suite/innodb/r/table_flags.result
@@ -172,6 +172,7 @@ SELECT * FROM tp;
a
DROP TABLE tr,tc,td,tz,tp;
# restart
+ib_logdata
ib_logfile0
ibdata1
sys_tables.bin
diff --git a/mysql-test/suite/innodb/t/log_file.test b/mysql-test/suite/innodb/t/log_file.test
index f03bce804f6..eb772cf23db 100644
--- a/mysql-test/suite/innodb/t/log_file.test
+++ b/mysql-test/suite/innodb/t/log_file.test
@@ -79,6 +79,7 @@ eval $check_yes_innodb;
--copy_file $bugdir/ibdata1 $bugdir/bak_ibdata1
--copy_file $bugdir/ibdata2 $bugdir/bak_ibdata2
--copy_file $bugdir/ib_logfile0 $bugdir/bak_ib_logfile0
+--copy_file $bugdir/ib_logdata $bugdir/bak_ib_logdata
--copy_file $bugdir/undo001 $bugdir/bak_undo001
--copy_file $bugdir/undo002 $bugdir/bak_undo002
--copy_file $bugdir/undo003 $bugdir/bak_undo003
@@ -124,6 +125,7 @@ let SEARCH_PATTERN=InnoDB: undo tablespace .*undo001.* exists\. Creating system
--echo # 4. Without ibdata*, ib_logfile* and with undo00*
--remove_files_wildcard $bugdir ibdata*
--remove_files_wildcard $bugdir ib_logfile*
+--remove_files_wildcard $bugdir ib_logdata
--list_files $bugdir
--source include/start_mysqld.inc
eval $check_no_innodb;
@@ -135,6 +137,7 @@ eval $check_no_innodb;
--echo # 5. Without ibdata*,ib_logfile* files & Without undo002
--remove_files_wildcard $bugdir ibdata*
--remove_files_wildcard $bugdir ib_logfile*
+--remove_files_wildcard $bugdir ib_logdata
--remove_file $bugdir/undo002
--list_files $bugdir
--source include/start_mysqld.inc
@@ -148,6 +151,7 @@ eval $check_no_innodb;
# and with undo003
--remove_files_wildcard $bugdir ibdata*
--remove_files_wildcard $bugdir ib_logfile*
+--remove_files_wildcard $bugdir ib_logdata
--remove_file $bugdir/undo001
--remove_file $bugdir/undo002
--list_files $bugdir
@@ -199,6 +203,7 @@ let SEARCH_PATTERN=redo log file .*ib_logfile0.* exists\. Creating system tables
--echo # 10. With ibdata*, without ib_logfile0
--remove_file $bugdir/ib_logfile0
+--remove_file $bugdir/ib_logdata
--source include/start_mysqld.inc
eval $check_no_innodb;
diff --git a/mysql-test/suite/innodb_fts/disabled.def b/mysql-test/suite/innodb_fts/disabled.def
index 92e1ad34c9c..a1e4ac99eda 100644
--- a/mysql-test/suite/innodb_fts/disabled.def
+++ b/mysql-test/suite/innodb_fts/disabled.def
@@ -1,2 +1,3 @@
crash_recovery : MDEV-14425 breaks recovery
sync : MDEV-14425 breaks recovery
+innodb-fts-ddl : MDEV-14425 breaks recovery
diff --git a/mysql-test/suite/mariabackup/disabled.def b/mysql-test/suite/mariabackup/disabled.def
index fcf7ee167fd..b81aa10f00d 100644
--- a/mysql-test/suite/mariabackup/disabled.def
+++ b/mysql-test/suite/mariabackup/disabled.def
@@ -1,6 +1,7 @@
log_page_corruption : MDEV-26210
apply-log-only : MDEV-14425 breaks recovery
apply-log-only-incr : MDEV-14425 breaks recovery
+backup_grants : MDEV-14425 breaks recovery
backup_ssl : MDEV-14425 breaks recovery
big_innodb_log : MDEV-14425 breaks recovery
binlog : MDEV-14425 breaks recovery
@@ -8,18 +9,23 @@ create_during_backup : MDEV-14425 breaks recovery
create_with_data_directory_during_backup : MDEV-14425 breaks recovery
data_directory : MDEV-14425 breaks recovery
drop_table_during_backup : MDEV-14425 breaks recovery
+encrypted_page_corruption : MDEV-14425 breaks recovery
extra_lsndir : MDEV-14425 breaks recovery
+extra_lsndir_stream : MDEV-14425 breaks recovery
full_backup : MDEV-14425 breaks recovery
huge_lsn : MDEV-14425 breaks recovery
incremental_backup : MDEV-14425 breaks recovery
incremental_ddl_before_backup : MDEV-14425 breaks recovery
incremental_ddl_during_backup : MDEV-14425 breaks recovery
incremental_encrypted : MDEV-14425 breaks recovery
+innodb_redo_overwrite : MDEV-14425 breaks recovery
lock_ddl_per_table : MDEV-14425 breaks recovery
log_checksum_mismatch : MDEV-14425 breaks recovery
log_page_corruption : MDEV-14425 breaks recovery
mdev-14447 : MDEV-14425 breaks recovery
+mdev-18438 : MDEV-14425 breaks recovery
nolock_ddl_during_backup_end : MDEV-14425 breaks recovery
+options_check : MDEV-14425 breaks recovery
page_compression_level : MDEV-14425 breaks recovery
partial : MDEV-14425 breaks recovery
partial_exclude : MDEV-14425 breaks recovery
@@ -28,6 +34,8 @@ partition_partial : MDEV-14425 breaks recovery
recreate_table_during_backup : MDEV-14425 breaks recovery
rename_during_backup : MDEV-14425 breaks recovery
rename_during_mdl_lock : MDEV-14425 breaks recovery
+rpl_slave_info : MDEV-14425 breaks recovery
+small_ibd : MDEV-14425 breaks recovery
system_versioning : MDEV-14425 breaks recovery
truncate_during_backup : MDEV-14425 breaks recovery
undo_space_id : MDEV-14425 breaks recovery
@@ -35,6 +43,7 @@ unsupported_redo : MDEV-14425 breaks recovery
xb_compressed_encrypted : MDEV-14425 breaks recovery
xb_file_key_management : MDEV-14425 breaks recovery
xb_fulltext_encrypted : MDEV-14425 breaks recovery
+xb_history : MDEV-14425 breaks recovery
xb_page_compress : MDEV-14425 breaks recovery
xb_partition : MDEV-14425 breaks recovery
xbstream : MDEV-14425 breaks recovery
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index ecaf89fe259..c743df09bad 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -18009,7 +18009,6 @@ checkpoint_now_set(THD*, st_mysql_sys_var*, void*, const void* save)
std::memory_order_acquire)
< (lsn= log_sys.get_lsn(std::memory_order_acquire))) {
log_make_checkpoint();
- log_sys.log.flush();
}
if (dberr_t err = fil_write_flushed_lsn(lsn)) {
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index ca792f9e439..366c03ebfcb 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -46,6 +46,12 @@ using st_::span;
static const char LOG_FILE_NAME_PREFIX[] = "ib_logfile";
static const char LOG_FILE_NAME[] = "ib_logfile0";
+/** this is where redo log data is stored (no header, no checkpoints) */
+static const char LOG_DATA_FILE_NAME[] = "ib_logdata";
+
+/** creates LOG_DATA_FILE_NAME with specified size */
+dberr_t create_data_file(os_offset_t size);
+
/** Composes full path for a redo log file
@param[in] filename name of the redo log file
@return path with log file name*/
@@ -346,7 +352,8 @@ or the MySQL version that created the redo log file. */
#define LOG_CHECKPOINT_2 (3 * OS_FILE_LOG_BLOCK_SIZE)
/* second checkpoint field in the log
header */
-#define LOG_FILE_HDR_SIZE (4 * OS_FILE_LOG_BLOCK_SIZE)
+/** size of LOG_FILE_NAME (header + checkpoints */
+constexpr size_t LOG_MAIN_FILE_SIZE= 4 * OS_FILE_LOG_BLOCK_SIZE;
/** Memory mapped file */
class mapped_file_t
@@ -506,42 +513,49 @@ public:
lsn_t lsn;
/** the byte offset of the above lsn */
lsn_t lsn_offset;
- /** log file */
+ /** main log file */
log_file_t fd;
+ /** log data file */
+ log_file_t data_fd;
public:
/** used only in recovery: recovery scan succeeded up to this
lsn in this log group */
lsn_t scanned_lsn;
- /** opens log file which must be closed prior this call */
- void open_file(std::string path);
+ /** opens log files which must be closed prior this call */
+ void open_files(std::string path);
/** writes header */
void write_header_durable(lsn_t lsn);
/** opens log file which must be closed prior this call */
dberr_t rename(std::string path) { return fd.rename(path); }
- /** reads buffer from log file
+ /** read from the main log file
@param[in] offset offset in log file
@param[in] buf buffer where to read */
- void read(os_offset_t offset, span<byte> buf);
- /** Tells whether writes require calling flush() */
- bool writes_are_durable() const noexcept;
+ void main_read(os_offset_t offset, span<byte> buf);
/** writes buffer to log file
@param[in] offset offset in log file
@param[in] buf buffer from which to write */
- void write(os_offset_t offset, span<byte> buf);
+ void main_write_durable(os_offset_t offset, span<byte> buf);
+ /** closes log files */
+ void close_files();
+
+ /** check that log data file is opened */
+ bool data_is_opened() const { return data_fd.is_opened(); }
+ /** reads from data file */
+ void data_read(os_offset_t offset, span<byte> buf);
+ /** Tells whether writes require calling flush_data_only() */
+ bool data_writes_are_durable() const noexcept;
+ /** writes to data file */
+ void data_write(os_offset_t offset, span<byte> buf);
/** flushes OS page cache (excluding metadata!) for log file */
void flush();
- /** closes log file */
- void close_file();
/** @return whether the redo log is encrypted */
bool is_encrypted() const { return format & FORMAT_ENCRYPTED; }
/** @return whether the redo log is in the physical format */
bool is_physical() const
{ return (format & ~FORMAT_ENCRYPTED) == FORMAT_10_5; }
- /** @return capacity in bytes */
- lsn_t capacity() const{ return file_size - LOG_FILE_HDR_SIZE; }
/** Calculate the offset of a log sequence number.
@param[in] lsn log sequence number
@return offset within the log */
@@ -567,7 +581,7 @@ public:
void create();
/** Close the redo log buffer. */
- void close() { close_file(); }
+ void close() { close_files(); }
void set_lsn(lsn_t a_lsn);
lsn_t get_lsn() const { return lsn; }
void set_lsn_offset(lsn_t a_lsn);
@@ -723,16 +737,17 @@ inline lsn_t log_t::file::calc_lsn_offset(lsn_t lsn) const
#ifdef SAFE_MUTEX
ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
#endif /* SAFE_MUTEX */
- const lsn_t size = capacity();
+ const lsn_t size= file_size;
lsn_t l= lsn - this->lsn;
- if (longlong(l) < 0) {
- l = lsn_t(-longlong(l)) % size;
- l = size - l;
+ if (longlong(l) < 0)
+ {
+ l= lsn_t(-longlong(l)) % size;
+ l= size - l;
}
- l+= lsn_offset - LOG_FILE_HDR_SIZE * (1 + lsn_offset / file_size);
- l %= size;
- return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE));
+ l+= lsn_offset;
+ l%= size;
+ return l;
}
inline void log_t::file::set_lsn(lsn_t a_lsn)
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index b776c82af62..0b686ffbe54 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -279,6 +279,12 @@ public:
/** Last added LSN to pages. */
lsn_t last_stored_lsn= 0;
+ /** this block should be copied to LOG_DATA_FILE_NAME on upgrade from old
+ file format */
+ void set_block_to_copy(os_offset_t off);
+ /** upgrades file format if needed */
+ dberr_t upgrade_file_format_to_10_6_if_needed();
+
void read(os_offset_t offset, span<byte> buf);
inline size_t files_size();
void close_files() { files.clear(); files.shrink_to_fit(); }
@@ -302,6 +308,11 @@ private:
from before MariaDB Server 10.5.1) */
std::vector<log_file_t> files;
+ /** Last checkpoint in empty pre-10.5 log files points to this block.
+ In old file format it's never 0, because old redo log file has a header. */
+ os_offset_t block_to_copy_when_upgrading_file_format= 0;
+
+ /** used for laziness */
void open_log_files_if_needed();
/** Base node of the redo block list.
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 4efe3a509eb..b17bc5933b8 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -136,7 +136,7 @@ log_set_capacity(ulonglong file_size)
lsn_t margin;
ulint free;
- lsn_t smallest_capacity = file_size - LOG_FILE_HDR_SIZE;
+ lsn_t smallest_capacity = file_size;
/* Add extra safety */
smallest_capacity -= smallest_capacity / 10;
@@ -440,11 +440,24 @@ dberr_t log_file_t::flush() noexcept
return m_file->flush();
}
-void log_t::file::open_file(std::string path)
+void log_t::file::open_files(std::string path)
{
fd= log_file_t(std::move(path));
if (const dberr_t err= fd.open(srv_read_only_mode))
ib::fatal() << "open(" << fd.get_path() << ") returned " << err;
+
+ data_fd= log_file_t(get_log_file_path(LOG_DATA_FILE_NAME));
+ bool exists;
+ os_file_type_t type;
+ os_file_status(data_fd.get_path().c_str(), &exists, &type);
+ if (exists)
+ {
+ if (const dberr_t err= data_fd.open(srv_read_only_mode))
+ ib::fatal() << "open(" << data_fd.get_path() << ") returned " << err;
+
+ srv_log_file_size=
+ os_file_get_size(data_fd.get_path().c_str()).m_total_size;
+ }
}
/** Update the log block checksum. */
@@ -474,23 +487,16 @@ void log_t::file::write_header_durable(lsn_t lsn)
DBUG_PRINT("ib_log", ("write " LSN_PF, lsn));
- log_sys.log.write(0, {buf, OS_FILE_LOG_BLOCK_SIZE});
- if (!log_sys.log.writes_are_durable())
- log_sys.log.flush();
+ log_sys.log.main_write_durable(0, {buf, OS_FILE_LOG_BLOCK_SIZE});
}
-void log_t::file::read(os_offset_t offset, span<byte> buf)
+void log_t::file::main_read(os_offset_t offset, span<byte> buf)
{
if (const dberr_t err= fd.read(offset, buf))
- ib::fatal() << "read(" << fd.get_path() << ") returned "<< err;
-}
-
-bool log_t::file::writes_are_durable() const noexcept
-{
- return fd.writes_are_durable();
+ ib::fatal() << "read(" << fd.get_path() << ") returned " << err;
}
-void log_t::file::write(os_offset_t offset, span<byte> buf)
+void log_t::file::main_write_durable(os_offset_t offset, span<byte> buf)
{
srv_stats.os_log_pending_writes.inc();
if (const dberr_t err= fd.write(offset, buf))
@@ -499,25 +505,54 @@ void log_t::file::write(os_offset_t offset, span<byte> buf)
srv_stats.os_log_written.add(buf.size());
srv_stats.log_writes.inc();
log_sys.n_log_ios++;
-}
-void log_t::file::flush()
-{
- log_sys.pending_flushes.fetch_add(1, std::memory_order_acquire);
- if (const dberr_t err= fd.flush())
- ib::fatal() << "flush(" << fd.get_path() << ") returned " << err;
- log_sys.pending_flushes.fetch_sub(1, std::memory_order_release);
- log_sys.flushes.fetch_add(1, std::memory_order_release);
+ if (!fd.writes_are_durable())
+ if (const dberr_t err= fd.flush())
+ ib::fatal() << "flush(" << fd.get_path() << ") returned " << err;
}
-void log_t::file::close_file()
+void log_t::file::close_files()
{
if (fd.is_opened())
- {
if (const dberr_t err= fd.close())
ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
- }
- fd.free(); // Free path
+ fd.free();
+
+ if (data_fd.is_opened())
+ if (const dberr_t err= data_fd.close())
+ ib::fatal() << "close(" << data_fd.get_path() << ") returned " << err;
+ data_fd.free();
+}
+
+void log_t::file::data_read(os_offset_t offset, span<byte> buf)
+{
+ if (const dberr_t err= data_fd.read(offset, buf))
+ ib::fatal() << "read(" << data_fd.get_path() << ") returned " << err;
+}
+
+bool log_t::file::data_writes_are_durable() const noexcept
+{
+ return data_fd.writes_are_durable();
+}
+
+void log_t::file::data_write(os_offset_t offset, span<byte> buf)
+{
+ srv_stats.os_log_pending_writes.inc();
+ if (const dberr_t err= data_fd.write(offset, buf))
+ ib::fatal() << "write(" << data_fd.get_path() << ") returned " << err;
+ srv_stats.os_log_pending_writes.dec();
+ srv_stats.os_log_written.add(buf.size());
+ srv_stats.log_writes.inc();
+ log_sys.n_log_ios++;
+}
+
+void log_t::file::/*data_*/flush()
+{
+ log_sys.pending_flushes.fetch_add(1, std::memory_order_acquire);
+ if (const dberr_t err= data_fd.flush())
+ ib::fatal() << "flush(" << data_fd.get_path() << ") returned " << err;
+ log_sys.pending_flushes.fetch_sub(1, std::memory_order_release);
+ log_sys.flushes.fetch_add(1, std::memory_order_release);
}
/** Initialize the redo log. */
@@ -530,7 +565,7 @@ void log_t::file::create()
subformat= 2;
file_size= srv_log_file_size;
lsn= LOG_START_LSN;
- lsn_offset= LOG_FILE_HDR_SIZE;
+ lsn_offset= 0;
}
/******************************************************//**
@@ -611,7 +646,7 @@ loop:
ut_a((next_offset >> srv_page_size_shift) <= ULINT_MAX);
- log_sys.log.write(static_cast<size_t>(next_offset), {buf, write_len});
+ log_sys.log.data_write(next_offset, {buf, write_len});
if (write_len < len) {
start_lsn += write_len;
@@ -621,11 +656,10 @@ loop:
}
}
-/** Flush the recently written changes to the log file.
-and invoke mysql_mutex_lock(&log_sys.mutex). */
+/** Flush the recently written changes to the log file */
static void log_write_flush_to_disk_low(lsn_t lsn)
{
- if (!log_sys.log.writes_are_durable())
+ if (!log_sys.log.data_writes_are_durable())
log_sys.log.flush();
ut_a(lsn >= log_sys.get_flushed_lsn());
log_sys.set_flushed_lsn(lsn);
@@ -762,7 +796,7 @@ static void log_write(bool rotate_key)
start_offset - area_start);
srv_stats.log_padded.add(pad_size);
log_sys.write_lsn = write_lsn;
- if (log_sys.log.writes_are_durable()) {
+ if (log_sys.log.data_writes_are_durable()) {
log_sys.set_flushed_lsn(write_lsn);
log_flush_notify(write_lsn);
}
@@ -906,11 +940,10 @@ ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
/* Note: We alternate the physical place of the checkpoint info.
See the (next_checkpoint_no & 1) below. */
- log_sys.log.write((log_sys.next_checkpoint_no & 1) ? LOG_CHECKPOINT_2
- : LOG_CHECKPOINT_1,
- {buf, OS_FILE_LOG_BLOCK_SIZE});
-
- log_sys.log.flush();
+ log_sys.log.main_write_durable((log_sys.next_checkpoint_no & 1)
+ ? LOG_CHECKPOINT_2
+ : LOG_CHECKPOINT_1,
+ {buf, OS_FILE_LOG_BLOCK_SIZE});
mysql_mutex_lock(&log_sys.mutex);
@@ -1333,3 +1366,46 @@ std::vector<std::string> get_existing_log_files_paths() {
return result;
}
+
+dberr_t create_data_file(os_offset_t size)
+{
+ ut_ad(size > LOG_MAIN_FILE_SIZE);
+
+ const auto path= get_log_file_path(LOG_DATA_FILE_NAME);
+ os_file_delete_if_exists(innodb_log_file_key, path.c_str(), nullptr);
+
+ bool ret;
+ pfs_os_file_t file=
+ os_file_create(innodb_log_file_key, path.c_str(),
+ OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT, OS_FILE_NORMAL,
+ OS_LOG_FILE, srv_read_only_mode, &ret);
+
+ if (!ret)
+ {
+ ib::error() << "Cannot create " << path;
+ return DB_ERROR;
+ }
+
+ ib::info() << "Setting log file " << path << " size to " << size << " bytes";
+
+ ret= os_file_set_size(path.c_str(), file, size);
+ if (!ret)
+ {
+ os_file_close(file);
+ ib::error() << "Cannot set log file " << path << " size to " << size
+ << " bytes";
+ return DB_ERROR;
+ }
+
+ if (!os_file_flush(file))
+ {
+ os_file_close(file);
+ ib::error() << "Error while flushing " << path;
+ return DB_ERROR;
+ }
+
+ ret= os_file_close(file);
+ ut_a(ret);
+
+ return DB_SUCCESS;
+}
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 7720c041ece..22df7fca821 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -27,6 +27,7 @@ Created 9/20/1997 Heikki Tuuri
#include "univ.i"
+#include <array>
#include <map>
#include <string>
#include <my_service_manager.h>
@@ -1053,8 +1054,87 @@ void recv_sys_t::open_log_files_if_needed()
}
}
+void recv_sys_t::set_block_to_copy(os_offset_t off)
+{
+ ut_ad(off > 0);
+ block_to_copy_when_upgrading_file_format= off;
+}
+
+dberr_t recv_sys_t::upgrade_file_format_to_10_6_if_needed()
+{
+ if (block_to_copy_when_upgrading_file_format == 0)
+ return DB_SUCCESS;
+
+ ut_ad(!log_sys.log.data_is_opened());
+
+ if (dberr_t err= create_data_file(srv_log_file_size))
+ return err;
+
+ // Copy one block from old file to new file.
+ log_file_t data_fd(get_log_file_path(LOG_DATA_FILE_NAME));
+
+ if (dberr_t err= data_fd.open(false))
+ return err;
+
+ std::array<byte, OS_FILE_LOG_BLOCK_SIZE> buf alignas(OS_FILE_LOG_BLOCK_SIZE);
+ read(block_to_copy_when_upgrading_file_format, buf);
+ if (dberr_t err= data_fd.write(
+ block_to_copy_when_upgrading_file_format - LOG_MAIN_FILE_SIZE, buf))
+ {
+ return err;
+ }
+
+ if (!data_fd.writes_are_durable())
+ if (dberr_t err= data_fd.flush())
+ return err;
+
+ if (dberr_t err= data_fd.close())
+ return err;
+
+ // Set LOG_FILE_NAME size to LOG_MAIN_FILE_SIZE
+ bool ret;
+ std::string logfile0_path= recv_sys.files.front().get_path();
+ pfs_os_file_t logfile0=
+ os_file_create(innodb_log_file_key, logfile0_path.c_str(),
+ OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, OS_FILE_NORMAL,
+ OS_LOG_FILE, true, &ret);
+
+ if (!ret)
+ {
+ ib::error() << "Cannot create " << logfile0_path;
+ return DB_ERROR;
+ }
+
+ ret= os_file_set_size(logfile0_path.c_str(), logfile0, LOG_MAIN_FILE_SIZE);
+ if (!ret)
+ {
+ os_file_close(logfile0);
+ ib::error() << "Cannot set log file " << logfile0_path << " size to "
+ << LOG_MAIN_FILE_SIZE << " bytes";
+ return DB_ERROR;
+ }
+
+ ret= os_file_close(logfile0);
+ ut_a(ret);
+
+ // Remove now unneeded multiple leftover log files
+ const size_t files_found= files.size();
+ files.clear();
+ for (size_t i= 1; i < files_found; i++)
+ delete_log_file(std::to_string(i).c_str());
+
+ block_to_copy_when_upgrading_file_format= 0;
+ return DB_SUCCESS;
+}
+
void recv_sys_t::read(os_offset_t total_offset, span<byte> buf)
{
+ if (log_sys.log.data_is_opened())
+ {
+ log_sys.log.data_read(total_offset, buf);
+ return;
+ }
+
open_log_files_if_needed();
size_t file_idx= static_cast<size_t>(total_offset / log_sys.log.file_size);
@@ -1416,7 +1496,9 @@ bool log_t::file::read_log_seg(lsn_t* start_lsn, lsn_t end_lsn)
ut_ad(!(end_lsn % OS_FILE_LOG_BLOCK_SIZE));
byte* buf = log_sys.buf;
loop:
- lsn_t source_offset = calc_lsn_offset_old(*start_lsn);
+ lsn_t source_offset = log_sys.log.data_is_opened()
+ ? calc_lsn_offset(*start_lsn)
+ : calc_lsn_offset_old(*start_lsn);
ut_a(end_lsn - *start_lsn <= ULINT_MAX);
len = (ulint) (end_lsn - *start_lsn);
@@ -1622,7 +1704,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
for (ulint field= LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1)
{
- log_sys.log.read(field, {buf, OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.main_read(field, {buf, OS_FILE_LOG_BLOCK_SIZE});
if (static_cast<uint32_t>(ut_fold_binary(buf, CHECKSUM_1)) !=
mach_read_from_4(buf + CHECKSUM_1) ||
@@ -1710,14 +1792,14 @@ in an old redo log file (during upgrade check).
@return byte offset within the log */
inline lsn_t log_t::file::calc_lsn_offset_old(lsn_t lsn) const
{
- const lsn_t size= capacity() * recv_sys.files_size();
+ constexpr size_t LOG_FILE_HDR_SIZE= 2048;
+ const lsn_t size= (file_size - LOG_FILE_HDR_SIZE) * recv_sys.files_size();
lsn_t l= lsn - this->lsn;
if (longlong(l) < 0)
{
l= lsn_t(-longlong(l)) % size;
l= size - l;
}
-
l+= lsn_offset - LOG_FILE_HDR_SIZE * (1 + lsn_offset / file_size);
l%= size;
return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE));
@@ -1738,8 +1820,8 @@ static dberr_t recv_log_recover_10_4()
return DB_CORRUPTION;
}
- recv_sys.read(source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1),
- {buf, OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.main_read(source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1),
+ {buf, OS_FILE_LOG_BLOCK_SIZE});
ulint crc = log_block_calc_checksum_crc32(buf);
ulint cksum = log_block_get_checksum(buf);
@@ -1797,7 +1879,7 @@ recv_find_max_checkpoint(ulint* max_field)
buf = log_sys.checkpoint_buf;
- log_sys.log.read(0, {buf, OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.main_read(0, {buf, OS_FILE_LOG_BLOCK_SIZE});
/* Check the header page checksum. There was no
checksum in the first redo log format (version 0). */
log_sys.log.format = mach_read_from_4(buf + LOG_HEADER_FORMAT);
@@ -1836,7 +1918,7 @@ recv_find_max_checkpoint(ulint* max_field)
for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
- log_sys.log.read(field, {buf, OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.main_read(field, {buf, OS_FILE_LOG_BLOCK_SIZE});
const ulint crc32 = log_block_calc_checksum_crc32(buf);
const ulint cksum = log_block_get_checksum(buf);
@@ -3925,7 +4007,7 @@ err_exit:
}
buf = log_sys.checkpoint_buf;
- log_sys.log.read(max_cp_field, {buf, OS_FILE_LOG_BLOCK_SIZE});
+ log_sys.log.main_read(max_cp_field, {buf, OS_FILE_LOG_BLOCK_SIZE});
checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 9a1a8f4969e..85d9805b628 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -268,14 +268,11 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
return DB_ERROR;
}
- ib::info() << "Setting log file " << logfile0 << " size to "
- << srv_log_file_size << " bytes";
-
- ret = os_file_set_size(logfile0.c_str(), file, srv_log_file_size);
+ ret = os_file_set_size(logfile0.c_str(), file, LOG_MAIN_FILE_SIZE);
if (!ret) {
os_file_close(file);
ib::error() << "Cannot set log file " << logfile0
- << " size to " << srv_log_file_size << " bytes";
+ << " size to " << LOG_MAIN_FILE_SIZE << " bytes";
return DB_ERROR;
}
@@ -285,16 +282,20 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
DBUG_EXECUTE_IF("innodb_log_abort_8", return(DB_ERROR););
DBUG_PRINT("ib_log", ("After innodb_log_abort_8"));
+ if (dberr_t err = create_data_file(srv_log_file_size)) {
+ return err;
+ }
+
/* We did not create the first log file initially as LOG_FILE_NAME, so
that crash recovery cannot find it until it has been completed and
- renamed. */
+ renamed. */
log_sys.log.create();
if (!log_set_capacity(srv_log_file_size_requested)) {
return DB_ERROR;
}
- log_sys.log.open_file(logfile0);
+ log_sys.log.open_files(logfile0);
if (!fil_system.sys_space->open(create_new_db)) {
return DB_ERROR;
}
@@ -308,7 +309,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);
log_sys.set_lsn(lsn + LOG_BLOCK_HDR_SIZE);
log_sys.log.set_lsn(lsn);
- log_sys.log.set_lsn_offset(LOG_FILE_HDR_SIZE);
+ log_sys.log.set_lsn_offset(0);
log_sys.buf_next_to_write = 0;
log_sys.write_lsn = lsn;
@@ -1017,18 +1018,7 @@ static dberr_t find_and_check_log_file(bool &log_file_found)
mariabackup --prepare. */
return DB_NOT_FOUND;
}
- /* The first log file must consist of at least the following 512-byte pages:
- header, checkpoint page 1, empty, checkpoint page 2, redo log page(s).
- Mariabackup --prepare would create an empty LOG_FILE_NAME. Tolerate it. */
- if (size == 0)
- srv_start_after_restore= true;
- else if (size <= OS_FILE_LOG_BLOCK_SIZE * 4)
- {
- ib::error() << "Log file " << logfile0 << " size " << size
- << " is too small";
- return DB_ERROR;
- }
srv_log_file_size= size;
log_file_found= true;
@@ -1339,7 +1329,7 @@ dberr_t srv_start(bool create_new_db)
srv_log_file_found = log_file_found;
- log_sys.log.open_file(get_log_file_path());
+ log_sys.log.open_files(get_log_file_path());
log_sys.log.create();
@@ -1442,6 +1432,10 @@ file_checked:
recv_sys.dblwr.pages.clear();
+ if (err == DB_SUCCESS && !create_new_log) {
+ err = recv_sys.upgrade_file_format_to_10_6_if_needed();
+ }
+
if (err != DB_SUCCESS) {
return(srv_init_abort(err));
}
@@ -1593,7 +1587,7 @@ file_checked:
ut_ad(recv_no_log_write);
err = fil_write_flushed_lsn(log_sys.get_lsn());
DBUG_ASSERT(!buf_pool.any_io_pending());
- log_sys.log.close_file();
+ log_sys.log.close_files();
if (err == DB_SUCCESS) {
bool trunc = srv_operation
== SRV_OPERATION_RESTORE;
@@ -1652,8 +1646,9 @@ file_checked:
return(srv_init_abort(err));
}
- /* Close the redo log file, so that we can replace it */
- log_sys.log.close_file();
+ /* Close the redo log files, so that we can
+ replace it */
+ log_sys.log.close_files();
DBUG_EXECUTE_IF("innodb_log_abort_5",
return(srv_init_abort(DB_ERROR)););