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:
Marko Mäkelä 2020-02-13 19:13:45 +02:00
parent 7ae21b18a6
commit f8a9f90667
37 changed files with 298 additions and 5224 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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 =========================*/
/*************************************************************//**

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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 */

View file

@ -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 */

View file

@ -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() */

View file

@ -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.

View file

@ -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 */

View file

@ -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 */

View file

@ -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 {

View file

@ -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 */

View file

@ -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 */

View file

@ -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.

View file

@ -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

View file

@ -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{

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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. */

View file

@ -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.

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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