summaryrefslogtreecommitdiff
path: root/storage/xtradb/fil/fil0fil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/fil/fil0fil.cc')
-rw-r--r--storage/xtradb/fil/fil0fil.cc106
1 files changed, 90 insertions, 16 deletions
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 58e08f11778..28f262b50c7 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -341,6 +341,8 @@ fil_space_get_by_id(
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
space->id == id);
+ /* The system tablespace must always be found */
+ ut_ad(space || id != 0 || srv_is_being_started);
return(space);
}
@@ -672,6 +674,7 @@ fil_node_open_file(
page = static_cast<byte*>(ut_align(buf2, UNIV_PAGE_SIZE));
success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE);
+ srv_stats.page0_read.add(1);
space_id = fsp_header_get_space_id(page);
flags = fsp_header_get_flags(page);
@@ -1001,8 +1004,13 @@ retry:
/* If the file is already open, no need to do anything; if the space
does not exist, we handle the situation in the function which called
this function */
+ if (!space) {
+ return;
+ }
- if (!space || UT_LIST_GET_FIRST(space->chain)->open) {
+ fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
+
+ if (!node || node->open) {
return;
}
@@ -1191,7 +1199,8 @@ fil_space_create(
ulint id, /*!< in: space id */
ulint flags, /*!< in: tablespace flags */
ulint purpose,/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
- fil_space_crypt_t* crypt_data) /*!< in: crypt data */
+ fil_space_crypt_t* crypt_data, /*!< in: crypt data */
+ bool create_table) /*!< in: true if create table */
{
fil_space_t* space;
@@ -1285,10 +1294,25 @@ fil_space_create(
space->is_in_unflushed_spaces = false;
space->is_corrupt = FALSE;
+ space->crypt_data = crypt_data;
- UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
+ /* In create table we write page 0 so we have already
+ "read" it and for system tablespaces we have read
+ crypt data at startup. */
+ if (create_table || crypt_data != NULL) {
+ space->page_0_crypt_read = true;
+ }
- space->crypt_data = crypt_data;
+#ifdef UNIV_DEBUG
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Created tablespace for space %lu name %s key_id %u encryption %d.",
+ space->id,
+ space->name,
+ space->crypt_data ? space->crypt_data->key_id : 0,
+ space->crypt_data ? space->crypt_data->encryption : 0);
+#endif
+
+ UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
mutex_exit(&fil_system->mutex);
@@ -1770,6 +1794,9 @@ fil_close_all_files(void)
{
fil_space_t* space;
+ // Must check both flags as it's possible for this to be called during
+ // server startup with srv_track_changed_pages == true but
+ // srv_redo_log_thread_started == false
if (srv_track_changed_pages && srv_redo_log_thread_started)
os_event_wait(srv_redo_log_tracked_event);
@@ -1809,6 +1836,9 @@ fil_close_log_files(
{
fil_space_t* space;
+ // Must check both flags as it's possible for this to be called during
+ // server startup with srv_track_changed_pages == true but
+ // srv_redo_log_thread_started == false
if (srv_track_changed_pages && srv_redo_log_thread_started)
os_event_wait(srv_redo_log_tracked_event);
@@ -2057,6 +2087,8 @@ fil_read_first_page(
os_file_read(data_file, page, 0, UNIV_PAGE_SIZE);
+ srv_stats.page0_read.add(1);
+
/* The FSP_HEADER on page 0 is only valid for the first file
in a tablespace. So if this is not the first datafile, leave
*flags and *space_id as they were read from the first file and
@@ -2077,6 +2109,7 @@ fil_read_first_page(
ulint space = fsp_header_get_space_id(page);
ulint offset = fsp_header_get_crypt_offset(
fsp_flags_get_zip_size(*flags), NULL);
+
cdata = fil_space_read_crypt_data(space, page, offset);
if (crypt_data) {
@@ -2085,9 +2118,7 @@ fil_read_first_page(
/* If file space is encrypted we need to have at least some
encryption service available where to get keys */
- if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) ||
- (srv_encrypt_tables &&
- cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
+ if (cdata && cdata->should_encrypt()) {
if (!encryption_key_id_exists(cdata->key_id)) {
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -3627,7 +3658,7 @@ fil_create_new_single_table_tablespace(
}
success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
- crypt_data);
+ crypt_data, true);
if (!success || !fil_node_create(path, size, space_id, FALSE)) {
err = DB_ERROR;
@@ -3861,6 +3892,7 @@ fil_open_single_table_tablespace(
if (table) {
table->crypt_data = def.crypt_data;
+ table->page_0_read = true;
}
/* Validate this single-table-tablespace with SYS_TABLES,
@@ -3897,6 +3929,7 @@ fil_open_single_table_tablespace(
if (table) {
table->crypt_data = remote.crypt_data;
+ table->page_0_read = true;
}
/* Validate this single-table-tablespace with SYS_TABLES,
@@ -3933,6 +3966,7 @@ fil_open_single_table_tablespace(
if (table) {
table->crypt_data = dict.crypt_data;
+ table->page_0_read = true;
}
/* Validate this single-table-tablespace with SYS_TABLES,
@@ -4104,7 +4138,7 @@ skip_validate:
if (err != DB_SUCCESS) {
; // Don't load the tablespace into the cache
} else if (!fil_space_create(tablename, id, flags, FIL_TABLESPACE,
- crypt_data)) {
+ crypt_data, false)) {
err = DB_ERROR;
} else {
/* We do not measure the size of the file, that is why
@@ -4710,7 +4744,7 @@ will_not_choose:
#endif /* UNIV_HOTBACKUP */
ibool file_space_create_success = fil_space_create(
tablename, fsp->id, fsp->flags, FIL_TABLESPACE,
- fsp->crypt_data);
+ fsp->crypt_data, false);
if (!file_space_create_success) {
if (srv_force_recovery > 0) {
@@ -6591,10 +6625,7 @@ fil_iterate(
bool encrypted = false;
/* Use additional crypt io buffer if tablespace is encrypted */
- if ((iter.crypt_data != NULL && iter.crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
- (srv_encrypt_tables &&
- iter.crypt_data && iter.crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
-
+ if (iter.crypt_data != NULL && iter.crypt_data->should_encrypt()) {
encrypted = true;
readptr = iter.crypt_io_buffer;
writeptr = iter.crypt_io_buffer;
@@ -7322,11 +7353,54 @@ fil_space_get_crypt_data(
space = fil_space_get_by_id(id);
+ mutex_exit(&fil_system->mutex);
+
if (space != NULL) {
+ /* If we have not yet read the page0
+ of this tablespace we will do it now. */
+ if (!space->crypt_data && !space->page_0_crypt_read) {
+ ulint space_id = space->id;
+ fil_node_t* node;
+
+ ut_a(space->crypt_data == NULL);
+ node = UT_LIST_GET_FIRST(space->chain);
+
+ byte *buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
+ byte *page = static_cast<byte*>(ut_align(buf, UNIV_PAGE_SIZE));
+ fil_read(true, space_id, 0, 0, 0, UNIV_PAGE_SIZE, page,
+ NULL, NULL);
+ ulint flags = fsp_header_get_flags(page);
+ ulint offset = fsp_header_get_crypt_offset(
+ fsp_flags_get_zip_size(flags), NULL);
+ space->crypt_data = fil_space_read_crypt_data(space_id, page, offset);
+ ut_free(buf);
+
+#ifdef UNIV_DEBUG
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Read page 0 from tablespace for space %lu name %s key_id %u encryption %d handle %d.",
+ space_id,
+ space->name,
+ space->crypt_data ? space->crypt_data->key_id : 0,
+ space->crypt_data ? space->crypt_data->encryption : 0,
+ node->handle);
+#endif
+
+ ut_a(space->id == space_id);
+
+ space->page_0_crypt_read = true;
+ }
+
crypt_data = space->crypt_data;
- }
- mutex_exit(&fil_system->mutex);
+ if (!space->page_0_crypt_read) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Space %lu name %s contains encryption %d information for key_id %u but page0 is not read.",
+ space->id,
+ space->name,
+ space->crypt_data ? space->crypt_data->encryption : 0,
+ space->crypt_data ? space->crypt_data->key_id : 0);
+ }
+ }
return(crypt_data);
}