diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-14 16:13:35 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-14 16:15:59 +0200 |
commit | 5fefcb0a2136e419d194f8b7b846adb0697fb23a (patch) | |
tree | 4cd8ef7b696e7a219c1825aa33ed51bbda8630a6 | |
parent | cfe8386296f1b104c55e538d408e2e4a9d08f4bb (diff) | |
parent | 94fa02f4d067285a57abb125829bfecd219df8fa (diff) | |
download | mariadb-git-5fefcb0a2136e419d194f8b7b846adb0697fb23a.tar.gz |
Merge 10.2 into 10.3
-rw-r--r-- | extra/mariabackup/fil_cur.cc | 70 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/encrypted_page_corruption.opt | 6 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/encrypted_page_corruption.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/encrypted_page_corruption.test | 51 | ||||
-rw-r--r-- | sql/sql_class.cc | 5 |
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(); } |