mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-8588: Assertion failure in file ha_innodb.cc line 21140 if at least one encrypted table exists and encryption service is not available
Analysis: Problem was that in fil_read_first_page we do find that table has encryption information and that encryption service or used key_id is not available. But, then we just printed fatal error message that causes above assertion. Fix: When we open single table tablespace if it has encryption information (crypt_data) store this crypt data to the table structure. When we open a table and we find out that tablespace is not available, check has table a encryption information and from there is encryption service or used key_id is not available. If it is, add additional warning for SQL-layer.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
call mtr.add_suppression("Plugin 'file_key_management' init function returned error");
|
||||
call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed.*");
|
||||
call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
|
||||
call mtr.add_suppression("InnoDB: Block in space_id .* in file test/.* encrypted");
|
||||
call mtr.add_suppression("InnoDB: However key management plugin or used key_id 1 is not found or used encryption algorithm or method does not match.");
|
||||
call mtr.add_suppression("InnoDB: Marking tablespace as missing. You may drop this table or install correct key management plugin and key file.");
|
||||
call mtr.add_suppression(".*InnoDB: Cannot open table test/.* from the internal data dictionary of InnoDB though the .frm file for the table exists. See .* for how you can resolve the problem.");
|
||||
call mtr.add_suppression("InnoDB: .ibd file is missing for table test/.*");
|
||||
|
||||
# Start server with keys2.txt
|
||||
SET GLOBAL innodb_file_format = `Barracuda`;
|
||||
@@ -33,3 +38,98 @@ Warning 1812 Tablespace is missing for table 'test/t1'
|
||||
Warning 155 Table test/t1 is encrypted but encryption service or used key_id 2 is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t1' doesn't exist in engine
|
||||
DROP TABLE t1;
|
||||
# Start server with keys.txt
|
||||
CREATE TABLE t2 (c VARCHAR(8), id int not null primary key, b int, key(b)) ENGINE=InnoDB ENCRYPTED=YES;
|
||||
INSERT INTO t2 VALUES ('foobar',1,2);
|
||||
|
||||
# Restart server with keys2.txt
|
||||
SELECT * FROM t2;
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 155 Table test/t2 in tablespace 7 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Warning 155 Table test/t2 in tablespace 7 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
SELECT * FROM t2 where id = 1;
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
SELECT * FROM t2 where b = 1;
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
INSERT INTO t2 VALUES ('tmp',3,3);
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist in engine
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
DELETE FROM t2 where b = 3;
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
DELETE FROM t2 where id = 3;
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
UPDATE t2 set b = b +1;
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
OPTIMIZE TABLE t2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 optimize Warning Tablespace is missing for table 'test/t2'
|
||||
test.t2 optimize Warning Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
test.t2 optimize Error Table 'test.t2' doesn't exist in engine
|
||||
test.t2 optimize status Operation failed
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
ALTER TABLE t2 ADD COLUMN c INT;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist in engine
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
ANALYZE TABLE t2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 analyze Warning Tablespace is missing for table 'test/t2'
|
||||
test.t2 analyze Warning Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
test.t2 analyze Error Table 'test.t2' doesn't exist in engine
|
||||
test.t2 analyze status Operation failed
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
TRUNCATE TABLE t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist in engine
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1812 Tablespace is missing for table 'test/t2'
|
||||
Warning 155 Table test/t2 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
|
||||
Error 1932 Table 'test.t2' doesn't exist in engine
|
||||
DROP TABLE t2;
|
||||
ERROR HY000: Table 't2' is read only
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Error 1036 Table 't2' is read only
|
||||
|
||||
# Restart server with keys.txt
|
||||
DROP TABLE t2;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
|
@@ -2,10 +2,24 @@
|
||||
-- source include/have_file_key_management_plugin.inc
|
||||
# embedded does not support restart
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/not_valgrind.inc
|
||||
# Avoid CrashReporter popup on Mac
|
||||
-- source include/not_crashrep.inc
|
||||
-- source include/not_windows.inc
|
||||
|
||||
#
|
||||
# MDEV-8588: Assertion failure in file ha_innodb.cc line 21140 if at least one encrypted
|
||||
# table exists and encryption service is not available.
|
||||
#
|
||||
|
||||
call mtr.add_suppression("Plugin 'file_key_management' init function returned error");
|
||||
call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed.*");
|
||||
call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
|
||||
call mtr.add_suppression("InnoDB: Block in space_id .* in file test/.* encrypted");
|
||||
call mtr.add_suppression("InnoDB: However key management plugin or used key_id 1 is not found or used encryption algorithm or method does not match.");
|
||||
call mtr.add_suppression("InnoDB: Marking tablespace as missing. You may drop this table or install correct key management plugin and key file.");
|
||||
call mtr.add_suppression(".*InnoDB: Cannot open table test/.* from the internal data dictionary of InnoDB though the .frm file for the table exists. See .* for how you can resolve the problem.");
|
||||
call mtr.add_suppression("InnoDB: .ibd file is missing for table test/.*");
|
||||
|
||||
--echo
|
||||
--echo # Start server with keys2.txt
|
||||
@@ -44,3 +58,63 @@ SHOW WARNINGS;
|
||||
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keysbad3.txt
|
||||
-- source include/restart_mysqld.inc
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# MDEV-8591: Database page corruption on disk or a failed space, Assertion failure in file buf0buf.cc
|
||||
# line 2856 on querying a table using wrong default encryption key
|
||||
#
|
||||
|
||||
--echo # Start server with keys.txt
|
||||
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt
|
||||
-- source include/restart_mysqld.inc
|
||||
|
||||
CREATE TABLE t2 (c VARCHAR(8), id int not null primary key, b int, key(b)) ENGINE=InnoDB ENCRYPTED=YES;
|
||||
INSERT INTO t2 VALUES ('foobar',1,2);
|
||||
|
||||
--echo
|
||||
--echo # Restart server with keys2.txt
|
||||
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
|
||||
-- source include/restart_mysqld.inc
|
||||
|
||||
--error 1932,1712
|
||||
SELECT * FROM t2;
|
||||
SHOW WARNINGS;
|
||||
--error 1932,1712
|
||||
SELECT * FROM t2 where id = 1;
|
||||
SHOW WARNINGS;
|
||||
--error 1932,1712
|
||||
SELECT * FROM t2 where b = 1;
|
||||
SHOW WARNINGS;
|
||||
--error 1932
|
||||
INSERT INTO t2 VALUES ('tmp',3,3);
|
||||
SHOW WARNINGS;
|
||||
--error 1932,1712
|
||||
DELETE FROM t2 where b = 3;
|
||||
SHOW WARNINGS;
|
||||
--error 1932,1712
|
||||
DELETE FROM t2 where id = 3;
|
||||
SHOW WARNINGS;
|
||||
--error 1932,1712
|
||||
UPDATE t2 set b = b +1;
|
||||
SHOW WARNINGS;
|
||||
OPTIMIZE TABLE t2;
|
||||
SHOW WARNINGS;
|
||||
--error 1932
|
||||
ALTER TABLE t2 ADD COLUMN c INT;
|
||||
SHOW WARNINGS;
|
||||
ANALYZE TABLE t2;
|
||||
SHOW WARNINGS;
|
||||
--error 1932
|
||||
TRUNCATE TABLE t2;
|
||||
SHOW WARNINGS;
|
||||
--error 1036
|
||||
DROP TABLE t2;
|
||||
SHOW WARNINGS;
|
||||
|
||||
--echo
|
||||
--echo # Restart server with keys.txt
|
||||
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt
|
||||
-- source include/restart_mysqld.inc
|
||||
|
||||
DROP TABLE t2;
|
||||
SHOW WARNINGS;
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2014, 2015, 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
|
||||
@@ -734,6 +735,20 @@ btr_root_block_get(
|
||||
root_page_no = dict_index_get_page(index);
|
||||
|
||||
block = btr_block_get(space, zip_size, root_page_no, mode, index, mtr);
|
||||
|
||||
if (!block) {
|
||||
index->table->is_encrypted = TRUE;
|
||||
index->table->corrupted = FALSE;
|
||||
|
||||
ib_push_warning(index->table->thd, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s in tablespace %lu is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name, space);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
btr_assert_not_corrupted(block, index);
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
if (!dict_index_is_ibuf(index)) {
|
||||
@@ -759,8 +774,10 @@ btr_root_get(
|
||||
const dict_index_t* index, /*!< in: index tree */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
return(buf_block_get_frame(btr_root_block_get(index, RW_X_LATCH,
|
||||
mtr)));
|
||||
buf_block_t* root = btr_root_block_get(index, RW_X_LATCH,
|
||||
mtr);
|
||||
|
||||
return(root ? buf_block_get_frame(root) : NULL);
|
||||
}
|
||||
|
||||
/**************************************************************//**
|
||||
@@ -775,7 +792,7 @@ btr_height_get(
|
||||
dict_index_t* index, /*!< in: index tree */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint height;
|
||||
ulint height=0;
|
||||
buf_block_t* root_block;
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
|
||||
@@ -786,6 +803,7 @@ btr_height_get(
|
||||
/* S latches the page */
|
||||
root_block = btr_root_block_get(index, RW_S_LATCH, mtr);
|
||||
|
||||
if (root_block) {
|
||||
height = btr_page_get_level(buf_block_get_frame(root_block), mtr);
|
||||
|
||||
/* Release the S latch on the root page. */
|
||||
@@ -793,6 +811,7 @@ btr_height_get(
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
sync_thread_reset_level(&root_block->lock);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
return(height);
|
||||
}
|
||||
@@ -1240,7 +1259,7 @@ btr_get_size_and_reserved(
|
||||
{
|
||||
fseg_header_t* seg_header;
|
||||
page_t* root;
|
||||
ulint n;
|
||||
ulint n=ULINT_UNDEFINED;
|
||||
ulint dummy;
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
|
||||
@@ -1254,6 +1273,9 @@ btr_get_size_and_reserved(
|
||||
}
|
||||
|
||||
root = btr_root_get(index, mtr);
|
||||
*used = 0;
|
||||
|
||||
if (root) {
|
||||
|
||||
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
|
||||
|
||||
@@ -1266,6 +1288,7 @@ btr_get_size_and_reserved(
|
||||
*used += dummy;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return(n);
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2015, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
@@ -347,7 +348,7 @@ search tuple should be performed in the B-tree. InnoDB does an insert
|
||||
immediately after the cursor. Thus, the cursor may end up on a user record,
|
||||
or on a page infimum record. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_search_to_nth_level(
|
||||
/*========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -397,6 +398,7 @@ btr_cur_search_to_nth_level(
|
||||
page_cur_t* page_cursor;
|
||||
btr_op_t btr_op;
|
||||
ulint root_height = 0; /* remove warning */
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
btr_search_t* info;
|
||||
@@ -513,7 +515,7 @@ btr_cur_search_to_nth_level(
|
||||
|| mode != PAGE_CUR_LE);
|
||||
btr_cur_n_sea++;
|
||||
|
||||
return;
|
||||
return err;
|
||||
}
|
||||
# endif /* BTR_CUR_HASH_ADAPT */
|
||||
#endif /* BTR_CUR_ADAPT */
|
||||
@@ -609,7 +611,21 @@ search_loop:
|
||||
retry_page_get:
|
||||
block = buf_page_get_gen(
|
||||
space, zip_size, page_no, rw_latch, guess, buf_mode,
|
||||
file, line, mtr);
|
||||
file, line, mtr, &err);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
/* This must be a search to perform an insert/delete
|
||||
@@ -822,12 +838,14 @@ func_exit:
|
||||
|
||||
rw_lock_s_lock(&btr_search_latch);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a cursor at either end of an index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_open_at_index_side_func(
|
||||
/*============================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
@@ -853,6 +871,8 @@ btr_cur_open_at_index_side_func(
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
estimate = latch_mode & BTR_ESTIMATE;
|
||||
@@ -890,11 +910,26 @@ btr_cur_open_at_index_side_func(
|
||||
height = ULINT_UNDEFINED;
|
||||
|
||||
for (;;) {
|
||||
buf_block_t* block;
|
||||
page_t* page;
|
||||
buf_block_t* block=NULL;
|
||||
page_t* page=NULL;
|
||||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
file, line, mtr);
|
||||
file, line, mtr, &err);
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
ut_ad(fil_page_get_type(page) == FIL_PAGE_INDEX);
|
||||
ut_ad(index->id == btr_page_get_index_id(page));
|
||||
@@ -979,9 +1014,12 @@ btr_cur_open_at_index_side_func(
|
||||
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
|
||||
}
|
||||
|
||||
exit_loop:
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
@@ -1029,10 +1067,25 @@ btr_cur_open_at_rnd_pos_func(
|
||||
for (;;) {
|
||||
buf_block_t* block;
|
||||
page_t* page;
|
||||
dberr_t err=DB_SUCCESS;
|
||||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
file, line, mtr);
|
||||
file, line, mtr, &err);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
ut_ad(fil_page_get_type(page) == FIL_PAGE_INDEX);
|
||||
ut_ad(index->id == btr_page_get_index_id(page));
|
||||
@@ -1066,6 +1119,7 @@ btr_cur_open_at_rnd_pos_func(
|
||||
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
|
||||
}
|
||||
|
||||
exit_loop:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
@@ -3562,6 +3616,7 @@ btr_estimate_n_rows_in_range_on_level(
|
||||
mtr_t mtr;
|
||||
page_t* page;
|
||||
buf_block_t* block;
|
||||
dberr_t err=DB_SUCCESS;
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
@@ -3572,7 +3627,23 @@ btr_estimate_n_rows_in_range_on_level(
|
||||
silence a debug assertion about this. */
|
||||
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH,
|
||||
NULL, BUF_GET_POSSIBLY_FREED,
|
||||
__FILE__, __LINE__, &mtr);
|
||||
__FILE__, __LINE__, &mtr, &err);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
goto inexact;
|
||||
}
|
||||
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
|
@@ -56,6 +56,7 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "srv0mon.h"
|
||||
#include "buf0checksum.h"
|
||||
#include "fil0pagecompress.h"
|
||||
#include "ha_prototypes.h"
|
||||
#include "ut0byte.h"
|
||||
#include <new>
|
||||
|
||||
@@ -312,6 +313,18 @@ on the io_type */
|
||||
? (counter##_READ) \
|
||||
: (counter##_WRITTEN))
|
||||
|
||||
/********************************************************************//**
|
||||
Check if page is maybe compressed, encrypted or both when we encounter
|
||||
corrupted page. Note that we can't be 100% sure if page is corrupted
|
||||
or decrypt/decompress just failed.
|
||||
*/
|
||||
static
|
||||
ibool
|
||||
buf_page_check_corrupt(
|
||||
/*===================*/
|
||||
buf_page_t* bpage); /*!< in/out: buffer page read from
|
||||
disk */
|
||||
|
||||
/********************************************************************//**
|
||||
Gets the smallest oldest_modification lsn for any page in the pool. Returns
|
||||
zero if all modified pages have been flushed to disk.
|
||||
@@ -1052,6 +1065,9 @@ buf_block_init(
|
||||
block->page.key_version = 0;
|
||||
block->page.page_encrypted = false;
|
||||
block->page.page_compressed = false;
|
||||
block->page.encrypted = false;
|
||||
block->page.stored_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
block->page.calculated_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
block->page.real_size = 0;
|
||||
block->page.write_size = 0;
|
||||
block->modify_clock = 0;
|
||||
@@ -2243,7 +2259,7 @@ lookup:
|
||||
/* Page not in buf_pool: needs to be read from file */
|
||||
|
||||
ut_ad(!hash_lock);
|
||||
buf_read_page(space, zip_size, offset);
|
||||
buf_read_page(space, zip_size, offset, NULL);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(++buf_dbg_counter % 5771 || buf_validate());
|
||||
@@ -2718,7 +2734,8 @@ buf_page_get_gen(
|
||||
BUF_GET_IF_IN_POOL_OR_WATCH */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mini-transaction */
|
||||
mtr_t* mtr, /*!< in: mini-transaction */
|
||||
dberr_t* err) /*!< out: error code */
|
||||
{
|
||||
buf_block_t* block;
|
||||
ulint fold;
|
||||
@@ -2735,6 +2752,11 @@ buf_page_get_gen(
|
||||
ut_ad((rw_latch == RW_S_LATCH)
|
||||
|| (rw_latch == RW_X_LATCH)
|
||||
|| (rw_latch == RW_NO_LATCH));
|
||||
|
||||
if (err) {
|
||||
*err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
switch (mode) {
|
||||
case BUF_GET_NO_LATCH:
|
||||
@@ -2795,6 +2817,8 @@ loop:
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
buf_page_t* bpage=NULL;
|
||||
|
||||
/* Page not in buf_pool: needs to be read from file */
|
||||
|
||||
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
|
||||
@@ -2827,19 +2851,47 @@ loop:
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (buf_read_page(space, zip_size, offset)) {
|
||||
if (buf_read_page(space, zip_size, offset, &bpage)) {
|
||||
buf_read_ahead_random(space, zip_size, offset,
|
||||
ibuf_inside(mtr));
|
||||
|
||||
retries = 0;
|
||||
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
|
||||
++retries;
|
||||
|
||||
bool corrupted = true;
|
||||
|
||||
if (bpage) {
|
||||
corrupted = buf_page_check_corrupt(bpage);
|
||||
}
|
||||
|
||||
/* Do not try again for encrypted pages */
|
||||
if (!corrupted) {
|
||||
ib_mutex_t* pmutex = buf_page_get_mutex(bpage);
|
||||
buf_pool_mutex_enter(buf_pool);
|
||||
mutex_enter(pmutex);
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
buf_pool_mutex_exit(buf_pool);
|
||||
mutex_exit(pmutex);
|
||||
|
||||
if (err) {
|
||||
*err = DB_ENCRYPTED_DECRYPT_FAILED;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
"innodb_page_corruption_retries",
|
||||
retries = BUF_PAGE_READ_MAX_RETRIES;
|
||||
);
|
||||
} else {
|
||||
bool corrupted = true;
|
||||
|
||||
if (bpage) {
|
||||
corrupted = buf_page_check_corrupt(bpage);
|
||||
}
|
||||
|
||||
if (corrupted) {
|
||||
fprintf(stderr, "InnoDB: Error: Unable"
|
||||
" to read tablespace %lu page no"
|
||||
" %lu into the buffer pool after"
|
||||
@@ -2857,6 +2909,19 @@ loop:
|
||||
BUF_PAGE_READ_MAX_RETRIES);
|
||||
|
||||
ut_error;
|
||||
} else {
|
||||
ib_mutex_t* pmutex = buf_page_get_mutex(bpage);
|
||||
buf_pool_mutex_enter(buf_pool);
|
||||
mutex_enter(pmutex);
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
buf_pool_mutex_exit(buf_pool);
|
||||
mutex_exit(pmutex);
|
||||
|
||||
if (err) {
|
||||
*err = DB_ENCRYPTED_DECRYPT_FAILED;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
@@ -3591,8 +3656,11 @@ buf_page_init_low(
|
||||
bpage->oldest_modification = 0;
|
||||
bpage->write_size = 0;
|
||||
bpage->key_version = 0;
|
||||
bpage->stored_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
bpage->calculated_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
bpage->page_encrypted = false;
|
||||
bpage->page_compressed = false;
|
||||
bpage->encrypted = false;
|
||||
bpage->real_size = 0;
|
||||
bpage->slot = NULL;
|
||||
|
||||
@@ -4245,6 +4313,7 @@ buf_mark_space_corrupt(
|
||||
ulint space = bpage->space;
|
||||
ibool ret = TRUE;
|
||||
|
||||
if (!bpage->encrypted) {
|
||||
/* First unfix and release lock on the bpage */
|
||||
buf_pool_mutex_enter(buf_pool);
|
||||
mutex_enter(buf_page_get_mutex(bpage));
|
||||
@@ -4261,18 +4330,23 @@ buf_mark_space_corrupt(
|
||||
}
|
||||
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
}
|
||||
|
||||
/* Find the table with specified space id, and mark it corrupted */
|
||||
if (dict_set_corrupted_by_space(space)) {
|
||||
if (!bpage->encrypted) {
|
||||
buf_LRU_free_one_page(bpage);
|
||||
}
|
||||
} else {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
if (!bpage->encrypted) {
|
||||
ut_ad(buf_pool->n_pend_reads > 0);
|
||||
buf_pool->n_pend_reads--;
|
||||
|
||||
buf_pool_mutex_exit(buf_pool);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@@ -4283,42 +4357,77 @@ corrupted page. Note that we can't be 100% sure if page is corrupted
|
||||
or decrypt/decompress just failed.
|
||||
*/
|
||||
static
|
||||
void
|
||||
ibool
|
||||
buf_page_check_corrupt(
|
||||
/*===================*/
|
||||
const buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
{
|
||||
ulint zip_size = buf_page_get_zip_size(bpage);
|
||||
byte* dst_frame = (zip_size) ? bpage->zip.data :
|
||||
((buf_block_t*) bpage)->frame;
|
||||
unsigned key_version = bpage->key_version;
|
||||
bool page_compressed = bpage->page_encrypted;
|
||||
ulint stored_checksum = bpage->stored_checksum;
|
||||
ulint calculated_checksum = bpage->stored_checksum;
|
||||
bool page_compressed_encrypted = bpage->page_compressed;
|
||||
ulint space_id = mach_read_from_4(
|
||||
dst_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id);
|
||||
fil_space_t* space = fil_space_found_by_id(space_id);
|
||||
bool corrupted = true;
|
||||
|
||||
if (key_version != 0 || page_compressed_encrypted) {
|
||||
bpage->encrypted = true;
|
||||
}
|
||||
|
||||
if (key_version != 0 ||
|
||||
(crypt_data && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED) ||
|
||||
page_compressed || page_compressed_encrypted) {
|
||||
|
||||
/* Page is really corrupted if post encryption stored
|
||||
checksum does not match calculated checksum after page was
|
||||
read. For pages compressed and then encrypted, there is no
|
||||
checksum. */
|
||||
corrupted = (!page_compressed_encrypted && stored_checksum != calculated_checksum);
|
||||
|
||||
if (corrupted) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Maybe corruption: Block space_id %lu in file %s maybe corrupted.",
|
||||
"%s: Block in space_id %lu in file %s corrupted.",
|
||||
page_compressed_encrypted ? "Maybe corruption" : "Corruption",
|
||||
space_id, space ? space->name : "NULL");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Page based on contents %s encrypted.",
|
||||
(key_version == 0 && page_compressed_encrypted == false) ? "not" : "maybe");
|
||||
if (stored_checksum != BUF_NO_CHECKSUM_MAGIC || calculated_checksum != BUF_NO_CHECKSUM_MAGIC) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Page stored checksum %lu but calculated checksum %lu.",
|
||||
stored_checksum, calculated_checksum);
|
||||
}
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Reason could be that key_version %u in page "
|
||||
"or in crypt_data %p could not be found.",
|
||||
key_version, crypt_data);
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Reason could be also that key management plugin is not found or"
|
||||
"used encryption algorithm or method does not match.");
|
||||
" used encryption algorithm or method does not match.");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Based on page page compressed %d, compressed and encrypted %d.",
|
||||
page_compressed, page_compressed_encrypted);
|
||||
} else {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Block in space_id %lu in file %s encrypted.",
|
||||
space_id, space ? space->name : "NULL");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"However key management plugin or used key_id %u is not found or"
|
||||
" used encryption algorithm or method does not match.",
|
||||
key_version);
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Marking tablespace as missing. You may drop this table or"
|
||||
" install correct key management plugin and key file.");
|
||||
}
|
||||
}
|
||||
|
||||
return corrupted;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
@@ -4437,10 +4546,12 @@ buf_page_io_complete(
|
||||
goto page_not_corrupt;
|
||||
;);
|
||||
corrupt:
|
||||
bool corrupted = buf_page_check_corrupt(bpage);
|
||||
|
||||
if (corrupted) {
|
||||
fil_system_enter();
|
||||
space = fil_space_get_by_id(bpage->space);
|
||||
fil_system_exit();
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Database page corruption on disk"
|
||||
" or a failed");
|
||||
@@ -4453,7 +4564,6 @@ corrupt:
|
||||
"You may have to recover"
|
||||
" from a backup.");
|
||||
|
||||
buf_page_check_corrupt(bpage);
|
||||
|
||||
buf_page_print(frame, buf_page_get_zip_size(bpage),
|
||||
BUF_PAGE_PRINT_NO_CRASH);
|
||||
@@ -4475,6 +4585,7 @@ corrupt:
|
||||
"See also "
|
||||
REFMAN "forcing-innodb-recovery.html"
|
||||
" about forcing recovery.");
|
||||
}
|
||||
|
||||
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
|
||||
/* If page space id is larger than TRX_SYS_SPACE
|
||||
@@ -4484,13 +4595,31 @@ corrupt:
|
||||
&& buf_mark_space_corrupt(bpage)) {
|
||||
return(false);
|
||||
} else {
|
||||
buf_page_check_corrupt(bpage);
|
||||
corrupted = buf_page_check_corrupt(bpage);
|
||||
|
||||
if (corrupted) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Ending processing because of a corrupt database page.");
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
||||
ib_push_warning((void *)NULL, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table in tablespace %lu encrypted."
|
||||
"However key management plugin or used key_id %lu is not found or"
|
||||
" used encryption algorithm or method does not match."
|
||||
" Can't continue opening the table.",
|
||||
bpage->key_version);
|
||||
|
||||
if (bpage->space > TRX_SYS_SPACE) {
|
||||
if (corrupted) {
|
||||
buf_mark_space_corrupt(bpage);
|
||||
}
|
||||
} else {
|
||||
ut_error;
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4630,6 +4759,7 @@ buf_all_freed_instance(
|
||||
const buf_block_t* block = buf_chunk_not_freed(chunk);
|
||||
|
||||
if (UNIV_LIKELY_NULL(block)) {
|
||||
if (block->page.key_version == 0) {
|
||||
fprintf(stderr,
|
||||
"Page %lu %lu still fixed or dirty\n",
|
||||
(ulong) block->page.space,
|
||||
@@ -4637,6 +4767,7 @@ buf_all_freed_instance(
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf_pool_mutex_exit(buf_pool);
|
||||
|
||||
@@ -5950,6 +6081,11 @@ buf_page_decrypt_after_read(
|
||||
bool page_compressed_encrypted = fil_page_is_compressed_encrypted(dst_frame);
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
|
||||
/* If page is encrypted read post-encryption checksum */
|
||||
if (!page_compressed_encrypted && key_version != 0) {
|
||||
bpage->stored_checksum = mach_read_from_4(dst_frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4);
|
||||
}
|
||||
|
||||
ut_ad(bpage->key_version == 0);
|
||||
|
||||
if (bpage->offset == 0) {
|
||||
@@ -5994,6 +6130,13 @@ buf_page_decrypt_after_read(
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* Calculate checksum before decrypt, this will be
|
||||
used later to find out if incorrect key was used. */
|
||||
if (!page_compressed_encrypted) {
|
||||
bpage->calculated_checksum = fil_crypt_calculate_checksum(zip_size, dst_frame);
|
||||
}
|
||||
|
||||
/* decrypt using crypt_buf to dst_frame */
|
||||
fil_space_decrypt(bpage->space,
|
||||
slot->crypt_buf,
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015. 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
|
||||
@@ -119,7 +120,8 @@ buf_read_page_low(
|
||||
treat the tablespace as dropped; this is a timestamp we
|
||||
use to stop dangling page reads from a tablespace
|
||||
which we have DISCARDed + IMPORTed back */
|
||||
ulint offset) /*!< in: page number */
|
||||
ulint offset, /*!< in: page number */
|
||||
buf_page_t** rbpage) /*!< out: page */
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
ulint wake_later;
|
||||
@@ -214,10 +216,17 @@ buf_read_page_low(
|
||||
/* The i/o is already completed when we arrive from
|
||||
fil_read */
|
||||
if (!buf_page_io_complete(bpage)) {
|
||||
if (rbpage) {
|
||||
*rbpage = bpage;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rbpage) {
|
||||
*rbpage = bpage;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -348,7 +357,7 @@ read_ahead:
|
||||
&err, false,
|
||||
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, FALSE,
|
||||
tablespace_version, i);
|
||||
tablespace_version, i, NULL);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@@ -398,7 +407,8 @@ buf_read_page(
|
||||
/*==========*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset) /*!< in: page number */
|
||||
ulint offset, /*!< in: page number */
|
||||
buf_page_t** bpage) /*!< out: page */
|
||||
{
|
||||
ib_int64_t tablespace_version;
|
||||
ulint count;
|
||||
@@ -411,7 +421,7 @@ buf_read_page(
|
||||
|
||||
count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
|
||||
zip_size, FALSE,
|
||||
tablespace_version, offset);
|
||||
tablespace_version, offset, bpage);
|
||||
srv_stats.buf_pool_reads.add(count);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
@@ -459,7 +469,7 @@ buf_read_page_async(
|
||||
| OS_AIO_SIMULATED_WAKE_LATER
|
||||
| BUF_READ_IGNORE_NONEXISTENT_PAGES,
|
||||
space, zip_size, FALSE,
|
||||
tablespace_version, offset);
|
||||
tablespace_version, offset, NULL);
|
||||
srv_stats.buf_pool_reads.add(count);
|
||||
|
||||
/* We do not increment number of I/O operations used for LRU policy
|
||||
@@ -718,7 +728,7 @@ buf_read_ahead_linear(
|
||||
count += buf_read_page_low(
|
||||
&err, false,
|
||||
ibuf_mode,
|
||||
space, zip_size, FALSE, tablespace_version, i);
|
||||
space, zip_size, FALSE, tablespace_version, i, NULL);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@@ -808,7 +818,7 @@ buf_read_ibuf_merge_pages(
|
||||
buf_read_page_low(&err, sync && (i + 1 == n_stored),
|
||||
BUF_READ_ANY_PAGE, space_ids[i],
|
||||
zip_size, TRUE, space_versions[i],
|
||||
page_nos[i]);
|
||||
page_nos[i], NULL);
|
||||
|
||||
if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
|
||||
tablespace_deleted:
|
||||
@@ -903,12 +913,12 @@ buf_read_recv_pages(
|
||||
if ((i + 1 == n_stored) && sync) {
|
||||
buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
|
||||
zip_size, TRUE, tablespace_version,
|
||||
page_nos[i]);
|
||||
page_nos[i], NULL);
|
||||
} else {
|
||||
buf_read_page_low(&err, false, BUF_READ_ANY_PAGE
|
||||
| OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, TRUE,
|
||||
tablespace_version, page_nos[i]);
|
||||
tablespace_version, page_nos[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -650,31 +650,8 @@ fil_space_encrypt(
|
||||
|
||||
/* handle post encryption checksum */
|
||||
ib_uint32_t checksum = 0;
|
||||
srv_checksum_algorithm_t algorithm =
|
||||
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
|
||||
|
||||
if (zip_size == 0) {
|
||||
switch (algorithm) {
|
||||
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
|
||||
checksum = buf_calc_page_crc32(dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
|
||||
checksum = (ib_uint32_t) buf_calc_page_new_checksum(
|
||||
dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_NONE:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||
checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
break;
|
||||
/* no default so the compiler will emit a warning
|
||||
* if new enum is added and not handled here */
|
||||
}
|
||||
} else {
|
||||
checksum = page_zip_calc_checksum(dst_frame, zip_size,
|
||||
algorithm);
|
||||
}
|
||||
checksum = fil_crypt_calculate_checksum(zip_size, dst_frame);
|
||||
|
||||
// store the post-encryption checksum after the key-version
|
||||
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
|
||||
@@ -818,6 +795,47 @@ fil_space_decrypt(
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Calculate post encryption checksum
|
||||
@return page checksum or BUF_NO_CHECKSUM_MAGIC
|
||||
not needed. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
fil_crypt_calculate_checksum(
|
||||
/*=========================*/
|
||||
ulint zip_size, /*!< in: zip_size or 0 */
|
||||
byte* dst_frame) /*!< in: page where to calculate */
|
||||
{
|
||||
ib_uint32_t checksum = 0;
|
||||
srv_checksum_algorithm_t algorithm =
|
||||
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
|
||||
|
||||
if (zip_size == 0) {
|
||||
switch (algorithm) {
|
||||
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
|
||||
checksum = buf_calc_page_crc32(dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
|
||||
checksum = (ib_uint32_t) buf_calc_page_new_checksum(
|
||||
dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_NONE:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||
checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
break;
|
||||
/* no default so the compiler will emit a warning
|
||||
* if new enum is added and not handled here */
|
||||
}
|
||||
} else {
|
||||
checksum = page_zip_calc_checksum(dst_frame, zip_size,
|
||||
algorithm);
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Verify checksum for a page (iff it's encrypted)
|
||||
NOTE: currently this function can only be run in single threaded mode
|
||||
|
@@ -1747,6 +1747,7 @@ convert_error_code_to_mysql(
|
||||
|
||||
case DB_TABLESPACE_DELETED:
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
case DB_ENCRYPTED_DECRYPT_FAILED:
|
||||
return(HA_ERR_NO_SUCH_TABLE);
|
||||
|
||||
case DB_TABLESPACE_NOT_FOUND:
|
||||
@@ -5592,7 +5593,14 @@ table_opened:
|
||||
|
||||
innobase_copy_frm_flags_from_table_share(ib_table, table->s);
|
||||
|
||||
ib_table->thd = (void*)thd;
|
||||
|
||||
/* No point to init any statistics if tablespace is still encrypted. */
|
||||
if (!ib_table->is_encrypted) {
|
||||
dict_stats_init(ib_table);
|
||||
} else {
|
||||
ib_table->stat_initialized = 1;
|
||||
}
|
||||
|
||||
MONITOR_INC(MONITOR_TABLE_OPEN);
|
||||
|
||||
@@ -5621,6 +5629,11 @@ table_opened:
|
||||
file, best to play it safe. */
|
||||
|
||||
no_tablespace = true;
|
||||
} else if (ib_table->is_encrypted) {
|
||||
/* This means that tablespace was found but we could not
|
||||
decrypt encrypted page. */
|
||||
no_tablespace = true;
|
||||
ib_table->ibd_file_missing = true;
|
||||
} else {
|
||||
no_tablespace = false;
|
||||
}
|
||||
@@ -5632,9 +5645,9 @@ table_opened:
|
||||
/* If table has no talespace but it has crypt data, check
|
||||
is tablespace made unaccessible because encryption service
|
||||
or used key_id is not available. */
|
||||
if (ib_table && ib_table->crypt_data) {
|
||||
if (ib_table) {
|
||||
fil_space_crypt_t* crypt_data = ib_table->crypt_data;
|
||||
if ((crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
|
||||
if ((crypt_data && crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
|
||||
(srv_encrypt_tables &&
|
||||
crypt_data && crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
|
||||
|
||||
@@ -5646,6 +5659,13 @@ table_opened:
|
||||
" Can't continue reading table.",
|
||||
ib_table->name, crypt_data->key_id);
|
||||
}
|
||||
} else if (ib_table->is_encrypted) {
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
HA_ERR_NO_SUCH_TABLE,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
ib_table->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20212,3 +20232,59 @@ static void innodb_remember_check_sysvar_funcs()
|
||||
ut_ad((MYSQL_SYSVAR_NAME(checksum_algorithm).flags & 0x1FF) == PLUGIN_VAR_ENUM);
|
||||
check_sysvar_enum = MYSQL_SYSVAR_NAME(checksum_algorithm).check;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
trx_t* trx, /*!< in: trx */
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
THD *thd = (THD *)trx->mysql_thd;
|
||||
char *buf;
|
||||
#define MAX_BUF_SIZE 4*1024
|
||||
|
||||
va_start(args, format);
|
||||
buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME));
|
||||
vsprintf(buf,format, args);
|
||||
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
convert_error_code_to_mysql((dberr_t)error, 0, thd),
|
||||
buf);
|
||||
my_free(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
void* ithd, /*!< in: thd */
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
THD *thd = (THD *)ithd;
|
||||
char *buf;
|
||||
#define MAX_BUF_SIZE 4*1024
|
||||
|
||||
if (ithd == NULL) {
|
||||
thd = current_thd;
|
||||
}
|
||||
|
||||
va_start(args, format);
|
||||
buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME));
|
||||
vsprintf(buf,format, args);
|
||||
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
convert_error_code_to_mysql((dberr_t)error, 0, thd),
|
||||
buf);
|
||||
my_free(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -59,12 +60,14 @@ btr_block_get_func(
|
||||
block = buf_page_get_gen(space, zip_size, page_no, mode,
|
||||
NULL, BUF_GET, file, line, mtr);
|
||||
|
||||
if (block) {
|
||||
if (mode != RW_NO_LATCH) {
|
||||
|
||||
buf_block_dbg_add_level(
|
||||
block, index != NULL && dict_index_is_ibuf(index)
|
||||
? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
|
||||
}
|
||||
}
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
@@ -136,7 +136,7 @@ Note that if mode is PAGE_CUR_LE, which is used in inserts, then
|
||||
cursor->up_match and cursor->low_match both will have sensible values.
|
||||
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_search_to_nth_level(
|
||||
/*========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -173,7 +173,7 @@ btr_cur_search_to_nth_level(
|
||||
/*****************************************************************//**
|
||||
Opens a cursor at either end of an index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_open_at_index_side_func(
|
||||
/*============================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
|
@@ -114,7 +114,7 @@ btr_pcur_open_low(
|
||||
Opens an persistent cursor to an index tree without initializing the
|
||||
cursor. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_with_no_init_func(
|
||||
/*============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -143,7 +143,7 @@ btr_pcur_open_with_no_init_func(
|
||||
/*****************************************************************//**
|
||||
Opens a persistent cursor at either end of an index. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_at_index_side(
|
||||
/*========================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
|
@@ -447,7 +447,7 @@ btr_pcur_open_low(
|
||||
Opens an persistent cursor to an index tree without initializing the
|
||||
cursor. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_with_no_init_func(
|
||||
/*============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -472,6 +472,7 @@ btr_pcur_open_with_no_init_func(
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
btr_cur_t* btr_cursor;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
cursor->latch_mode = latch_mode;
|
||||
cursor->search_mode = mode;
|
||||
@@ -480,7 +481,7 @@ btr_pcur_open_with_no_init_func(
|
||||
|
||||
btr_cursor = btr_pcur_get_btr_cur(cursor);
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
|
||||
err = btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
|
||||
btr_cursor, has_search_latch,
|
||||
file, line, mtr);
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
@@ -488,12 +489,13 @@ btr_pcur_open_with_no_init_func(
|
||||
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
|
||||
cursor->trx_if_known = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a persistent cursor at either end of an index. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_at_index_side(
|
||||
/*========================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
@@ -506,6 +508,8 @@ btr_pcur_open_at_index_side(
|
||||
(0=leaf) */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
pcur->latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
|
||||
|
||||
pcur->search_mode = from_left ? PAGE_CUR_G : PAGE_CUR_L;
|
||||
@@ -514,13 +518,15 @@ btr_pcur_open_at_index_side(
|
||||
btr_pcur_init(pcur);
|
||||
}
|
||||
|
||||
btr_cur_open_at_index_side(from_left, index, latch_mode,
|
||||
err = btr_cur_open_at_index_side(from_left, index, latch_mode,
|
||||
btr_pcur_get_btr_cur(pcur), level, mtr);
|
||||
pcur->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
|
||||
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
|
||||
pcur->trx_if_known = NULL;
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, 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
|
||||
@@ -430,7 +430,8 @@ buf_page_get_gen(
|
||||
BUF_GET_IF_IN_POOL_OR_WATCH */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mini-transaction */
|
||||
mtr_t* mtr, /*!< in: mini-transaction */
|
||||
dberr_t* err = NULL); /*!< out: error code */
|
||||
/********************************************************************//**
|
||||
Initializes a page to the buffer buf_pool. The page is usually not read
|
||||
from a file even if it cannot be found in the buffer buf_pool. This is one
|
||||
@@ -1582,9 +1583,14 @@ struct buf_page_t{
|
||||
operation needed. */
|
||||
|
||||
unsigned key_version; /*!< key version for this block */
|
||||
bool page_encrypted; /*!< page is encrypted */
|
||||
bool page_encrypted; /*!< page is page encrypted */
|
||||
bool page_compressed;/*!< page is page compressed */
|
||||
|
||||
ulint stored_checksum;/*!< stored page checksum if page
|
||||
encrypted */
|
||||
bool encrypted; /*!< page is still encrypted */
|
||||
ulint calculated_checksum;
|
||||
/*!< calculated checksum if page
|
||||
encrypted */
|
||||
ulint real_size; /*!< Real size of the page
|
||||
Normal pages == UNIV_PAGE_SIZE
|
||||
page compressed pages, payload
|
||||
|
@@ -663,13 +663,18 @@ buf_block_get_frame(
|
||||
/*================*/
|
||||
const buf_block_t* block) /*!< in: pointer to the control block */
|
||||
{
|
||||
ut_ad(block);
|
||||
if (!block) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (buf_block_get_state(block)) {
|
||||
case BUF_BLOCK_POOL_WATCH:
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
case BUF_BLOCK_NOT_USED:
|
||||
if (block->page.encrypted) {
|
||||
goto ok;
|
||||
}
|
||||
ut_error;
|
||||
break;
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -41,7 +42,8 @@ buf_read_page(
|
||||
/*==========*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset);/*!< in: page number */
|
||||
ulint offset, /*!< in: page number */
|
||||
buf_page_t** bpage);/*!< out: page */
|
||||
/********************************************************************//**
|
||||
High-level function which reads a page asynchronously from a file to the
|
||||
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -132,6 +133,11 @@ enum dberr_t {
|
||||
/*< Too many words in a phrase */
|
||||
DB_TOO_BIG_FOR_REDO, /* Record length greater than 10%
|
||||
of redo log */
|
||||
DB_ENCRYPTED_DECRYPT_FAILED, /* Tablespace encrypted and
|
||||
decrypt operaton failed because
|
||||
of missing key management plugin,
|
||||
or missing or incorrect key or
|
||||
incorret AES method or algorithm. */
|
||||
/* The following are partial failure codes */
|
||||
DB_FAIL = 1000,
|
||||
DB_OVERFLOW,
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, 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
|
||||
@@ -1017,6 +1017,7 @@ struct dict_table_t{
|
||||
table_id_t id; /*!< id of the table */
|
||||
mem_heap_t* heap; /*!< memory heap */
|
||||
char* name; /*!< table name */
|
||||
void* thd; /*!< thd */
|
||||
fil_space_crypt_t *crypt_data; /*!< crypt data if present */
|
||||
const char* dir_path_of_temp_table;/*!< NULL or the directory path
|
||||
where a TEMPORARY table that was explicitly
|
||||
@@ -1330,6 +1331,7 @@ struct dict_table_t{
|
||||
locks; /*!< list of locks on the table; protected
|
||||
by lock_sys->mutex */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
ibool is_encrypted;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint magic_n;/*!< magic number */
|
||||
|
@@ -382,6 +382,17 @@ fil_crypt_set_encrypt_tables(
|
||||
uint val); /*!< in: New srv_encrypt_tables setting */
|
||||
|
||||
|
||||
/******************************************************************
|
||||
Calculate post encryption checksum
|
||||
@return page checksum or BUF_NO_CHECKSUM_MAGIC
|
||||
not needed. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
fil_crypt_calculate_checksum(
|
||||
/*=========================*/
|
||||
ulint zip_size, /*!< in: zip_size or 0 */
|
||||
byte* dst_frame); /*!< in: page where to calculate */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "fil0crypt.ic"
|
||||
#endif
|
||||
|
@@ -634,5 +634,13 @@ ib_push_warning(
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...);
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
void* ithd, /*!< in: thd */
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...);
|
||||
#endif /* HA_INNODB_PROTOTYPES_H */
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -39,7 +40,10 @@ page_cur_get_page(
|
||||
page_cur_t* cur) /*!< in: page cursor */
|
||||
{
|
||||
ut_ad(cur);
|
||||
|
||||
if (cur->rec) {
|
||||
ut_ad(page_align(cur->rec) == cur->block->frame);
|
||||
}
|
||||
|
||||
return(page_align(cur->rec));
|
||||
}
|
||||
@@ -54,7 +58,11 @@ page_cur_get_block(
|
||||
page_cur_t* cur) /*!< in: page cursor */
|
||||
{
|
||||
ut_ad(cur);
|
||||
|
||||
if (cur->rec) {
|
||||
ut_ad(page_align(cur->rec) == cur->block->frame);
|
||||
}
|
||||
|
||||
return(cur->block);
|
||||
}
|
||||
|
||||
@@ -80,7 +88,10 @@ page_cur_get_rec(
|
||||
page_cur_t* cur) /*!< in: page cursor */
|
||||
{
|
||||
ut_ad(cur);
|
||||
|
||||
if (cur->rec) {
|
||||
ut_ad(page_align(cur->rec) == cur->block->frame);
|
||||
}
|
||||
|
||||
return(cur->rec);
|
||||
}
|
||||
|
@@ -2338,7 +2338,7 @@ row_ins_clust_index_entry_low(
|
||||
{
|
||||
btr_cur_t cursor;
|
||||
ulint* offsets = NULL;
|
||||
dberr_t err;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
big_rec_t* big_rec = NULL;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* offsets_heap = NULL;
|
||||
@@ -2361,9 +2361,16 @@ row_ins_clust_index_entry_low(
|
||||
the function will return in both low_match and up_match of the
|
||||
cursor sensible values */
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, mode,
|
||||
err = btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, mode,
|
||||
&cursor, 0, __FILE__, __LINE__, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
index->table->is_encrypted = true;
|
||||
index->table->ibd_file_missing = true;
|
||||
mtr_commit(&mtr);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
page_t* page = btr_cur_get_page(&cursor);
|
||||
@@ -2669,10 +2676,23 @@ row_ins_sec_index_entry_low(
|
||||
search_mode |= BTR_IGNORE_SEC_UNIQUE;
|
||||
}
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
|
||||
err = btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
|
||||
search_mode,
|
||||
&cursor, 0, __FILE__, __LINE__, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning(trx->mysql_thd,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
|
||||
/* The insert was buffered during the search: we are done */
|
||||
goto func_exit;
|
||||
|
@@ -623,6 +623,8 @@ handle_new_error:
|
||||
case DB_FTS_INVALID_DOCID:
|
||||
case DB_INTERRUPTED:
|
||||
case DB_DICT_CHANGED:
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
case DB_ENCRYPTED_DECRYPT_FAILED:
|
||||
if (savept) {
|
||||
/* Roll back the latest, possibly incomplete insertion
|
||||
or update */
|
||||
@@ -1315,7 +1317,13 @@ row_insert_for_mysql(
|
||||
prebuilt->table->name);
|
||||
|
||||
return(DB_TABLESPACE_NOT_FOUND);
|
||||
|
||||
} else if (prebuilt->table->is_encrypted) {
|
||||
ib_push_warning(trx, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s in tablespace %lu encrypted."
|
||||
"However key management plugin or used key_id is not found or"
|
||||
" used encryption algorithm or method does not match.",
|
||||
prebuilt->table->name, prebuilt->table->space);
|
||||
return(DB_ENCRYPTED_DECRYPT_FAILED);
|
||||
} else if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
@@ -1710,6 +1718,13 @@ row_update_for_mysql(
|
||||
"InnoDB: how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
return(DB_ERROR);
|
||||
} else if (prebuilt->table->is_encrypted) {
|
||||
ib_push_warning(trx, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s in tablespace %lu encrypted."
|
||||
"However key management plugin or used key_id is not found or"
|
||||
" used encryption algorithm or method does not match.",
|
||||
prebuilt->table->name, prebuilt->table->space);
|
||||
return (DB_TABLE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
|
||||
@@ -3919,6 +3934,19 @@ row_drop_table_for_mysql(
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* If table is encrypted and table page encryption failed
|
||||
mark this table read only. */
|
||||
if (table->is_encrypted) {
|
||||
|
||||
if (table->can_be_evicted) {
|
||||
dict_table_move_from_lru_to_non_lru(table);
|
||||
}
|
||||
|
||||
dict_table_close(table, TRUE, FALSE);
|
||||
err = DB_READ_ONLY;
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* Turn on this drop bit before we could release the dictionary
|
||||
latch */
|
||||
table->to_be_dropped = true;
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2015, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
@@ -3717,6 +3718,9 @@ row_search_for_mysql(
|
||||
|
||||
return(DB_TABLESPACE_NOT_FOUND);
|
||||
|
||||
} else if (prebuilt->table->is_encrypted) {
|
||||
|
||||
return(DB_ENCRYPTED_DECRYPT_FAILED);
|
||||
} else if (!prebuilt->index_usable) {
|
||||
|
||||
return(DB_MISSING_HISTORY);
|
||||
@@ -4143,10 +4147,15 @@ wait_table_again:
|
||||
|
||||
} else if (dtuple_get_n_fields(search_tuple) > 0) {
|
||||
|
||||
btr_pcur_open_with_no_init(index, search_tuple, mode,
|
||||
err = btr_pcur_open_with_no_init(index, search_tuple, mode,
|
||||
BTR_SEARCH_LEAF,
|
||||
pcur, 0, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
rec = NULL;
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
|
||||
pcur->trx_if_known = trx;
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
@@ -4179,9 +4188,23 @@ wait_table_again:
|
||||
}
|
||||
}
|
||||
} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_L) {
|
||||
btr_pcur_open_at_index_side(
|
||||
err = btr_pcur_open_at_index_side(
|
||||
mode == PAGE_CUR_G, index, BTR_SEARCH_LEAF,
|
||||
pcur, false, 0, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning(trx->mysql_thd,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
prebuilt->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
rec = NULL;
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
||||
rec_loop:
|
||||
@@ -4196,6 +4219,12 @@ rec_loop:
|
||||
/* PHASE 4: Look for matching records in a loop */
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
if (!rec) {
|
||||
err = DB_ENCRYPTED_DECRYPT_FAILED;
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
|
||||
ut_ad(!!page_rec_is_comp(rec) == comp);
|
||||
#ifdef UNIV_SEARCH_DEBUG
|
||||
/*
|
||||
@@ -5113,7 +5142,9 @@ lock_wait_or_error:
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
if (rec) {
|
||||
btr_pcur_store_position(pcur, &mtr);
|
||||
}
|
||||
|
||||
lock_table_wait:
|
||||
mtr_commit(&mtr);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2014, 2015, 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
|
||||
@@ -741,6 +742,19 @@ btr_root_block_get(
|
||||
|
||||
block = btr_block_get(space, zip_size, root_page_no, mode, index, mtr);
|
||||
|
||||
if (!block) {
|
||||
index->table->is_encrypted = TRUE;
|
||||
index->table->corrupted = FALSE;
|
||||
|
||||
ib_push_warning(index->table->thd, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s in tablespace %lu is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name, space);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRV_CORRUPT_TABLE_CHECK(block, return(0););
|
||||
|
||||
btr_assert_not_corrupted(block, index);
|
||||
@@ -779,8 +793,10 @@ btr_root_get(
|
||||
const dict_index_t* index, /*!< in: index tree */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
return(buf_block_get_frame(btr_root_block_get(index, RW_X_LATCH,
|
||||
mtr)));
|
||||
buf_block_t* root = btr_root_block_get(index, RW_X_LATCH,
|
||||
mtr);
|
||||
|
||||
return(root ? buf_block_get_frame(root) : NULL);
|
||||
}
|
||||
|
||||
/**************************************************************//**
|
||||
@@ -795,7 +811,7 @@ btr_height_get(
|
||||
dict_index_t* index, /*!< in: index tree */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint height;
|
||||
ulint height=0;
|
||||
buf_block_t* root_block;
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
|
||||
@@ -806,6 +822,8 @@ btr_height_get(
|
||||
/* S latches the page */
|
||||
root_block = btr_root_block_get(index, RW_S_LATCH, mtr);
|
||||
|
||||
if (root_block) {
|
||||
|
||||
height = btr_page_get_level(buf_block_get_frame_fast(root_block), mtr);
|
||||
|
||||
/* Release the S latch on the root page. */
|
||||
@@ -813,6 +831,7 @@ btr_height_get(
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
sync_thread_reset_level(&root_block->lock);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
return(height);
|
||||
}
|
||||
@@ -1260,7 +1279,7 @@ btr_get_size_and_reserved(
|
||||
{
|
||||
fseg_header_t* seg_header;
|
||||
page_t* root;
|
||||
ulint n;
|
||||
ulint n=ULINT_UNDEFINED;
|
||||
ulint dummy;
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
|
||||
@@ -1274,6 +1293,9 @@ btr_get_size_and_reserved(
|
||||
}
|
||||
|
||||
root = btr_root_get(index, mtr);
|
||||
*used = 0;
|
||||
|
||||
if (root) {
|
||||
|
||||
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
|
||||
|
||||
@@ -1286,6 +1308,7 @@ btr_get_size_and_reserved(
|
||||
*used += dummy;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return(n);
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2015, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
@@ -386,7 +387,7 @@ search tuple should be performed in the B-tree. InnoDB does an insert
|
||||
immediately after the cursor. Thus, the cursor may end up on a user record,
|
||||
or on a page infimum record. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_search_to_nth_level(
|
||||
/*========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -436,6 +437,7 @@ btr_cur_search_to_nth_level(
|
||||
page_cur_t* page_cursor;
|
||||
btr_op_t btr_op;
|
||||
ulint root_height = 0; /* remove warning */
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
#ifdef BTR_CUR_ADAPT
|
||||
btr_search_t* info;
|
||||
@@ -553,7 +555,7 @@ btr_cur_search_to_nth_level(
|
||||
|| mode != PAGE_CUR_LE);
|
||||
btr_cur_n_sea++;
|
||||
|
||||
return;
|
||||
return err;
|
||||
}
|
||||
# endif /* BTR_CUR_HASH_ADAPT */
|
||||
#endif /* BTR_CUR_ADAPT */
|
||||
@@ -649,7 +651,21 @@ search_loop:
|
||||
retry_page_get:
|
||||
block = buf_page_get_gen(
|
||||
space, zip_size, page_no, rw_latch, guess, buf_mode,
|
||||
file, line, mtr);
|
||||
file, line, mtr, &err);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
SRV_CORRUPT_TABLE_CHECK(buf_mode == BUF_GET_IF_IN_POOL ||
|
||||
@@ -889,12 +905,14 @@ func_exit:
|
||||
|
||||
rw_lock_s_lock(btr_search_get_latch(cursor->index));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a cursor at either end of an index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_open_at_index_side_func(
|
||||
/*============================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
@@ -920,6 +938,8 @@ btr_cur_open_at_index_side_func(
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
estimate = latch_mode & BTR_ESTIMATE;
|
||||
@@ -957,11 +977,26 @@ btr_cur_open_at_index_side_func(
|
||||
height = ULINT_UNDEFINED;
|
||||
|
||||
for (;;) {
|
||||
buf_block_t* block;
|
||||
page_t* page;
|
||||
buf_block_t* block=NULL;
|
||||
page_t* page=NULL;
|
||||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
file, line, mtr);
|
||||
file, line, mtr, &err);
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
SRV_CORRUPT_TABLE_CHECK(page,
|
||||
@@ -1066,6 +1101,8 @@ exit_loop:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
@@ -1113,10 +1150,25 @@ btr_cur_open_at_rnd_pos_func(
|
||||
for (;;) {
|
||||
buf_block_t* block;
|
||||
page_t* page;
|
||||
dberr_t err=DB_SUCCESS;
|
||||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
file, line, mtr);
|
||||
file, line, mtr, &err);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
SRV_CORRUPT_TABLE_CHECK(page,
|
||||
@@ -3749,6 +3801,7 @@ btr_estimate_n_rows_in_range_on_level(
|
||||
mtr_t mtr;
|
||||
page_t* page;
|
||||
buf_block_t* block;
|
||||
dberr_t err=DB_SUCCESS;
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
@@ -3759,7 +3812,23 @@ btr_estimate_n_rows_in_range_on_level(
|
||||
silence a debug assertion about this. */
|
||||
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH,
|
||||
NULL, BUF_GET_POSSIBLY_FREED,
|
||||
__FILE__, __LINE__, &mtr);
|
||||
__FILE__, __LINE__, &mtr, &err);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
goto inexact;
|
||||
}
|
||||
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
|
@@ -59,11 +59,24 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "srv0start.h"
|
||||
#include "ut0byte.h"
|
||||
#include "fil0pagecompress.h"
|
||||
#include "ha_prototypes.h"
|
||||
|
||||
|
||||
/* prototypes for new functions added to ha_innodb.cc */
|
||||
trx_t* innobase_get_trx();
|
||||
|
||||
/********************************************************************//**
|
||||
Check if page is maybe compressed, encrypted or both when we encounter
|
||||
corrupted page. Note that we can't be 100% sure if page is corrupted
|
||||
or decrypt/decompress just failed.
|
||||
*/
|
||||
static
|
||||
ibool
|
||||
buf_page_check_corrupt(
|
||||
/*===================*/
|
||||
buf_page_t* bpage); /*!< in/out: buffer page read from
|
||||
disk */
|
||||
|
||||
static inline
|
||||
void
|
||||
_increment_page_get_statistics(buf_block_t* block, trx_t* trx)
|
||||
@@ -1128,6 +1141,9 @@ buf_block_init(
|
||||
block->page.key_version = 0;
|
||||
block->page.page_encrypted = false;
|
||||
block->page.page_compressed = false;
|
||||
block->page.encrypted = false;
|
||||
block->page.stored_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
block->page.calculated_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
block->page.real_size = 0;
|
||||
block->page.write_size = 0;
|
||||
block->modify_clock = 0;
|
||||
@@ -2234,7 +2250,7 @@ lookup:
|
||||
/* Page not in buf_pool: needs to be read from file */
|
||||
|
||||
ut_ad(!hash_lock);
|
||||
buf_read_page(space, zip_size, offset, trx);
|
||||
buf_read_page(space, zip_size, offset, trx, NULL);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(++buf_dbg_counter % 5771 || buf_validate());
|
||||
@@ -2753,7 +2769,8 @@ buf_page_get_gen(
|
||||
BUF_GET_IF_IN_POOL_OR_WATCH */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mini-transaction */
|
||||
mtr_t* mtr, /*!< in: mini-transaction */
|
||||
dberr_t* err) /*!< out: error code */
|
||||
{
|
||||
buf_block_t* block;
|
||||
ulint fold;
|
||||
@@ -2771,6 +2788,11 @@ buf_page_get_gen(
|
||||
ut_ad((rw_latch == RW_S_LATCH)
|
||||
|| (rw_latch == RW_X_LATCH)
|
||||
|| (rw_latch == RW_NO_LATCH));
|
||||
|
||||
if (err) {
|
||||
*err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
switch (mode) {
|
||||
case BUF_GET_NO_LATCH:
|
||||
@@ -2834,6 +2856,8 @@ loop:
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
buf_page_t* bpage=NULL;
|
||||
|
||||
/* Page not in buf_pool: needs to be read from file */
|
||||
|
||||
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
|
||||
@@ -2868,19 +2892,47 @@ loop:
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (buf_read_page(space, zip_size, offset, trx)) {
|
||||
if (buf_read_page(space, zip_size, offset, trx, &bpage)) {
|
||||
buf_read_ahead_random(space, zip_size, offset,
|
||||
ibuf_inside(mtr), trx);
|
||||
|
||||
retries = 0;
|
||||
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
|
||||
++retries;
|
||||
|
||||
bool corrupted = true;
|
||||
|
||||
if (bpage) {
|
||||
corrupted = buf_page_check_corrupt(bpage);
|
||||
}
|
||||
|
||||
/* Do not try again for encrypted pages */
|
||||
if (!corrupted) {
|
||||
ib_mutex_t* pmutex = buf_page_get_mutex(bpage);
|
||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||
mutex_enter(pmutex);
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
buf_LRU_free_page(bpage, zip_size ? true : false);
|
||||
mutex_exit(pmutex);
|
||||
|
||||
if (err) {
|
||||
*err = DB_ENCRYPTED_DECRYPT_FAILED;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
"innodb_page_corruption_retries",
|
||||
retries = BUF_PAGE_READ_MAX_RETRIES;
|
||||
);
|
||||
} else {
|
||||
bool corrupted = true;
|
||||
|
||||
if (bpage) {
|
||||
corrupted = buf_page_check_corrupt(bpage);
|
||||
}
|
||||
|
||||
if (corrupted) {
|
||||
fprintf(stderr, "InnoDB: Error: Unable"
|
||||
" to read tablespace %lu page no"
|
||||
" %lu into the buffer pool after"
|
||||
@@ -2898,6 +2950,19 @@ loop:
|
||||
BUF_PAGE_READ_MAX_RETRIES);
|
||||
|
||||
ut_error;
|
||||
} else {
|
||||
ib_mutex_t* pmutex = buf_page_get_mutex(bpage);
|
||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||
mutex_enter(pmutex);
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
buf_LRU_free_page(bpage, zip_size ? true : false);
|
||||
mutex_exit(pmutex);
|
||||
|
||||
if (err) {
|
||||
*err = DB_ENCRYPTED_DECRYPT_FAILED;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
@@ -3670,8 +3735,11 @@ buf_page_init_low(
|
||||
bpage->oldest_modification = 0;
|
||||
bpage->write_size = 0;
|
||||
bpage->key_version = 0;
|
||||
bpage->stored_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
bpage->calculated_checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
bpage->page_encrypted = false;
|
||||
bpage->page_compressed = false;
|
||||
bpage->encrypted = false;
|
||||
bpage->real_size = 0;
|
||||
|
||||
HASH_INVALIDATE(bpage, hash);
|
||||
@@ -4341,6 +4409,8 @@ buf_mark_space_corrupt(
|
||||
|
||||
/* First unfix and release lock on the bpage */
|
||||
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
|
||||
|
||||
if (!bpage->encrypted) {
|
||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||
rw_lock_x_lock(hash_lock);
|
||||
mutex_enter(buf_page_get_mutex(bpage));
|
||||
@@ -4355,19 +4425,25 @@ buf_mark_space_corrupt(
|
||||
&((buf_block_t*) bpage)->lock,
|
||||
BUF_IO_READ);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the table with specified space id, and mark it corrupted */
|
||||
if (dict_set_corrupted_by_space(space)) {
|
||||
if (!bpage->encrypted) {
|
||||
buf_LRU_free_one_page(bpage);
|
||||
}
|
||||
} else {
|
||||
if (!bpage->encrypted) {
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
}
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
if(!bpage->encrypted) {
|
||||
mutex_exit(&buf_pool->LRU_list_mutex);
|
||||
|
||||
ut_ad(buf_pool->n_pend_reads > 0);
|
||||
os_atomic_decrement_ulint(&buf_pool->n_pend_reads, 1);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@@ -4378,42 +4454,77 @@ corrupted page. Note that we can't be 100% sure if page is corrupted
|
||||
or decrypt/decompress just failed.
|
||||
*/
|
||||
static
|
||||
void
|
||||
ibool
|
||||
buf_page_check_corrupt(
|
||||
/*===================*/
|
||||
const buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
{
|
||||
ulint zip_size = buf_page_get_zip_size(bpage);
|
||||
byte* dst_frame = (zip_size) ? bpage->zip.data :
|
||||
((buf_block_t*) bpage)->frame;
|
||||
unsigned key_version = bpage->key_version;
|
||||
bool page_compressed = bpage->page_encrypted;
|
||||
ulint stored_checksum = bpage->stored_checksum;
|
||||
ulint calculated_checksum = bpage->stored_checksum;
|
||||
bool page_compressed_encrypted = bpage->page_compressed;
|
||||
ulint space_id = mach_read_from_4(
|
||||
dst_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id);
|
||||
fil_space_t* space = fil_space_found_by_id(space_id);
|
||||
bool corrupted = true;
|
||||
|
||||
if (key_version != 0 || page_compressed_encrypted) {
|
||||
bpage->encrypted = true;
|
||||
}
|
||||
|
||||
if (key_version != 0 ||
|
||||
(crypt_data && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED) ||
|
||||
page_compressed || page_compressed_encrypted) {
|
||||
|
||||
/* Page is really corrupted if post encryption stored
|
||||
checksum does not match calculated checksum after page was
|
||||
read. For pages compressed and then encrypted, there is no
|
||||
checksum. */
|
||||
corrupted = (!page_compressed_encrypted && stored_checksum != calculated_checksum);
|
||||
|
||||
if (corrupted) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Maybe corruption: Block space_id %lu in file %s maybe corrupted.",
|
||||
"%s: Block in space_id %lu in file %s corrupted.",
|
||||
page_compressed_encrypted ? "Maybe corruption" : "Corruption",
|
||||
space_id, space ? space->name : "NULL");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Page based on contents %s encrypted.",
|
||||
(key_version == 0 && page_compressed_encrypted == false) ? "not" : "maybe");
|
||||
if (stored_checksum != BUF_NO_CHECKSUM_MAGIC || calculated_checksum != BUF_NO_CHECKSUM_MAGIC) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Page stored checksum %lu but calculated checksum %lu.",
|
||||
stored_checksum, calculated_checksum);
|
||||
}
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Reason could be that key_version %u in page "
|
||||
"or in crypt_data %p could not be found.",
|
||||
key_version, crypt_data);
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Reason could be also that key management plugin is not found or"
|
||||
"used encryption algorithm or method does not match.");
|
||||
" used encryption algorithm or method does not match.");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Based on page page compressed %d, compressed and encrypted %d.",
|
||||
page_compressed, page_compressed_encrypted);
|
||||
} else {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Block in space_id %lu in file %s encrypted.",
|
||||
space_id, space ? space->name : "NULL");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"However key management plugin or used key_id %u is not found or"
|
||||
" used encryption algorithm or method does not match.",
|
||||
key_version);
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Marking tablespace as missing. You may drop this table or"
|
||||
" install correct key management plugin and key file.");
|
||||
}
|
||||
}
|
||||
|
||||
return corrupted;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
@@ -4534,6 +4645,9 @@ buf_page_io_complete(
|
||||
;);
|
||||
corrupt:
|
||||
|
||||
bool corrupted = buf_page_check_corrupt(bpage);
|
||||
|
||||
if (corrupted) {
|
||||
fil_system_enter();
|
||||
space = fil_space_get_by_id(bpage->space);
|
||||
fil_system_exit();
|
||||
@@ -4549,10 +4663,10 @@ corrupt:
|
||||
"You may have to recover"
|
||||
" from a backup.");
|
||||
|
||||
buf_page_check_corrupt(bpage);
|
||||
|
||||
buf_page_print(frame, buf_page_get_zip_size(bpage),
|
||||
BUF_PAGE_PRINT_NO_CRASH);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"It is also possible that your operating"
|
||||
"system has corrupted its own file cache.");
|
||||
@@ -4570,6 +4684,7 @@ corrupt:
|
||||
"See also "
|
||||
REFMAN "forcing-innodb-recovery.html"
|
||||
" about forcing recovery.");
|
||||
}
|
||||
|
||||
if (srv_pass_corrupt_table && bpage->space != 0
|
||||
&& bpage->space < SRV_LOG_SPACE_FIRST_ID) {
|
||||
@@ -4597,13 +4712,31 @@ corrupt:
|
||||
&& buf_mark_space_corrupt(bpage)) {
|
||||
return(false);
|
||||
} else {
|
||||
buf_page_check_corrupt(bpage);
|
||||
corrupted = buf_page_check_corrupt(bpage);
|
||||
|
||||
if (corrupted) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Ending processing because of a corrupt database page.");
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
||||
ib_push_warning(innobase_get_trx(), DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table in tablespace %lu encrypted."
|
||||
"However key management plugin or used key_id %lu is not found or"
|
||||
" used encryption algorithm or method does not match."
|
||||
" Can't continue opening the table.",
|
||||
bpage->key_version);
|
||||
|
||||
if (bpage->space > TRX_SYS_SPACE) {
|
||||
if (corrupted) {
|
||||
buf_mark_space_corrupt(bpage);
|
||||
}
|
||||
} else {
|
||||
ut_error;
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /**/
|
||||
@@ -4780,6 +4913,7 @@ buf_all_freed_instance(
|
||||
mutex_exit(&buf_pool->LRU_list_mutex);
|
||||
|
||||
if (UNIV_LIKELY_NULL(block)) {
|
||||
if (block->page.key_version == 0) {
|
||||
fprintf(stderr,
|
||||
"Page %lu %lu still fixed or dirty\n",
|
||||
(ulong) block->page.space,
|
||||
@@ -4787,6 +4921,7 @@ buf_all_freed_instance(
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
@@ -6124,6 +6259,11 @@ buf_page_decrypt_after_read(
|
||||
bool page_compressed_encrypted = fil_page_is_compressed_encrypted(dst_frame);
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
|
||||
/* If page is encrypted read post-encryption checksum */
|
||||
if (!page_compressed_encrypted && key_version != 0) {
|
||||
bpage->stored_checksum = mach_read_from_4(dst_frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4);
|
||||
}
|
||||
|
||||
ut_ad(bpage->key_version == 0);
|
||||
|
||||
if (bpage->offset == 0) {
|
||||
@@ -6168,6 +6308,13 @@ buf_page_decrypt_after_read(
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* Calculate checksum before decrypt, this will be
|
||||
used later to find out if incorrect key was used. */
|
||||
if (!page_compressed_encrypted) {
|
||||
bpage->calculated_checksum = fil_crypt_calculate_checksum(zip_size, dst_frame);
|
||||
}
|
||||
|
||||
/* decrypt using crypt_buf to dst_frame */
|
||||
fil_space_decrypt(bpage->space,
|
||||
slot->crypt_buf,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2014, 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
|
||||
@@ -124,7 +124,8 @@ buf_read_page_low(
|
||||
use to stop dangling page reads from a tablespace
|
||||
which we have DISCARDed + IMPORTed back */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx)
|
||||
trx_t* trx, /*!< in: trx */
|
||||
buf_page_t** rbpage) /*!< out: page */
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
ulint wake_later;
|
||||
@@ -259,10 +260,17 @@ not_to_recover:
|
||||
/* The i/o is already completed when we arrive from
|
||||
fil_read */
|
||||
if (!buf_page_io_complete(bpage)) {
|
||||
if (rbpage) {
|
||||
*rbpage = bpage;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rbpage) {
|
||||
*rbpage = bpage;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -398,7 +406,7 @@ read_ahead:
|
||||
&err, false,
|
||||
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, FALSE,
|
||||
tablespace_version, i, trx);
|
||||
tablespace_version, i, trx, NULL);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@@ -447,9 +455,10 @@ ibool
|
||||
buf_read_page(
|
||||
/*==========*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint zip_size, /*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx)
|
||||
trx_t* trx, /*!< in: trx */
|
||||
buf_page_t** bpage) /*!< out: page */
|
||||
{
|
||||
ib_int64_t tablespace_version;
|
||||
ulint count;
|
||||
@@ -462,7 +471,7 @@ buf_read_page(
|
||||
|
||||
count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
|
||||
zip_size, FALSE,
|
||||
tablespace_version, offset, trx);
|
||||
tablespace_version, offset, trx, bpage);
|
||||
srv_stats.buf_pool_reads.add(count);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
@@ -510,7 +519,7 @@ buf_read_page_async(
|
||||
| OS_AIO_SIMULATED_WAKE_LATER
|
||||
| BUF_READ_IGNORE_NONEXISTENT_PAGES,
|
||||
space, zip_size, FALSE,
|
||||
tablespace_version, offset, NULL);
|
||||
tablespace_version, offset, NULL,NULL);
|
||||
srv_stats.buf_pool_reads.add(count);
|
||||
|
||||
/* We do not increment number of I/O operations used for LRU policy
|
||||
@@ -778,7 +787,7 @@ buf_read_ahead_linear(
|
||||
count += buf_read_page_low(
|
||||
&err, false,
|
||||
ibuf_mode,
|
||||
space, zip_size, FALSE, tablespace_version, i, trx);
|
||||
space, zip_size, FALSE, tablespace_version, i, trx, NULL);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@@ -868,7 +877,7 @@ buf_read_ibuf_merge_pages(
|
||||
buf_read_page_low(&err, sync && (i + 1 == n_stored),
|
||||
BUF_READ_ANY_PAGE, space_ids[i],
|
||||
zip_size, TRUE, space_versions[i],
|
||||
page_nos[i], NULL);
|
||||
page_nos[i], NULL, NULL);
|
||||
|
||||
if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
|
||||
tablespace_deleted:
|
||||
@@ -1008,12 +1017,12 @@ not_to_recover:
|
||||
if ((i + 1 == n_stored) && sync) {
|
||||
buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
|
||||
zip_size, TRUE, tablespace_version,
|
||||
page_nos[i], NULL);
|
||||
page_nos[i], NULL, NULL);
|
||||
} else {
|
||||
buf_read_page_low(&err, false, BUF_READ_ANY_PAGE
|
||||
| OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, TRUE,
|
||||
tablespace_version, page_nos[i], NULL);
|
||||
tablespace_version, page_nos[i], NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -650,31 +650,8 @@ fil_space_encrypt(
|
||||
|
||||
/* handle post encryption checksum */
|
||||
ib_uint32_t checksum = 0;
|
||||
srv_checksum_algorithm_t algorithm =
|
||||
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
|
||||
|
||||
if (zip_size == 0) {
|
||||
switch (algorithm) {
|
||||
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
|
||||
checksum = buf_calc_page_crc32(dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
|
||||
checksum = (ib_uint32_t) buf_calc_page_new_checksum(
|
||||
dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_NONE:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||
checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
break;
|
||||
/* no default so the compiler will emit a warning
|
||||
* if new enum is added and not handled here */
|
||||
}
|
||||
} else {
|
||||
checksum = page_zip_calc_checksum(dst_frame, zip_size,
|
||||
algorithm);
|
||||
}
|
||||
checksum = fil_crypt_calculate_checksum(zip_size, dst_frame);
|
||||
|
||||
// store the post-encryption checksum after the key-version
|
||||
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
|
||||
@@ -818,6 +795,47 @@ fil_space_decrypt(
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Calculate post encryption checksum
|
||||
@return page checksum or BUF_NO_CHECKSUM_MAGIC
|
||||
not needed. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
fil_crypt_calculate_checksum(
|
||||
/*=========================*/
|
||||
ulint zip_size, /*!< in: zip_size or 0 */
|
||||
byte* dst_frame) /*!< in: page where to calculate */
|
||||
{
|
||||
ib_uint32_t checksum = 0;
|
||||
srv_checksum_algorithm_t algorithm =
|
||||
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
|
||||
|
||||
if (zip_size == 0) {
|
||||
switch (algorithm) {
|
||||
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
|
||||
checksum = buf_calc_page_crc32(dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
|
||||
checksum = (ib_uint32_t) buf_calc_page_new_checksum(
|
||||
dst_frame);
|
||||
break;
|
||||
case SRV_CHECKSUM_ALGORITHM_NONE:
|
||||
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||
checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||
break;
|
||||
/* no default so the compiler will emit a warning
|
||||
* if new enum is added and not handled here */
|
||||
}
|
||||
} else {
|
||||
checksum = page_zip_calc_checksum(dst_frame, zip_size,
|
||||
algorithm);
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Verify checksum for a page (iff it's encrypted)
|
||||
NOTE: currently this function can only be run in single threaded mode
|
||||
|
@@ -2006,6 +2006,7 @@ convert_error_code_to_mysql(
|
||||
|
||||
case DB_TABLESPACE_DELETED:
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
case DB_ENCRYPTED_DECRYPT_FAILED:
|
||||
return(HA_ERR_NO_SUCH_TABLE);
|
||||
|
||||
case DB_TABLESPACE_NOT_FOUND:
|
||||
@@ -6043,7 +6044,14 @@ table_opened:
|
||||
|
||||
innobase_copy_frm_flags_from_table_share(ib_table, table->s);
|
||||
|
||||
ib_table->thd = (void*)thd;
|
||||
|
||||
/* No point to init any statistics if tablespace is still encrypted. */
|
||||
if (!ib_table->is_encrypted) {
|
||||
dict_stats_init(ib_table);
|
||||
} else {
|
||||
ib_table->stat_initialized = 1;
|
||||
}
|
||||
|
||||
MONITOR_INC(MONITOR_TABLE_OPEN);
|
||||
|
||||
@@ -6072,6 +6080,11 @@ table_opened:
|
||||
file, best to play it safe. */
|
||||
|
||||
no_tablespace = true;
|
||||
} else if (ib_table->is_encrypted) {
|
||||
/* This means that tablespace was found but we could not
|
||||
decrypt encrypted page. */
|
||||
no_tablespace = true;
|
||||
ib_table->ibd_file_missing = true;
|
||||
} else {
|
||||
no_tablespace = false;
|
||||
}
|
||||
@@ -6083,9 +6096,9 @@ table_opened:
|
||||
/* If table has no talespace but it has crypt data, check
|
||||
is tablespace made unaccessible because encryption service
|
||||
or used key_id is not available. */
|
||||
if (ib_table && ib_table->crypt_data) {
|
||||
if (ib_table) {
|
||||
fil_space_crypt_t* crypt_data = ib_table->crypt_data;
|
||||
if ((crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
|
||||
if ((crypt_data && crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
|
||||
(srv_encrypt_tables &&
|
||||
crypt_data && crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
|
||||
|
||||
@@ -6097,6 +6110,13 @@ table_opened:
|
||||
" Can't continue reading table.",
|
||||
ib_table->name, crypt_data->key_id);
|
||||
}
|
||||
} else if (ib_table->is_encrypted) {
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
HA_ERR_NO_SUCH_TABLE,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
ib_table->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21402,3 +21422,59 @@ static void innodb_remember_check_sysvar_funcs()
|
||||
ut_ad((MYSQL_SYSVAR_NAME(checksum_algorithm).flags & 0x1FF) == PLUGIN_VAR_ENUM);
|
||||
check_sysvar_enum = MYSQL_SYSVAR_NAME(checksum_algorithm).check;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
trx_t* trx, /*!< in: trx */
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
THD *thd = (THD *)trx->mysql_thd;
|
||||
char *buf;
|
||||
#define MAX_BUF_SIZE 4*1024
|
||||
|
||||
va_start(args, format);
|
||||
buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME));
|
||||
vsprintf(buf,format, args);
|
||||
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
convert_error_code_to_mysql((dberr_t)error, 0, thd),
|
||||
buf);
|
||||
my_free(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
void* ithd, /*!< in: thd */
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
THD *thd = (THD *)ithd;
|
||||
char *buf;
|
||||
#define MAX_BUF_SIZE 4*1024
|
||||
|
||||
if (ithd == NULL) {
|
||||
thd = current_thd;
|
||||
}
|
||||
|
||||
va_start(args, format);
|
||||
buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME));
|
||||
vsprintf(buf,format, args);
|
||||
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
convert_error_code_to_mysql((dberr_t)error, 0, thd),
|
||||
buf);
|
||||
my_free(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -59,12 +60,14 @@ btr_block_get_func(
|
||||
block = buf_page_get_gen(space, zip_size, page_no, mode,
|
||||
NULL, BUF_GET, file, line, mtr);
|
||||
|
||||
if (block) {
|
||||
if (mode != RW_NO_LATCH) {
|
||||
|
||||
buf_block_dbg_add_level(
|
||||
block, index != NULL && dict_index_is_ibuf(index)
|
||||
? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
|
||||
}
|
||||
}
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
@@ -136,7 +136,7 @@ Note that if mode is PAGE_CUR_LE, which is used in inserts, then
|
||||
cursor->up_match and cursor->low_match both will have sensible values.
|
||||
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_search_to_nth_level(
|
||||
/*========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -173,7 +173,7 @@ btr_cur_search_to_nth_level(
|
||||
/*****************************************************************//**
|
||||
Opens a cursor at either end of an index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dberr_t
|
||||
btr_cur_open_at_index_side_func(
|
||||
/*============================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
|
@@ -114,7 +114,7 @@ btr_pcur_open_low(
|
||||
Opens an persistent cursor to an index tree without initializing the
|
||||
cursor. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_with_no_init_func(
|
||||
/*============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -143,7 +143,7 @@ btr_pcur_open_with_no_init_func(
|
||||
/*****************************************************************//**
|
||||
Opens a persistent cursor at either end of an index. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_at_index_side(
|
||||
/*========================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
|
@@ -447,7 +447,7 @@ btr_pcur_open_low(
|
||||
Opens an persistent cursor to an index tree without initializing the
|
||||
cursor. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_with_no_init_func(
|
||||
/*============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
@@ -472,6 +472,7 @@ btr_pcur_open_with_no_init_func(
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
btr_cur_t* btr_cursor;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
cursor->latch_mode = latch_mode;
|
||||
cursor->search_mode = mode;
|
||||
@@ -480,7 +481,7 @@ btr_pcur_open_with_no_init_func(
|
||||
|
||||
btr_cursor = btr_pcur_get_btr_cur(cursor);
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
|
||||
err = btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
|
||||
btr_cursor, has_search_latch,
|
||||
file, line, mtr);
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
@@ -488,12 +489,13 @@ btr_pcur_open_with_no_init_func(
|
||||
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
|
||||
cursor->trx_if_known = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a persistent cursor at either end of an index. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dberr_t
|
||||
btr_pcur_open_at_index_side(
|
||||
/*========================*/
|
||||
bool from_left, /*!< in: true if open to the low end,
|
||||
@@ -506,6 +508,8 @@ btr_pcur_open_at_index_side(
|
||||
(0=leaf) */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
pcur->latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
|
||||
|
||||
pcur->search_mode = from_left ? PAGE_CUR_G : PAGE_CUR_L;
|
||||
@@ -514,13 +518,15 @@ btr_pcur_open_at_index_side(
|
||||
btr_pcur_init(pcur);
|
||||
}
|
||||
|
||||
btr_cur_open_at_index_side(from_left, index, latch_mode,
|
||||
err = btr_cur_open_at_index_side(from_left, index, latch_mode,
|
||||
btr_pcur_get_btr_cur(pcur), level, mtr);
|
||||
pcur->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
|
||||
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
|
||||
pcur->trx_if_known = NULL;
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, 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
|
||||
@@ -428,7 +428,8 @@ buf_page_get_gen(
|
||||
BUF_GET_IF_IN_POOL_OR_WATCH */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mini-transaction */
|
||||
mtr_t* mtr, /*!< in: mini-transaction */
|
||||
dberr_t* err = NULL); /*!< out: error code */
|
||||
/********************************************************************//**
|
||||
Initializes a page to the buffer buf_pool. The page is usually not read
|
||||
from a file even if it cannot be found in the buffer buf_pool. This is one
|
||||
@@ -1611,8 +1612,14 @@ struct buf_page_t{
|
||||
operation needed. */
|
||||
|
||||
unsigned key_version; /*!< key version for this block */
|
||||
bool page_encrypted; /*!< page is encrypted */
|
||||
bool page_encrypted; /*!< page is page encrypted */
|
||||
bool page_compressed;/*!< page is page compressed */
|
||||
ulint stored_checksum;/*!< stored page checksum if page
|
||||
encrypted */
|
||||
bool encrypted; /*!< page is still encrypted */
|
||||
ulint calculated_checksum;
|
||||
/*!< calculated checksum if page
|
||||
encrypted */
|
||||
|
||||
ulint real_size; /*!< Real size of the page
|
||||
Normal pages == UNIV_PAGE_SIZE
|
||||
|
@@ -689,6 +689,10 @@ buf_block_get_frame(
|
||||
/*================*/
|
||||
const buf_block_t* block) /*!< in: pointer to the control block */
|
||||
{
|
||||
if (!block) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRV_CORRUPT_TABLE_CHECK(block, return(0););
|
||||
|
||||
switch (buf_block_get_state(block)) {
|
||||
@@ -696,6 +700,9 @@ buf_block_get_frame(
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
case BUF_BLOCK_NOT_USED:
|
||||
if (block->page.encrypted) {
|
||||
goto ok;
|
||||
}
|
||||
ut_error;
|
||||
break;
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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,9 +41,11 @@ ibool
|
||||
buf_read_page(
|
||||
/*==========*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint zip_size, /*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx);
|
||||
trx_t* trx, /*!< in: trx */
|
||||
buf_page_t** bpage /*!< out: page */
|
||||
);
|
||||
/********************************************************************//**
|
||||
High-level function which reads a page asynchronously from a file to the
|
||||
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -132,6 +133,11 @@ enum dberr_t {
|
||||
/*< Too many words in a phrase */
|
||||
DB_TOO_BIG_FOR_REDO, /* Record length greater than 10%
|
||||
of redo log */
|
||||
DB_ENCRYPTED_DECRYPT_FAILED, /* Tablespace encrypted and
|
||||
decrypt operaton failed because
|
||||
of missing key management plugin,
|
||||
or missing or incorrect key or
|
||||
incorret AES method or algorithm. */
|
||||
/* The following are partial failure codes */
|
||||
DB_FAIL = 1000,
|
||||
DB_OVERFLOW,
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, 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
|
||||
@@ -1033,6 +1033,7 @@ struct dict_table_t{
|
||||
table_id_t id; /*!< id of the table */
|
||||
mem_heap_t* heap; /*!< memory heap */
|
||||
char* name; /*!< table name */
|
||||
void* thd; /*!< thd */
|
||||
fil_space_crypt_t *crypt_data; /*!< crypt data if present */
|
||||
const char* dir_path_of_temp_table;/*!< NULL or the directory path
|
||||
where a TEMPORARY table that was explicitly
|
||||
@@ -1346,6 +1347,7 @@ struct dict_table_t{
|
||||
locks; /*!< list of locks on the table; protected
|
||||
by lock_sys->mutex */
|
||||
ibool is_corrupt;
|
||||
ibool is_encrypted;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
|
@@ -381,6 +381,17 @@ fil_crypt_set_encrypt_tables(
|
||||
/*=========================*/
|
||||
uint val); /*!< in: New srv_encrypt_tables setting */
|
||||
|
||||
/******************************************************************
|
||||
Calculate post encryption checksum
|
||||
@return page checksum or BUF_NO_CHECKSUM_MAGIC
|
||||
not needed. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
fil_crypt_calculate_checksum(
|
||||
/*=========================*/
|
||||
ulint zip_size, /*!< in: zip_size or 0 */
|
||||
byte* dst_frame); /*!< in: page where to calculate */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "fil0crypt.ic"
|
||||
#endif
|
||||
|
@@ -636,5 +636,13 @@ ib_push_warning(
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...);
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
void* ithd, /*!< in: thd */
|
||||
ulint error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...);
|
||||
#endif /* HA_INNODB_PROTOTYPES_H */
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 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
|
||||
@@ -39,7 +40,10 @@ page_cur_get_page(
|
||||
page_cur_t* cur) /*!< in: page cursor */
|
||||
{
|
||||
ut_ad(cur);
|
||||
|
||||
if (cur->rec) {
|
||||
ut_ad(page_align(cur->rec) == cur->block->frame);
|
||||
}
|
||||
|
||||
return(page_align(cur->rec));
|
||||
}
|
||||
@@ -54,7 +58,11 @@ page_cur_get_block(
|
||||
page_cur_t* cur) /*!< in: page cursor */
|
||||
{
|
||||
ut_ad(cur);
|
||||
|
||||
if (cur->rec) {
|
||||
ut_ad(page_align(cur->rec) == cur->block->frame);
|
||||
}
|
||||
|
||||
return(cur->block);
|
||||
}
|
||||
|
||||
@@ -80,7 +88,10 @@ page_cur_get_rec(
|
||||
page_cur_t* cur) /*!< in: page cursor */
|
||||
{
|
||||
ut_ad(cur);
|
||||
|
||||
if (cur->rec) {
|
||||
ut_ad(page_align(cur->rec) == cur->block->frame);
|
||||
}
|
||||
|
||||
return(cur->rec);
|
||||
}
|
||||
|
@@ -2350,7 +2350,7 @@ row_ins_clust_index_entry_low(
|
||||
{
|
||||
btr_cur_t cursor;
|
||||
ulint* offsets = NULL;
|
||||
dberr_t err;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
big_rec_t* big_rec = NULL;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* offsets_heap = NULL;
|
||||
@@ -2380,9 +2380,16 @@ row_ins_clust_index_entry_low(
|
||||
the function will return in both low_match and up_match of the
|
||||
cursor sensible values */
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, mode,
|
||||
err = btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, mode,
|
||||
&cursor, 0, __FILE__, __LINE__, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
index->table->is_encrypted = true;
|
||||
index->table->ibd_file_missing = true;
|
||||
mtr_commit(&mtr);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
page_t* page = btr_cur_get_page(&cursor);
|
||||
@@ -2696,10 +2703,23 @@ row_ins_sec_index_entry_low(
|
||||
search_mode |= BTR_IGNORE_SEC_UNIQUE;
|
||||
}
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
|
||||
err = btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
|
||||
search_mode,
|
||||
&cursor, 0, __FILE__, __LINE__, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning(trx->mysql_thd,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
|
||||
/* The insert was buffered during the search: we are done */
|
||||
goto func_exit;
|
||||
|
@@ -622,6 +622,8 @@ handle_new_error:
|
||||
case DB_FTS_INVALID_DOCID:
|
||||
case DB_INTERRUPTED:
|
||||
case DB_DICT_CHANGED:
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
case DB_ENCRYPTED_DECRYPT_FAILED:
|
||||
if (savept) {
|
||||
/* Roll back the latest, possibly incomplete insertion
|
||||
or update */
|
||||
@@ -1314,7 +1316,13 @@ row_insert_for_mysql(
|
||||
prebuilt->table->name);
|
||||
|
||||
return(DB_TABLESPACE_NOT_FOUND);
|
||||
|
||||
} else if (prebuilt->table->is_encrypted) {
|
||||
ib_push_warning(trx, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s in tablespace %lu encrypted."
|
||||
"However key management plugin or used key_id is not found or"
|
||||
" used encryption algorithm or method does not match.",
|
||||
prebuilt->table->name, prebuilt->table->space);
|
||||
return(DB_ENCRYPTED_DECRYPT_FAILED);
|
||||
} else if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
@@ -1713,6 +1721,13 @@ row_update_for_mysql(
|
||||
"InnoDB: how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
return(DB_ERROR);
|
||||
} else if (prebuilt->table->is_encrypted) {
|
||||
ib_push_warning(trx, DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s in tablespace %lu encrypted."
|
||||
"However key management plugin or used key_id is not found or"
|
||||
" used encryption algorithm or method does not match.",
|
||||
prebuilt->table->name, prebuilt->table->space);
|
||||
return (DB_TABLE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
|
||||
@@ -3932,6 +3947,19 @@ row_drop_table_for_mysql(
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* If table is encrypted and table page encryption failed
|
||||
mark this table read only. */
|
||||
if (table->is_encrypted) {
|
||||
|
||||
if (table->can_be_evicted) {
|
||||
dict_table_move_from_lru_to_non_lru(table);
|
||||
}
|
||||
|
||||
dict_table_close(table, TRUE, FALSE);
|
||||
err = DB_READ_ONLY;
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* Turn on this drop bit before we could release the dictionary
|
||||
latch */
|
||||
table->to_be_dropped = true;
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2015, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
@@ -3726,6 +3727,9 @@ row_search_for_mysql(
|
||||
|
||||
return(DB_TABLESPACE_NOT_FOUND);
|
||||
|
||||
} else if (prebuilt->table->is_encrypted) {
|
||||
|
||||
return(DB_ENCRYPTED_DECRYPT_FAILED);
|
||||
} else if (!prebuilt->index_usable) {
|
||||
|
||||
return(DB_MISSING_HISTORY);
|
||||
@@ -4137,10 +4141,15 @@ wait_table_again:
|
||||
|
||||
} else if (dtuple_get_n_fields(search_tuple) > 0) {
|
||||
|
||||
btr_pcur_open_with_no_init(index, search_tuple, mode,
|
||||
err = btr_pcur_open_with_no_init(index, search_tuple, mode,
|
||||
BTR_SEARCH_LEAF,
|
||||
pcur, 0, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
rec = NULL;
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
|
||||
pcur->trx_if_known = trx;
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
@@ -4173,9 +4182,23 @@ wait_table_again:
|
||||
}
|
||||
}
|
||||
} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_L) {
|
||||
btr_pcur_open_at_index_side(
|
||||
err = btr_pcur_open_at_index_side(
|
||||
mode == PAGE_CUR_G, index, BTR_SEARCH_LEAF,
|
||||
pcur, false, 0, &mtr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_ENCRYPTED_DECRYPT_FAILED) {
|
||||
ib_push_warning(trx->mysql_thd,
|
||||
DB_ENCRYPTED_DECRYPT_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
prebuilt->table->name);
|
||||
index->table->is_encrypted = true;
|
||||
}
|
||||
rec = NULL;
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
||||
rec_loop:
|
||||
@@ -4191,6 +4214,11 @@ rec_loop:
|
||||
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
if (!rec) {
|
||||
err = DB_ENCRYPTED_DECRYPT_FAILED;
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
|
||||
SRV_CORRUPT_TABLE_CHECK(rec,
|
||||
{
|
||||
err = DB_CORRUPTION;
|
||||
@@ -5132,7 +5160,9 @@ lock_wait_or_error:
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
if (rec) {
|
||||
btr_pcur_store_position(pcur, &mtr);
|
||||
}
|
||||
|
||||
lock_table_wait:
|
||||
mtr_commit(&mtr);
|
||||
|
Reference in New Issue
Block a user