summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-12-14 16:13:35 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-12-14 16:15:59 +0200
commit5fefcb0a2136e419d194f8b7b846adb0697fb23a (patch)
tree4cd8ef7b696e7a219c1825aa33ed51bbda8630a6
parentcfe8386296f1b104c55e538d408e2e4a9d08f4bb (diff)
parent94fa02f4d067285a57abb125829bfecd219df8fa (diff)
downloadmariadb-git-5fefcb0a2136e419d194f8b7b846adb0697fb23a.tar.gz
Merge 10.2 into 10.3
-rw-r--r--extra/mariabackup/fil_cur.cc70
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_corruption.opt6
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_corruption.result8
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_corruption.test51
-rw-r--r--sql/sql_class.cc5
5 files changed, 117 insertions, 23 deletions
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index d37c8e2f752..258317bec05 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <trx0sys.h>
#include "fil_cur.h"
+#include "fil0crypt.h"
#include "common.h"
#include "read_filt.h"
#include "xtrabackup.h"
@@ -230,7 +231,7 @@ xb_fil_cur_open(
posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL);
- const page_size_t page_size(cursor->node->space->flags);
+ const page_size_t page_size(node->space->flags);
cursor->page_size = page_size;
/* Allocate read buffer */
@@ -246,6 +247,19 @@ xb_fil_cur_open(
cursor->buf_page_no = 0;
cursor->thread_n = thread_n;
+ if (!node->space->crypt_data
+ && os_file_read(IORequestRead,
+ node->handle, cursor->buf, 0,
+ page_size.physical())) {
+ mutex_enter(&fil_system.mutex);
+ if (!node->space->crypt_data) {
+ node->space->crypt_data
+ = fil_space_read_crypt_data(page_size,
+ cursor->buf);
+ }
+ mutex_exit(&fil_system.mutex);
+ }
+
cursor->space_size = (ulint)(cursor->statinfo.st_size
/ page_size.physical());
@@ -267,7 +281,6 @@ xb_fil_cur_read(
/*============*/
xb_fil_cur_t* cursor) /*!< in/out: source file cursor */
{
- ibool success;
byte* page;
ulint i;
ulint npages;
@@ -275,6 +288,8 @@ xb_fil_cur_read(
xb_fil_cur_result_t ret;
ib_int64_t offset;
ib_int64_t to_read;
+ byte tmp_frame[UNIV_PAGE_SIZE_MAX];
+ byte tmp_page[UNIV_PAGE_SIZE_MAX];
const ulint page_size = cursor->page_size.physical();
xb_ad(!cursor->is_system() || page_size == srv_page_size);
@@ -317,6 +332,12 @@ xb_fil_cur_read(
retry_count = 10;
ret = XB_FIL_CUR_SUCCESS;
+ fil_space_t *space = fil_space_acquire_for_io(cursor->space_id);
+
+ if (!space) {
+ return XB_FIL_CUR_ERROR;
+ }
+
read_retry:
xtrabackup_io_throttling();
@@ -325,19 +346,11 @@ read_retry:
cursor->buf_offset = offset;
cursor->buf_page_no = (ulint)(offset / cursor->page_size.physical());
- fil_space_t* space = fil_space_get(cursor->space_id);
-
- if (!space) {
- return(XB_FIL_CUR_ERROR);
- }
-
- success = os_file_read(IORequestRead,
- cursor->file, cursor->buf, offset,
- (ulint) to_read);
- if (!success) {
- return(XB_FIL_CUR_ERROR);
+ if (!os_file_read(IORequestRead, cursor->file, cursor->buf, offset,
+ (ulint) to_read)) {
+ ret = XB_FIL_CUR_ERROR;
+ goto func_exit;
}
-
/* check pages for corruption and re-read if necessary. i.e. in case of
partially written pages */
for (page = cursor->buf, i = 0; i < npages;
@@ -348,11 +361,26 @@ read_retry:
page_no >= FSP_EXTENT_SIZE &&
page_no < FSP_EXTENT_SIZE * 3) {
/* We ignore the doublewrite buffer pages */
- } else if (!fil_space_verify_crypt_checksum(
- page, cursor->page_size, space->id, page_no)
- && buf_page_is_corrupted(true, page,
- cursor->page_size,
- space)) {
+ } else if (fil_space_verify_crypt_checksum(
+ page, cursor->page_size,
+ space->id, page_no)) {
+ ut_ad(mach_read_from_4(page + FIL_PAGE_SPACE_ID)
+ == space->id);
+
+ bool decrypted = false;
+
+ memcpy(tmp_page, page, page_size);
+
+ if (!fil_space_decrypt(space, tmp_frame,
+ tmp_page, &decrypted)
+ || buf_page_is_corrupted(true, tmp_page,
+ cursor->page_size,
+ space)) {
+ goto corrupted;
+ }
+ } else if (buf_page_is_corrupted(true, page, cursor->page_size,
+ space)) {
+corrupted:
retry_count--;
if (retry_count == 0) {
msg("[%02u] mariabackup: "
@@ -372,7 +400,6 @@ read_retry:
}
os_thread_sleep(100000);
-
goto read_retry;
}
cursor->buf_read += page_size;
@@ -380,7 +407,8 @@ read_retry:
}
posix_fadvise(cursor->file, offset, to_read, POSIX_FADV_DONTNEED);
-
+func_exit:
+ space->release_for_io();
return(ret);
}
diff --git a/mysql-test/suite/mariabackup/encrypted_page_corruption.opt b/mysql-test/suite/mariabackup/encrypted_page_corruption.opt
new file mode 100644
index 00000000000..74a6450a1ef
--- /dev/null
+++ b/mysql-test/suite/mariabackup/encrypted_page_corruption.opt
@@ -0,0 +1,6 @@
+--innodb-encrypt-log=ON
+--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
+--loose-file-key-management
+--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key
+--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc
+--loose-file-key-management-encryption-algorithm=aes_cbc
diff --git a/mysql-test/suite/mariabackup/encrypted_page_corruption.result b/mysql-test/suite/mariabackup/encrypted_page_corruption.result
new file mode 100644
index 00000000000..8ae34b2a6f0
--- /dev/null
+++ b/mysql-test/suite/mariabackup/encrypted_page_corruption.result
@@ -0,0 +1,8 @@
+call mtr.add_suppression("\\[ERROR\\] InnoDB: The page .* in file .* cannot be decrypted.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` has an unreadable root page");
+CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes;
+insert into t1 select repeat('a',100);
+# Corrupt the table
+# xtrabackup backup
+FOUND 1 /Database page corruption detected/ in backup.log
+drop table t1;
diff --git a/mysql-test/suite/mariabackup/encrypted_page_corruption.test b/mysql-test/suite/mariabackup/encrypted_page_corruption.test
new file mode 100644
index 00000000000..923875275e6
--- /dev/null
+++ b/mysql-test/suite/mariabackup/encrypted_page_corruption.test
@@ -0,0 +1,51 @@
+--source include/have_file_key_management.inc
+
+call mtr.add_suppression("\\[ERROR\\] InnoDB: The page .* in file .* cannot be decrypted.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` has an unreadable root page");
+CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes;
+insert into t1 select repeat('a',100);
+
+let $MYSQLD_DATADIR=`select @@datadir`;
+let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd;
+
+--source include/shutdown_mysqld.inc
+
+--echo # Corrupt the table
+
+perl;
+use strict;
+use warnings;
+use Fcntl qw(:DEFAULT :seek);
+
+my $ibd_file = $ENV{'t1_IBD'};
+
+my $chunk;
+my $len;
+
+sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file";
+sysseek IBD_FILE, 16384 * 3, SEEK_CUR;
+$chunk = '\xAA\xAA\xAA\xAA';
+syswrite IBD_FILE, $chunk, 4;
+
+close IBD_FILE;
+EOF
+
+--source include/start_mysqld.inc
+
+echo # xtrabackup backup;
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log;
+
+--disable_result_log
+--error 1
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backuplog;
+--enable_result_log
+
+
+--let SEARCH_PATTERN=Database page corruption detected
+--let SEARCH_FILE=$backuplog
+--source include/search_pattern_in_file.inc
+remove_file $backuplog;
+
+drop table t1;
+rmdir $targetdir;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index e4f3171bd14..a42a2f5afdd 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2017, MariaDB Corporation.
+ Copyright (c) 2008, 2018, 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
@@ -4792,7 +4792,8 @@ extern "C" int thd_slave_thread(const MYSQL_THD thd)
extern "C" int thd_rpl_stmt_based(const MYSQL_THD thd)
{
- return !thd->is_current_stmt_binlog_format_row() &&
+ return thd &&
+ !thd->is_current_stmt_binlog_format_row() &&
!thd->is_current_stmt_binlog_disabled();
}