Skip to content

Commit 7cb16dc

Browse files
author
Jan Lindström
committed
MDEV-9422: Checksum errors on restart when killing busy instance that uses encrypted XtraDB tables
Fix incorrectly merged files on innodb_plugin.
1 parent 4fdac6c commit 7cb16dc

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

storage/innobase/log/log0crypt.cc

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
3636

3737
#include "my_crypt.h"
3838

39+
/* Used for debugging */
40+
// #define DEBUG_CRYPT 1
3941
#define UNENCRYPTED_KEY_VER 0
4042

4143
/* If true, enable redo log encryption. */
@@ -97,16 +99,24 @@ get_crypt_info(
9799
{
98100
/* so that no one is modifying array while we search */
99101
ut_ad(mutex_own(&(log_sys->mutex)));
102+
size_t items = crypt_info.size();
100103

101104
/* a log block only stores 4-bytes of checkpoint no */
102105
checkpoint_no &= 0xFFFFFFFF;
103-
for (size_t i = 0; i < crypt_info.size(); i++) {
106+
for (size_t i = 0; i < items; i++) {
104107
struct crypt_info_t* it = &crypt_info[i];
105108

106109
if (it->checkpoint_no == checkpoint_no) {
107110
return it;
108111
}
109112
}
113+
114+
/* If checkpoint contains more than one key and we did not
115+
find the correct one use the first one. */
116+
if (items) {
117+
return (&crypt_info[0]);
118+
}
119+
110120
return NULL;
111121
}
112122

@@ -131,7 +141,8 @@ log_blocks_crypt(
131141
const byte* block, /*!< in: blocks before encrypt/decrypt*/
132142
ulint size, /*!< in: size of block */
133143
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
134-
int what) /*!< in: encrypt or decrypt*/
144+
int what, /*!< in: encrypt or decrypt*/
145+
const crypt_info_t* crypt_info) /*!< in: crypt info or NULL */
135146
{
136147
byte *log_block = (byte*)block;
137148
Crypt_result rc = MY_AES_OK;
@@ -146,7 +157,8 @@ log_blocks_crypt(
146157
lsn_t log_block_start_lsn = log_block_get_start_lsn(
147158
lsn, log_block_no);
148159

149-
const crypt_info_t* info = get_crypt_info(log_block);
160+
const crypt_info_t* info = crypt_info == NULL ? get_crypt_info(log_block) :
161+
crypt_info;
150162
#ifdef DEBUG_CRYPT
151163
fprintf(stderr,
152164
"%s %lu chkpt: %lu key: %u lsn: %lu\n",
@@ -301,7 +313,7 @@ log_blocks_encrypt(
301313
const ulint size, /*!< in: size of blocks, must be multiple of a log block */
302314
byte* dst_block) /*!< out: blocks after encryption */
303315
{
304-
return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT);
316+
return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT, NULL);
305317
}
306318

307319
/*********************************************************************//**
@@ -364,14 +376,16 @@ log_encrypt_before_write(
364376
return;
365377
}
366378

367-
if (info->key_version == UNENCRYPTED_KEY_VER) {
379+
/* If the key is not encrypted or user has requested not to
380+
encrypt, do not change log block. */
381+
if (info->key_version == UNENCRYPTED_KEY_VER || !srv_encrypt_log) {
368382
return;
369383
}
370384

371385
byte* dst_frame = (byte*)malloc(size);
372386

373387
//encrypt log blocks content
374-
Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT);
388+
Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
375389

376390
if (result == MY_AES_OK) {
377391
ut_ad(block[0] == dst_frame[0]);
@@ -397,7 +411,7 @@ log_decrypt_after_read(
397411
byte* dst_frame = (byte*)malloc(size);
398412

399413
// decrypt log blocks content
400-
Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT);
414+
Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
401415

402416
if (result == MY_AES_OK) {
403417
memcpy(frame, dst_frame, size);

storage/innobase/log/log0recv.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
44
Copyright (c) 2012, Facebook Inc.
5-
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
5+
Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
66
77
This program is free software; you can redistribute it and/or modify it under
88
the terms of the GNU General Public License as published by the Free Software
@@ -2666,6 +2666,7 @@ recv_scan_log_recs(
26662666
ibool finished;
26672667
ulint data_len;
26682668
ibool more_data;
2669+
bool maybe_encrypted=false;
26692670

26702671
ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
26712672
ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -2680,6 +2681,8 @@ recv_scan_log_recs(
26802681
*err = DB_SUCCESS;
26812682

26822683
do {
2684+
log_crypt_err_t log_crypt_err;
2685+
26832686
no = log_block_get_hdr_no(log_block);
26842687
/*
26852688
fprintf(stderr, "Log block header no %lu\n", no);
@@ -2689,7 +2692,6 @@ recv_scan_log_recs(
26892692
*/
26902693
if (no != log_block_convert_lsn_to_no(scanned_lsn)
26912694
|| !log_block_checksum_is_ok_or_old_format(log_block, true)) {
2692-
log_crypt_err_t log_crypt_err;
26932695

26942696
if (no == log_block_convert_lsn_to_no(scanned_lsn)
26952697
&& !log_block_checksum_is_ok_or_old_format(
@@ -2707,12 +2709,14 @@ recv_scan_log_recs(
27072709
log_block));
27082710
}
27092711

2712+
maybe_encrypted = log_crypt_block_maybe_encrypted(log_block,
2713+
&log_crypt_err);
2714+
27102715
/* Garbage or an incompletely written log block */
27112716

27122717
finished = TRUE;
27132718

2714-
if (log_crypt_block_maybe_encrypted(log_block,
2715-
&log_crypt_err)) {
2719+
if (maybe_encrypted) {
27162720
/* Log block maybe encrypted finish processing*/
27172721
log_crypt_print_error(log_crypt_err);
27182722
*err = DB_ERROR;

0 commit comments

Comments
 (0)