mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-12353: Remove support for crash-upgrade
We tighten some assertions regarding dict_index_t::is_dummy and crash recovery, now that redo log processing will no longer create dummy objects.
This commit is contained in:
parent
7ae21b18a6
commit
f8a9f90667
37 changed files with 298 additions and 5224 deletions
|
@ -2649,12 +2649,8 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
|
|||
}
|
||||
}
|
||||
|
||||
store_t store = STORE_NO;
|
||||
|
||||
if (more_data && recv_parse_log_recs(0, &store, false)) {
|
||||
|
||||
if (more_data && recv_sys.parse(0, STORE_NO, false)) {
|
||||
msg("Error: copying the log failed");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\./ in mysqld.1.err
|
||||
# same, but with current-version header
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
@ -64,7 +64,6 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 2 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
|
||||
FOUND 2 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
|
||||
# --innodb-force-recovery=6 (skip the entire redo log)
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=6
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
@ -93,12 +92,7 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
|||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Starting crash recovery from checkpoint LSN=1213964/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: MLOG_FILE_NAME incorrect:bogus/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: ############### CORRUPT LOG RECORD FOUND ##################/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Log record type 55, page 151:488\. Log parsing proceeded successfully up to 1213973\. Previous log record type 56, is multi 0 Recv offset 9, prev 0/ in mysqld.1.err
|
||||
FOUND 1 /len 22. hex 38000000000012860cb7809781e80006626f67757300. asc 8 bogus / in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Set innodb_force_recovery to ignore this error/ in mysqld.1.err
|
||||
FOUND 1 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err
|
||||
# Test a corrupted MLOG_FILE_NAME record.
|
||||
# valid header, invalid checkpoint 1, valid checkpoint 2, invalid block
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
|
@ -107,28 +101,28 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 2454333373 found: 150151/ in mysqld.1.err
|
||||
FOUND 3 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1, and it appears corrupted\./ in mysqld.1.err
|
||||
# valid header, invalid checkpoint 1, valid checkpoint 2, invalid log record
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: MLOG_FILE_NAME incorrect:bigot/ in mysqld.1.err
|
||||
FOUND 1 /len 22; hex 38000000000012860cb7809781e800066269676f7400; asc 8 bigot ;/ in mysqld.1.err
|
||||
FOUND 2 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err
|
||||
# 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
|
||||
FOUND 1 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with ibbackup was here!!!1!\./ in mysqld.1.err
|
||||
# 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 2 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
|
||||
FOUND 3 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err
|
||||
# Empty 10.3 redo log
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5 --innodb-log-file-size=2m
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
@ -136,7 +130,7 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
COUNT(*)
|
||||
1
|
||||
FOUND 1 /InnoDB: .* started; log sequence number 12139[78]\d; transaction id 0/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: .* started; log sequence number 1213964; transaction id 0/ in mysqld.1.err
|
||||
# Empty 10.2 redo log
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5 --innodb-log-file-size=2m
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
|
|
@ -56,7 +56,7 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\./ in mysqld.1.err
|
||||
# same, but with current-version header
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
@ -64,7 +64,6 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 2 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122/ in mysqld.1.err
|
||||
FOUND 2 /InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\./ in mysqld.1.err
|
||||
# --innodb-force-recovery=6 (skip the entire redo log)
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=6
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
@ -93,12 +92,7 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
|||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Starting crash recovery from checkpoint LSN=1213964/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: MLOG_FILE_NAME incorrect:bogus/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: ############### CORRUPT LOG RECORD FOUND ##################/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Log record type 55, page 151:488\. Log parsing proceeded successfully up to 1213973\. Previous log record type 56, is multi 0 Recv offset 9, prev 0/ in mysqld.1.err
|
||||
FOUND 1 /len 22. hex 38000000000012860cb7809781e80006626f67757300. asc 8 bogus / in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Set innodb_force_recovery to ignore this error/ in mysqld.1.err
|
||||
FOUND 1 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err
|
||||
# Test a corrupted MLOG_FILE_NAME record.
|
||||
# valid header, invalid checkpoint 1, valid checkpoint 2, invalid block
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
|
@ -107,28 +101,28 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 2454333373 found: 150151/ in mysqld.1.err
|
||||
FOUND 3 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1, and it appears corrupted\./ in mysqld.1.err
|
||||
# valid header, invalid checkpoint 1, valid checkpoint 2, invalid log record
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: MLOG_FILE_NAME incorrect:bigot/ in mysqld.1.err
|
||||
FOUND 1 /len 22; hex 38000000000012860cb7809781e800066269676f7400; asc 8 bigot ;/ in mysqld.1.err
|
||||
FOUND 2 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err
|
||||
# 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
|
||||
FOUND 1 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with ibbackup was here!!!1!\./ in mysqld.1.err
|
||||
# 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 2 /InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42/ in mysqld.1.err
|
||||
FOUND 3 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err
|
||||
# Empty 10.3 redo log
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5 --innodb-log-file-size=2m
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
@ -136,7 +130,7 @@ WHERE engine = 'innodb'
|
|||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
COUNT(*)
|
||||
1
|
||||
FOUND 1 /InnoDB: .* started; log sequence number 12139[78]\d; transaction id 0/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: .* started; log sequence number 1213964; transaction id 0/ in mysqld.1.err
|
||||
# Empty 10.2 redo log
|
||||
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5 --innodb-log-file-size=2m
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
|
||||
|
|
|
@ -230,7 +230,7 @@ eval $check_no_innodb;
|
|||
--source include/shutdown_mysqld.inc
|
||||
let SEARCH_PATTERN=InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\.;
|
||||
let SEARCH_PATTERN=InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # same, but with current-version header
|
||||
|
@ -247,8 +247,6 @@ eval $check_no_innodb;
|
|||
|
||||
let SEARCH_PATTERN=InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 3362026715 found: 144444122;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=InnoDB: Missing MLOG_CHECKPOINT between the checkpoint 1213964 and the end 1213952\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
--echo # --innodb-force-recovery=6 (skip the entire redo log)
|
||||
--let $restart_parameters= $dirs --innodb-force-recovery=6
|
||||
--source include/start_mysqld.inc
|
||||
|
@ -302,17 +300,7 @@ EOF
|
|||
--source include/start_mysqld.inc
|
||||
eval $check_no_innodb;
|
||||
--source include/shutdown_mysqld.inc
|
||||
let SEARCH_PATTERN=InnoDB: Starting crash recovery from checkpoint LSN=1213964;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=InnoDB: MLOG_FILE_NAME incorrect:bogus;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=InnoDB: ############### CORRUPT LOG RECORD FOUND ##################;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=InnoDB: Log record type 55, page 151:488\. Log parsing proceeded successfully up to 1213973\. Previous log record type 56, is multi 0 Recv offset 9, prev 0;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN= len 22. hex 38000000000012860cb7809781e80006626f67757300. asc 8 bogus ;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=InnoDB: Set innodb_force_recovery to ignore this error;
|
||||
let SEARCH_PATTERN=\\[ERROR\\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # Test a corrupted MLOG_FILE_NAME record.
|
||||
|
@ -343,6 +331,8 @@ eval $check_no_innodb;
|
|||
--source include/shutdown_mysqld.inc
|
||||
let SEARCH_PATTERN=InnoDB: Invalid log block checksum. block: 2372 checkpoint no: 1 expected: 2454333373 found: 150151;
|
||||
--source include/search_pattern_in_file.inc
|
||||
let SEARCH_PATTERN=\\[ERROR\\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1, and it appears corrupted\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
--echo # valid header, invalid checkpoint 1, valid checkpoint 2, invalid log record
|
||||
perl;
|
||||
die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
|
||||
|
@ -355,9 +345,7 @@ EOF
|
|||
--source include/start_mysqld.inc
|
||||
eval $check_no_innodb;
|
||||
--source include/shutdown_mysqld.inc
|
||||
let SEARCH_PATTERN=InnoDB: MLOG_FILE_NAME incorrect:bigot;
|
||||
--source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN= len 22; hex 38000000000012860cb7809781e800066269676f7400; asc 8 bigot ;
|
||||
let SEARCH_PATTERN=\\[ERROR\\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
|
||||
|
@ -388,7 +376,7 @@ EOF
|
|||
--source include/start_mysqld.inc
|
||||
eval $check_no_innodb;
|
||||
--source include/shutdown_mysqld.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42
|
||||
let SEARCH_PATTERN=\\[ERROR\\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with ibbackup was here!!!1!\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT
|
||||
|
@ -403,7 +391,7 @@ EOF
|
|||
--source include/start_mysqld.inc
|
||||
eval $check_no_innodb;
|
||||
--source include/shutdown_mysqld.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT for tablespace 42
|
||||
let SEARCH_PATTERN=\\[ERROR\\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\.;
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # Empty 10.3 redo log
|
||||
|
@ -421,11 +409,7 @@ SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
|
|||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
--source include/shutdown_mysqld.inc
|
||||
# In encryption.innodb_encrypt_log_corruption, we would convert the
|
||||
# log to encrypted format. Writing an extra log checkpoint before the
|
||||
# redo log conversion would advance the LSN by the size of a
|
||||
# FILE_CHECKPOINT record (12 bytes).
|
||||
--let SEARCH_PATTERN= InnoDB: .* started; log sequence number 12139[78]\d; transaction id 0
|
||||
--let SEARCH_PATTERN= InnoDB: .* started; log sequence number 1213964; transaction id 0
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # Empty 10.2 redo log
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 2019, MariaDB Corporation.
|
||||
# Copyright (c) 2014, 2020, MariaDB Corporation.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -84,9 +84,7 @@ SET(INNOBASE_SOURCES
|
|||
log/log0log.cc
|
||||
log/log0recv.cc
|
||||
log/log0crypt.cc
|
||||
mach/mach0data.cc
|
||||
mem/mem0mem.cc
|
||||
mtr/mtr0log.cc
|
||||
mtr/mtr0mtr.cc
|
||||
os/os0file.cc
|
||||
os/os0proc.cc
|
||||
|
|
|
@ -1376,11 +1376,9 @@ btr_write_autoinc(dict_index_t* index, ib_uint64_t autoinc, bool reset)
|
|||
}
|
||||
|
||||
/** Reorganize an index page.
|
||||
@tparam recovery whether this is invoked by btr_parse_page_reorganize()
|
||||
@param cursor index page cursor
|
||||
@param index the index that the cursor belongs to
|
||||
@param mtr mini-transaction */
|
||||
template<bool recovery= false>
|
||||
static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
|
||||
mtr_t *mtr)
|
||||
{
|
||||
|
@ -1413,9 +1411,7 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
|
|||
memcpy_aligned<UNIV_PAGE_SIZE_MIN>(temp_block->frame, block->frame,
|
||||
srv_page_size);
|
||||
|
||||
if (!recovery) {
|
||||
btr_search_drop_page_hash_index(block);
|
||||
}
|
||||
btr_search_drop_page_hash_index(block);
|
||||
|
||||
/* Save the cursor position. */
|
||||
pos = page_rec_get_n_recs_before(page_cur_get_rec(cursor));
|
||||
|
@ -1447,9 +1443,9 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
|
|||
if (trx_id_t trx_id = page_get_max_trx_id(temp_block->frame)) {
|
||||
/* PAGE_MAX_TRX_ID must be zero on non-leaf pages other than
|
||||
clustered index root pages. */
|
||||
ut_ad(recovery || (dict_index_is_sec_or_ibuf(index)
|
||||
? page_is_leaf(temp_block->frame)
|
||||
: block->page.id.page_no() == index->page));
|
||||
ut_ad(dict_index_is_sec_or_ibuf(index)
|
||||
? page_is_leaf(temp_block->frame)
|
||||
: block->page.id.page_no() == index->page);
|
||||
page_set_max_trx_id(block, NULL, trx_id, mtr);
|
||||
} else {
|
||||
/* PAGE_MAX_TRX_ID is unused in clustered index pages
|
||||
|
@ -1458,7 +1454,7 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
|
|||
It was always zero-initialized in page_create().
|
||||
PAGE_MAX_TRX_ID must be nonzero on
|
||||
dict_index_is_sec_or_ibuf() leaf pages. */
|
||||
ut_ad(recovery || index->table->is_temporary()
|
||||
ut_ad(index->table->is_temporary()
|
||||
|| !page_is_leaf(temp_block->frame)
|
||||
|| !dict_index_is_sec_or_ibuf(index));
|
||||
}
|
||||
|
@ -1482,46 +1478,44 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
|
|||
ut_ad(cursor->rec == page_get_infimum_rec(block->frame));
|
||||
}
|
||||
|
||||
if (!recovery) {
|
||||
if (block->page.id.page_no() == index->page
|
||||
&& fil_page_get_type(temp_block->frame)
|
||||
== FIL_PAGE_TYPE_INSTANT) {
|
||||
/* Preserve the PAGE_INSTANT information. */
|
||||
ut_ad(index->is_instant());
|
||||
static_assert(!(FIL_PAGE_TYPE % 2), "alignment");
|
||||
memcpy_aligned<2>(FIL_PAGE_TYPE + block->frame,
|
||||
FIL_PAGE_TYPE + temp_block->frame, 2);
|
||||
static_assert(!((PAGE_HEADER+PAGE_INSTANT) % 2), "");
|
||||
memcpy_aligned<2>(PAGE_HEADER + PAGE_INSTANT
|
||||
+ block->frame,
|
||||
PAGE_HEADER + PAGE_INSTANT
|
||||
+ temp_block->frame, 2);
|
||||
if (!index->table->instant) {
|
||||
} else if (page_is_comp(block->frame)) {
|
||||
memcpy(PAGE_NEW_INFIMUM + block->frame,
|
||||
PAGE_NEW_INFIMUM + temp_block->frame, 8);
|
||||
memcpy(PAGE_NEW_SUPREMUM + block->frame,
|
||||
PAGE_NEW_SUPREMUM + temp_block->frame, 8);
|
||||
} else {
|
||||
memcpy(PAGE_OLD_INFIMUM + block->frame,
|
||||
PAGE_OLD_INFIMUM + temp_block->frame, 8);
|
||||
memcpy(PAGE_OLD_SUPREMUM + block->frame,
|
||||
PAGE_OLD_SUPREMUM + temp_block->frame, 8);
|
||||
}
|
||||
if (block->page.id.page_no() == index->page
|
||||
&& fil_page_get_type(temp_block->frame)
|
||||
== FIL_PAGE_TYPE_INSTANT) {
|
||||
/* Preserve the PAGE_INSTANT information. */
|
||||
ut_ad(index->is_instant());
|
||||
static_assert(!(FIL_PAGE_TYPE % 2), "alignment");
|
||||
memcpy_aligned<2>(FIL_PAGE_TYPE + block->frame,
|
||||
FIL_PAGE_TYPE + temp_block->frame, 2);
|
||||
static_assert(!((PAGE_HEADER+PAGE_INSTANT) % 2), "");
|
||||
memcpy_aligned<2>(PAGE_HEADER + PAGE_INSTANT
|
||||
+ block->frame,
|
||||
PAGE_HEADER + PAGE_INSTANT
|
||||
+ temp_block->frame, 2);
|
||||
if (!index->table->instant) {
|
||||
} else if (page_is_comp(block->frame)) {
|
||||
memcpy(PAGE_NEW_INFIMUM + block->frame,
|
||||
PAGE_NEW_INFIMUM + temp_block->frame, 8);
|
||||
memcpy(PAGE_NEW_SUPREMUM + block->frame,
|
||||
PAGE_NEW_SUPREMUM + temp_block->frame, 8);
|
||||
} else {
|
||||
memcpy(PAGE_OLD_INFIMUM + block->frame,
|
||||
PAGE_OLD_INFIMUM + temp_block->frame, 8);
|
||||
memcpy(PAGE_OLD_SUPREMUM + block->frame,
|
||||
PAGE_OLD_SUPREMUM + temp_block->frame, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dict_table_is_locking_disabled(index->table)) {
|
||||
/* Update the record lock bitmaps */
|
||||
lock_move_reorganize_page(block, temp_block);
|
||||
}
|
||||
if (!dict_table_is_locking_disabled(index->table)) {
|
||||
/* Update the record lock bitmaps */
|
||||
lock_move_reorganize_page(block, temp_block);
|
||||
}
|
||||
|
||||
buf_block_free(temp_block);
|
||||
|
||||
MONITOR_INC(MONITOR_INDEX_REORG_SUCCESSFUL);
|
||||
|
||||
if (!recovery && UNIV_UNLIKELY(fil_page_get_type(block->frame)
|
||||
== FIL_PAGE_TYPE_INSTANT)) {
|
||||
if (UNIV_UNLIKELY(fil_page_get_type(block->frame)
|
||||
== FIL_PAGE_TYPE_INSTANT)) {
|
||||
/* Log the PAGE_INSTANT information. */
|
||||
ut_ad(index->is_instant());
|
||||
mtr->write<2,mtr_t::FORCED>(*block, FIL_PAGE_TYPE
|
||||
|
@ -1610,54 +1604,6 @@ btr_page_reorganize(
|
|||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a redo log record of reorganizing a page.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_parse_page_reorganize(
|
||||
/*======================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
bool compressed,/*!< in: true if compressed page */
|
||||
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
|
||||
mtr_t* mtr) /*!< in: mtr or NULL */
|
||||
{
|
||||
ulint level = page_zip_level;
|
||||
|
||||
ut_ad(ptr != NULL);
|
||||
ut_ad(end_ptr != NULL);
|
||||
ut_ad(index != NULL);
|
||||
|
||||
/* If dealing with a compressed page the record has the
|
||||
compression level used during original compression written in
|
||||
one byte. Otherwise record is empty. */
|
||||
if (compressed) {
|
||||
if (ptr == end_ptr) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
level = mach_read_from_1(ptr);
|
||||
|
||||
ut_a(level <= 9);
|
||||
++ptr;
|
||||
} else {
|
||||
level = page_zip_level;
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
} else if (block->page.zip.data) {
|
||||
page_zip_reorganize(block, index, level, mtr, true);
|
||||
} else {
|
||||
page_cur_t cur;
|
||||
page_cur_set_before_first(block, &cur);
|
||||
btr_page_reorganize_low<true>(&cur, index, mtr);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/** Empty an index page (possibly the root page). @see btr_page_create().
|
||||
@param[in,out] block page to be emptied
|
||||
@param[in,out] page_zip compressed page frame, or NULL
|
||||
|
@ -3196,38 +3142,6 @@ void btr_level_list_remove(const buf_block_t& block, const dict_index_t& index,
|
|||
}
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Parses the redo log record for setting an index record as the predefined
|
||||
minimum record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_parse_set_min_rec_mark(
|
||||
/*=======================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
ulint comp, /*!< in: nonzero=compact page format */
|
||||
buf_block_t* block, /*!< in: page or NULL */
|
||||
mtr_t* mtr) /*!< in: mtr or NULL */
|
||||
{
|
||||
rec_t* rec;
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (block) {
|
||||
ut_a(!page_is_comp(block->frame) == !comp);
|
||||
|
||||
rec = block->frame + mach_read_from_2(ptr);
|
||||
|
||||
btr_set_min_rec_mark(rec, *block, mtr);
|
||||
}
|
||||
|
||||
return(ptr + 2);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
If page is the only on its level, this function moves its records to the
|
||||
father page, thus reducing the tree height.
|
||||
|
|
|
@ -3988,313 +3988,6 @@ static void btr_cur_upd_rec_sys(buf_block_t *block, rec_t *rec,
|
|||
mtr->memcpy<mtr_t::OPT>(*block, dest, sys + d, len);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Parses the log data of system field values.
|
||||
@return log data end or NULL */
|
||||
static
|
||||
byte*
|
||||
row_upd_parse_sys_vals(
|
||||
/*===================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
ulint* pos, /*!< out: TRX_ID position in record */
|
||||
trx_id_t* trx_id, /*!< out: trx id */
|
||||
roll_ptr_t* roll_ptr)/*!< out: roll ptr */
|
||||
{
|
||||
*pos = mach_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (end_ptr < ptr + DATA_ROLL_PTR_LEN) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
*roll_ptr = trx_read_roll_ptr(ptr);
|
||||
ptr += DATA_ROLL_PTR_LEN;
|
||||
|
||||
*trx_id = mach_u64_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
return(const_cast<byte*>(ptr));
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Sets the value of the ith field SQL null bit of an old-style record. */
|
||||
static
|
||||
void
|
||||
rec_set_nth_field_null_bit(
|
||||
/*=======================*/
|
||||
rec_t* rec, /*!< in: record */
|
||||
ulint i, /*!< in: ith field */
|
||||
ibool val) /*!< in: value to set */
|
||||
{
|
||||
ulint info;
|
||||
|
||||
if (rec_get_1byte_offs_flag(rec)) {
|
||||
|
||||
info = rec_1_get_field_end_info(rec, i);
|
||||
|
||||
if (val) {
|
||||
info = info | REC_1BYTE_SQL_NULL_MASK;
|
||||
} else {
|
||||
info = info & ~REC_1BYTE_SQL_NULL_MASK;
|
||||
}
|
||||
|
||||
rec_1_set_field_end_info(rec, i, info);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
info = rec_2_get_field_end_info(rec, i);
|
||||
|
||||
if (val) {
|
||||
info = info | REC_2BYTE_SQL_NULL_MASK;
|
||||
} else {
|
||||
info = info & ~REC_2BYTE_SQL_NULL_MASK;
|
||||
}
|
||||
|
||||
rec_2_set_field_end_info(rec, i, info);
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Sets an old-style record field to SQL null.
|
||||
The physical size of the field is not changed. */
|
||||
static
|
||||
void
|
||||
rec_set_nth_field_sql_null(
|
||||
/*=======================*/
|
||||
rec_t* rec, /*!< in: record */
|
||||
ulint n) /*!< in: index of the field */
|
||||
{
|
||||
ulint offset;
|
||||
|
||||
offset = rec_get_field_start_offs(rec, n);
|
||||
|
||||
data_write_sql_null(rec + offset, rec_get_nth_field_size(rec, n));
|
||||
|
||||
rec_set_nth_field_null_bit(rec, n, TRUE);
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
This is used to modify the value of an already existing field in a record.
|
||||
The previous value must have exactly the same size as the new value. If len
|
||||
is UNIV_SQL_NULL then the field is treated as an SQL null.
|
||||
For records in ROW_FORMAT=COMPACT (new-style records), len must not be
|
||||
UNIV_SQL_NULL unless the field already is SQL null. */
|
||||
static
|
||||
void
|
||||
rec_set_nth_field(
|
||||
/*==============*/
|
||||
rec_t* rec, /*!< in: record */
|
||||
const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||
ulint n, /*!< in: index number of the field */
|
||||
const void* data, /*!< in: pointer to the data
|
||||
if not SQL null */
|
||||
ulint len) /*!< in: length of the data or UNIV_SQL_NULL */
|
||||
{
|
||||
byte* data2;
|
||||
ulint len2;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||
ut_ad(!rec_offs_nth_default(offsets, n));
|
||||
|
||||
if (len == UNIV_SQL_NULL) {
|
||||
if (!rec_offs_nth_sql_null(offsets, n)) {
|
||||
ut_a(!rec_offs_comp(offsets));
|
||||
rec_set_nth_field_sql_null(rec, n);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data2 = (byte*)rec_get_nth_field(rec, offsets, n, &len2);
|
||||
if (len2 == UNIV_SQL_NULL) {
|
||||
ut_ad(!rec_offs_comp(offsets));
|
||||
rec_set_nth_field_null_bit(rec, n, FALSE);
|
||||
ut_ad(len == rec_get_nth_field_size(rec, n));
|
||||
} else {
|
||||
ut_ad(len2 == len);
|
||||
}
|
||||
|
||||
memcpy(data2, data, len);
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Replaces the new column values stored in the update vector to the
|
||||
record given. No field size changes are allowed. This function is
|
||||
usually invoked on a clustered index. The only use case for a
|
||||
secondary index is row_ins_sec_index_entry_by_modify() or its
|
||||
counterpart in ibuf_insert_to_index_page(). */
|
||||
static
|
||||
void
|
||||
row_upd_rec_in_place(
|
||||
/*=================*/
|
||||
buf_block_t* block, /*!< in/out: index page */
|
||||
rec_t* rec, /*!< in/out: record where replaced */
|
||||
dict_index_t* index, /*!< in: the index the record belongs to */
|
||||
const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||
const upd_t* update, /*!< in: update vector */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
const upd_field_t* upd_field;
|
||||
const dfield_t* new_val;
|
||||
ulint n_fields;
|
||||
ulint i;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||
ut_ad(!index->table->skip_alter_undo);
|
||||
|
||||
if (rec_offs_comp(offsets)) {
|
||||
#ifdef UNIV_DEBUG
|
||||
switch (rec_get_status(rec)) {
|
||||
case REC_STATUS_ORDINARY:
|
||||
break;
|
||||
case REC_STATUS_INSTANT:
|
||||
ut_ad(index->is_instant());
|
||||
break;
|
||||
case REC_STATUS_NODE_PTR:
|
||||
if (index->is_dummy
|
||||
&& fil_page_get_type(page_align(rec))
|
||||
== FIL_PAGE_RTREE) {
|
||||
/* The function rtr_update_mbr_field_in_place()
|
||||
is generating MLOG_COMP_REC_UPDATE_IN_PLACE
|
||||
and MLOG_REC_UPDATE_IN_PLACE records for
|
||||
node pointer pages. */
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case REC_STATUS_INFIMUM:
|
||||
case REC_STATUS_SUPREMUM:
|
||||
ut_ad(!"wrong record status in update");
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
rec_set_bit_field_1(rec, update->info_bits, REC_NEW_INFO_BITS,
|
||||
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
|
||||
} else {
|
||||
rec_set_bit_field_1(rec, update->info_bits, REC_OLD_INFO_BITS,
|
||||
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
|
||||
}
|
||||
|
||||
n_fields = upd_get_n_fields(update);
|
||||
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
upd_field = upd_get_nth_field(update, i);
|
||||
|
||||
/* No need to update virtual columns for non-virtual index */
|
||||
if (upd_fld_is_virtual_col(upd_field)
|
||||
&& !dict_index_has_virtual(index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_val = &(upd_field->new_val);
|
||||
ut_ad(!dfield_is_ext(new_val) ==
|
||||
!rec_offs_nth_extern(offsets, upd_field->field_no));
|
||||
|
||||
rec_set_nth_field(rec, offsets, upd_field->field_no,
|
||||
dfield_get_data(new_val),
|
||||
dfield_get_len(new_val));
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||
page_zip_write_rec(block, rec, index, offsets, 0, mtr);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a redo log record of updating a record in-place.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_cur_parse_update_in_place(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: page or NULL */
|
||||
dict_index_t* index, /*!< in: index corresponding to page */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint flags;
|
||||
upd_t* update;
|
||||
ulint pos;
|
||||
trx_id_t trx_id;
|
||||
roll_ptr_t roll_ptr;
|
||||
ulint rec_offset;
|
||||
mem_heap_t* heap;
|
||||
offset_t* offsets;
|
||||
|
||||
if (end_ptr < ptr + 1) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
flags = mach_read_from_1(ptr);
|
||||
ptr++;
|
||||
|
||||
ptr = row_upd_parse_sys_vals(ptr, end_ptr, &pos, &trx_id, &roll_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
rec_offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
ut_a(rec_offset <= srv_page_size);
|
||||
|
||||
heap = mem_heap_create(256);
|
||||
|
||||
ptr = row_upd_index_parse(ptr, end_ptr, heap, &update);
|
||||
|
||||
if (!ptr || !block) {
|
||||
func_exit:
|
||||
mem_heap_free(heap);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ut_a(!!page_is_comp(block->frame) == index->table->not_redundant());
|
||||
rec_t* rec = block->frame + rec_offset;
|
||||
|
||||
/* We do not need to reserve search latch, as the page is only
|
||||
being recovered, and there cannot be a hash index to it. */
|
||||
|
||||
/* The function rtr_update_mbr_field_in_place() is generating
|
||||
these records on node pointer pages; therefore we have to
|
||||
check if this is a leaf page. */
|
||||
|
||||
offsets = rec_get_offsets(rec, index, NULL,
|
||||
flags != (BTR_NO_UNDO_LOG_FLAG
|
||||
| BTR_NO_LOCKING_FLAG
|
||||
| BTR_KEEP_SYS_FLAG)
|
||||
|| page_is_leaf(block->frame),
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
if (flags & BTR_KEEP_SYS_FLAG) {
|
||||
} else if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||
page_zip_write_trx_id_and_roll_ptr(
|
||||
block, rec, offsets, pos, trx_id, roll_ptr, mtr);
|
||||
} else {
|
||||
ulint len;
|
||||
byte* field = rec_get_nth_field(rec, offsets, pos, &len);
|
||||
ut_ad(len == DATA_TRX_ID_LEN);
|
||||
compile_time_assert(DATA_TRX_ID + 1 == DATA_ROLL_PTR);
|
||||
trx_write_trx_id(field, trx_id);
|
||||
trx_write_roll_ptr(field + DATA_TRX_ID_LEN, roll_ptr);
|
||||
}
|
||||
|
||||
row_upd_rec_in_place(block, rec, index, offsets, update, mtr);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
See if there is enough place in the page modification log to log
|
||||
an update-in-place.
|
||||
|
@ -5607,134 +5300,6 @@ void btr_rec_set_deleted(buf_block_t *block, rec_t *rec, mtr_t *mtr)
|
|||
template void btr_rec_set_deleted<false>(buf_block_t *, rec_t *, mtr_t *);
|
||||
template void btr_rec_set_deleted<true>(buf_block_t *, rec_t *, mtr_t *);
|
||||
|
||||
/****************************************************************//**
|
||||
Parses the redo log record for delete marking or unmarking of a clustered
|
||||
index record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_cur_parse_del_mark_set_clust_rec(
|
||||
/*=================================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: page or NULL */
|
||||
dict_index_t* index, /*!< in: index corresponding to page */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint flags;
|
||||
ulint val;
|
||||
ulint pos;
|
||||
trx_id_t trx_id;
|
||||
roll_ptr_t roll_ptr;
|
||||
ulint offset;
|
||||
|
||||
ut_ad(!block
|
||||
|| !!page_is_comp(block->frame)
|
||||
== index->table->not_redundant());
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
flags = mach_read_from_1(ptr);
|
||||
ptr++;
|
||||
val = mach_read_from_1(ptr);
|
||||
ptr++;
|
||||
|
||||
ptr = row_upd_parse_sys_vals(ptr, end_ptr, &pos, &trx_id, &roll_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
ut_a(offset <= srv_page_size);
|
||||
|
||||
/* In delete-marked records, DB_TRX_ID must
|
||||
always refer to an existing undo log record. */
|
||||
ut_ad(trx_id || (flags & BTR_KEEP_SYS_FLAG));
|
||||
|
||||
if (block) {
|
||||
rec_t* rec = block->frame + offset;
|
||||
|
||||
/* We do not need to reserve search latch, as the page
|
||||
is only being recovered, and there cannot be a hash index to
|
||||
it. Besides, these fields are being updated in place
|
||||
and the adaptive hash index does not depend on them. */
|
||||
byte* b = rec - (page_is_comp(block->frame)
|
||||
? REC_NEW_INFO_BITS
|
||||
: REC_OLD_INFO_BITS);
|
||||
|
||||
if (val) {
|
||||
*b |= REC_INFO_DELETED_FLAG;
|
||||
} else {
|
||||
*b &= ~REC_INFO_DELETED_FLAG;
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||
page_zip_rec_set_deleted(block, rec, val, mtr);
|
||||
}
|
||||
|
||||
/* pos is the offset of DB_TRX_ID in the clustered index.
|
||||
Debug assertions may also access DB_ROLL_PTR at pos+1.
|
||||
Therefore, we must compute offsets for the first pos+2
|
||||
clustered index fields. */
|
||||
ut_ad(pos <= MAX_REF_PARTS);
|
||||
|
||||
offset_t offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
|
||||
rec_offs_init(offsets_);
|
||||
mem_heap_t* heap = NULL;
|
||||
|
||||
if (!(flags & BTR_KEEP_SYS_FLAG)) {
|
||||
offset_t* offsets = rec_get_offsets(rec, index,
|
||||
offsets_, true,
|
||||
pos + 2, &heap);
|
||||
if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||
page_zip_write_trx_id_and_roll_ptr(
|
||||
block, rec, offsets, pos, trx_id,
|
||||
roll_ptr, mtr);
|
||||
} else {
|
||||
ulint len;
|
||||
|
||||
byte* field = rec_get_nth_field(
|
||||
rec, offsets, pos, &len);
|
||||
ut_ad(len == DATA_TRX_ID_LEN);
|
||||
compile_time_assert(DATA_TRX_ID + 1
|
||||
== DATA_ROLL_PTR);
|
||||
trx_write_trx_id(field, trx_id);
|
||||
trx_write_roll_ptr(field + DATA_TRX_ID_LEN,
|
||||
roll_ptr);
|
||||
}
|
||||
} else {
|
||||
/* In delete-marked records, DB_TRX_ID must
|
||||
always refer to an existing undo log record. */
|
||||
ut_ad(memcmp(rec_get_nth_field(
|
||||
rec,
|
||||
rec_get_offsets(rec, index,
|
||||
offsets_, true,
|
||||
pos, &heap),
|
||||
pos, &offset),
|
||||
field_ref_zero, DATA_TRX_ID_LEN));
|
||||
ut_ad(offset == DATA_TRX_ID_LEN);
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Marks a clustered index record deleted. Writes an undo log record to
|
||||
undo log on this delete marking. Writes in the trx id field the id
|
||||
|
@ -5810,62 +5375,6 @@ btr_cur_del_mark_set_clust_rec(
|
|||
return(err);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Parses the redo log record for delete marking or unmarking of a secondary
|
||||
index record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_cur_parse_del_mark_set_sec_rec(
|
||||
/*===============================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: page or NULL */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint val;
|
||||
ulint offset;
|
||||
|
||||
if (end_ptr < ptr + 3) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
val = mach_read_from_1(ptr);
|
||||
ptr++;
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
ut_a(offset <= srv_page_size);
|
||||
|
||||
if (!block) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
rec_t* rec = block->frame + offset;
|
||||
|
||||
/* We do not need to reserve search latch, as the page
|
||||
is only being recovered, and there cannot be a hash index to
|
||||
it. Besides, the delete-mark flag is being updated in place
|
||||
and the adaptive hash index does not depend on it. */
|
||||
byte* b = rec - (page_is_comp(block->frame)
|
||||
? REC_NEW_INFO_BITS
|
||||
: REC_OLD_INFO_BITS);
|
||||
|
||||
if (val) {
|
||||
*b |= REC_INFO_DELETED_FLAG;
|
||||
} else {
|
||||
*b &= ~REC_INFO_DELETED_FLAG;
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||
page_zip_rec_set_deleted(block, rec, val, mtr);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*==================== B-TREE RECORD REMOVE =========================*/
|
||||
|
||||
/*************************************************************//**
|
||||
|
|
|
@ -242,8 +242,7 @@ too_small:
|
|||
ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1);
|
||||
page_no = new_block->page.id.page_no();
|
||||
/* We only do this in the debug build, to ensure that
|
||||
both the check in buf_flush_init_for_writing() and
|
||||
recv_parse_or_apply_log_rec_body() will see a valid
|
||||
the check in buf_flush_init_for_writing() will see a valid
|
||||
page type. The flushes of new_block are actually
|
||||
unnecessary here. */
|
||||
ut_d(mtr.write<2>(*new_block,
|
||||
|
|
|
@ -439,97 +439,6 @@ void fil_space_crypt_t::write_page0(buf_block_t* block, mtr_t* mtr)
|
|||
mtr->memcpy(*block, offset + MAGIC_SZ, b - start);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Parse a MLOG_FILE_WRITE_CRYPT_DATA log entry
|
||||
@param[in] ptr Log entry start
|
||||
@param[in] end_ptr Log entry end
|
||||
@param[in] block buffer block
|
||||
@return position on log buffer */
|
||||
UNIV_INTERN
|
||||
const byte*
|
||||
fil_parse_write_crypt_data(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
dberr_t* err)
|
||||
{
|
||||
/* check that redo log entry is complete */
|
||||
uint entry_size =
|
||||
4 + // size of space_id
|
||||
2 + // size of offset
|
||||
1 + // size of type
|
||||
1 + // size of iv-len
|
||||
4 + // size of min_key_version
|
||||
4 + // size of key_id
|
||||
1; // fil_encryption_t
|
||||
|
||||
*err = DB_SUCCESS;
|
||||
|
||||
if (ptr + entry_size > end_ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ulint space_id = mach_read_from_4(ptr);
|
||||
ptr += 4;
|
||||
// uint offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
uint type = mach_read_from_1(ptr);
|
||||
ptr += 1;
|
||||
uint len = mach_read_from_1(ptr);
|
||||
ptr += 1;
|
||||
|
||||
if ((type != CRYPT_SCHEME_1 && type != CRYPT_SCHEME_UNENCRYPTED)
|
||||
|| len != CRYPT_SCHEME_1_IV_LEN) {
|
||||
*err = DB_CORRUPTION;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint min_key_version = mach_read_from_4(ptr);
|
||||
ptr += 4;
|
||||
|
||||
uint key_id = mach_read_from_4(ptr);
|
||||
ptr += 4;
|
||||
|
||||
fil_encryption_t encryption = (fil_encryption_t)mach_read_from_1(ptr);
|
||||
ptr +=1;
|
||||
|
||||
if (ptr + len > end_ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mutex_enter(&fil_system.mutex);
|
||||
|
||||
fil_space_t* space = fil_space_get_by_id(space_id);
|
||||
|
||||
if (!space) {
|
||||
mutex_exit(&fil_system.mutex);
|
||||
return ptr + len;
|
||||
}
|
||||
|
||||
fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(
|
||||
encryption, key_id);
|
||||
|
||||
crypt_data->min_key_version = min_key_version;
|
||||
crypt_data->type = type;
|
||||
memcpy(crypt_data->iv, ptr, len);
|
||||
ptr += len;
|
||||
|
||||
if (space->crypt_data) {
|
||||
fil_space_merge_crypt_data(space->crypt_data, crypt_data);
|
||||
fil_space_destroy_crypt_data(&crypt_data);
|
||||
crypt_data = space->crypt_data;
|
||||
} else {
|
||||
space->crypt_data = crypt_data;
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system.mutex);
|
||||
|
||||
if (crypt_data->should_encrypt() && !crypt_data->is_key_found()) {
|
||||
*err = DB_DECRYPTION_FAILED;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/** Encrypt a buffer for non full checksum.
|
||||
@param[in,out] crypt_data Crypt data
|
||||
@param[in] space space_id
|
||||
|
|
|
@ -521,25 +521,6 @@ ibuf_max_size_update(
|
|||
mutex_exit(&ibuf_mutex);
|
||||
}
|
||||
|
||||
|
||||
/** Apply MLOG_IBUF_BITMAP_INIT when crash-upgrading */
|
||||
ATTRIBUTE_COLD void ibuf_bitmap_init_apply(buf_block_t* block)
|
||||
{
|
||||
page_t* page;
|
||||
ulint byte_offset;
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP);
|
||||
|
||||
/* Write all zeros to the bitmap */
|
||||
compile_time_assert(!(IBUF_BITS_PER_PAGE % 2));
|
||||
|
||||
byte_offset = UT_BITS_IN_BYTES(block->physical_size()
|
||||
* IBUF_BITS_PER_PAGE);
|
||||
|
||||
memset(page + IBUF_BITMAP, 0, byte_offset);
|
||||
}
|
||||
|
||||
# ifdef UNIV_DEBUG
|
||||
/** Gets the desired bits for a given page from a bitmap page.
|
||||
@param[in] page bitmap page
|
||||
|
|
|
@ -572,34 +572,6 @@ btr_discard_page(
|
|||
btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
|
||||
the root page */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
/****************************************************************//**
|
||||
Parses the redo log record for setting an index record as the predefined
|
||||
minimum record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
MY_ATTRIBUTE((nonnull(1,2), warn_unused_result))
|
||||
const byte*
|
||||
btr_parse_set_min_rec_mark(
|
||||
/*=======================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
ulint comp, /*!< in: nonzero=compact page format */
|
||||
buf_block_t* block, /*!< in: page or NULL */
|
||||
mtr_t* mtr); /*!< in: mtr or NULL */
|
||||
/***********************************************************//**
|
||||
Parses a redo log record of reorganizing a page.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_parse_page_reorganize(
|
||||
/*======================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
bool compressed,/*!< in: true if compressed page */
|
||||
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
|
||||
mtr_t* mtr) /*!< in: mtr or NULL */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
/**************************************************************//**
|
||||
Gets the number of pages in a B-tree.
|
||||
@return number of pages, or ULINT_UNDEFINED if the index is unavailable */
|
||||
|
|
|
@ -555,44 +555,6 @@ btr_cur_pessimistic_delete(
|
|||
@param[in,out] mtr mini-transaction */
|
||||
void btr_cur_node_ptr_delete(btr_cur_t* parent, mtr_t* mtr)
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
/***********************************************************//**
|
||||
Parses a redo log record of updating a record in-place.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_cur_parse_update_in_place(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: page or NULL */
|
||||
dict_index_t* index, /*!< in: index corresponding to page */
|
||||
mtr_t* mtr); /*!< in/out: mini-transaction */
|
||||
/****************************************************************//**
|
||||
Parses the redo log record for delete marking or unmarking of a clustered
|
||||
index record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_cur_parse_del_mark_set_clust_rec(
|
||||
/*=================================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: page or NULL */
|
||||
dict_index_t* index, /*!< in: index corresponding to page */
|
||||
mtr_t* mtr); /*!< in/out: mini-transaction */
|
||||
/****************************************************************//**
|
||||
Parses the redo log record for delete marking or unmarking of a secondary
|
||||
index record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
btr_cur_parse_del_mark_set_sec_rec(
|
||||
/*===============================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: page or NULL */
|
||||
mtr_t* mtr); /*!< in/out: mini-transaction */
|
||||
|
||||
/** Estimates the number of rows in a given index range.
|
||||
@param[in] index index
|
||||
@param[in] tuple1 range start, may also be empty tuple
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
|
||||
Copyright (c) 2015, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2015, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -291,20 +291,6 @@ void
|
|||
fil_space_destroy_crypt_data(
|
||||
fil_space_crypt_t **crypt_data);
|
||||
|
||||
/******************************************************************
|
||||
Parse a MLOG_FILE_WRITE_CRYPT_DATA log entry
|
||||
@param[in] ptr Log entry start
|
||||
@param[in] end_ptr Log entry end
|
||||
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
|
||||
@return position on log buffer */
|
||||
UNIV_INTERN
|
||||
const byte*
|
||||
fil_parse_write_crypt_data(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
dberr_t* err)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Amend encryption information from redo log.
|
||||
@param[in] space tablespace
|
||||
@param[in] data encryption metadata */
|
||||
|
|
|
@ -362,9 +362,6 @@ ibuf_merge_space(
|
|||
/*=============*/
|
||||
ulint space); /*!< in: space id */
|
||||
|
||||
/** Apply MLOG_IBUF_BITMAP_INIT when crash-upgrading */
|
||||
ATTRIBUTE_COLD void ibuf_bitmap_init_apply(buf_block_t* block);
|
||||
|
||||
/******************************************************************//**
|
||||
Looks if the insert buffer is empty.
|
||||
@return true if empty */
|
||||
|
|
|
@ -99,15 +99,6 @@ recv_sys.parse_start_lsn is non-zero.
|
|||
@return true if more data added */
|
||||
bool recv_sys_add_to_parsing_buf(const byte* log_block, lsn_t scanned_lsn);
|
||||
|
||||
/** Parse log records from a buffer and optionally store them to recv_sys.pages
|
||||
to wait merging to file pages.
|
||||
@param[in] checkpoint_lsn the LSN of the latest checkpoint
|
||||
@param[in] store whether to store page operations
|
||||
@param[in] apply whether to apply the records
|
||||
@return whether MLOG_CHECKPOINT or FILE_CHECKPOINT record
|
||||
was seen the first time, or corruption was noticed */
|
||||
bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t *store, bool apply);
|
||||
|
||||
/** Moves the parsing buffer data left to the buffer start */
|
||||
void recv_sys_justify_left_parsing_buf();
|
||||
|
||||
|
@ -276,7 +267,7 @@ struct recv_sys_t{
|
|||
the file system contents is detected
|
||||
during log scan or apply */
|
||||
lsn_t mlog_checkpoint_lsn;
|
||||
/*!< the LSN of a MLOG_CHECKPOINT
|
||||
/*!< the LSN of a FILE_CHECKPOINT
|
||||
record, or 0 if none was parsed */
|
||||
/** the time when progress was last reported */
|
||||
time_t progress_time;
|
||||
|
@ -328,27 +319,16 @@ public:
|
|||
/** whether all redo log in the current batch has been applied */
|
||||
bool after_apply= false;
|
||||
#endif
|
||||
/** Initialize the redo log recovery subsystem. */
|
||||
void create();
|
||||
/** Initialize the redo log recovery subsystem. */
|
||||
void create();
|
||||
|
||||
/** Free most recovery data structures. */
|
||||
void debug_free();
|
||||
/** Free most recovery data structures. */
|
||||
void debug_free();
|
||||
|
||||
/** Clean up after create() */
|
||||
void close();
|
||||
/** Clean up after create() */
|
||||
void close();
|
||||
|
||||
bool is_initialised() const { return buf_size != 0; }
|
||||
|
||||
/** Store a redo log record for applying.
|
||||
@param type record type
|
||||
@param page_id page identifier
|
||||
@param body record body
|
||||
@param rec_end end of record
|
||||
@param lsn start LSN of the mini-transaction
|
||||
@param end_lsn end LSN of the mini-transaction */
|
||||
inline void add(mlog_id_t type, const page_id_t page_id,
|
||||
const byte* body, const byte* rec_end, lsn_t lsn,
|
||||
lsn_t end_lsn);
|
||||
bool is_initialised() const { return buf_size != 0; }
|
||||
|
||||
/** Register a redo log snippet for a page.
|
||||
@param page_id page identifier
|
||||
|
@ -365,24 +345,23 @@ public:
|
|||
@param apply whether to apply file-level log records
|
||||
@return whether FILE_CHECKPOINT record was seen the first time,
|
||||
or corruption was noticed */
|
||||
inline bool parse(lsn_t checkpoint_lsn, store_t store, bool apply);
|
||||
bool parse(lsn_t checkpoint_lsn, store_t store, bool apply);
|
||||
|
||||
/** Clear a fully processed set of stored redo log records. */
|
||||
inline void clear();
|
||||
|
||||
/** Determine whether redo log recovery progress should be reported.
|
||||
@param[in] time the current time
|
||||
@return whether progress should be reported
|
||||
(the last report was at least 15 seconds ago) */
|
||||
bool report(time_t time)
|
||||
{
|
||||
if (time - progress_time < 15) {
|
||||
return false;
|
||||
}
|
||||
/** Determine whether redo log recovery progress should be reported.
|
||||
@param time the current time
|
||||
@return whether progress should be reported
|
||||
(the last report was at least 15 seconds ago) */
|
||||
bool report(time_t time)
|
||||
{
|
||||
if (time - progress_time < 15)
|
||||
return false;
|
||||
|
||||
progress_time = time;
|
||||
return true;
|
||||
}
|
||||
progress_time= time;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** The alloc() memory alignment, in bytes */
|
||||
static constexpr size_t ALIGNMENT= sizeof(size_t);
|
||||
|
@ -390,7 +369,7 @@ public:
|
|||
/** Allocate memory for log_rec_t
|
||||
@param len allocation size, in bytes
|
||||
@return pointer to len bytes of memory (never NULL) */
|
||||
inline void *alloc(size_t len, bool store_recv= false);
|
||||
inline void *alloc(size_t len);
|
||||
|
||||
/** Free a redo log snippet.
|
||||
@param data buffer returned by alloc() */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -251,25 +251,6 @@ mach_u64_read_much_compressed(
|
|||
/*==========================*/
|
||||
const byte* b) /*!< in: pointer to memory from where to read */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
/** Read a 32-bit integer in a compressed form.
|
||||
@param[in,out] ptr pointer to memory where to read;
|
||||
advanced by the number of bytes consumed, or set NULL if out of space
|
||||
@param[in] end_ptr end of the buffer
|
||||
@return unsigned value */
|
||||
ib_uint32_t
|
||||
mach_parse_compressed(
|
||||
const byte** ptr,
|
||||
const byte* end_ptr);
|
||||
/** Read a 64-bit integer in a compressed form.
|
||||
@param[in,out] ptr pointer to memory where to read;
|
||||
advanced by the number of bytes consumed, or set NULL if out of space
|
||||
@param[in] end_ptr end of the buffer
|
||||
@return unsigned value */
|
||||
UNIV_INLINE
|
||||
ib_uint64_t
|
||||
mach_u64_parse_compressed(
|
||||
const byte** ptr,
|
||||
const byte* end_ptr);
|
||||
|
||||
/*********************************************************//**
|
||||
Reads a double. It is stored in a little-endian format.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -546,38 +546,6 @@ mach_read_next_much_compressed(
|
|||
return(val);
|
||||
}
|
||||
|
||||
/** Read a 64-bit integer in a compressed form.
|
||||
@param[in,out] ptr pointer to memory where to read;
|
||||
advanced by the number of bytes consumed, or set NULL if out of space
|
||||
@param[in] end_ptr end of the buffer
|
||||
@return unsigned value */
|
||||
UNIV_INLINE
|
||||
ib_uint64_t
|
||||
mach_u64_parse_compressed(
|
||||
const byte** ptr,
|
||||
const byte* end_ptr)
|
||||
{
|
||||
ib_uint64_t val = 0;
|
||||
|
||||
if (end_ptr < *ptr + 5) {
|
||||
*ptr = NULL;
|
||||
return(val);
|
||||
}
|
||||
|
||||
val = mach_read_next_compressed(ptr);
|
||||
|
||||
if (end_ptr < *ptr + 4) {
|
||||
*ptr = NULL;
|
||||
return(val);
|
||||
}
|
||||
|
||||
val <<= 32;
|
||||
val |= mach_read_from_4(*ptr);
|
||||
*ptr += 4;
|
||||
|
||||
return(val);
|
||||
}
|
||||
|
||||
/*********************************************************//**
|
||||
Reads a double. It is stored in a little-endian format.
|
||||
@return double read */
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2018, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2019, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -17,21 +16,13 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
*****************************************************************************/
|
||||
|
||||
/**************************************************//**
|
||||
/**
|
||||
@file include/mtr0log.h
|
||||
Mini-transaction logging routines
|
||||
|
||||
Created 12/7/1995 Heikki Tuuri
|
||||
Mini-transaction log record encoding and decoding
|
||||
*******************************************************/
|
||||
|
||||
#ifndef mtr0log_h
|
||||
#define mtr0log_h
|
||||
|
||||
#pragma once
|
||||
#include "mtr0mtr.h"
|
||||
#include "dyn0buf.h"
|
||||
|
||||
// Forward declaration
|
||||
struct dict_index_t;
|
||||
|
||||
/** The minimum 2-byte integer (0b10xxxxxx xxxxxxxx) */
|
||||
constexpr uint32_t MIN_2BYTE= 1 << 7;
|
||||
|
@ -543,53 +534,3 @@ inline void mtr_t::page_create(const buf_block_t &block, bool comp)
|
|||
m_log.close(l);
|
||||
m_last_offset= FIL_PAGE_TYPE;
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Parses an initial log record written by mlog_write_initial_log_record_low().
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
mlog_parse_initial_log_record(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
mlog_id_t* type, /*!< out: log record type: MLOG_1BYTE, ... */
|
||||
ulint* space, /*!< out: space id */
|
||||
ulint* page_no);/*!< out: page number */
|
||||
/********************************************************//**
|
||||
Parses a log record written by mtr_t::write(), mtr_t::memset().
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
const byte*
|
||||
mlog_parse_nbytes(
|
||||
/*==============*/
|
||||
mlog_id_t type, /*!< in: log record type: MLOG_1BYTE, ... */
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
byte* page, /*!< in: page where to apply the log record,
|
||||
or NULL */
|
||||
void* page_zip);/*!< in/out: compressed page, or NULL */
|
||||
/********************************************************//**
|
||||
Parses a log record written by mtr_t::memcpy().
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
const byte*
|
||||
mlog_parse_string(
|
||||
/*==============*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
byte* page, /*!< in: page where to apply the log record,
|
||||
or NULL */
|
||||
void* page_zip);/*!< in/out: compressed page, or NULL */
|
||||
|
||||
/********************************************************//**
|
||||
Parses a log record written by mlog_open_and_write_index.
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
mlog_parse_index(
|
||||
/*=============*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
bool comp, /*!< in: TRUE=compact record format */
|
||||
dict_index_t** index); /*!< out, own: dummy index */
|
||||
|
||||
#endif /* mtr0log_h */
|
||||
|
|
|
@ -276,201 +276,6 @@ terminate the mini-transaction. */
|
|||
constexpr byte SIZE_OF_FILE_CHECKPOINT= 3/*type,page_id*/ + 8/*LSN*/ + 1;
|
||||
#endif
|
||||
|
||||
/** @name Log item types
|
||||
The log items are declared 'byte' so that the compiler can warn if val
|
||||
and type parameters are switched in a call to mlog_write. NOTE!
|
||||
For 1 - 8 bytes, the flag value must give the length also! @{ */
|
||||
enum mlog_id_t {
|
||||
/** if the mtr contains only one log record for one page,
|
||||
i.e., write_initial_log_record has been called only once,
|
||||
this flag is ORed to the type of that first log record */
|
||||
MLOG_SINGLE_REC_FLAG = 128,
|
||||
|
||||
/** one byte is written */
|
||||
MLOG_1BYTE = 1,
|
||||
|
||||
/** 2 bytes ... */
|
||||
MLOG_2BYTES = 2,
|
||||
|
||||
/** 4 bytes ... */
|
||||
MLOG_4BYTES = 4,
|
||||
|
||||
/** 8 bytes ... */
|
||||
MLOG_8BYTES = 8,
|
||||
|
||||
/** Record insert */
|
||||
MLOG_REC_INSERT = 9,
|
||||
|
||||
/** Mark clustered index record deleted */
|
||||
MLOG_REC_CLUST_DELETE_MARK = 10,
|
||||
|
||||
/** Mark secondary index record deleted */
|
||||
MLOG_REC_SEC_DELETE_MARK = 11,
|
||||
|
||||
/** update of a record, preserves record field sizes */
|
||||
MLOG_REC_UPDATE_IN_PLACE = 13,
|
||||
|
||||
/*!< Delete a record from a page */
|
||||
MLOG_REC_DELETE = 14,
|
||||
|
||||
/** Delete record list end on index page */
|
||||
MLOG_LIST_END_DELETE = 15,
|
||||
|
||||
/** Delete record list start on index page */
|
||||
MLOG_LIST_START_DELETE = 16,
|
||||
|
||||
/** Copy record list end to a new created index page */
|
||||
MLOG_LIST_END_COPY_CREATED = 17,
|
||||
|
||||
/** Reorganize an index page in ROW_FORMAT=REDUNDANT */
|
||||
MLOG_PAGE_REORGANIZE = 18,
|
||||
|
||||
/** Create an index page */
|
||||
MLOG_PAGE_CREATE = 19,
|
||||
|
||||
/** insert an undo log record */
|
||||
MLOG_UNDO_INSERT = 20,
|
||||
|
||||
/** erase an undo log page end (used in MariaDB 10.2) */
|
||||
MLOG_UNDO_ERASE_END = 21,
|
||||
|
||||
/** initialize a page in an undo log */
|
||||
MLOG_UNDO_INIT = 22,
|
||||
|
||||
/** reuse an insert undo log header (used in MariaDB 10.2) */
|
||||
MLOG_UNDO_HDR_REUSE = 24,
|
||||
|
||||
/** create an undo log header */
|
||||
MLOG_UNDO_HDR_CREATE = 25,
|
||||
|
||||
/** mark an index record as the predefined minimum record */
|
||||
MLOG_REC_MIN_MARK = 26,
|
||||
|
||||
/** initialize an ibuf bitmap page (used in MariaDB 10.2 and 10.3) */
|
||||
MLOG_IBUF_BITMAP_INIT = 27,
|
||||
|
||||
/** write a string to a page */
|
||||
MLOG_WRITE_STRING = 30,
|
||||
|
||||
/** If a single mtr writes several log records, this log
|
||||
record ends the sequence of these records */
|
||||
MLOG_MULTI_REC_END = 31,
|
||||
|
||||
/** dummy log record used to pad a log block full */
|
||||
MLOG_DUMMY_RECORD = 32,
|
||||
|
||||
/** log record about an .ibd file creation */
|
||||
//MLOG_FILE_CREATE = 33,
|
||||
|
||||
/** rename databasename/tablename (no .ibd file name suffix) */
|
||||
//MLOG_FILE_RENAME = 34,
|
||||
|
||||
/** delete a tablespace file that starts with (space_id,page_no) */
|
||||
MLOG_FILE_DELETE = 35,
|
||||
|
||||
/** mark a compact index record as the predefined minimum record */
|
||||
MLOG_COMP_REC_MIN_MARK = 36,
|
||||
|
||||
/** create a compact index page */
|
||||
MLOG_COMP_PAGE_CREATE = 37,
|
||||
|
||||
/** compact record insert */
|
||||
MLOG_COMP_REC_INSERT = 38,
|
||||
|
||||
/** mark compact clustered index record deleted */
|
||||
MLOG_COMP_REC_CLUST_DELETE_MARK = 39,
|
||||
|
||||
/** update of a compact record, preserves record field sizes */
|
||||
MLOG_COMP_REC_UPDATE_IN_PLACE = 41,
|
||||
|
||||
/** delete a compact record from a page */
|
||||
MLOG_COMP_REC_DELETE = 42,
|
||||
|
||||
/** delete compact record list end on index page */
|
||||
MLOG_COMP_LIST_END_DELETE = 43,
|
||||
|
||||
/*** delete compact record list start on index page */
|
||||
MLOG_COMP_LIST_START_DELETE = 44,
|
||||
|
||||
/** copy compact record list end to a new created index page */
|
||||
MLOG_COMP_LIST_END_COPY_CREATED = 45,
|
||||
|
||||
/** reorganize an index page */
|
||||
MLOG_COMP_PAGE_REORGANIZE = 46,
|
||||
|
||||
/** log record about creating an .ibd file, with format */
|
||||
MLOG_FILE_CREATE2 = 47,
|
||||
|
||||
/** write the node pointer of a record on a compressed
|
||||
non-leaf B-tree page */
|
||||
MLOG_ZIP_WRITE_NODE_PTR = 48,
|
||||
|
||||
/** write the BLOB pointer of an externally stored column
|
||||
on a compressed page */
|
||||
MLOG_ZIP_WRITE_BLOB_PTR = 49,
|
||||
|
||||
/** write to compressed page header */
|
||||
MLOG_ZIP_WRITE_HEADER = 50,
|
||||
|
||||
/** compress an index page */
|
||||
MLOG_ZIP_PAGE_COMPRESS = 51,
|
||||
|
||||
/** compress an index page without logging it's image */
|
||||
MLOG_ZIP_PAGE_COMPRESS_NO_DATA = 52,
|
||||
|
||||
/** reorganize a compressed page */
|
||||
MLOG_ZIP_PAGE_REORGANIZE = 53,
|
||||
|
||||
/** rename a tablespace file that starts with (space_id,page_no) */
|
||||
MLOG_FILE_RENAME2 = 54,
|
||||
|
||||
/** note the first use of a tablespace file since checkpoint */
|
||||
MLOG_FILE_NAME = 55,
|
||||
|
||||
/** note that all buffered log was written since a checkpoint */
|
||||
MLOG_CHECKPOINT = 56,
|
||||
|
||||
/** Create a R-Tree index page */
|
||||
MLOG_PAGE_CREATE_RTREE = 57,
|
||||
|
||||
/** create a R-tree compact page */
|
||||
MLOG_COMP_PAGE_CREATE_RTREE = 58,
|
||||
|
||||
/** initialize a file page */
|
||||
MLOG_INIT_FILE_PAGE2 = 59,
|
||||
|
||||
/** Table is being truncated. (Was used in 10.2 and 10.3;
|
||||
not supported for crash-upgrade to 10.4 or later.) */
|
||||
MLOG_TRUNCATE = 60,
|
||||
|
||||
/** write DB_TRX_ID,DB_ROLL_PTR to a clustered index leaf page
|
||||
of a ROW_FORMAT=COMPRESSED table */
|
||||
MLOG_ZIP_WRITE_TRX_ID = 62,
|
||||
|
||||
/** initialize a page with a string of identical bytes */
|
||||
MLOG_MEMSET = 63,
|
||||
|
||||
/** Zero-fill a page that is not allocated. */
|
||||
MLOG_INIT_FREE_PAGE = 64,
|
||||
|
||||
/** biggest value (used in assertions) */
|
||||
MLOG_BIGGEST_TYPE = MLOG_INIT_FREE_PAGE,
|
||||
|
||||
/** log record for writing/updating crypt data of
|
||||
a tablespace */
|
||||
MLOG_FILE_WRITE_CRYPT_DATA = 100,
|
||||
};
|
||||
|
||||
/* @} */
|
||||
|
||||
#define EXTRA_CHECK_MLOG_NUMBER(x) \
|
||||
((x) == MLOG_FILE_WRITE_CRYPT_DATA)
|
||||
|
||||
/** Size of a MLOG_CHECKPOINT record in bytes.
|
||||
The record consists of a MLOG_CHECKPOINT byte followed by
|
||||
mach_write_to_8(checkpoint_lsn). */
|
||||
#define SIZE_OF_MLOG_CHECKPOINT 9
|
||||
|
||||
#ifndef UNIV_INNOCHECKSUM
|
||||
/** Types for the mlock objects to store in the mtr_t::m_memo */
|
||||
enum mtr_memo_type_t {
|
||||
|
|
|
@ -285,45 +285,6 @@ page_cur_open_on_rnd_user_rec(
|
|||
/*==========================*/
|
||||
buf_block_t* block, /*!< in: page */
|
||||
page_cur_t* cursor);/*!< out: page cursor */
|
||||
/***********************************************************//**
|
||||
Parses a log record of a record insert on a page.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_cur_parse_insert_rec(
|
||||
/*======================*/
|
||||
bool is_short,/*!< in: true if short inserts */
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in: page or NULL */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr); /*!< in: mtr or NULL */
|
||||
/**********************************************************//**
|
||||
Parses a log record of copying a record list end to a new created page.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_parse_copy_rec_list_to_created_page(
|
||||
/*=====================================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in: page or NULL */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr); /*!< in: mtr or NULL */
|
||||
/***********************************************************//**
|
||||
Parses log record of a record delete on a page.
|
||||
@return pointer to record end or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_cur_parse_delete_rec(
|
||||
/*======================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in: page or NULL */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction,
|
||||
or NULL if block=NULL */
|
||||
MY_ATTRIBUTE((warn_unused_result, nonnull(1,2,4)));
|
||||
|
||||
/** Index page cursor */
|
||||
|
||||
|
|
|
@ -1063,22 +1063,6 @@ page_move_rec_list_start(
|
|||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
MY_ATTRIBUTE((nonnull(1, 2, 4, 5)));
|
||||
/**********************************************************//**
|
||||
Parses a log record of a record list end or start deletion.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_parse_delete_rec_list(
|
||||
/*=======================*/
|
||||
mlog_id_t type, /*!< in: MLOG_LIST_END_DELETE,
|
||||
MLOG_LIST_START_DELETE,
|
||||
MLOG_COMP_LIST_END_DELETE or
|
||||
MLOG_COMP_LIST_START_DELETE */
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: buffer block or NULL */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr); /*!< in: mtr or NULL */
|
||||
/** Create an index page.
|
||||
@param[in,out] block buffer block
|
||||
@param[in] comp nonzero=compact page format */
|
||||
|
|
|
@ -243,18 +243,6 @@ void page_zip_write_rec(buf_block_t *block, const byte *rec,
|
|||
ulint create, mtr_t *mtr)
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a log record of writing a BLOB pointer of a record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_blob_ptr(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: redo log buffer */
|
||||
const byte* end_ptr,/*!< in: redo log buffer end */
|
||||
page_t* page, /*!< in/out: uncompressed page */
|
||||
page_zip_des_t* page_zip);/*!< in/out: compressed page */
|
||||
|
||||
/**********************************************************************//**
|
||||
Write a BLOB pointer of a record on the leaf page of a clustered index.
|
||||
The information must already have been updated on the uncompressed page. */
|
||||
|
@ -270,18 +258,6 @@ page_zip_write_blob_ptr(
|
|||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a log record of writing the node pointer of a record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_node_ptr(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: redo log buffer */
|
||||
const byte* end_ptr,/*!< in: redo log buffer end */
|
||||
page_t* page, /*!< in/out: uncompressed page */
|
||||
page_zip_des_t* page_zip);/*!< in/out: compressed page */
|
||||
|
||||
/**********************************************************************//**
|
||||
Write the node pointer of a record on a non-leaf compressed page. */
|
||||
void
|
||||
|
@ -313,22 +289,6 @@ page_zip_write_trx_id_and_roll_ptr(
|
|||
mtr_t* mtr)
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
||||
/** Parse a MLOG_ZIP_WRITE_TRX_ID record.
|
||||
@param[in] ptr redo log buffer
|
||||
@param[in] end_ptr end of redo log buffer
|
||||
@param[in,out] page uncompressed page
|
||||
@param[in,out] page_zip compressed page
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_trx_id(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
page_t* page,
|
||||
page_zip_des_t* page_zip)
|
||||
MY_ATTRIBUTE((nonnull(1,2), warn_unused_result));
|
||||
|
||||
/** Modify the delete-mark flag of a ROW_FORMAT=COMPRESSED record.
|
||||
@param[in,out] block buffer block
|
||||
@param[in,out] rec record on a physical index page
|
||||
|
@ -363,22 +323,10 @@ void page_zip_dir_delete(buf_block_t *block, byte *rec,
|
|||
const byte *free, mtr_t *mtr)
|
||||
MY_ATTRIBUTE((nonnull(1,2,3,4,6)));
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a log record of writing to the header of a page.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_header(
|
||||
/*========================*/
|
||||
const byte* ptr, /*!< in: redo log buffer */
|
||||
const byte* end_ptr,/*!< in: redo log buffer end */
|
||||
page_t* page, /*!< in/out: uncompressed page */
|
||||
page_zip_des_t* page_zip);/*!< in/out: compressed page */
|
||||
|
||||
/**********************************************************************//**
|
||||
Reorganize and compress a page. This is a low-level operation for
|
||||
compressed pages, to be used when page_zip_compress() fails.
|
||||
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
|
||||
On success, redo log will be written.
|
||||
The function btr_page_reorganize() should be preferred whenever possible.
|
||||
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
|
||||
non-clustered index, the caller must update the insert buffer free
|
||||
|
@ -410,17 +358,6 @@ page_zip_copy_recs(
|
|||
const page_t* src, /*!< in: page */
|
||||
dict_index_t* index, /*!< in: index of the B-tree */
|
||||
mtr_t* mtr); /*!< in: mini-transaction */
|
||||
|
||||
/** Parse and optionally apply MLOG_ZIP_PAGE_COMPRESS.
|
||||
@param[in] ptr log record
|
||||
@param[in] end_ptr end of log
|
||||
@param[in,out] block ROW_FORMAT=COMPRESSED block, or NULL for parsing only
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte* page_zip_parse_compress(const byte* ptr, const byte* end_ptr,
|
||||
buf_block_t* block);
|
||||
|
||||
#endif /* !UNIV_INNOCHECKSUM */
|
||||
|
||||
/** Calculate the compressed page checksum.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2019, MariaDB Corporation.
|
||||
Copyright (c) 2019, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -40,11 +40,12 @@ typedef unsigned short int offset_t;
|
|||
|
||||
/* Maximum number of user defined fields/columns. The reserved columns
|
||||
are the ones InnoDB adds internally: DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR.
|
||||
We need "* 2" because mlog_parse_index() creates a dummy table object
|
||||
possibly, with some of the system columns in it, and then adds the 3
|
||||
system columns (again) using dict_table_add_system_columns(). The problem
|
||||
is that mlog_parse_index() cannot recognize the system columns by
|
||||
just having n_fields, n_uniq and the lengths of the columns. */
|
||||
Before MariaDB Server 10.5, we needed "* 2" because mlog_parse_index()
|
||||
created a dummy table object possibly, with some of the system columns
|
||||
in it, and then adds the 3 system columns (again) using
|
||||
dict_table_add_system_columns().
|
||||
For now, we will keep this limitation to maintain file format compatibility
|
||||
with older versions. */
|
||||
#define REC_MAX_N_USER_FIELDS (REC_MAX_N_FIELDS - DATA_N_SYS_COLS * 2)
|
||||
|
||||
/* REC_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
|
||||
|
|
|
@ -316,19 +316,6 @@ que_thr_t*
|
|||
row_upd_step(
|
||||
/*=========*/
|
||||
que_thr_t* thr); /*!< in: query thread */
|
||||
/*********************************************************************//**
|
||||
Parses the log data written by row_upd_index_write_log.
|
||||
@return log data end or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
row_upd_index_parse(
|
||||
/*================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
mem_heap_t* heap, /*!< in: memory heap where update vector is
|
||||
built */
|
||||
upd_t** update_out);/*!< out: update vector */
|
||||
|
||||
|
||||
/* Update vector field */
|
||||
struct upd_field_t{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -240,19 +240,6 @@ trx_undo_prev_version_build(
|
|||
into this function by purge thread or not.
|
||||
And if we read "after image" of undo log */
|
||||
|
||||
/** Parse MLOG_UNDO_INSERT.
|
||||
@param[in] ptr log record
|
||||
@param[in] end_ptr end of log record buffer
|
||||
@param[in,out] page page or NULL
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_add_undo_rec(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
page_t* page);
|
||||
|
||||
/** Read from an undo log record a non-virtual column value.
|
||||
@param[in,out] ptr pointer to remaining part of the undo record
|
||||
@param[in,out] field stored field
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -250,41 +250,6 @@ trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp);
|
|||
void
|
||||
trx_undo_free_at_shutdown(trx_t *trx);
|
||||
|
||||
/** Parse MLOG_UNDO_INIT.
|
||||
@param[in] ptr log record
|
||||
@param[in] end_ptr end of log record buffer
|
||||
@param[in,out] page page or NULL
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_page_init(const byte* ptr, const byte* end_ptr, page_t* page);
|
||||
/** Parse MLOG_UNDO_HDR_REUSE for crash-upgrade from MariaDB 10.2.
|
||||
@param[in] ptr redo log record
|
||||
@param[in] end_ptr end of log buffer
|
||||
@param[in,out] page undo page or NULL
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_page_header_reuse(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
page_t* page);
|
||||
|
||||
/** Parse the redo log entry of an undo log page header create.
|
||||
@param[in] ptr redo log record
|
||||
@param[in] end_ptr end of log buffer
|
||||
@param[in,out] block page frame or NULL
|
||||
@param[in,out] mtr mini-transaction or NULL
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_page_header(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
buf_block_t* block,
|
||||
mtr_t* mtr);
|
||||
/** Read an undo log when starting up the database.
|
||||
@param[in,out] rseg rollback segment
|
||||
@param[in] id rollback segment slot
|
||||
|
|
|
@ -58,28 +58,9 @@ Created 12/9/1995 Heikki Tuuri
|
|||
/*
|
||||
General philosophy of InnoDB redo-logs:
|
||||
|
||||
1) Every change to a contents of a data page must be done
|
||||
through mtr, which in mtr_commit() writes log records
|
||||
to the InnoDB redo log.
|
||||
|
||||
2) Normally these changes are performed using a mlog_write()
|
||||
or similar function.
|
||||
|
||||
3) In some page level operations only a code number of a
|
||||
c-function and its parameters are written to the log to
|
||||
reduce the size of the log.
|
||||
|
||||
3a) You should not add parameters to these kind of functions
|
||||
(e.g. trx_undo_header_create())
|
||||
|
||||
3b) You should not add such functionality which either change
|
||||
working when compared with the old or are dependent on data
|
||||
outside of the page. These kind of functions should implement
|
||||
self-contained page transformation and it should be unchanged
|
||||
if you don't have very essential reasons to change log
|
||||
semantics or format.
|
||||
|
||||
*/
|
||||
Every change to a contents of a data page must be done
|
||||
through mtr_t, and mtr_t::commit() will write log records
|
||||
to the InnoDB redo log. */
|
||||
|
||||
/** Redo log system */
|
||||
log_t log_sys;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,129 +0,0 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************//**
|
||||
@file mach/mach0data.cc
|
||||
Utilities for converting data from the database file
|
||||
to the machine format.
|
||||
|
||||
Created 11/28/1995 Heikki Tuuri
|
||||
***********************************************************************/
|
||||
|
||||
#include "mach0data.h"
|
||||
|
||||
/** Read a 32-bit integer in a compressed form.
|
||||
@param[in,out] ptr pointer to memory where to read;
|
||||
advanced by the number of bytes consumed, or set NULL if out of space
|
||||
@param[in] end_ptr end of the buffer
|
||||
@return unsigned value */
|
||||
ib_uint32_t
|
||||
mach_parse_compressed(
|
||||
const byte** ptr,
|
||||
const byte* end_ptr)
|
||||
{
|
||||
ulint val;
|
||||
|
||||
if (*ptr >= end_ptr) {
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
val = mach_read_from_1(*ptr);
|
||||
|
||||
if (val < 0x80) {
|
||||
/* 0nnnnnnn (7 bits) */
|
||||
++*ptr;
|
||||
return(static_cast<ib_uint32_t>(val));
|
||||
}
|
||||
|
||||
/* Workaround GCC bug
|
||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
|
||||
the compiler moves mach_read_from_4 right to the beginning of the
|
||||
function, causing and out-of-bounds read if we are reading a short
|
||||
integer close to the end of buffer. */
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
|
||||
#define DEPLOY_FENCE
|
||||
#endif
|
||||
|
||||
#ifdef DEPLOY_FENCE
|
||||
__atomic_thread_fence(__ATOMIC_ACQUIRE);
|
||||
#endif
|
||||
|
||||
if (val < 0xC0) {
|
||||
/* 10nnnnnn nnnnnnnn (14 bits) */
|
||||
if (end_ptr >= *ptr + 2) {
|
||||
val = mach_read_from_2(*ptr) & 0x3FFF;
|
||||
ut_ad(val > 0x7F);
|
||||
*ptr += 2;
|
||||
return(static_cast<ib_uint32_t>(val));
|
||||
}
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef DEPLOY_FENCE
|
||||
__atomic_thread_fence(__ATOMIC_ACQUIRE);
|
||||
#endif
|
||||
|
||||
if (val < 0xE0) {
|
||||
/* 110nnnnn nnnnnnnn nnnnnnnn (21 bits) */
|
||||
if (end_ptr >= *ptr + 3) {
|
||||
val = mach_read_from_3(*ptr) & 0x1FFFFF;
|
||||
ut_ad(val > 0x3FFF);
|
||||
*ptr += 3;
|
||||
return(static_cast<ib_uint32_t>(val));
|
||||
}
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef DEPLOY_FENCE
|
||||
__atomic_thread_fence(__ATOMIC_ACQUIRE);
|
||||
#endif
|
||||
|
||||
if (val < 0xF0) {
|
||||
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
|
||||
if (end_ptr >= *ptr + 4) {
|
||||
val = mach_read_from_4(*ptr) & 0xFFFFFFF;
|
||||
ut_ad(val > 0x1FFFFF);
|
||||
*ptr += 4;
|
||||
return(static_cast<ib_uint32_t>(val));
|
||||
}
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef DEPLOY_FENCE
|
||||
__atomic_thread_fence(__ATOMIC_ACQUIRE);
|
||||
#endif
|
||||
|
||||
#undef DEPLOY_FENCE
|
||||
|
||||
ut_ad(val == 0xF0);
|
||||
|
||||
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
|
||||
if (end_ptr >= *ptr + 5) {
|
||||
val = mach_read_from_4(*ptr + 1);
|
||||
ut_ad(val > 0xFFFFFFF);
|
||||
*ptr += 5;
|
||||
return(static_cast<ib_uint32_t>(val));
|
||||
}
|
||||
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
|
@ -1,360 +0,0 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/**************************************************//**
|
||||
@file mtr/mtr0log.cc
|
||||
Mini-transaction log routines
|
||||
|
||||
Created 12/7/1995 Heikki Tuuri
|
||||
*******************************************************/
|
||||
|
||||
#include "mtr0log.h"
|
||||
#include "buf0buf.h"
|
||||
#include "dict0mem.h"
|
||||
#include "log0recv.h"
|
||||
#include "page0page.h"
|
||||
|
||||
/********************************************************//**
|
||||
Parses an initial log record written by mlog_write_initial_log_record_low().
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
mlog_parse_initial_log_record(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
mlog_id_t* type, /*!< out: log record type: MLOG_1BYTE, ... */
|
||||
ulint* space, /*!< out: space id */
|
||||
ulint* page_no)/*!< out: page number */
|
||||
{
|
||||
if (end_ptr < ptr + 1) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
*type = mlog_id_t(*ptr & ~MLOG_SINGLE_REC_FLAG);
|
||||
if (UNIV_UNLIKELY(*type > MLOG_BIGGEST_TYPE
|
||||
&& !EXTRA_CHECK_MLOG_NUMBER(*type))) {
|
||||
recv_sys.found_corrupt_log = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
*space = mach_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr != NULL) {
|
||||
*page_no = mach_parse_compressed(&ptr, end_ptr);
|
||||
}
|
||||
|
||||
return(const_cast<byte*>(ptr));
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Parses a log record written by mtr_t::write(), mtr_t::memset().
|
||||
@return parsed record end, NULL if not a complete record or a corrupt record */
|
||||
const byte*
|
||||
mlog_parse_nbytes(
|
||||
/*==============*/
|
||||
mlog_id_t type, /*!< in: log record type: MLOG_1BYTE, ... */
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
byte* page, /*!< in: page where to apply the log
|
||||
record, or NULL */
|
||||
void* page_zip)/*!< in/out: compressed page, or NULL */
|
||||
{
|
||||
ulint offset;
|
||||
ulint val;
|
||||
ib_uint64_t dval;
|
||||
|
||||
ut_ad(type <= MLOG_8BYTES || type == MLOG_MEMSET);
|
||||
ut_a(!page || !page_zip
|
||||
|| type == MLOG_MEMSET
|
||||
|| !fil_page_index_page_check(page));
|
||||
if (end_ptr < ptr + 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
if (UNIV_UNLIKELY(offset >= srv_page_size)) {
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MLOG_MEMSET:
|
||||
if (end_ptr < ptr + 3) {
|
||||
return NULL;
|
||||
}
|
||||
val = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
if (UNIV_UNLIKELY(offset + val > srv_page_size)) {
|
||||
goto corrupt;
|
||||
}
|
||||
if (page) {
|
||||
memset(page + offset, *ptr, val);
|
||||
if (page_zip) {
|
||||
ut_ad(offset + val <= PAGE_DATA
|
||||
|| !fil_page_index_page_check(page));
|
||||
memset(static_cast<page_zip_des_t*>(page_zip)
|
||||
->data + offset, *ptr, val);
|
||||
}
|
||||
}
|
||||
return const_cast<byte*>(++ptr);
|
||||
case MLOG_8BYTES:
|
||||
dval = mach_u64_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (page) {
|
||||
if (page_zip) {
|
||||
mach_write_to_8
|
||||
(((page_zip_des_t*) page_zip)->data
|
||||
+ offset, dval);
|
||||
}
|
||||
mach_write_to_8(page + offset, dval);
|
||||
}
|
||||
|
||||
return const_cast<byte*>(ptr);
|
||||
default:
|
||||
val = mach_parse_compressed(&ptr, end_ptr);
|
||||
}
|
||||
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MLOG_1BYTE:
|
||||
if (val > 0xFFUL) {
|
||||
goto corrupt;
|
||||
}
|
||||
if (page) {
|
||||
if (page_zip) {
|
||||
mach_write_to_1
|
||||
(((page_zip_des_t*) page_zip)->data
|
||||
+ offset, val);
|
||||
}
|
||||
mach_write_to_1(page + offset, val);
|
||||
}
|
||||
break;
|
||||
case MLOG_2BYTES:
|
||||
if (val > 0xFFFFUL) {
|
||||
goto corrupt;
|
||||
}
|
||||
if (page) {
|
||||
if (page_zip) {
|
||||
mach_write_to_2
|
||||
(((page_zip_des_t*) page_zip)->data
|
||||
+ offset, val);
|
||||
}
|
||||
mach_write_to_2(page + offset, val);
|
||||
}
|
||||
|
||||
break;
|
||||
case MLOG_4BYTES:
|
||||
if (page) {
|
||||
if (page_zip) {
|
||||
mach_write_to_4
|
||||
(((page_zip_des_t*) page_zip)->data
|
||||
+ offset, val);
|
||||
}
|
||||
mach_write_to_4(page + offset, val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
corrupt:
|
||||
recv_sys.found_corrupt_log = true;
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
return const_cast<byte*>(ptr);
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Parses a log record written by mtr_t::memcpy().
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
const byte*
|
||||
mlog_parse_string(
|
||||
/*==============*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
byte* page, /*!< in: page where to apply the log record,
|
||||
or NULL */
|
||||
void* page_zip)/*!< in/out: compressed page, or NULL */
|
||||
{
|
||||
ulint offset;
|
||||
ulint len;
|
||||
|
||||
ut_a(!page || !page_zip
|
||||
|| (fil_page_get_type(page) != FIL_PAGE_INDEX
|
||||
&& fil_page_get_type(page) != FIL_PAGE_RTREE));
|
||||
|
||||
if (end_ptr < ptr + 4) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
len = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
if (offset >= srv_page_size || len + offset > srv_page_size) {
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (end_ptr < ptr + len) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
if (page_zip) {
|
||||
memcpy(((page_zip_des_t*) page_zip)->data
|
||||
+ offset, ptr, len);
|
||||
}
|
||||
memcpy(page + offset, ptr, len);
|
||||
}
|
||||
|
||||
return(ptr + len);
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Parses a log record written by mlog_open_and_write_index.
|
||||
@return parsed record end, NULL if not a complete record */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
mlog_parse_index(
|
||||
/*=============*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
bool comp, /*!< in: TRUE=compact row format */
|
||||
dict_index_t** index) /*!< out, own: dummy index */
|
||||
{
|
||||
ulint i, n, n_uniq;
|
||||
dict_table_t* table;
|
||||
dict_index_t* ind;
|
||||
ulint n_core_fields = 0;
|
||||
|
||||
if (comp) {
|
||||
if (end_ptr < ptr + 4) {
|
||||
return(NULL);
|
||||
}
|
||||
n = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
if (n & 0x8000) { /* record after instant ADD COLUMN */
|
||||
n &= 0x7FFF;
|
||||
|
||||
n_core_fields = mach_read_from_2(ptr);
|
||||
|
||||
if (!n_core_fields || n_core_fields > n) {
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
ptr += 2;
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
n_uniq = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
ut_ad(n_uniq <= n);
|
||||
if (end_ptr < ptr + n * 2) {
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
n = n_uniq = 1;
|
||||
}
|
||||
table = dict_mem_table_create("LOG_DUMMY", NULL, n, 0,
|
||||
comp ? DICT_TF_COMPACT : 0, 0);
|
||||
ind = dict_mem_index_create(table, "LOG_DUMMY", 0, n);
|
||||
ind->n_uniq = (unsigned int) n_uniq;
|
||||
if (n_uniq != n) {
|
||||
ut_a(n_uniq + DATA_ROLL_PTR <= n);
|
||||
ind->type = DICT_CLUSTERED;
|
||||
}
|
||||
if (comp) {
|
||||
for (i = 0; i < n; i++) {
|
||||
ulint len = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
/* The high-order bit of len is the NOT NULL flag;
|
||||
the rest is 0 or 0x7fff for variable-length fields,
|
||||
and 1..0x7ffe for fixed-length fields. */
|
||||
dict_mem_table_add_col(
|
||||
table, NULL, NULL,
|
||||
((len + 1) & 0x7fff) <= 1
|
||||
? DATA_BINARY : DATA_FIXBINARY,
|
||||
len & 0x8000 ? DATA_NOT_NULL : 0,
|
||||
len & 0x7fff);
|
||||
|
||||
dict_index_add_col(ind, table,
|
||||
dict_table_get_nth_col(table, i),
|
||||
0);
|
||||
}
|
||||
dict_table_add_system_columns(table, table->heap);
|
||||
if (n_uniq != n) {
|
||||
/* Identify DB_TRX_ID and DB_ROLL_PTR in the index. */
|
||||
ut_a(DATA_TRX_ID_LEN
|
||||
== dict_index_get_nth_col(ind, DATA_TRX_ID - 1
|
||||
+ n_uniq)->len);
|
||||
ut_a(DATA_ROLL_PTR_LEN
|
||||
== dict_index_get_nth_col(ind, DATA_ROLL_PTR - 1
|
||||
+ n_uniq)->len);
|
||||
ind->fields[DATA_TRX_ID - 1 + n_uniq].col
|
||||
= &table->cols[n + DATA_TRX_ID];
|
||||
ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col
|
||||
= &table->cols[n + DATA_ROLL_PTR];
|
||||
}
|
||||
|
||||
ut_ad(table->n_cols == table->n_def);
|
||||
|
||||
if (n_core_fields) {
|
||||
for (i = n_core_fields; i < n; i++) {
|
||||
ind->fields[i].col->def_val.len
|
||||
= UNIV_SQL_NULL;
|
||||
}
|
||||
ind->n_core_fields = n_core_fields;
|
||||
ind->n_core_null_bytes = UT_BITS_IN_BYTES(
|
||||
ind->get_n_nullable(n_core_fields));
|
||||
} else {
|
||||
ind->n_core_null_bytes = UT_BITS_IN_BYTES(
|
||||
unsigned(ind->n_nullable));
|
||||
ind->n_core_fields = ind->n_fields;
|
||||
}
|
||||
}
|
||||
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
|
||||
ind->cached = TRUE;
|
||||
ut_d(ind->is_dummy = true);
|
||||
*index = ind;
|
||||
return(ptr);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -826,62 +826,6 @@ zip_reorganize:
|
|||
return(ret);
|
||||
}
|
||||
|
||||
/**********************************************************//**
|
||||
Parses a log record of a record list end or start deletion.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_parse_delete_rec_list(
|
||||
/*=======================*/
|
||||
mlog_id_t type, /*!< in: MLOG_LIST_END_DELETE,
|
||||
MLOG_LIST_START_DELETE,
|
||||
MLOG_COMP_LIST_END_DELETE or
|
||||
MLOG_COMP_LIST_START_DELETE */
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
buf_block_t* block, /*!< in/out: buffer block or NULL */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr or NULL */
|
||||
{
|
||||
page_t* page;
|
||||
ulint offset;
|
||||
|
||||
ut_ad(type == MLOG_LIST_END_DELETE
|
||||
|| type == MLOG_LIST_START_DELETE
|
||||
|| type == MLOG_COMP_LIST_END_DELETE
|
||||
|| type == MLOG_COMP_LIST_START_DELETE);
|
||||
|
||||
/* Read the record offset as a 2-byte ulint */
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
if (!block) {
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
|
||||
|
||||
if (type == MLOG_LIST_END_DELETE
|
||||
|| type == MLOG_COMP_LIST_END_DELETE) {
|
||||
page_delete_rec_list_end(page + offset, block, index,
|
||||
ULINT_UNDEFINED, ULINT_UNDEFINED,
|
||||
mtr);
|
||||
} else {
|
||||
page_delete_rec_list_start(page + offset, block, index, mtr);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Deletes records from a page from a given record onward, including that record.
|
||||
The infimum and supremum records are not deleted. */
|
||||
|
|
|
@ -3847,67 +3847,6 @@ void page_zip_write_rec(buf_block_t *block, const byte *rec,
|
|||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a log record of writing a BLOB pointer of a record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_blob_ptr(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: redo log buffer */
|
||||
const byte* end_ptr,/*!< in: redo log buffer end */
|
||||
page_t* page, /*!< in/out: uncompressed page */
|
||||
page_zip_des_t* page_zip)/*!< in/out: compressed page */
|
||||
{
|
||||
ulint offset;
|
||||
ulint z_offset;
|
||||
|
||||
ut_ad(ptr != NULL);
|
||||
ut_ad(end_ptr != NULL);
|
||||
ut_ad(!page == !page_zip);
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
(end_ptr < ptr + (2 + 2 + BTR_EXTERN_FIELD_REF_SIZE))) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
z_offset = mach_read_from_2(ptr + 2);
|
||||
|
||||
if (offset < PAGE_ZIP_START
|
||||
|| offset >= srv_page_size
|
||||
|| z_offset >= srv_page_size) {
|
||||
corrupt:
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
|
||||
if (!page_zip || !page_is_leaf(page)) {
|
||||
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
memcpy(page + offset,
|
||||
ptr + 4, BTR_EXTERN_FIELD_REF_SIZE);
|
||||
memcpy(page_zip->data + z_offset,
|
||||
ptr + 4, BTR_EXTERN_FIELD_REF_SIZE);
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
return(ptr + (2 + 2 + BTR_EXTERN_FIELD_REF_SIZE));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Write a BLOB pointer of a record on the leaf page of a clustered index.
|
||||
The information must already have been updated on the uncompressed page. */
|
||||
|
@ -3973,82 +3912,6 @@ page_zip_write_blob_ptr(
|
|||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a log record of writing the node pointer of a record.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_node_ptr(
|
||||
/*==========================*/
|
||||
const byte* ptr, /*!< in: redo log buffer */
|
||||
const byte* end_ptr,/*!< in: redo log buffer end */
|
||||
page_t* page, /*!< in/out: uncompressed page */
|
||||
page_zip_des_t* page_zip)/*!< in/out: compressed page */
|
||||
{
|
||||
ulint offset;
|
||||
ulint z_offset;
|
||||
|
||||
ut_ad(ptr != NULL);
|
||||
ut_ad(end_ptr!= NULL);
|
||||
ut_ad(!page == !page_zip);
|
||||
|
||||
if (UNIV_UNLIKELY(end_ptr < ptr + (2 + 2 + REC_NODE_PTR_SIZE))) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
offset = mach_read_from_2(ptr);
|
||||
z_offset = mach_read_from_2(ptr + 2);
|
||||
|
||||
if (offset < PAGE_ZIP_START
|
||||
|| offset >= srv_page_size
|
||||
|| z_offset >= srv_page_size) {
|
||||
corrupt:
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
byte* storage_end;
|
||||
byte* field;
|
||||
byte* storage;
|
||||
ulint heap_no;
|
||||
|
||||
if (!page_zip || page_is_leaf(page)) {
|
||||
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
field = page + offset;
|
||||
storage = page_zip->data + z_offset;
|
||||
|
||||
storage_end = page_zip_dir_start(page_zip);
|
||||
|
||||
heap_no = 1 + ulint(storage_end - storage) / REC_NODE_PTR_SIZE;
|
||||
|
||||
if (UNIV_UNLIKELY((storage_end - storage) % REC_NODE_PTR_SIZE)
|
||||
|| UNIV_UNLIKELY(heap_no < PAGE_HEAP_NO_USER_LOW)
|
||||
|| UNIV_UNLIKELY(heap_no >= page_dir_get_n_heap(page))) {
|
||||
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
memcpy(field, ptr + 4, REC_NODE_PTR_SIZE);
|
||||
memcpy(storage, ptr + 4, REC_NODE_PTR_SIZE);
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
return(ptr + (2 + 2 + REC_NODE_PTR_SIZE));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Write the node pointer of a record on a non-leaf compressed page. */
|
||||
void
|
||||
|
@ -4194,67 +4057,6 @@ write:
|
|||
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
|
||||
}
|
||||
|
||||
/** Parse a MLOG_ZIP_WRITE_TRX_ID record.
|
||||
@param[in] ptr redo log buffer
|
||||
@param[in] end_ptr end of redo log buffer
|
||||
@param[in,out] page uncompressed page
|
||||
@param[in,out] page_zip compressed page
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_trx_id(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
page_t* page,
|
||||
page_zip_des_t* page_zip)
|
||||
{
|
||||
const byte* const end = 2 + 2 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN
|
||||
+ ptr;
|
||||
|
||||
if (UNIV_UNLIKELY(end_ptr < end)) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
uint offset = mach_read_from_2(ptr);
|
||||
uint z_offset = mach_read_from_2(ptr + 2);
|
||||
|
||||
if (offset < PAGE_ZIP_START
|
||||
|| offset >= srv_page_size
|
||||
|| z_offset >= srv_page_size) {
|
||||
corrupt:
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
if (!page_zip || !page_is_leaf(page)) {
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
byte* field = page + offset;
|
||||
byte* storage = page_zip->data + z_offset;
|
||||
|
||||
if (storage >= page_zip_dir_start(page_zip)) {
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
memcpy(field, ptr + 4, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
|
||||
memcpy(storage, ptr + 4, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Clear an area on the uncompressed and compressed page.
|
||||
Do not clear the data payload, as that would grow the modification log. */
|
||||
|
@ -4589,69 +4391,10 @@ void page_zip_dir_delete(buf_block_t *block, byte *rec,
|
|||
page_zip_clear_rec(block, rec, index, offsets, mtr);
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Parses a log record of writing to the header of a page.
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte*
|
||||
page_zip_parse_write_header(
|
||||
/*========================*/
|
||||
const byte* ptr, /*!< in: redo log buffer */
|
||||
const byte* end_ptr,/*!< in: redo log buffer end */
|
||||
page_t* page, /*!< in/out: uncompressed page */
|
||||
page_zip_des_t* page_zip)/*!< in/out: compressed page */
|
||||
{
|
||||
ulint offset;
|
||||
ulint len;
|
||||
|
||||
ut_ad(ptr != NULL);
|
||||
ut_ad(end_ptr!= NULL);
|
||||
ut_ad(!page == !page_zip);
|
||||
|
||||
if (UNIV_UNLIKELY(end_ptr < ptr + (1 + 1))) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
offset = (ulint) *ptr++;
|
||||
len = (ulint) *ptr++;
|
||||
|
||||
if (len == 0 || offset + len >= PAGE_DATA) {
|
||||
corrupt:
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (end_ptr < ptr + len) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
if (!page_zip) {
|
||||
|
||||
goto corrupt;
|
||||
}
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
memcpy(page + offset, ptr, len);
|
||||
memcpy(page_zip->data + offset, ptr, len);
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(page_zip_validate(page_zip, page, NULL));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
return(ptr + len);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Reorganize and compress a page. This is a low-level operation for
|
||||
compressed pages, to be used when page_zip_compress() fails.
|
||||
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
|
||||
On success, redo log will be written.
|
||||
The function btr_page_reorganize() should be preferred whenever possible.
|
||||
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
|
||||
non-clustered index, the caller must update the insert buffer free
|
||||
|
@ -4861,72 +4604,6 @@ page_zip_copy_recs(
|
|||
#endif /* UNIV_ZIP_DEBUG */
|
||||
page_zip_compress_write_log(block, index, mtr);
|
||||
}
|
||||
|
||||
/** Parse and optionally apply MLOG_ZIP_PAGE_COMPRESS.
|
||||
@param[in] ptr log record
|
||||
@param[in] end_ptr end of log
|
||||
@param[in,out] block ROW_FORMAT=COMPRESSED block, or NULL for parsing only
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
const byte* page_zip_parse_compress(const byte* ptr, const byte* end_ptr,
|
||||
buf_block_t* block)
|
||||
{
|
||||
ulint size;
|
||||
ulint trailer_size;
|
||||
|
||||
ut_ad(ptr != NULL);
|
||||
ut_ad(end_ptr!= NULL);
|
||||
|
||||
if (UNIV_UNLIKELY(ptr + (2 + 2) > end_ptr)) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
size = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
trailer_size = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
if (UNIV_UNLIKELY(ptr + 8 + size + trailer_size > end_ptr)) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (block) {
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
||||
if (!page_zip || page_zip_get_size(page_zip) < size
|
||||
|| block->page.id.page_no() < 3) {
|
||||
corrupt:
|
||||
recv_sys.found_corrupt_log = TRUE;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
memset(page_zip->data, 0, page_zip_get_size(page_zip));
|
||||
mach_write_to_4(FIL_PAGE_OFFSET
|
||||
+ page_zip->data, block->page.id.page_no());
|
||||
mach_write_to_4(FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
|
||||
+ page_zip->data, block->page.id.space());
|
||||
memcpy(page_zip->data + FIL_PAGE_PREV, ptr, 4);
|
||||
memcpy(page_zip->data + FIL_PAGE_NEXT, ptr + 4, 4);
|
||||
memcpy(page_zip->data + FIL_PAGE_TYPE, ptr + 8, size);
|
||||
memset(page_zip->data + FIL_PAGE_TYPE + size, 0,
|
||||
page_zip_get_size(page_zip) - trailer_size
|
||||
- (FIL_PAGE_TYPE + size));
|
||||
memcpy(page_zip->data + page_zip_get_size(page_zip)
|
||||
- trailer_size, ptr + 8 + size, trailer_size);
|
||||
|
||||
if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, block->frame,
|
||||
TRUE))) {
|
||||
|
||||
goto corrupt;
|
||||
}
|
||||
}
|
||||
|
||||
return(const_cast<byte*>(ptr) + 8 + size + trailer_size);
|
||||
}
|
||||
#endif /* !UNIV_INNOCHECKSUM */
|
||||
|
||||
/** Calculate the compressed page checksum.
|
||||
|
|
|
@ -166,7 +166,7 @@ rec_get_n_extern_new(
|
|||
ulint i;
|
||||
|
||||
ut_ad(dict_table_is_comp(index->table));
|
||||
ut_ad(!index->table->supports_instant() || index->is_dummy);
|
||||
ut_ad(!index->table->supports_instant());
|
||||
ut_ad(!index->is_instant());
|
||||
ut_ad(rec_get_status(rec) == REC_STATUS_ORDINARY
|
||||
|| rec_get_status(rec) == REC_STATUS_INSTANT);
|
||||
|
@ -283,8 +283,8 @@ rec_init_offsets_comp_ordinary(
|
|||
ut_d(ulint n_null= 0);
|
||||
|
||||
if (mblob) {
|
||||
ut_ad(index->is_dummy || index->table->instant);
|
||||
ut_ad(index->is_dummy || index->is_instant());
|
||||
ut_ad(index->table->instant);
|
||||
ut_ad(index->is_instant());
|
||||
ut_ad(rec_offs_n_fields(offsets)
|
||||
<= ulint(index->n_fields) + 1);
|
||||
ut_ad(!def_val);
|
||||
|
@ -908,8 +908,8 @@ rec_get_offsets_func(
|
|||
memcpy(&offsets[INDEX_OFFSET], &index, sizeof index);
|
||||
#endif /* UNIV_DEBUG */
|
||||
ut_ad(leaf);
|
||||
ut_ad(index->is_dummy || index->table->instant);
|
||||
ut_ad(index->is_dummy || index->is_instant());
|
||||
ut_ad(index->table->instant);
|
||||
ut_ad(index->is_instant());
|
||||
ut_ad(rec_offs_n_fields(offsets)
|
||||
<= ulint(index->n_fields) + 1);
|
||||
rec_init_offsets_comp_ordinary<true>(rec, index, offsets,
|
||||
|
|
|
@ -585,92 +585,6 @@ row_upd_changes_disowned_external(
|
|||
return(false);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Parses the log data written by row_upd_index_write_log.
|
||||
@return log data end or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
row_upd_index_parse(
|
||||
/*================*/
|
||||
const byte* ptr, /*!< in: buffer */
|
||||
const byte* end_ptr,/*!< in: buffer end */
|
||||
mem_heap_t* heap, /*!< in: memory heap where update vector is
|
||||
built */
|
||||
upd_t** update_out)/*!< out: update vector */
|
||||
{
|
||||
upd_t* update;
|
||||
upd_field_t* upd_field;
|
||||
dfield_t* new_val;
|
||||
ulint len;
|
||||
ulint n_fields;
|
||||
ulint info_bits;
|
||||
ulint i;
|
||||
|
||||
if (end_ptr < ptr + 1) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
info_bits = mach_read_from_1(ptr);
|
||||
ptr++;
|
||||
n_fields = mach_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
update = upd_create(n_fields, heap);
|
||||
update->info_bits = info_bits;
|
||||
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
ulint field_no;
|
||||
upd_field = upd_get_nth_field(update, i);
|
||||
new_val = &(upd_field->new_val);
|
||||
|
||||
field_no = mach_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Check if this is a virtual column, mark the prtype
|
||||
if that is the case */
|
||||
if (field_no >= REC_MAX_N_FIELDS) {
|
||||
new_val->type.prtype |= DATA_VIRTUAL;
|
||||
field_no -= REC_MAX_N_FIELDS;
|
||||
}
|
||||
|
||||
upd_field->field_no = field_no;
|
||||
|
||||
len = mach_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (len != UNIV_SQL_NULL) {
|
||||
|
||||
if (end_ptr < ptr + len) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
dfield_set_data(new_val,
|
||||
mem_heap_dup(heap, ptr, len), len);
|
||||
ptr += len;
|
||||
} else {
|
||||
dfield_set_null(new_val);
|
||||
}
|
||||
}
|
||||
|
||||
*update_out = update;
|
||||
|
||||
return(const_cast<byte*>(ptr));
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Builds an update vector from those fields which in a secondary index entry
|
||||
differ from a record that has the equal ordering fields. NOTE: we compare
|
||||
|
|
|
@ -54,50 +54,6 @@ const dtuple_t trx_undo_metadata = {
|
|||
|
||||
/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/
|
||||
|
||||
/** Parse MLOG_UNDO_INSERT.
|
||||
@param[in] ptr log record
|
||||
@param[in] end_ptr end of log record buffer
|
||||
@param[in,out] page page or NULL
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_add_undo_rec(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
page_t* page)
|
||||
{
|
||||
ulint len;
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
len = mach_read_from_2(ptr);
|
||||
ptr += 2;
|
||||
|
||||
if (end_ptr < ptr + len) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (page) {
|
||||
ulint first_free = mach_read_from_2(page + TRX_UNDO_PAGE_HDR
|
||||
+ TRX_UNDO_PAGE_FREE);
|
||||
byte* rec = page + first_free;
|
||||
|
||||
mach_write_to_2(rec, first_free + 4 + len);
|
||||
mach_write_to_2(rec + 2 + len, first_free);
|
||||
|
||||
mach_write_to_2(page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
|
||||
first_free + 4 + len);
|
||||
memcpy(rec + 2, ptr, len);
|
||||
}
|
||||
|
||||
return(const_cast<byte*>(ptr + len));
|
||||
}
|
||||
|
||||
/** Calculate the free space left for extending an undo log record.
|
||||
@param[in] undo_block undo log page
|
||||
@param[in] ptr current end of the undo page
|
||||
|
|
|
@ -292,90 +292,6 @@ trx_undo_get_first_rec(const fil_space_t &space, uint32_t page_no,
|
|||
|
||||
/*============== UNDO LOG FILE COPY CREATION AND FREEING ==================*/
|
||||
|
||||
/** Parse MLOG_UNDO_INIT.
|
||||
@param[in] ptr log record
|
||||
@param[in] end_ptr end of log record buffer
|
||||
@param[in,out] page page or NULL
|
||||
@return end of log record
|
||||
@retval NULL if the log record is incomplete */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_page_init(const byte* ptr, const byte* end_ptr, page_t* page)
|
||||
{
|
||||
if (end_ptr <= ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ulint type = *ptr++;
|
||||
|
||||
if (type > TRX_UNDO_UPDATE) {
|
||||
recv_sys.found_corrupt_log = true;
|
||||
} else if (page) {
|
||||
/* Starting with MDEV-12288 in MariaDB 10.3.1, we use
|
||||
type=0 for the combined insert/update undo log
|
||||
pages. MariaDB 10.2 would use TRX_UNDO_INSERT or
|
||||
TRX_UNDO_UPDATE. */
|
||||
mach_write_to_2(FIL_PAGE_TYPE + page, FIL_PAGE_UNDO_LOG);
|
||||
mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + page,
|
||||
type);
|
||||
mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_START + page,
|
||||
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
|
||||
mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE + page,
|
||||
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
|
||||
}
|
||||
|
||||
return(const_cast<byte*>(ptr));
|
||||
}
|
||||
|
||||
/** Parse MLOG_UNDO_HDR_REUSE for crash-upgrade from MariaDB 10.2.
|
||||
@param[in] ptr redo log record
|
||||
@param[in] end_ptr end of log buffer
|
||||
@param[in,out] page undo log page or NULL
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_page_header_reuse(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
page_t* undo_page)
|
||||
{
|
||||
trx_id_t trx_id = mach_u64_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (!ptr || !undo_page) {
|
||||
return(const_cast<byte*>(ptr));
|
||||
}
|
||||
|
||||
compile_time_assert(TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE
|
||||
+ TRX_UNDO_LOG_XA_HDR_SIZE
|
||||
< UNIV_PAGE_SIZE_MIN - 100);
|
||||
|
||||
const ulint new_free = TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE
|
||||
+ TRX_UNDO_LOG_OLD_HDR_SIZE;
|
||||
|
||||
/* Insert undo data is not needed after commit: we may free all
|
||||
the space on the page */
|
||||
|
||||
ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
|
||||
+ undo_page)
|
||||
== TRX_UNDO_INSERT);
|
||||
|
||||
byte* page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
|
||||
mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free);
|
||||
mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free);
|
||||
mach_write_to_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE + undo_page,
|
||||
TRX_UNDO_ACTIVE);
|
||||
|
||||
byte* log_hdr = undo_page + TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE;
|
||||
|
||||
mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id);
|
||||
mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free);
|
||||
|
||||
mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE);
|
||||
mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, FALSE);
|
||||
|
||||
return(const_cast<byte*>(ptr));
|
||||
}
|
||||
|
||||
/** Initialize the fields in an undo log segment page.
|
||||
@param[in,out] undo_block undo log segment page
|
||||
@param[in,out] mtr mini-transaction */
|
||||
|
@ -609,30 +525,6 @@ trx_undo_read_xid(const trx_ulogf_t* log_hdr, XID* xid)
|
|||
memcpy(xid->data, log_hdr + TRX_UNDO_XA_XID, XIDDATASIZE);
|
||||
}
|
||||
|
||||
/** Parse the redo log entry of an undo log page header create.
|
||||
@param[in] ptr redo log record
|
||||
@param[in] end_ptr end of log buffer
|
||||
@param[in,out] block page frame or NULL
|
||||
@param[in,out] mtr mini-transaction or NULL
|
||||
@return end of log record or NULL */
|
||||
ATTRIBUTE_COLD /* only used when crash-upgrading */
|
||||
byte*
|
||||
trx_undo_parse_page_header(
|
||||
const byte* ptr,
|
||||
const byte* end_ptr,
|
||||
buf_block_t* block,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
trx_id_t trx_id = mach_u64_parse_compressed(&ptr, end_ptr);
|
||||
|
||||
if (ptr && block) {
|
||||
trx_undo_header_create(block, trx_id, mtr);
|
||||
|
||||
}
|
||||
|
||||
return const_cast<byte*>(ptr);
|
||||
}
|
||||
|
||||
/** Allocate an undo log page.
|
||||
@param[in,out] undo undo log
|
||||
@param[in,out] mtr mini-transaction that does not hold any page latch
|
||||
|
|
Loading…
Reference in a new issue