From 37a65e3335bd2dc28574b2f938d2a18b1b52f8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 30 Mar 2016 16:08:05 +0300 Subject: [PATCH] MDEV-9793: getting mysqld crypto key from key version failed Make sure that we read all possible encryption keys from checkpoint and if log block checksum does not match, print all found checkpoint encryption keys. --- storage/innobase/include/log0crypt.h | 10 +++++++++- storage/innobase/log/log0crypt.cc | 30 ++++++++++++++++++++++++++-- storage/innobase/log/log0recv.cc | 2 ++ storage/xtradb/include/log0crypt.h | 10 +++++++++- storage/xtradb/log/log0crypt.cc | 30 ++++++++++++++++++++++++++-- storage/xtradb/log/log0recv.cc | 2 ++ 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h index 7e737853465..6b164e90d6e 100644 --- a/storage/innobase/include/log0crypt.h +++ b/storage/innobase/include/log0crypt.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2014, 2016, MariaDB Corporation. 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 @@ -117,4 +117,12 @@ log_crypt_print_error( /*==================*/ log_crypt_err_t err_info); /*!< out: error info */ +/*********************************************************************//** +Print checkpoint no from log block and all encryption keys from +checkpoints if they are present. Used for problem analysis. */ +void +log_crypt_print_checkpoint_keys( +/*============================*/ + const byte* log_block); + #endif // log0crypt.h diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc index 852148899e9..c404ad8dd0d 100644 --- a/storage/innobase/log/log0crypt.cc +++ b/storage/innobase/log/log0crypt.cc @@ -127,11 +127,34 @@ static const crypt_info_t* get_crypt_info( /*===========*/ - const byte* log_block) { + const byte* log_block) +{ ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block); return get_crypt_info(checkpoint_no); } +/*********************************************************************//** +Print checkpoint no from log block and all encryption keys from +checkpoints if they are present. Used for problem analysis. */ +void +log_crypt_print_checkpoint_keys( +/*============================*/ + const byte* log_block) +{ + ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block); + + if (crypt_info.size()) { + fprintf(stderr, "InnoDB: redo log checkpoint: %lu [ chk key ]: ", checkpoint_no); + for (size_t i = 0; i < crypt_info.size(); i++) { + struct crypt_info_t* it = &crypt_info[i]; + fprintf(stderr, "[ %lu %u ] ", + it->checkpoint_no, + it->key_version); + } + fprintf(stderr, "\n"); + } +} + /*********************************************************************//** Call AES CTR to encrypt/decrypt log blocks. */ static @@ -280,10 +303,13 @@ static bool add_crypt_info(crypt_info_t* info) { + const crypt_info_t* found=NULL; /* so that no one is searching array while we modify it */ ut_ad(mutex_own(&(log_sys->mutex))); - if (get_crypt_info(info->checkpoint_no) != NULL) { + found = get_crypt_info(info->checkpoint_no); + + if (found != NULL && found->checkpoint_no == info->checkpoint_no) { // already present... return true; } diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 2304f4885c2..d574cd55397 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2714,6 +2714,8 @@ recv_scan_log_recs( /* Garbage or an incompletely written log block */ + /* Print checkpoint encryption keys if present */ + log_crypt_print_checkpoint_keys(log_block); finished = TRUE; if (maybe_encrypted) { diff --git a/storage/xtradb/include/log0crypt.h b/storage/xtradb/include/log0crypt.h index 7e737853465..6b164e90d6e 100644 --- a/storage/xtradb/include/log0crypt.h +++ b/storage/xtradb/include/log0crypt.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2014, 2016, MariaDB Corporation. 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 @@ -117,4 +117,12 @@ log_crypt_print_error( /*==================*/ log_crypt_err_t err_info); /*!< out: error info */ +/*********************************************************************//** +Print checkpoint no from log block and all encryption keys from +checkpoints if they are present. Used for problem analysis. */ +void +log_crypt_print_checkpoint_keys( +/*============================*/ + const byte* log_block); + #endif // log0crypt.h diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc index 852148899e9..c404ad8dd0d 100644 --- a/storage/xtradb/log/log0crypt.cc +++ b/storage/xtradb/log/log0crypt.cc @@ -127,11 +127,34 @@ static const crypt_info_t* get_crypt_info( /*===========*/ - const byte* log_block) { + const byte* log_block) +{ ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block); return get_crypt_info(checkpoint_no); } +/*********************************************************************//** +Print checkpoint no from log block and all encryption keys from +checkpoints if they are present. Used for problem analysis. */ +void +log_crypt_print_checkpoint_keys( +/*============================*/ + const byte* log_block) +{ + ib_uint64_t checkpoint_no = log_block_get_checkpoint_no(log_block); + + if (crypt_info.size()) { + fprintf(stderr, "InnoDB: redo log checkpoint: %lu [ chk key ]: ", checkpoint_no); + for (size_t i = 0; i < crypt_info.size(); i++) { + struct crypt_info_t* it = &crypt_info[i]; + fprintf(stderr, "[ %lu %u ] ", + it->checkpoint_no, + it->key_version); + } + fprintf(stderr, "\n"); + } +} + /*********************************************************************//** Call AES CTR to encrypt/decrypt log blocks. */ static @@ -280,10 +303,13 @@ static bool add_crypt_info(crypt_info_t* info) { + const crypt_info_t* found=NULL; /* so that no one is searching array while we modify it */ ut_ad(mutex_own(&(log_sys->mutex))); - if (get_crypt_info(info->checkpoint_no) != NULL) { + found = get_crypt_info(info->checkpoint_no); + + if (found != NULL && found->checkpoint_no == info->checkpoint_no) { // already present... return true; } diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index f98adbbca08..23ca8b1381f 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -2786,6 +2786,8 @@ recv_scan_log_recs( /* Garbage or an incompletely written log block */ + /* Print checkpoint encryption keys if present */ + log_crypt_print_checkpoint_keys(log_block); finished = TRUE; if (maybe_encrypted) {