summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-02-25 11:40:40 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2016-02-25 11:40:40 +0200
commit905807140321541f04ac3c559e36d1a101b0f714 (patch)
tree44c4ce7f8beca30ead448542960dc96daec7014b
parent1ac64b7510fd006268936e46442f46a28250c249 (diff)
downloadmariadb-git-905807140321541f04ac3c559e36d1a101b0f714.tar.gz
MDEV-9362: InnoDB tables using DATA_DIRECTORY created using MySQL 5.6 do not work with MariaDB 10.1
MDEV-9581: [PATCH] Innodb in Mariadb-10.1.x is unable to start up with data files generated by older version Analysis: Both MariaDB and Oracle has done independent development and used same tablespace (fsp) flags bits and dictionary flags bits to indicate different extended new features. This could lead problems if same bit is used to indicate different features. Fix: Remove MariaDB extended feature bits from tablespace (fsp) flags from page 0 and dictionary flags (table type). Introduce a new system table SYS_TABLE_OPTIONS where every table option is stored and these options are stored if needed. Add migration code to migrate MariaDB 10.1.0 - 10.1.11 databases to MariaDB 10.1.12 format. Note that migration is needed only if DATA_DIRECTORY, PAGE_COMPRESSED, ENCRYPTED, ATOMIC_WRITES table options are used or if database used not default page size. Caution: Please take backups of your database before migrating 10.1.12.
-rw-r--r--mysql-test/suite/encryption/r/innodb-bad-key-change.result3
-rw-r--r--mysql-test/suite/innodb/t/innodb_information_schema_tables.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_information_schema_tables.test3
-rw-r--r--storage/innobase/CMakeLists.txt1
-rw-r--r--storage/innobase/api/api0api.cc7
-rw-r--r--storage/innobase/buf/buf0buf.cc5
-rw-r--r--storage/innobase/dict/dict0crea.cc117
-rw-r--r--storage/innobase/dict/dict0dict.cc16
-rw-r--r--storage/innobase/dict/dict0load.cc36
-rw-r--r--storage/innobase/dict/dict0mem.cc7
-rw-r--r--storage/innobase/dict/dict0tableoptions.cc482
-rw-r--r--storage/innobase/fil/fil0fil.cc342
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc4
-rw-r--r--storage/innobase/fts/fts0fts.cc11
-rw-r--r--storage/innobase/handler/ha_innodb.cc147
-rw-r--r--storage/innobase/handler/ha_innodb.h6
-rw-r--r--storage/innobase/handler/handler0alter.cc17
-rw-r--r--storage/innobase/handler/i_s.cc240
-rw-r--r--storage/innobase/handler/i_s.h11
-rw-r--r--storage/innobase/include/dict0boot.h24
-rw-r--r--storage/innobase/include/dict0crea.h18
-rw-r--r--storage/innobase/include/dict0dict.h19
-rw-r--r--storage/innobase/include/dict0dict.ic159
-rw-r--r--storage/innobase/include/dict0load.h6
-rw-r--r--storage/innobase/include/dict0mem.h99
-rw-r--r--storage/innobase/include/dict0pagecompress.h31
-rw-r--r--storage/innobase/include/dict0pagecompress.ic86
-rw-r--r--storage/innobase/include/dict0priv.ic2
-rw-r--r--storage/innobase/include/dict0tableoptions.h127
-rw-r--r--storage/innobase/include/fil0crypt.ic2
-rw-r--r--storage/innobase/include/fil0fil.h39
-rw-r--r--storage/innobase/include/fil0pagecompress.h59
-rw-r--r--storage/innobase/include/fsp0fsp.h78
-rw-r--r--storage/innobase/include/fsp0fsp.ic35
-rw-r--r--storage/innobase/include/fsp0pagecompress.h32
-rw-r--r--storage/innobase/include/fsp0pagecompress.ic157
-rw-r--r--storage/innobase/include/ha_prototypes.h13
-rw-r--r--storage/innobase/include/mtr0mtr.h7
-rw-r--r--storage/innobase/include/row0mysql.h7
-rw-r--r--storage/innobase/log/log0recv.cc5
-rw-r--r--storage/innobase/os/os0file.cc2
-rw-r--r--storage/innobase/pars/pars0pars.cc6
-rw-r--r--storage/innobase/row/row0import.cc14
-rw-r--r--storage/innobase/row/row0ins.cc2
-rw-r--r--storage/innobase/row/row0mysql.cc40
-rw-r--r--storage/innobase/row/row0sel.cc2
-rw-r--r--storage/innobase/row/row0upd.cc4
-rw-r--r--storage/innobase/srv/srv0start.cc39
-rw-r--r--storage/xtradb/CMakeLists.txt1
-rw-r--r--storage/xtradb/api/api0api.cc7
-rw-r--r--storage/xtradb/buf/buf0buf.cc5
-rw-r--r--storage/xtradb/dict/dict0crea.cc118
-rw-r--r--storage/xtradb/dict/dict0dict.cc18
-rw-r--r--storage/xtradb/dict/dict0load.cc36
-rw-r--r--storage/xtradb/dict/dict0mem.cc7
-rw-r--r--storage/xtradb/dict/dict0tableoptions.cc482
-rw-r--r--storage/xtradb/fil/fil0fil.cc347
-rw-r--r--storage/xtradb/fil/fil0pagecompress.cc4
-rw-r--r--storage/xtradb/fts/fts0fts.cc11
-rw-r--r--storage/xtradb/handler/ha_innodb.cc147
-rw-r--r--storage/xtradb/handler/ha_innodb.h6
-rw-r--r--storage/xtradb/handler/handler0alter.cc19
-rw-r--r--storage/xtradb/handler/i_s.cc239
-rw-r--r--storage/xtradb/handler/i_s.h11
-rw-r--r--storage/xtradb/include/dict0boot.h23
-rw-r--r--storage/xtradb/include/dict0crea.h18
-rw-r--r--storage/xtradb/include/dict0dict.h19
-rw-r--r--storage/xtradb/include/dict0dict.ic159
-rw-r--r--storage/xtradb/include/dict0load.h6
-rw-r--r--storage/xtradb/include/dict0mem.h101
-rw-r--r--storage/xtradb/include/dict0pagecompress.h31
-rw-r--r--storage/xtradb/include/dict0pagecompress.ic86
-rw-r--r--storage/xtradb/include/dict0priv.ic2
-rw-r--r--storage/xtradb/include/dict0tableoptions.h127
-rw-r--r--storage/xtradb/include/fil0crypt.ic4
-rw-r--r--storage/xtradb/include/fil0fil.h38
-rw-r--r--storage/xtradb/include/fil0pagecompress.h59
-rw-r--r--storage/xtradb/include/fsp0fsp.h84
-rw-r--r--storage/xtradb/include/fsp0fsp.ic35
-rw-r--r--storage/xtradb/include/fsp0pagecompress.h32
-rw-r--r--storage/xtradb/include/fsp0pagecompress.ic157
-rw-r--r--storage/xtradb/include/ha_prototypes.h13
-rw-r--r--storage/xtradb/include/mtr0mtr.h8
-rw-r--r--storage/xtradb/include/row0mysql.h7
-rw-r--r--storage/xtradb/log/log0recv.cc5
-rw-r--r--storage/xtradb/os/os0file.cc2
-rw-r--r--storage/xtradb/pars/pars0pars.cc6
-rw-r--r--storage/xtradb/row/row0import.cc14
-rw-r--r--storage/xtradb/row/row0ins.cc2
-rw-r--r--storage/xtradb/row/row0mysql.cc38
-rw-r--r--storage/xtradb/row/row0sel.cc2
-rw-r--r--storage/xtradb/row/row0upd.cc4
-rw-r--r--storage/xtradb/srv/srv0start.cc41
93 files changed, 3591 insertions, 1560 deletions
diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
index cf9791887cc..39e08f45731 100644
--- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result
+++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
@@ -36,8 +36,7 @@ SELECT * FROM t1;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
SHOW WARNINGS;
Level Code Message
-Warning 1812 Tablespace is missing for table 'test/t1'
-Warning 192 Table test/t1 is encrypted but encryption service or used key_id 2 is not available. Can't continue reading table.
+Warning 192 Table test/t1 is encrypted but encryption service or used key_id is not available. Can't continue reading table.
Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
DROP TABLE t1;
# Start server with keys.txt
diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt
index 9f30d81ef9c..b6755dded08 100644
--- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt
+++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt
@@ -27,3 +27,4 @@
--loose-innodb_buffer_pool_pages
--loose-innodb_buffer_pool_pages_index
--loose-innodb_buffer_pool_pages_blob
+--loose-innodb-sys-table-options
diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test
index 15b3bf4f561..7b4a555f81a 100644
--- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test
+++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test
@@ -59,6 +59,9 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_PAGES_BLOB;
--error 0,1109
SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES;
COMMIT;
+--error 0,1109
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLE_OPTIONS;
+COMMIT;
--enable_query_log
--enable_result_log
DROP TABLE t1;
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 7ae962880d1..b9d117b4aa5 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -389,6 +389,7 @@ SET(INNOBASE_SOURCES
dict/dict0mem.cc
dict/dict0stats.cc
dict/dict0stats_bg.cc
+ dict/dict0tableoptions.cc
dyn/dyn0dyn.cc
eval/eval0eval.cc
eval/eval0proc.cc
diff --git a/storage/innobase/api/api0api.cc b/storage/innobase/api/api0api.cc
index 739ea9f7572..4af32a5819f 100644
--- a/storage/innobase/api/api0api.cc
+++ b/storage/innobase/api/api0api.cc
@@ -36,8 +36,9 @@ InnoDB Native API
#include "api0api.h"
#include "api0misc.h"
-#include "srv0start.h"
+#include "dict0tableoptions.h"
#include "dict0dict.h"
+#include "srv0start.h"
#include "btr0pcur.h"
#include "row0ins.h"
#include "row0upd.h"
@@ -270,7 +271,7 @@ ib_open_table_by_name(
dict_table_t* table;
table = dict_table_open_on_name(name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table != NULL && table->ibd_file_missing) {
table = NULL;
@@ -3723,7 +3724,7 @@ ib_table_truncate(
dict_mutex_enter_for_mysql();
table = dict_table_open_on_name(table_name, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table != NULL && dict_table_get_first_index(table)) {
err = ib_create_cursor_with_index_id(&ib_crsr, table, 0,
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index f4e7c0d0c6b..f1953afd336 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -59,6 +59,7 @@ Created 11/5/1995 Heikki Tuuri
#include <numa.h>
#include <numaif.h>
#endif // HAVE_LIBNUMA
+#include "fil0fil.h"
#include "fil0pagecompress.h"
#include "ha_prototypes.h"
#include "ut0byte.h"
@@ -4677,7 +4678,7 @@ corrupt:
"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);
+ bpage->space, bpage->key_version);
if (bpage->space > TRX_SYS_SPACE) {
if (corrupted) {
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 4a8dcd2f840..fa23c3762d3 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -310,7 +310,7 @@ dict_build_table_def_step(
dict_tf_to_fsp_flags(table->flags),
table->flags2,
FIL_IBD_FILE_INITIAL_SIZE,
- node->mode, node->key_id);
+ table);
table->space = (unsigned int) space;
@@ -935,10 +935,8 @@ tab_create_graph_create(
dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
mem_heap_t* heap, /*!< in: heap where created */
- bool commit, /*!< in: true if the commit node should be
+ bool commit) /*!< in: true if the commit node should be
added to the query graph */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
{
tab_node_t* node;
@@ -951,8 +949,6 @@ tab_create_graph_create(
node->state = TABLE_BUILD_TABLE_DEF;
node->heap = mem_heap_create(256);
- node->mode = mode;
- node->key_id = key_id;
node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables,
heap);
@@ -1989,3 +1985,112 @@ dict_create_add_tablespace_to_dictionary(
return(error);
}
+
+/****************************************************************//**
+Creates the sys_table_options system tables inside InnoDB
+at server bootstrap or server start if it is not found or is
+not of the right form.
+@return DB_SUCCESS or error code */
+UNIV_INTERN
+dberr_t
+dict_create_or_check_sys_table_options(void)
+/*========================================*/
+{
+ trx_t* trx;
+ my_bool srv_file_per_table_backup;
+ dberr_t err;
+ dberr_t sys_tableoptions_err;
+
+ ut_a(srv_get_active_thread_type() == SRV_NONE);
+
+ /* Note: The master thread has not been started at this point. */
+
+ sys_tableoptions_err = dict_check_if_system_table_exists(
+ "SYS_TABLE_OPTIONS", DICT_NUM_FIELDS__SYS_TABLEOPTIONS + 1, 1);
+
+ if (sys_tableoptions_err == DB_SUCCESS) {
+
+ return(DB_SUCCESS);
+ }
+
+ trx = trx_allocate_for_mysql();
+
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ trx->op_info = "creating table options sys table";
+
+ row_mysql_lock_data_dictionary(trx);
+
+ /* Check which incomplete table definition to drop. */
+
+ if (sys_tableoptions_err == DB_CORRUPTION) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Dropping incompletely created "
+ "SYS_TABLE_OPTIONS table.");
+ row_drop_table_for_mysql("SYS_TABLE_OPTIONS", trx, TRUE);
+ }
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Creating table options system table.");
+
+ /* We always want SYSTEM tables to be created inside the system
+ tablespace. */
+ srv_file_per_table_backup = srv_file_per_table;
+ srv_file_per_table = 0;
+
+ err = que_eval_sql(
+ NULL,
+ "PROCEDURE CREATE_SYS_TABLE_OPTIONS_PROC () IS\n"
+ "BEGIN\n"
+ "CREATE TABLE SYS_TABLE_OPTIONS(\n"
+ " TABLE_ID BIGINT,"
+ " PAGE_COMPRESSED INT,"
+ " PAGE_COMPRESSION_LEVEL INT,"
+ " ATOMIC_WRITES INT,"
+ " ENCRYPTED INT,"
+ " ENCRYPTION_KEY_ID INT"
+ ");\n"
+ "CREATE UNIQUE CLUSTERED INDEX SYS_TABLE_OPTIONS_TABLE_ID"
+ " ON SYS_TABLE_OPTIONS (TABLE_ID);\n"
+ "END;\n",
+ FALSE, trx);
+
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Creation of SYS_TABLE_OPTIONS "
+ "has failed with error %lu. Tablespace is full. "
+ "Dropping incompletely created tables.",
+ (ulong) err);
+
+ ut_a(err == DB_OUT_OF_FILE_SPACE
+ || err == DB_TOO_MANY_CONCURRENT_TRXS);
+
+ row_drop_table_for_mysql("SYS_TABLE_OPTIONS", trx, TRUE);
+
+ if (err == DB_OUT_OF_FILE_SPACE) {
+ err = DB_MUST_GET_MORE_FILE_SPACE;
+ }
+ }
+
+ trx_commit_for_mysql(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ srv_file_per_table = srv_file_per_table_backup;
+
+ if (err == DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Table options system table created.");
+ }
+
+ /* Note: The master thread has not been started at this point. */
+ /* Confirm and move to the non-LRU part of the table LRU list. */
+
+ sys_tableoptions_err = dict_check_if_system_table_exists(
+ "SYS_TABLE_OPTIONS", DICT_NUM_FIELDS__SYS_TABLEOPTIONS + 1, 1);
+ ut_a(sys_tableoptions_err == DB_SUCCESS);
+
+ return(err);
+}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 2b728353d99..13f1ee6fc3c 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1163,8 +1163,10 @@ dict_table_open_on_name(
indexes after an aborted online
index creation */
dict_err_ignore_t
- ignore_err) /*!< in: error to be ignored when
+ ignore_err, /*!< in: error to be ignored when
loading a table definition */
+ dict_tableoptions_t*
+ options) /*!< in: table options */
{
dict_table_t* table;
@@ -1178,7 +1180,7 @@ dict_table_open_on_name(
table = dict_table_check_if_in_cache_low(table_name);
if (table == NULL) {
- table = dict_load_table(table_name, TRUE, ignore_err);
+ table = dict_load_table(table_name, TRUE, ignore_err, options);
}
ut_ad(!table || table->cached);
@@ -1187,6 +1189,16 @@ dict_table_open_on_name(
/* If table is encrypted return table */
if (ignore_err == DICT_ERR_IGNORE_NONE
+ && !table->is_encrypted && options) {
+ if ((options->encryption == FIL_SPACE_ENCRYPTION_ON ||
+ (options->encryption == FIL_SPACE_ENCRYPTION_DEFAULT && srv_encrypt_tables))
+ && !encryption_key_id_exists((unsigned int)options->encryption_key_id)) {
+ table->is_encrypted = true;
+ }
+ }
+
+ /* If table is encrypted return table */
+ if (ignore_err == DICT_ERR_IGNORE_NONE
&& table->is_encrypted) {
/* Make life easy for drop table. */
if (table->can_be_evicted) {
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index d8bd0a66ade..2b732f12a46 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2016, 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
@@ -24,6 +25,13 @@ from dictionary tables
Created 4/24/1996 Heikki Tuuri
*******************************************************/
+#include "univ.i"
+#include "dict0dict.h"
+#include "fil0fil.h"
+#include "my_crypt.h"
+#include "fil0crypt.h"
+#include "dict0types.h"
+#include "dict0tableoptions.h"
#include "dict0load.h"
#include "mysql_version.h"
@@ -56,7 +64,8 @@ static const char* SYSTEM_TABLE_NAME[] = {
"SYS_FOREIGN",
"SYS_FOREIGN_COLS",
"SYS_TABLESPACES",
- "SYS_DATAFILES"
+ "SYS_DATAFILES",
+ "SYS_TABLE_OPTIONS"
};
/* If this flag is TRUE, then we will load the cluster index's (and tables')
@@ -1083,6 +1092,11 @@ loop:
discarded = !!(flags2 & DICT_TF2_DISCARDED);
}
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLES__ID, &len);
+ table_id_t table_id = static_cast<table_id_t>(
+ mach_read_from_8(field));
+
if (space_id == 0) {
/* The system tablespace always exists. */
ut_ad(!discarded);
@@ -1148,6 +1162,7 @@ loop:
/* Use the remote filepath if known. */
char* filepath = NULL;
+
if (DICT_TF_HAS_DATA_DIR(flags)) {
filepath = dict_get_first_path(
space_id, name);
@@ -1158,6 +1173,10 @@ loop:
since if it's off we should decrypt a potentially
already encrypted table */
bool read_page_0 = true;
+ dict_tableoptions_t options;
+
+ memset(&options, 0, sizeof(dict_tableoptions_t));
+ dict_get_table_options(table_id, &options, true);
/* We set the 2nd param (fix_dict = true)
here because we already have an x-lock on
@@ -1168,7 +1187,7 @@ loop:
dberr_t err = fil_open_single_table_tablespace(
read_page_0, srv_read_only_mode ? false : true,
space_id, dict_tf_to_fsp_flags(flags),
- name, filepath, NULL);
+ name, filepath, NULL, &options);
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -2280,9 +2299,11 @@ dict_load_table(
const char* name, /*!< in: table name in the
databasename/tablename format */
ibool cached, /*!< in: TRUE=add to cache, FALSE=do not */
- dict_err_ignore_t ignore_err)
+ dict_err_ignore_t ignore_err,
/*!< in: error to be ignored when loading
table and its indexes' definition */
+ dict_tableoptions_t* options)
+ /*!< in: table options */
{
dberr_t err;
dict_table_t* table;
@@ -2365,6 +2386,11 @@ err_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
+ if (table && options) {
+ ut_ad(table->table_options);
+ memcpy(table->table_options, options, sizeof(dict_tableoptions_t));
+ }
+
if (table->space == 0) {
/* The system tablespace is always available. */
} else if (table->flags2 & DICT_TF2_DISCARDED) {
@@ -2412,7 +2438,7 @@ err_exit:
err = fil_open_single_table_tablespace(
true, false, table->space,
dict_tf_to_fsp_flags(table->flags),
- name, filepath, table);
+ name, filepath, table, table->table_options);
if (err != DB_SUCCESS) {
/* We failed to find a sensible
@@ -2634,7 +2660,7 @@ check_rec:
table = dict_load_table(
mem_heap_strdupl(
heap, (char*) field, len),
- TRUE, ignore_err);
+ TRUE, ignore_err, NULL);
}
}
}
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 1724ac024fa..39d0d558c18 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -2,6 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2015, 2016, 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
@@ -85,7 +86,6 @@ dict_mem_table_create(
mem_heap_t* heap;
ut_ad(name);
- ut_a(dict_tf_is_valid(flags));
ut_a(!(flags2 & ~DICT_TF2_BIT_MASK));
heap = mem_heap_create(DICT_HEAP_SIZE);
@@ -95,6 +95,11 @@ dict_mem_table_create(
table->heap = heap;
+ table->table_options = static_cast<dict_tableoptions_t*>(
+ mem_heap_zalloc(heap, sizeof(dict_tableoptions_t)));
+
+ table->table_options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+
table->flags = (unsigned int) flags;
table->flags2 = (unsigned int) flags2;
table->name = static_cast<char*>(ut_malloc(strlen(name) + 1));
diff --git a/storage/innobase/dict/dict0tableoptions.cc b/storage/innobase/dict/dict0tableoptions.cc
new file mode 100644
index 00000000000..527c5e356d9
--- /dev/null
+++ b/storage/innobase/dict/dict0tableoptions.cc
@@ -0,0 +1,482 @@
+/*****************************************************************************
+
+Copyright (c) 2016, 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
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**************************************************//**
+@file dict/dict0tableoptions.cc
+Function implementations for the system table SYS_TABLE_OPTIONS
+
+Created 22/01/2006 Jan Lindström
+*******************************************************/
+
+#include "mysql_version.h"
+#include "btr0pcur.h"
+#include "btr0btr.h"
+#include "page0page.h"
+#include "mach0data.h"
+#include "dict0dict.h"
+#include "dict0boot.h"
+#include "dict0stats.h"
+#include "dict0mem.h"
+#include "rem0cmp.h"
+#include "srv0start.h"
+#include "srv0srv.h"
+#include "dict0crea.h"
+#include "dict0priv.h"
+#include "ha_prototypes.h" /* innobase_casedn_str() */
+#include "fts0priv.h"
+#include "dict0tableoptions.h"
+#include "dict0load.h"
+#include "row0mysql.h"
+
+/********************************************************************//**
+This function parses a SYS_TABLE_OPTIONS record, extracts necessary
+information from the record and returns it to the caller.
+@return error message or NULL if successfull */
+UNIV_INTERN
+const char*
+dict_process_sys_tableoptions(
+/*==========================*/
+ mem_heap_t* heap, /*!< in/out: heap memory */
+ const rec_t* rec, /*!< in: current SYS_TABLE_OPTIONS rec */
+ dict_tableoptions_t* table_options) /*!< out: table options */
+{
+ const byte* field;
+ ulint len=0;
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ return("delete-marked record in SYS_TABLE_OPTIONS");
+ }
+
+ if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLEOPTIONS) {
+ return("wrong number of columns in SYS_TABLE_OPTIONS record");
+ }
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__TABLE_ID, &len);
+ if (len != 8) {
+err_len:
+ return("incorrect column length in SYS_TABLE_OPTIONS");
+ }
+
+ table_options->table_id = mach_read_from_8(field);
+
+ rec_get_nth_field_offs_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__DB_TRX_ID, &len);
+ if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ rec_get_nth_field_offs_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__DB_ROLL_PTR, &len);
+ if (len != DATA_ROLL_PTR_LEN && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSED, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->page_compressed = mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSION_LEVEL, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->page_compression_level = mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__ATOMIC_WRITES, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->atomic_writes = (atomic_writes_t)mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTED, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->encryption = (fil_encryption_t)mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTION_KEY_ID, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->encryption_key_id = mach_read_from_4(field);
+
+ return(NULL);
+}
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS based on table_id
+@return true if found, false if not */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ table_id_t table_id, /*!< in: table id */
+ dict_tableoptions_t* options, /*!< out:table options */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ mtr_t mtr;
+ dict_table_t* sys_tableoptions;
+ dict_index_t* sys_index;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ byte* buf;
+ btr_pcur_t pcur;
+ const rec_t* rec;
+ mem_heap_t* heap = mem_heap_create(1024);
+ const char* err=NULL;
+ bool found = false;
+
+ mtr_start(&mtr);
+
+ if (!fixed) {
+ /* We have taken dict_sys on dict_load_table() */
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ mutex_exit(&dict_sys->mutex);
+ rw_lock_x_lock(&dict_operation_lock);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ sys_tableoptions = dict_table_get_low("SYS_TABLE_OPTIONS");
+ sys_index = UT_LIST_GET_FIRST(sys_tableoptions->indexes);
+ ut_ad(!dict_table_is_comp(sys_tableoptions));
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, DICT_FLD__SYS_TABLEOPTIONS__TABLE_ID);
+
+ buf = static_cast<byte*>(mem_heap_alloc(heap, 8));
+ mach_write_to_8(buf, table_id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_SEARCH_LEAF, &pcur, &mtr);
+
+ rec = btr_pcur_get_rec(&pcur);
+
+ /* If the file-per-table tablespace was created with
+ an earlier version of InnoDB, then this record is not
+ in SYS_TABLE_OPTIONS.*/
+
+ memset(options, 0, sizeof(dict_tableoptions_t));
+
+ if (btr_pcur_is_on_user_rec(&pcur)) {
+ err = dict_process_sys_tableoptions(heap, rec, options);
+
+ if (err) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: %s\n", err);
+ } else {
+ found = true;
+ }
+ }
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+ mem_heap_free(heap);
+
+ if (!fixed) {
+ mutex_exit(&(dict_sys->mutex));
+ rw_lock_x_unlock(&dict_operation_lock);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ return(found);
+}
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS
+@return true if found, false if not */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ dict_table_t* table, /*!< in/out: table */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ bool found=false;
+
+ found = dict_get_table_options(table->id, table->table_options, fixed);
+
+ return(found);
+}
+
+/********************************************************************//**
+Update the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_tableoptions(
+/*=====================*/
+ const dict_table_t* table) /*!< in: table object */
+{
+ dberr_t err = DB_SUCCESS;
+ trx_t* trx;
+
+ trx = trx_allocate_for_background();
+ trx->op_info = "update sys_table_options";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+ row_mysql_lock_data_dictionary(trx);
+
+ pars_info_t* info = pars_info_create();
+
+ pars_info_add_ull_literal(info, "tableid", table->id);
+ pars_info_add_int4_literal(info, "pagecomp", (ulint)table->table_options->page_compressed);
+ pars_info_add_int4_literal(info, "level", (ulint)table->table_options->page_compression_level);
+ pars_info_add_int4_literal(info, "awrite", (ulint)table->table_options->atomic_writes);
+ pars_info_add_int4_literal(info, "encrypt", (ulint)table->table_options->encryption);
+ pars_info_add_int4_literal(info, "keyid", (ulint)table->table_options->encryption_key_id);
+
+ err = que_eval_sql(info,
+ "PROCEDURE UPDATE_TABLE_OPTIONS () IS\n"
+ "BEGIN\n"
+ "UPDATE SYS_TABLE_OPTIONS"
+ " SET PAGE_COMPRESSED = :pagecomp,\n"
+ " PAGE_COMPRESSION_LEVEL = :level,\n"
+ " ATOMIC_WRITES = :awrite,\n"
+ " ENCRYPTED = :encrypt,\n"
+ " ENCRYPTION_KEY_ID = : keyid\n"
+ " WHERE TABLE_ID = :tableid;\n"
+ "END;\n", FALSE, trx);
+
+ trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary(trx);
+ trx_free_for_background(trx);
+
+ if (err == DB_SUCCESS) {
+ /* We just updated SYS_TABLE_OPTIONS due to the contents in
+ tablespace or dictionary. Make note of that */
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "The InnoDB data dictionary table SYS_TABLE_OPTIONS "
+ "for table ID %lu name %s was updated to use "
+ "page_compressed %lu compression_level %lu "
+ " atomic_writes %lu encrypted %lu key_id %lu.",
+ table->id, table->name,
+ (ulint)table->table_options->page_compressed,
+ (ulint)table->table_options->page_compression_level,
+ (ulint)table->table_options->atomic_writes,
+ (ulint)table->table_options->encryption,
+ (ulint)table->table_options->encryption_key_id);
+ } else {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem updating InnoDB data dictionary table "
+ "SYS_TABLE_OPTIONS for table ID %lu name %s err %lu.",
+ table->id, table->name, (ulint)err);
+ }
+
+ return(err);
+}
+
+/********************************************************************//**
+Insert record into SYS_TABLE_OPTIONS
+@return DB_SUCCESS if OK, dberr_t if the insert failed */
+UNIV_INTERN
+dberr_t
+dict_insert_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ dberr_t err = DB_SUCCESS;
+ trx_t* trx;
+
+ trx = trx_allocate_for_background();
+ trx->op_info = "insert tableoptions";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ if (!fixed) {
+ /* We have taken dict_sys on dict_load_table() */
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ mutex_exit(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ pars_info_t* info = pars_info_create();
+ pars_info_add_ull_literal(info, "tableid", table->id);
+ pars_info_add_int4_literal(info, "pagecomp", (ulint)table->table_options->page_compressed);
+ pars_info_add_int4_literal(info, "level", (ulint)table->table_options->page_compression_level);
+ pars_info_add_int4_literal(info, "awrite", (ulint)table->table_options->atomic_writes);
+ pars_info_add_int4_literal(info, "encrypt", (ulint)table->table_options->encryption);
+ pars_info_add_int4_literal(info, "keyid", (ulint)table->table_options->encryption_key_id);
+
+ err = que_eval_sql(info,
+ "PROCEDURE INSERT_TABLEOPTIONS () IS\n"
+ "BEGIN\n"
+ "INSERT INTO SYS_TABLE_OPTIONS VALUES"
+ "(:tableid, :pagecomp, :level, :awrite, :encrypt, :keyid);\n"
+ "END;\n",
+ FALSE, trx);
+
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem inserting row to InnoDB data dictionary table SYS_TABLE_OPTIONS "
+ "for table ID %lu name %s "
+ "page_compressed %lu compression_level %lu "
+ " atomic_writes %lu encrypted %lu key_id %lu.",
+ table->id, table->name,
+ (ulint)table->table_options->page_compressed,
+ (ulint)table->table_options->page_compression_level,
+ (ulint)table->table_options->atomic_writes,
+ (ulint)table->table_options->encryption,
+ (ulint)table->table_options->encryption_key_id);
+ }
+
+ trx->op_info = "";
+ trx_commit_for_mysql(trx);
+
+ if (!fixed) {
+ row_mysql_unlock_data_dictionary(trx);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ trx_free_for_background(trx);
+
+ return(err);
+}
+
+/********************************************************************//**
+Update the table flags in SYS_TABLES.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_table_flags(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ dberr_t err = DB_SUCCESS;
+ trx_t* trx;
+
+ trx = trx_allocate_for_background();
+ trx->op_info = "update sys_tables options";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ ulint type = dict_tf_to_sys_tables_type(table->flags);
+
+ if (!fixed) {
+ /* We have taken dict_sys on dict_load_table() */
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ mutex_exit(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ pars_info_t* info = pars_info_create();
+
+ pars_info_add_str_literal(info, "tablename", table->name);
+ pars_info_add_int4_literal(info, "type", type);
+
+ err = que_eval_sql(info,
+ "PROCEDURE UPDATE_TABLE_FLAGS () IS\n"
+ "BEGIN\n"
+ "UPDATE SYS_TABLES"
+ " SET TYPE = :type\n"
+ " WHERE NAME = :tablename;\n"
+ "END;\n", FALSE, trx);
+
+ trx_commit_for_mysql(trx);
+
+ if (!fixed) {
+ row_mysql_unlock_data_dictionary(trx);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ trx_free_for_background(trx);
+
+ if (err == DB_SUCCESS) {
+ /* We just updated SYS_TABLES due to the contents in
+ tablespace or dictionary. Make note of that */
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "The InnoDB data dictionary table SYS_TABLES "
+ "for table ID %lu name %s was updated to use "
+ "flags %lu. ",
+ table->id, table->name,
+ (ulint)type);
+ } else {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem updating InnoDB data dictionary table "
+ "SYS_TABLES for table ID %lu name %s err %lu.",
+ table->id, table->name, (ulint)err);
+ }
+
+ return(err);
+}
+
+/********************************************************************//**
+Delete the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_delete_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ trx_t* trx, /*!< in: trx */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ dberr_t err = DB_SUCCESS;
+
+ trx->op_info = "delete sys_table_options";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ if (!fixed) {
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ if (dict_get_table_options((dict_table_t*)table, true)) {
+
+ pars_info_t* info = pars_info_create();
+
+ pars_info_add_ull_literal(info, "tableid", table->id);
+
+ err = que_eval_sql(info,
+ "PROCEDURE DELETE_TABLE_OPTIONS () IS\n"
+ "BEGIN\n"
+ "DELETE FROM SYS_TABLE_OPTIONS"
+ " WHERE TABLE_ID = :tableid;\n"
+ "END;\n", FALSE, trx);
+
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem deleting InnoDB data dictionary table "
+ "SYS_TABLE_OPTIONS for table ID %lu name %s err %lu.",
+ table->id, table->name, (ulint)err);
+ }
+ }
+
+ if (!fixed) {
+ row_mysql_unlock_data_dictionary(trx);
+ }
+
+ return(err);
+}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 928c72cf546..4f7546519e8 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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
@@ -25,6 +25,8 @@ Created 10/25/1995 Heikki Tuuri
*******************************************************/
#include "fil0fil.h"
+#include "rem0rec.h"
+#include "dict0tableoptions.h"
#include "fil0pagecompress.h"
#include "fsp0pagecompress.h"
#include "fil0crypt.h"
@@ -674,7 +676,6 @@ fil_node_open_file(
flags = fsp_header_get_flags(page);
page_size = fsp_flags_get_page_size(flags);
- atomic_writes = fsp_flags_get_atomic_writes(flags);
ut_free(buf2);
@@ -716,27 +717,6 @@ fil_node_open_file(
ut_error;
}
- if (UNIV_UNLIKELY(space->flags != flags)) {
- fprintf(stderr,
- "InnoDB: Error: table flags are 0x%lx"
- " in the data dictionary\n"
- "InnoDB: but the flags in file %s are 0x%lx!\n",
- space->flags, node->name, flags);
-
- ut_error;
- }
-
- if (UNIV_UNLIKELY(space->flags != flags)) {
- if (!dict_tf_verify_flags(space->flags, flags)) {
- fprintf(stderr,
- "InnoDB: Error: table flags are 0x%lx"
- " in the data dictionary\n"
- "InnoDB: but the flags in file %s are 0x%lx!\n",
- space->flags, node->name, flags);
- ut_error;
- }
- }
-
if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
/* Truncate the size to whole extent size. */
size_bytes = ut_2pow_round(size_bytes,
@@ -758,7 +738,7 @@ add_size:
space->size += node->size;
}
- atomic_writes = fsp_flags_get_atomic_writes(space->flags);
+ atomic_writes = fil_space_get_atomic_writes(space);
/* printf("Opening file %s\n", node->name); */
@@ -1147,11 +1127,12 @@ UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- const char* name, /*!< in: space name */
- 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 */
+ const char* name, /*!< in: space name */
+ 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 */
+ const void *options)/*!< in: table options*/
{
fil_space_t* space;
@@ -1248,6 +1229,13 @@ fil_space_create(
space->crypt_data = crypt_data;
+ if (options) {
+ space->table_options = static_cast<dict_tableoptions_t*>(mem_zalloc(sizeof(dict_tableoptions_t)));
+ memcpy(space->table_options, (dict_tableoptions_t*)options, sizeof(dict_tableoptions_t));
+ } else {
+ space->table_options = NULL;
+ }
+
mutex_exit(&fil_system->mutex);
return(TRUE);
@@ -1384,6 +1372,10 @@ fil_space_free(
fil_space_destroy_crypt_data(&(space->crypt_data));
+ if (space->table_options) {
+ mem_free(space->table_options);
+ }
+
mem_free(space->name);
mem_free(space);
@@ -1917,12 +1909,7 @@ fil_check_first_page(
flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) {
- fprintf(stderr,
- "InnoDB: Error: Current page size %lu != "
- " page size on page %lu\n",
- UNIV_PAGE_SIZE, fsp_flags_get_page_size(flags));
-
- return("innodb-page-size mismatch");
+ return("innodb-page-size mismatch");
}
if (!space_id && !flags) {
@@ -1998,14 +1985,11 @@ fil_read_first_page(
*flags and *space_id as they were read from the first file and
do not validate the first page. */
if (!one_read_already) {
+ check_msg = fil_check_first_page(page);
*flags = fsp_header_get_flags(page);
*space_id = fsp_header_get_space_id(page);
}
- if (!one_read_already) {
- check_msg = fil_check_first_page(page);
- }
-
flushed_lsn = mach_read_from_8(page +
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
@@ -2396,8 +2380,7 @@ fil_op_log_parse_or_replay(
space_id, name, path, flags,
DICT_TF2_USE_TABLESPACE,
FIL_IBD_FILE_INITIAL_SIZE,
- FIL_SPACE_ENCRYPTION_DEFAULT,
- FIL_DEFAULT_ENCRYPTION_KEY) != DB_SUCCESS) {
+ NULL) != DB_SUCCESS) {
ut_error;
}
}
@@ -3379,8 +3362,7 @@ fil_create_new_single_table_tablespace(
ulint size, /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ const dict_table_t* table) /*!< in: table or NULL */
{
os_file_t file;
ibool ret;
@@ -3392,8 +3374,11 @@ fil_create_new_single_table_tablespace(
/* TRUE if a table is created with CREATE TEMPORARY TABLE */
bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY);
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
- ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
+ ulint atomic_writes = table ? table->table_options->atomic_writes :
+ ATOMIC_WRITES_DEFAULT;
fil_space_crypt_t *crypt_data = NULL;
+ fil_encryption_t mode = table ? table->table_options->encryption :
+ FIL_SPACE_ENCRYPTION_DEFAULT;
ut_a(space_id > 0);
ut_ad(!srv_read_only_mode);
@@ -3551,11 +3536,13 @@ fil_create_new_single_table_tablespace(
requested it to remain unencrypted. */
if (mode == FIL_SPACE_ENCRYPTION_ON || mode == FIL_SPACE_ENCRYPTION_OFF ||
srv_encrypt_tables) {
+ uint key_id = table ? table->table_options->encryption_key_id :
+ FIL_DEFAULT_ENCRYPTION_KEY;
crypt_data = fil_space_create_crypt_data(mode, key_id);
}
success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
- crypt_data);
+ crypt_data, table ? table->table_options : NULL);
if (!success || !fil_node_create(path, size, space_id, FALSE)) {
err = DB_ERROR;
@@ -3640,6 +3627,140 @@ fil_report_bad_tablespace(
(ulong) expected_id, (ulong) expected_flags);
}
+/******************************************************************
+Set flags for a tablespace */
+static
+void
+fil_space_set_fsp_flags(
+/*=====================*/
+ ulint id, /*!< in: space id */
+ uint flags) /*!< in: fsp flags */
+{
+ fil_space_t* space;
+
+ ut_ad(fil_system);
+
+ mutex_enter(&fil_system->mutex);
+
+ space = fil_space_get_by_id(id);
+
+ if (space != NULL) {
+ space->flags = flags;
+ }
+
+ mutex_exit(&fil_system->mutex);
+}
+
+/******************************************************************
+Update tablespace (fsp) flags on page 0
+@return true if successfull, false if not */
+static
+void
+fil_update_page0(
+/*=============*/
+ byte* page0, /*!< in: page 0 or NULL */
+ os_file_t data_file, /*!< in: data file */
+ ulint space, /*!< in: space id */
+ ulint flags, /*!< in: old fsp flags */
+ ulint fsp_flags)/*!< in: new fsp flags */
+{
+ ulint psize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB(flags);
+ ulint zip_size = FSP_FLAGS_GET_ZIP_SSIZE(flags);
+
+ if (!psize) {
+ psize = UNIV_PAGE_SIZE_ORIG;
+ }
+
+ fsp_flags = fsp_flags_set_page_size(fsp_flags, psize);
+
+ if (flags != fsp_flags) {
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "InnoDB: Adjusted space_id %lu tablespace flags from %lu to %lu.\n",
+ space, flags, fsp_flags);
+
+ mtr_t mtr;
+ mtr_start(&mtr);
+
+ if (!page0) {
+ buf_block_t* block = buf_page_get_gen(space,
+ zip_size, 0,
+ RW_X_LATCH,
+ NULL,
+ BUF_GET,
+ __FILE__, __LINE__,
+ &mtr);
+ page0 = buf_block_get_frame(block);
+ }
+
+ mlog_write_ulint(page0 + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS,
+ fsp_flags, MLOG_4BYTES, &mtr);
+ /* Redo log this as bytewise update to page 0
+ followed by an MLOG_FILE_WRITE_FSP_FLAGS */
+ byte* log_ptr = mlog_open(&mtr, 11 + 8);
+ if (log_ptr != NULL) {
+ log_ptr = mlog_write_initial_log_record_fast(
+ page0,
+ MLOG_FILE_WRITE_FSP_FLAGS,
+ log_ptr, &mtr);
+ mach_write_to_4(log_ptr, fsp_flags);
+ log_ptr += 4;
+ mach_write_to_4(log_ptr, space);
+ log_ptr += 4;
+ mlog_close(&mtr, log_ptr);
+ }
+
+ mtr_commit(&mtr);
+ lsn_t end_lsn = mtr.end_lsn;
+ buf_flush_init_for_writing(page0, NULL, end_lsn);
+ flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page0);
+ ut_ad(flags == fsp_flags);
+
+ /* Flush dirty page to the storage */
+ ulint n_pages = 0;
+ ulint sum_pages = 0;
+ bool success = false;
+ do {
+ success = buf_flush_list(ULINT_MAX, end_lsn, &n_pages);
+ buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
+ sum_pages += n_pages;
+ } while (!success);
+
+ fil_space_set_fsp_flags(space, fsp_flags);
+ }
+}
+
+/******************************************************************
+Parse a MLOG_FILE_WRITE_FSP_FLAGS log entry
+@return position on log buffer */
+UNIV_INTERN
+byte*
+fil_parse_write_fsp_flags(
+/*======================*/
+ byte* ptr, /*!< in: Log entry start */
+ byte* end_ptr,/*!< in: Log entry end */
+ buf_block_t* block) /*!< in: buffer block */
+{
+ /* check that redo log entry is complete */
+ uint entry_size = 4 + 4; // size of flags + space_id
+
+ if (end_ptr - ptr < entry_size){
+ return NULL;
+ }
+
+ ulint flags = mach_read_from_4(ptr);
+ ptr += 4;
+ ulint space_id = mach_read_from_4(ptr);
+ ptr += 4;
+
+ ut_a(fsp_flags_is_valid(flags));
+
+ /* update fil_space memory cache with flags */
+ fil_space_set_fsp_flags(space_id, flags);
+
+ return ptr;
+}
+
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks that the
space id in it is correct. If this does not succeed, print an error message
@@ -3673,7 +3794,8 @@ fil_open_single_table_tablespace(
const char* tablename, /*!< in: table name in the
databasename/tablename format */
const char* path_in, /*!< in: tablespace filepath */
- dict_table_t* table) /*!< in: table */
+ dict_table_t* table, /*!< in: table or NULL */
+ void* options) /*!< in: table options or NULL*/
{
dberr_t err = DB_SUCCESS;
bool dict_filepath_same_as_default = false;
@@ -3686,6 +3808,8 @@ fil_open_single_table_tablespace(
ulint valid_tablespaces_found = 0;
ulint atomic_writes = 0;
fil_space_crypt_t* crypt_data = NULL;
+ bool fix_flags = false;
+ ulint nflags = 0;
#ifdef UNIV_SYNC_DEBUG
ut_ad(!fix_dict || rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
@@ -3702,7 +3826,7 @@ fil_open_single_table_tablespace(
return(DB_CORRUPTION);
}
- atomic_writes = fsp_flags_get_atomic_writes(flags);
+ atomic_writes = options ? ((dict_tableoptions_t*)options)->atomic_writes : 0;
/* If the tablespace was relocated, we do not
compare the DATA_DIR flag */
@@ -3794,18 +3918,27 @@ fil_open_single_table_tablespace(
table->crypt_data = def.crypt_data;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
- if (def.valid && def.id == id
- && (def.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ /* This could mean that tablespace flags are corrupted
+ or that they are old */
+ if ((def.flags & ~FSP_FLAGS_MASK_DATA_DIR) != mod_flags &&
+ table && options) {
+ fix_flags = true;
valid_tablespaces_found++;
} else {
- def.valid = false;
- /* Do not use this tablespace. */
- fil_report_bad_tablespace(
- def.filepath, def.check_msg, def.id,
- def.flags, id, flags);
+
+ /* Validate this single-table-tablespace with SYS_TABLES,
+ but do not compare the DATA_DIR flag, in case the
+ tablespace was relocated. */
+ if (def.valid && def.id == id
+ && (def.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ valid_tablespaces_found++;
+ } else {
+ def.valid = false;
+ /* Do not use this tablespace. */
+ fil_report_bad_tablespace(
+ def.filepath, def.check_msg, def.id,
+ def.flags, id, flags);
+ }
}
}
@@ -3827,15 +3960,22 @@ fil_open_single_table_tablespace(
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
if (remote.valid && remote.id == id
- && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) != mod_flags &&
+ table && options ) {
+ fix_flags = true;
valid_tablespaces_found++;
} else {
- remote.valid = false;
- /* Do not use this linked tablespace. */
- fil_report_bad_tablespace(
- remote.filepath, remote.check_msg, remote.id,
- remote.flags, id, flags);
- link_file_is_bad = true;
+ if (remote.valid && remote.id == id
+ && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ valid_tablespaces_found++;
+ } else {
+ remote.valid = false;
+ /* Do not use this linked tablespace. */
+ fil_report_bad_tablespace(
+ remote.filepath, remote.check_msg, remote.id,
+ remote.flags, id, flags);
+ link_file_is_bad = true;
+ }
}
}
@@ -3853,18 +3993,27 @@ fil_open_single_table_tablespace(
table->crypt_data = dict.crypt_data;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
- if (dict.valid && dict.id == id
- && (dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ /* This could mean that tablespace flags are corrupted
+ or that they are old */
+ if ((dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) != mod_flags &&
+ table && options ) {
+ fix_flags = true;
valid_tablespaces_found++;
} else {
- dict.valid = false;
- /* Do not use this tablespace. */
- fil_report_bad_tablespace(
- dict.filepath, dict.check_msg, dict.id,
- dict.flags, id, flags);
+
+ /* Validate this single-table-tablespace with SYS_TABLES,
+ but do not compare the DATA_DIR flag, in case the
+ tablespace was relocated. */
+ if (dict.valid && dict.id == id
+ && (dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ valid_tablespaces_found++;
+ } else {
+ dict.valid = false;
+ /* Do not use this tablespace. */
+ fil_report_bad_tablespace(
+ dict.filepath, dict.check_msg, dict.id,
+ dict.flags, id, flags);
+ }
}
}
@@ -4013,7 +4162,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, options)) {
err = DB_ERROR;
} else {
/* We do not measure the size of the file, that is why
@@ -4026,6 +4175,46 @@ skip_validate:
}
}
+ if (fix_flags) {
+ /* Here we remove PAGE_COMPRESSION, PAGE_COMPRESSION_LEVEL,
+ ATOMIC_WRITES, PAGE_ENCRYPTION and PAGE_ENCRYPTION_KEY
+ values from table flags. */
+ nflags = (DICT_TF_GET_COMPACT(table->flags) << DICT_TF_POS_COMPACT)
+ | (DICT_TF_GET_ZIP_SSIZE(table->flags) << DICT_TF_POS_ZIP_SSIZE)
+ | (DICT_TF_HAS_ATOMIC_BLOBS(table->flags) << DICT_TF_POS_ATOMIC_BLOBS)
+ | (DICT_TF_HAS_DATA_DIR(table->flags) << DICT_TF_POS_DATA_DIR);
+ ulint fsp_flags = dict_tf_to_fsp_flags(nflags);
+
+ if (def.success) {
+ fil_update_page0(NULL, def.file, def.id, def.flags, fsp_flags);
+ } else if (dict.success) {
+ fil_update_page0(NULL, dict.file, dict.id, dict.flags, fsp_flags);
+ } else {
+ fil_update_page0(NULL, remote.file, remote.id, remote.flags, fsp_flags);
+ }
+
+ if (((dict_tableoptions_t*)options)->need_stored) {
+ dict_insert_tableoptions(table, fix_dict);
+ }
+
+ if (def.success) {
+ def.check_msg = fil_read_first_page(
+ def.file, FALSE, &def.flags, &def.id,
+ &def.lsn, &def.lsn, &def.crypt_data);
+ } else if (dict.success) {
+ dict.check_msg = fil_read_first_page(
+ dict.file, FALSE, &dict.flags, &dict.id,
+ &dict.lsn, &dict.lsn, &dict.crypt_data);
+ } else {
+ remote.check_msg = fil_read_first_page(
+ remote.file, FALSE, &remote.flags, &remote.id,
+ &remote.lsn, &remote.lsn, &remote.crypt_data);
+ }
+
+ table->flags = nflags;
+ dict_update_table_flags(table, fix_dict);
+ }
+
cleanup_and_exit:
if (remote.success) {
os_file_close(remote.file);
@@ -4420,6 +4609,7 @@ fil_load_single_table_tablespace(
if (!remote.success) {
os_file_close(remote.file);
mem_free(remote.filepath);
+ remote.filepath = NULL;
}
}
@@ -4630,7 +4820,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, NULL);
if (!file_space_create_success) {
if (srv_force_recovery > 0) {
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index 85bdeaf053f..f7de24353c9 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +25,8 @@ Updated 14/02/2015
***********************************************************************/
#include "fil0fil.h"
+#include "rem0rec.h"
+#include "dict0tableoptions.h"
#include "fil0pagecompress.h"
#include <debug_sync.h>
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index cc4a4f9f1a8..f81fd31c733 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1489,7 +1489,8 @@ fts_drop_table(
table = dict_table_open_on_name(
table_name, TRUE, FALSE,
static_cast<dict_err_ignore_t>(
- DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT));
+ DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT),
+ NULL);
if (table != 0) {
@@ -1981,7 +1982,13 @@ fts_create_one_index_table(
dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB,
4130048, 0);
- error = row_create_table_for_mysql(new_table, trx, false, FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ /* Get default encryption key id if set */
+ if (new_table && new_table->table_options &&
+ new_table->table_options->encryption_key_id == 0) {
+ new_table->table_options->encryption_key_id = innobase_get_default_encryption_key_id(trx);
+ }
+
+ error = row_create_table_for_mysql(new_table, trx, false);
if (error != DB_SUCCESS) {
trx->error_state = error;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 527c5beb47c..3d5aaee468a 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4,7 +4,7 @@ Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -87,6 +87,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "dict0boot.h"
#include "dict0stats.h"
#include "dict0stats_bg.h"
+#include "dict0tableoptions.h"
#include "ha_prototypes.h"
#include "ut0mem.h"
#include "ut0timer.h"
@@ -5459,6 +5460,43 @@ ha_innobase::innobase_initialize_autoinc()
}
/*****************************************************************//**
+Set up the table options structure based on frm. */
+UNIV_INTERN
+void
+ha_innobase::set_table_options(
+/*===========================*/
+ THD* thd, /*!< in: thd */
+ TABLE* table, /*!< in: table */
+ dict_tableoptions_t* options) /*!< in: table options */
+{
+ ha_table_option_struct* moptions = table->s->option_struct;
+
+ options->page_compressed = moptions->page_compressed;
+ options->page_compression_level = moptions->page_compression_level;
+ options->atomic_writes = (atomic_writes_t)moptions->atomic_writes;
+ options->encryption = (fil_encryption_t)moptions->encryption;
+ options->encryption_key_id = moptions->encryption_key_id;
+
+ if (options->encryption_key_id == 0) {
+ options->encryption_key_id = THDVAR(thd, default_encryption_key_id);
+ }
+
+ if (options->page_compression_level == 0) {
+ options->page_compression_level = page_zip_level;
+ }
+
+ /* Table options should be stored if they are not same as
+ defaults */
+ if (moptions->page_compressed ||
+ (options->atomic_writes == ATOMIC_WRITES_ON ||
+ options->atomic_writes == ATOMIC_WRITES_OFF) ||
+ (options->encryption == FIL_SPACE_ENCRYPTION_OFF ||
+ options->encryption == FIL_SPACE_ENCRYPTION_ON)) {
+ options->need_stored = true;
+ }
+}
+
+/*****************************************************************//**
Creates and opens a handle to a table which already exists in an InnoDB
database.
@return 1 if error, 0 if success */
@@ -5477,6 +5515,7 @@ ha_innobase::open(
ibool par_case_name_set = FALSE;
char par_case_name[FN_REFLEN];
dict_err_ignore_t ignore_err = DICT_ERR_IGNORE_NONE;
+ dict_tableoptions_t table_options;
DBUG_ENTER("ha_innobase::open");
@@ -5485,6 +5524,8 @@ ha_innobase::open(
thd = ha_thd();
+ set_table_options(thd, table, &table_options);
+
/* Under some cases MySQL seems to call this function while
holding btr_search_latch. This breaks the latching order as
we acquire dict_sys->mutex below and leads to a deadlock. */
@@ -5521,7 +5562,7 @@ ha_innobase::open(
}
/* Get pointer to a table object in InnoDB dictionary cache */
- ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err);
+ ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err, &table_options);
if (ib_table
&& ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)
@@ -5587,7 +5628,7 @@ ha_innobase::open(
ib_table = dict_table_open_on_name(
par_case_name, FALSE, TRUE,
- ignore_err);
+ ignore_err, &table_options);
}
if (ib_table) {
@@ -10435,8 +10476,7 @@ create_table_def(
const char* remote_path, /*!< in: Remote path or zero length-string */
ulint flags, /*!< in: table flags */
ulint flags2, /*!< in: table flags2 */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ dict_tableoptions_t* table_options) /*!< in: table options */
{
THD* thd = trx->mysql_thd;
dict_table_t* table;
@@ -10626,7 +10666,10 @@ err_col:
fts_add_doc_id_column(table, heap);
}
- err = row_create_table_for_mysql(table, trx, false, mode, key_id);
+ /* Copy table options to table */
+ memcpy(table->table_options, table_options, sizeof(dict_tableoptions_t));
+
+ err = row_create_table_for_mysql(table, trx, false);
mem_heap_free(heap);
@@ -11213,16 +11256,11 @@ innobase_table_flags(
enum row_type row_format;
rec_format_t innodb_row_format = REC_FORMAT_COMPACT;
bool use_data_dir;
- ha_table_option_struct *options= form->s->option_struct;
/* Cache the value of innodb_file_format, in case it is
modified by another thread while the table is being created. */
const ulint file_format_allowed = srv_file_format;
- /* Cache the value of innobase_compression_level, in case it is
- modified by another thread while the table is being created. */
- const ulint default_compression_level = page_zip_level;
-
*flags = 0;
*flags2 = 0;
@@ -11431,11 +11469,7 @@ index_bad:
dict_tf_set(flags,
innodb_row_format,
zip_ssize,
- use_data_dir,
- options->page_compressed,
- options->page_compression_level == 0 ?
- default_compression_level : options->page_compression_level,
- options->atomic_writes);
+ use_data_dir);
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) {
*flags2 |= DICT_TF2_TEMPORARY;
@@ -11467,7 +11501,8 @@ ha_innobase::check_table_options(
created table, contains also the
create statement string */
const bool use_tablespace, /*!< in: use file par table */
- const ulint file_format)
+ const ulint file_format, /*!< in: table row format */
+ dict_tableoptions_t* table_options) /*!< out: used table options */
{
enum row_type row_format = table->s->row_type;
ha_table_option_struct *options= table->s->option_struct;
@@ -11537,6 +11572,8 @@ ha_innobase::check_table_options(
" key_block_size");
return "PAGE_COMPRESSED";
}
+
+ table_options->need_stored = true;
}
/* Check page compression level requirements, some of them are
@@ -11560,6 +11597,10 @@ ha_innobase::check_table_options(
options->page_compression_level);
return "PAGE_COMPRESSION_LEVEL";
}
+
+ table_options->need_stored = true;
+ } else if (options->page_compressed) {
+ options->page_compression_level = page_zip_level;
}
/* If encryption is set up make sure that used key_id is found */
@@ -11585,7 +11626,10 @@ ha_innobase::check_table_options(
"InnoDB: Ignored ENCRYPTION_KEY_ID %u when encryption is disabled",
(uint)options->encryption_key_id
);
+
options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+ table_options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+ table_options->need_stored = true;
}
/* If default encryption is used make sure that used kay is found
@@ -11603,6 +11647,10 @@ ha_innobase::check_table_options(
return "ENCRYPTION_KEY_ID";
}
+
+ table_options->need_stored = true;
+
+ table_options->need_stored = true;
}
/* Check atomic writes requirements */
@@ -11616,8 +11664,16 @@ ha_innobase::check_table_options(
" innodb_file_per_table.");
return "ATOMIC_WRITES";
}
+
+ table_options->need_stored = true;
}
+ table_options->page_compressed = options->page_compressed;
+ table_options->page_compression_level = options->page_compression_level;
+ table_options->atomic_writes = awrites;
+ table_options->encryption = encrypt;
+ table_options->encryption_key_id = options->encryption_key_id;
+
return 0;
}
@@ -11659,13 +11715,10 @@ ha_innobase::create(
ulint flags;
ulint flags2;
dict_table_t* innobase_table = NULL;
+ dict_tableoptions_t table_options;
const char* stmt;
size_t stmt_len;
- /* Cache table options */
- ha_table_option_struct *options= form->s->option_struct;
- fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
- uint key_id = (uint)options->encryption_key_id;
DBUG_ENTER("ha_innobase::create");
@@ -11680,9 +11733,11 @@ ha_innobase::create(
/* Create the table definition in InnoDB */
+ memset(&table_options, 0, sizeof(dict_tableoptions_t));
+
/* Validate table options not handled by the SQL-parser */
if(check_table_options(thd, form, create_info, use_tablespace,
- file_format)) {
+ file_format, &table_options)) {
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
@@ -11758,7 +11813,8 @@ ha_innobase::create(
row_mysql_lock_data_dictionary(trx);
error = create_table_def(trx, form, norm_name, temp_path,
- remote_path, flags, flags2, encrypt, key_id);
+ remote_path, flags, flags2, &table_options);
+
if (error) {
goto cleanup;
}
@@ -11792,7 +11848,7 @@ ha_innobase::create(
enum fts_doc_id_index_enum ret;
innobase_table = dict_table_open_on_name(
- norm_name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ norm_name, TRUE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
ut_a(innobase_table);
@@ -11914,7 +11970,7 @@ ha_innobase::create(
log_buffer_flush_to_disk();
innobase_table = dict_table_open_on_name(
- norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
DBUG_ASSERT(innobase_table != 0);
@@ -12270,22 +12326,26 @@ ha_innobase::defragment_table(
bool async) /*!< in: whether to wait until finish */
{
char norm_name[FN_REFLEN];
- dict_table_t* table = NULL;
+ dict_table_t* itable = NULL;
dict_index_t* index = NULL;
ibool one_index = (index_name != 0);
int ret = 0;
dberr_t err = DB_SUCCESS;
+ dict_tableoptions_t options;
+ THD* thd;
if (!srv_defragment) {
return ER_FEATURE_DISABLED;
}
normalize_table_name(norm_name, name);
+ thd = ha_thd();
+ set_table_options(thd, table, &options);
- table = dict_table_open_on_name(norm_name, FALSE,
- FALSE, DICT_ERR_IGNORE_NONE);
+ itable = dict_table_open_on_name(norm_name, FALSE,
+ FALSE, DICT_ERR_IGNORE_NONE, &options);
- for (index = dict_table_get_first_index(table); index;
+ for (index = dict_table_get_first_index(itable); index;
index = dict_table_get_next_index(index)) {
if (one_index && strcasecmp(index_name, index->name) != 0) {
@@ -12344,7 +12404,7 @@ ha_innobase::defragment_table(
}
}
- dict_table_close(table, FALSE, FALSE);
+ dict_table_close(itable, FALSE, FALSE);
if (ret == 0 && one_index) {
ret = ER_NO_SUCH_INDEX;
@@ -16620,7 +16680,7 @@ innodb_internal_table_validate(
}
user_table = dict_table_open_on_name(
- table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE);
+ table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE, NULL);
if (user_table) {
if (dict_table_has_fts_index(user_table)) {
@@ -19765,7 +19825,8 @@ i_s_innodb_sys_datafiles,
i_s_innodb_mutexes,
i_s_innodb_sys_semaphore_waits,
i_s_innodb_tablespaces_encryption,
-i_s_innodb_tablespaces_scrubbing
+i_s_innodb_tablespaces_scrubbing,
+i_s_innodb_sys_table_options
maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
@@ -20422,3 +20483,25 @@ ib_push_warning(
my_free(buf);
va_end(args);
}
+
+/********************************************************************//**
+Helper function to get default_encryption_key_id from THD
+(trx->mysql_thd).
+@return default_encryption_key_id from THD or
+FIL_DEFAULT_ENCRYPTION_KEY */
+UNIV_INTERN
+ulint
+innobase_get_default_encryption_key_id(
+/*===================================*/
+ trx_t* trx) /*! in: trx */
+{
+ ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+
+ if (trx && trx->mysql_thd) {
+ THD *thd = (THD *)trx->mysql_thd;
+
+ key_id = THDVAR(thd, default_encryption_key_id);
+ }
+
+ return (key_id);
+}
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 4f4a0b2f999..1f407107fc0 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -201,7 +201,9 @@ class ha_innobase: public handler
char* temp_path,
char* remote_path);
const char* check_table_options(THD *thd, TABLE* table,
- HA_CREATE_INFO* create_info, const bool use_tablespace, const ulint file_format);
+ HA_CREATE_INFO* create_info, const bool use_tablespace, const ulint file_format,
+ dict_tableoptions_t* table_options);
+ void set_table_options(THD *thd, TABLE*table, dict_tableoptions_t* table_options);
int create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info);
int truncate();
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 74f36467f1f..ab2dcd5fc57 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -2826,7 +2826,6 @@ prepare_inplace_alter_table_dict(
to rebuild the table with a temporary name. */
if (new_clustered) {
- fil_space_crypt_t* crypt_data;
const char* new_table_name
= dict_mem_create_temporary_tablename(
ctx->heap,
@@ -2834,15 +2833,6 @@ prepare_inplace_alter_table_dict(
ctx->new_table->id);
ulint n_cols;
dtuple_t* add_cols;
- ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
- fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT;
-
- crypt_data = fil_space_get_crypt_data(ctx->prebuilt->table->space);
-
- if (crypt_data) {
- key_id = crypt_data->key_id;
- mode = crypt_data->encryption;
- }
if (innobase_check_foreigns(
ha_alter_info, altered_table, old_table,
@@ -2974,7 +2964,7 @@ prepare_inplace_alter_table_dict(
}
error = row_create_table_for_mysql(
- ctx->new_table, ctx->trx, false, mode, key_id);
+ ctx->new_table, ctx->trx, false);
switch (error) {
dict_table_t* temp_table;
@@ -2987,7 +2977,7 @@ prepare_inplace_alter_table_dict(
ut_ad(mutex_own(&dict_sys->mutex));
temp_table = dict_table_open_on_name(
ctx->new_table->name, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
ut_a(ctx->new_table == temp_table);
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
@@ -3494,7 +3484,8 @@ ha_innobase::prepare_inplace_alter_table(
user_thd, altered_table,
ha_alter_info->create_info,
prebuilt->table->space != 0,
- srv_file_format)) {
+ srv_file_format,
+ prebuilt->table->table_options)) {
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
table_type(), invalid_tbopt);
goto err_exit_no_heap;
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index ef69e7df29d..75baa9d925a 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2015, Oracle and/or its affiliates.
-Copyrigth (c) 2014, 2015, MariaDB Corporation
+Copyrigth (c) 2014, 2016, 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
@@ -48,6 +48,7 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
#include "ibuf0ibuf.h"
#include "dict0mem.h"
#include "dict0types.h"
+#include "dict0tableoptions.h"
#include "ha_prototypes.h"
#include "srv0start.h"
#include "trx0i_s.h"
@@ -2944,7 +2945,7 @@ i_s_fts_deleted_generic_fill(
deleted = fts_doc_ids_create();
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -3344,7 +3345,7 @@ i_s_fts_index_cache_fill(
}
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -3785,7 +3786,7 @@ i_s_fts_index_table_fill(
}
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -3936,7 +3937,7 @@ i_s_fts_config_fill(
fields = table->field;
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -9059,8 +9060,6 @@ static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
END_OF_ST_FIELD_INFO
};
-
-
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS
@return 0 on success */
@@ -9130,3 +9129,230 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_semaphore_waits =
STRUCT_FLD(version_info, INNODB_VERSION_STR),
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA),
};
+
+/** SYS_TABLE_OPTIONS ************************************************/
+/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLE_OPTIONS */
+static ST_FIELD_INFO innodb_sys_tableoptions_fields_info[] =
+{
+ // SYS_TABLE_OPTIONS_TABLE_ID 0
+ {STRUCT_FLD(field_name, "TABLE_ID"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_PAGE_COMPRESSED 1
+ {STRUCT_FLD(field_name, "PAGE_COMPRESSED"),
+ STRUCT_FLD(field_length, 7),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_PAGE_COMPRESSION_LEVEL 2
+ {STRUCT_FLD(field_name, "PAGE_COMPRESSION_LEVEL"),
+ STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_ATOMIC_WRITES 3
+ {STRUCT_FLD(field_name, "ATOMIC_WRITES"),
+ STRUCT_FLD(field_length, 9),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_ENCRYPTED 4
+ {STRUCT_FLD(field_name, "ENCRYPTED"),
+ STRUCT_FLD(field_length, 9),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_ENCRYPTION_KEY_ID 5
+ {STRUCT_FLD(field_name, "ENCRYPTION_KEY_ID"),
+ STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+
+/*******************************************************************//**
+Function to go through each record in SYS_TABLE_OPTIONS table, and fill the
+information_schema.innodb_sys_table_options table with related table information
+@return 0 on success */
+static
+int
+i_s_dict_fill_sys_table_options(
+/*============================*/
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ Item* ) /*!< in: condition (not used) */
+{
+ btr_pcur_t pcur;
+ const rec_t* rec;
+ mem_heap_t* heap;
+ mtr_t mtr;
+
+ DBUG_ENTER("i_s_sys_table_options_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
+ /* deny access to user without PROCESS_ACL privilege */
+ if (check_global_access(thd, PROCESS_ACL, true)) {
+ DBUG_RETURN(0);
+ }
+
+ heap = mem_heap_create(1000);
+ mutex_enter(&(dict_sys->mutex));
+ mtr_start(&mtr);
+
+ rec = dict_startscan_system(&pcur, &mtr, SYS_TABLE_OPTIONS);
+
+ while (rec) {
+ const char* err_msg;
+ dict_tableoptions_t options;
+
+ /* Create and populate a dict_tableoptions_t structure with
+ information from SYS_TABLE_OPTIONS row */
+ memset(&options, 0, sizeof(dict_tableoptions_t));
+
+ err_msg = dict_process_sys_tableoptions(
+ heap, rec, &options);
+
+ mtr_commit(&mtr);
+ mutex_exit(&dict_sys->mutex);
+
+ if (!err_msg) {
+ Field** fields = tables->table->field;
+
+ OK(fields[SYS_TABLE_OPTIONS_TABLE_ID]->store((longlong) options.table_id));
+ OK(fields[SYS_TABLE_OPTIONS_PAGE_COMPRESSION_LEVEL]->store((ulint)options.page_compression_level));
+ OK(fields[SYS_TABLE_OPTIONS_ENCRYPTION_KEY_ID]->store((ulint)options.encryption_key_id));
+
+ if (options.page_compressed) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_PAGE_COMPRESSED], "YES"));
+ } else {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_PAGE_COMPRESSED], "NO"));
+ }
+
+ if (options.encryption == FIL_SPACE_ENCRYPTION_DEFAULT) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ENCRYPTED], "DEFAULT"));
+ } else if (options.encryption == FIL_SPACE_ENCRYPTION_ON) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ENCRYPTED], "ON"));
+ } else {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ENCRYPTED], "OFF"));
+ }
+
+ if (options.atomic_writes == ATOMIC_WRITES_DEFAULT) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ATOMIC_WRITES], "DEFAULT"));
+ } else if (options.atomic_writes == ATOMIC_WRITES_ON) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ATOMIC_WRITES], "ON"));
+ } else {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ATOMIC_WRITES], "OFF"));
+ }
+
+ OK(schema_table_store_record(thd, tables->table));
+
+ } else {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_CANT_FIND_SYSTEM_REC, "%s",
+ err_msg);
+ }
+
+ mem_heap_empty(heap);
+
+ /* Get the next record */
+ mutex_enter(&dict_sys->mutex);
+ mtr_start(&mtr);
+ rec = dict_getnext_system(&pcur, &mtr);
+ }
+
+ mtr_commit(&mtr);
+ mutex_exit(&dict_sys->mutex);
+ mem_heap_free(heap);
+
+ DBUG_RETURN(0);
+}
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLE_OPTIONS
+@return 0 on success */
+static
+int
+innodb_sys_table_options_init(
+/*============================*/
+ void* p) /*!< in/out: table schema object */
+{
+ ST_SCHEMA_TABLE* schema;
+
+ DBUG_ENTER("innodb_sys_table_options_init");
+
+ schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = innodb_sys_tableoptions_fields_info;
+ schema->fill_table = i_s_dict_fill_sys_table_options;
+
+ DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_table_options =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_SYS_TABLE_OPTIONS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, maria_plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB SYS_TABLE_OPTIONS"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_sys_table_options_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* Maria extension */
+ STRUCT_FLD(version_info, INNODB_VERSION_STR),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA),
+};
diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
index 979d9d80a7f..d06b3d015be 100644
--- a/storage/innobase/handler/i_s.h
+++ b/storage/innobase/handler/i_s.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyrigth (c) 2014, 2015, MariaDB Corporation
+Copyrigth (c) 2014, 2016, 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
@@ -63,6 +63,7 @@ extern struct st_maria_plugin i_s_innodb_mutexes;
extern struct st_maria_plugin i_s_innodb_tablespaces_encryption;
extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing;
extern struct st_maria_plugin i_s_innodb_sys_semaphore_waits;
+extern struct st_maria_plugin i_s_innodb_sys_table_options;
/** maximum number of buffer page info we would cache. */
#define MAX_BUF_INFO_CACHED 10000
@@ -130,6 +131,14 @@ HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
+/** Fields on INFORMATION_SCHEMA.SYS_TABLE_OPTIONS table */
+#define SYS_TABLE_OPTIONS_TABLE_ID 0
+#define SYS_TABLE_OPTIONS_PAGE_COMPRESSED 1
+#define SYS_TABLE_OPTIONS_PAGE_COMPRESSION_LEVEL 2
+#define SYS_TABLE_OPTIONS_ATOMIC_WRITES 3
+#define SYS_TABLE_OPTIONS_ENCRYPTED 4
+#define SYS_TABLE_OPTIONS_ENCRYPTION_KEY_ID 5
+
/*******************************************************************//**
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
If the value is ULINT_UNDEFINED then the field it set to NULL.
diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h
index a994c9d8ff1..22cb541cbe0 100644
--- a/storage/innobase/include/dict0boot.h
+++ b/storage/innobase/include/dict0boot.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -325,6 +326,29 @@ enum dict_fld_sys_datafiles_enum {
DICT_NUM_FIELDS__SYS_DATAFILES = 4
};
+/* The columns in SYS_TABLE_OPTIONS */
+enum dict_col_sys_tableoptions_enum {
+ DICT_COL__SYS_TABLEOPTIONS__TABLE_ID = 0,
+ DICT_COL__SYS_TABLEOPTIONS__PAGE_COMPRESSED = 1,
+ DICT_COL__SYS_TABLEOPTIONS__PAGE_COMPRESSION_LEVEL = 2,
+ DICT_COL__SYS_TABLEOPTIONS__ATOMIC_WRITES = 3,
+ DICT_COL__SYS_TABLEOPTIONS__ENCRYPTED = 4,
+ DICT_COL__SYS_TABLEOPTIONS__ENCRYPTION_KEY_ID = 5,
+ DICT_NUM_COLS__SYS_TABLEOPTIONS = 6
+};
+/* The field numbers in the SYS_TABLE_OPTIONS clustered index */
+enum dict_fld_sys_tableoptions_enum {
+ DICT_FLD__SYS_TABLEOPTIONS__TABLE_ID = 0,
+ DICT_FLD__SYS_TABLEOPTIONS__DB_TRX_ID = 1,
+ DICT_FLD__SYS_TABLEOPTIONS__DB_ROLL_PTR = 2,
+ DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSED = 3,
+ DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSION_LEVEL = 4,
+ DICT_FLD__SYS_TABLEOPTIONS__ATOMIC_WRITES = 5,
+ DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTED = 6,
+ DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTION_KEY_ID = 7,
+ DICT_NUM_FIELDS__SYS_TABLEOPTIONS = 8
+};
+
/* A number of the columns above occur in multiple tables. These are the
length of thos fields. */
#define DICT_FLD_LEN_SPACE 4
diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h
index 564fad35748..09717bf5774 100644
--- a/storage/innobase/include/dict0crea.h
+++ b/storage/innobase/include/dict0crea.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -44,10 +45,8 @@ tab_create_graph_create(
dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
mem_heap_t* heap, /*!< in: heap where created */
- bool commit, /*!< in: true if the commit node should be
+ bool commit);/*!< in: true if the commit node should be
added to the query graph */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id);/*!< in: encryption key_id */
/*********************************************************************//**
Creates an index create graph.
@return own: index create node */
@@ -204,6 +203,17 @@ dict_foreign_def_get(
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx); /*!< in: trx */
+/****************************************************************//**
+Creates the sys_table_options system tables inside InnoDB
+at server bootstrap or server start if it is not found or is
+not of the right form.
+@return DB_SUCCESS or error code */
+UNIV_INTERN
+dberr_t
+dict_create_or_check_sys_table_options(void)
+/*========================================*/
+__attribute__((warn_unused_result));
+
/* Table create node structure */
struct tab_node_t{
que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */
@@ -222,8 +232,6 @@ struct tab_node_t{
/* Local storage for this graph node */
ulint state; /*!< node execution state */
ulint col_no; /*!< next column definition to insert */
- ulint key_id; /*!< encryption key_id */
- fil_encryption_t mode; /*!< encryption mode */
mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index b15d364948c..fa65884a75c 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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
@@ -44,6 +44,7 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#include "row0types.h"
#include "fsp0fsp.h"
+#include "dict0tableoptions.h"
#include "dict0pagecompress.h"
extern bool innodb_table_stats_not_found;
@@ -568,9 +569,12 @@ dict_table_open_on_name(
indexes after an aborted online
index creation */
dict_err_ignore_t
- ignore_err) /*!< in: error to be ignored when
+ ignore_err, /*!< in: error to be ignored when
loading the table */
- __attribute__((nonnull, warn_unused_result));
+ dict_tableoptions_t* options)
+ /*!< in: table options */
+
+ __attribute__((warn_unused_result));
/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
@@ -944,15 +948,8 @@ dict_tf_set(
ulint* flags, /*!< in/out: table */
rec_format_t format, /*!< in: file format */
ulint zip_ssize, /*!< in: zip shift size */
- bool remote_path, /*!< in: table uses DATA DIRECTORY
+ bool remote_path); /*!< in: table uses DATA DIRECTORY
*/
- bool page_compressed,/*!< in: table uses page compressed
- pages */
- ulint page_compression_level, /*!< in: table page compression
- level */
- ulint atomic_writes) /*!< in: table atomic
- writes option value*/
- __attribute__((nonnull));
/********************************************************************//**
Convert a 32 bit integer table flags to the 32 bit integer that is
written into the tablespace header at the offset FSP_SPACE_FLAGS and is
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index a3a3446d507..35800816c4c 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates
-Copyright (c) 2013, 2015, SkySQL Ab
+Copyright (c) 2013, 2016, 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
@@ -538,10 +538,7 @@ dict_tf_is_valid(
ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(flags);
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(flags);
ulint unused = DICT_TF_GET_UNUSED(flags);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags);
ulint data_dir = DICT_TF_HAS_DATA_DIR(flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(flags);
/* Make sure there are no bits that we do not know about. */
if (unused != 0) {
@@ -550,12 +547,9 @@ dict_tf_is_valid(
" in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
unused,
- compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
@@ -572,11 +566,8 @@ dict_tf_is_valid(
" in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- compact, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
+ compact, compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
}
@@ -589,11 +580,8 @@ dict_tf_is_valid(
" in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- flags, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
+ flags, compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
}
@@ -611,54 +599,10 @@ dict_tf_is_valid(
"InnoDB: Error: table compact flags are %ld in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
flags,
- compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ compact, atomic_blobs, unused, data_dir, zip_ssize);
- );
- return(false);
- }
- }
-
- if (page_compression || page_compression_level) {
- /* Page compression format must have compact and
- atomic_blobs and page_compression_level requires
- page_compression */
- if (!compact
- || !page_compression
- || !atomic_blobs) {
-
- fprintf(stderr,
- "InnoDB: Error: table flags are %ld in the data dictionary and are corrupted\n"
- "InnoDB: Error: data dictionary flags are\n"
- "InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- flags, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
- );
- return(false);
- }
- }
-
- if (atomic_writes) {
-
- if(atomic_writes > ATOMIC_WRITES_OFF) {
-
- fprintf(stderr,
- "InnoDB: Error: table flags are %ld in the data dictionary and are corrupted\n"
- "InnoDB: Error: data dictionary flags are\n"
- "InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- flags, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
- );
return(false);
}
}
@@ -685,11 +629,7 @@ dict_sys_tables_type_validate(
ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(type);
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(type);
ulint unused = DICT_TF_GET_UNUSED(type);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(type);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(type);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(type);
-
- ut_a(atomic_writes <= ATOMIC_WRITES_OFF);
+ ulint unused_mariadb = DICT_TF_GET_UNUSED_MARIADB(type);
/* The low order bit of SYS_TABLES.TYPE is always set to 1.
If the format is UNIV_FORMAT_B or higher, this field is the same
@@ -708,9 +648,12 @@ dict_sys_tables_type_validate(
/* Make sure there are no bits that we do not know about. */
if (unused) {
- fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, unused %lu\n",
- type, unused);
- return(ULINT_UNDEFINED);
+ /* We deal the MariaDB extended dictionary flags at ::open() */
+ if (unused_mariadb) {
+ fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, unused %lu\n",
+ type, unused);
+ return(ULINT_UNDEFINED);
+ }
}
if (atomic_blobs) {
@@ -753,27 +696,6 @@ dict_sys_tables_type_validate(
format, so the DATA_DIR flag is compatible with any other
table flags. However, it is not used with TEMPORARY tables.*/
- if (page_compression || page_compression_level) {
- /* page compressed row format must have low_order_bit and
- atomic_blobs bits set and the DICT_N_COLS_COMPACT flag
- should be in N_COLS, but we already know about the
- low_order_bit and DICT_N_COLS_COMPACT flags. */
-
- if (!atomic_blobs || !page_compression) {
- fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, page_compression %lu page_compression_level %lu\n"
- "InnoDB: Error: atomic_blobs %lu\n",
- type, page_compression, page_compression_level, atomic_blobs);
- return(ULINT_UNDEFINED);
- }
- }
-
- /* Validate that the atomic writes number is within allowed range. */
- if (atomic_writes > ATOMIC_WRITES_OFF) {
- fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, atomic_writes %lu\n",
- type, atomic_writes);
- return(ULINT_UNDEFINED);
- }
-
/* Return the validated SYS_TABLES.TYPE. */
return(type);
}
@@ -846,16 +768,9 @@ dict_tf_set(
ulint* flags, /*!< in/out: table flags */
rec_format_t format, /*!< in: file format */
ulint zip_ssize, /*!< in: zip shift size */
- bool use_data_dir, /*!< in: table uses DATA DIRECTORY
+ bool use_data_dir) /*!< in: table uses DATA DIRECTORY
*/
- bool page_compressed,/*!< in: table uses page compressed
- pages */
- ulint page_compression_level, /*!< in: table page compression
- level */
- ulint atomic_writes) /*!< in: table atomic writes setup */
{
- atomic_writes_t awrites = (atomic_writes_t)atomic_writes;
-
switch (format) {
case REC_FORMAT_REDUNDANT:
*flags = 0;
@@ -877,19 +792,6 @@ dict_tf_set(
break;
}
- if (page_compressed) {
- *flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
- | (1 << DICT_TF_POS_PAGE_COMPRESSION)
- | (page_compression_level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL);
-
- ut_ad(zip_ssize == 0);
- ut_ad(dict_tf_get_page_compression(*flags) == TRUE);
- ut_ad(dict_tf_get_page_compression_level(*flags) == page_compression_level);
- }
-
- *flags |= (atomic_writes << DICT_TF_POS_ATOMIC_WRITES);
- ut_a(dict_tf_get_atomic_writes(*flags) == awrites);
-
if (use_data_dir) {
*flags |= (1 << DICT_TF_POS_DATA_DIR);
}
@@ -913,9 +815,6 @@ dict_tf_to_fsp_flags(
ulint table_flags) /*!< in: dict_table_t::flags */
{
ulint fsp_flags;
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
return(ULINT_UNDEFINED););
@@ -934,18 +833,6 @@ dict_tf_to_fsp_flags(
fsp_flags |= DICT_TF_HAS_DATA_DIR(table_flags)
? FSP_FLAGS_MASK_DATA_DIR : 0;
- /* In addition, tablespace flags also contain if the page
- compression is used for this table. */
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(fsp_flags, page_compression);
-
- /* In addition, tablespace flags also contain page compression level
- if page compression is used for this table. */
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level);
-
- /* In addition, tablespace flags also contain flag if atomic writes
- is used for this table */
- fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes);
-
ut_a(fsp_flags_is_valid(fsp_flags));
ut_a(dict_tf_verify_flags(table_flags, fsp_flags));
@@ -980,10 +867,6 @@ dict_sys_tables_type_to_tf(
flags |= type & (DICT_TF_MASK_ZIP_SSIZE
| DICT_TF_MASK_ATOMIC_BLOBS
| DICT_TF_MASK_DATA_DIR
- | DICT_TF_MASK_PAGE_COMPRESSION
- | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL
- | DICT_TF_MASK_ATOMIC_WRITES
-
);
return(flags);
@@ -1012,14 +895,10 @@ dict_tf_to_sys_tables_type(
/* Adjust bit zero. It is always 1 in SYS_TABLES.TYPE */
type = 1;
- /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION,
- PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES are the same. */
+ /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR are the same. */
type |= flags & (DICT_TF_MASK_ZIP_SSIZE
| DICT_TF_MASK_ATOMIC_BLOBS
- | DICT_TF_MASK_DATA_DIR
- | DICT_TF_MASK_PAGE_COMPRESSION
- | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL
- | DICT_TF_MASK_ATOMIC_WRITES);
+ | DICT_TF_MASK_DATA_DIR);
return(type);
}
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 030190b1a8e..1b67f054e55 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -44,6 +45,7 @@ enum dict_system_id_t {
SYS_FOREIGN_COLS,
SYS_TABLESPACES,
SYS_DATAFILES,
+ SYS_TABLE_OPTIONS,
/* This must be last item. Defines the number of system tables. */
SYS_NUM_SYSTEM_TABLES
@@ -201,9 +203,11 @@ dict_load_table(
const char* name, /*!< in: table name in the
databasename/tablename format */
ibool cached, /*!< in: TRUE=add to cache, FALSE=do not */
- dict_err_ignore_t ignore_err);
+ dict_err_ignore_t ignore_err,
/*!< in: error to be ignored when loading
table and its indexes' definition */
+ dict_tableoptions_t* options);
+ /*!< in: table options */
/***********************************************************************//**
Loads a table object based on the table id.
@return table; NULL if table does not exist */
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 53a5d6cb08b..5365a06c1ce 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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
@@ -58,6 +58,7 @@ Created 1/8/1996 Heikki Tuuri
/* Forward declaration. */
struct ib_rbt_t;
+struct dict_tableoptions_t;
/** Type flags of an index: OR'ing of the flags is allowed to define a
combination of types */
@@ -129,34 +130,11 @@ This flag prevents older engines from attempting to open the table and
allows InnoDB to update_create_info() accordingly. */
#define DICT_TF_WIDTH_DATA_DIR 1
-/**
-Width of the page compression flag
-*/
-#define DICT_TF_WIDTH_PAGE_COMPRESSION 1
-#define DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL 4
-
-/**
-Width of the page encryption flag
-*/
-#define DICT_TF_WIDTH_PAGE_ENCRYPTION 1
-#define DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY 8
-
-/**
-Width of atomic writes flag
-DEFAULT=0, ON = 1, OFF = 2
-*/
-#define DICT_TF_WIDTH_ATOMIC_WRITES 2
-
/** Width of all the currently known table flags */
#define DICT_TF_BITS (DICT_TF_WIDTH_COMPACT \
+ DICT_TF_WIDTH_ZIP_SSIZE \
+ DICT_TF_WIDTH_ATOMIC_BLOBS \
- + DICT_TF_WIDTH_DATA_DIR \
- + DICT_TF_WIDTH_PAGE_COMPRESSION \
- + DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL \
- + DICT_TF_WIDTH_ATOMIC_WRITES \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)
+ + DICT_TF_WIDTH_DATA_DIR)
/** A mask of all the known/used bits in table flags */
#define DICT_TF_BIT_MASK (~(~0 << DICT_TF_BITS))
@@ -172,23 +150,14 @@ DEFAULT=0, ON = 1, OFF = 2
/** Zero relative shift position of the DATA_DIR field */
#define DICT_TF_POS_DATA_DIR (DICT_TF_POS_ATOMIC_BLOBS \
+ DICT_TF_WIDTH_ATOMIC_BLOBS)
-/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define DICT_TF_POS_PAGE_COMPRESSION (DICT_TF_POS_DATA_DIR \
- + DICT_TF_WIDTH_DATA_DIR)
-/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
-#define DICT_TF_POS_PAGE_COMPRESSION_LEVEL (DICT_TF_POS_PAGE_COMPRESSION \
- + DICT_TF_WIDTH_PAGE_COMPRESSION)
-/** Zero relative shift position of the ATOMIC_WRITES field */
-#define DICT_TF_POS_ATOMIC_WRITES (DICT_TF_POS_PAGE_COMPRESSION_LEVEL \
- + DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL)
-/** Zero relative shift position of the PAGE_ENCRYPTION field */
-#define DICT_TF_POS_PAGE_ENCRYPTION (DICT_TF_POS_ATOMIC_WRITES \
- + DICT_TF_WIDTH_ATOMIC_WRITES)
-/** Zero relative shift position of the PAGE_ENCRYPTION_KEY field */
-#define DICT_TF_POS_PAGE_ENCRYPTION_KEY (DICT_TF_POS_PAGE_ENCRYPTION \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION)
-#define DICT_TF_POS_UNUSED (DICT_TF_POS_PAGE_ENCRYPTION_KEY \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)
+/** Zero relative shift position of the start of the UNUSED bits */
+#define DICT_TF_POS_UNUSED (DICT_TF_POS_DATA_DIR \
+ + DICT_TF_WIDTH_DATA_DIR)
+
+/** Zero relative shift position of the start of the MARIADB bits */
+#define DICT_TF_POS_UNUSED_MARIADB (DICT_TF_POS_DATA_DIR \
+ + 1 + 1 + 4 + 1 + 8 + 2)
+
/** Bit mask of the COMPACT field */
#define DICT_TF_MASK_COMPACT \
@@ -206,26 +175,6 @@ DEFAULT=0, ON = 1, OFF = 2
#define DICT_TF_MASK_DATA_DIR \
((~(~0 << DICT_TF_WIDTH_DATA_DIR)) \
<< DICT_TF_POS_DATA_DIR)
-/** Bit mask of the PAGE_COMPRESSION field */
-#define DICT_TF_MASK_PAGE_COMPRESSION \
- ((~(~0 << DICT_TF_WIDTH_PAGE_COMPRESSION)) \
- << DICT_TF_POS_PAGE_COMPRESSION)
-/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
-#define DICT_TF_MASK_PAGE_COMPRESSION_LEVEL \
- ((~(~0 << DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL)) \
- << DICT_TF_POS_PAGE_COMPRESSION_LEVEL)
-/** Bit mask of the ATOMIC_WRITES field */
-#define DICT_TF_MASK_ATOMIC_WRITES \
- ((~(~0 << DICT_TF_WIDTH_ATOMIC_WRITES)) \
- << DICT_TF_POS_ATOMIC_WRITES)
-/** Bit mask of the PAGE_ENCRYPTION field */
-#define DICT_TF_MASK_PAGE_ENCRYPTION \
- ((~(~0 << DICT_TF_WIDTH_PAGE_ENCRYPTION)) \
- << DICT_TF_POS_PAGE_ENCRYPTION)
-/** Bit mask of the PAGE_ENCRYPTION_KEY field */
-#define DICT_TF_MASK_PAGE_ENCRYPTION_KEY \
- ((~(~0 << DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)) \
- << DICT_TF_POS_PAGE_ENCRYPTION_KEY)
/** Return the value of the COMPACT field */
#define DICT_TF_GET_COMPACT(flags) \
@@ -239,34 +188,17 @@ DEFAULT=0, ON = 1, OFF = 2
#define DICT_TF_HAS_ATOMIC_BLOBS(flags) \
((flags & DICT_TF_MASK_ATOMIC_BLOBS) \
>> DICT_TF_POS_ATOMIC_BLOBS)
-/** Return the value of the ATOMIC_BLOBS field */
+/** Return the value of the HAS_DATA_DIR field */
#define DICT_TF_HAS_DATA_DIR(flags) \
((flags & DICT_TF_MASK_DATA_DIR) \
>> DICT_TF_POS_DATA_DIR)
-/** Return the value of the PAGE_COMPRESSION field */
-#define DICT_TF_GET_PAGE_COMPRESSION(flags) \
- ((flags & DICT_TF_MASK_PAGE_COMPRESSION) \
- >> DICT_TF_POS_PAGE_COMPRESSION)
-/** Return the value of the PAGE_COMPRESSION_LEVEL field */
-#define DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags) \
- ((flags & DICT_TF_MASK_PAGE_COMPRESSION_LEVEL) \
- >> DICT_TF_POS_PAGE_COMPRESSION_LEVEL)
-/** Return the value of the ATOMIC_WRITES field */
-#define DICT_TF_GET_ATOMIC_WRITES(flags) \
- ((flags & DICT_TF_MASK_ATOMIC_WRITES) \
- >> DICT_TF_POS_ATOMIC_WRITES)
-/** Return the contents of the PAGE_ENCRYPTION field */
-#define DICT_TF_GET_PAGE_ENCRYPTION(flags) \
- ((flags & DICT_TF_MASK_PAGE_ENCRYPTION) \
- >> DICT_TF_POS_PAGE_ENCRYPTION)
-/** Return the contents of the PAGE_ENCRYPTION KEY field */
-#define DICT_TF_GET_PAGE_ENCRYPTION_KEY(flags) \
- ((flags & DICT_TF_MASK_PAGE_ENCRYPTION_KEY) \
- >> DICT_TF_POS_PAGE_ENCRYPTION_KEY)
/** Return the contents of the UNUSED bits */
#define DICT_TF_GET_UNUSED(flags) \
(flags >> DICT_TF_POS_UNUSED)
+/** Return the contents of the UNUSED bits */
+#define DICT_TF_GET_UNUSED_MARIADB(flags) \
+ (flags >> DICT_TF_POS_UNUSED_MARIADB)
/* @} */
/** @brief Table Flags set number 2.
@@ -1019,6 +951,7 @@ struct dict_table_t{
char* name; /*!< table name */
void* thd; /*!< thd */
fil_space_crypt_t *crypt_data; /*!< crypt data if present */
+ dict_tableoptions_t* table_options; /*!< table options */
const char* dir_path_of_temp_table;/*!< NULL or the directory path
where a TEMPORARY table that was explicitly
created by a user should be placed if
diff --git a/storage/innobase/include/dict0pagecompress.h b/storage/innobase/include/dict0pagecompress.h
index 19a2a6c52f3..23cc0fcf997 100644
--- a/storage/innobase/include/dict0pagecompress.h
+++ b/storage/innobase/include/dict0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,25 +28,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
#define dict0pagecompress_h
/********************************************************************//**
-Extract the page compression level from table flags.
-@return page compression level, or 0 if not compressed */
-UNIV_INLINE
-ulint
-dict_tf_get_page_compression_level(
-/*===============================*/
- ulint flags) /*!< in: flags */
- __attribute__((const));
-/********************************************************************//**
-Extract the page compression flag from table flags
-@return page compression flag, or false if not compressed */
-UNIV_INLINE
-ibool
-dict_tf_get_page_compression(
-/*==========================*/
- ulint flags) /*!< in: flags */
- __attribute__((const));
-
-/********************************************************************//**
Check whether the table uses the page compressed page format.
@return page compression level, or 0 if not compressed */
UNIV_INLINE
@@ -68,16 +49,6 @@ dict_tf_verify_flags(
__attribute__((const));
/********************************************************************//**
-Extract the atomic writes flag from table flags.
-@return true if atomic writes are used, false if not used */
-UNIV_INLINE
-atomic_writes_t
-dict_tf_get_atomic_writes(
-/*======================*/
- ulint flags) /*!< in: flags */
- __attribute__((const));
-
-/********************************************************************//**
Check whether the table uses the atomic writes.
@return true if atomic writes is used, false if not */
UNIV_INLINE
diff --git a/storage/innobase/include/dict0pagecompress.ic b/storage/innobase/include/dict0pagecompress.ic
index 811976434a8..f921b948b80 100644
--- a/storage/innobase/include/dict0pagecompress.ic
+++ b/storage/innobase/include/dict0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -39,17 +39,11 @@ dict_tf_verify_flags(
ulint ssize = DICT_TF_GET_ZIP_SSIZE(table_flags);
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table_flags);
ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags);
ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags);
ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags);
ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags);
- ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
- ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
- ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags);
DBUG_EXECUTE_IF("dict_tf_verify_flags_failure",
return(ULINT_UNDEFINED););
@@ -78,56 +72,11 @@ dict_tf_verify_flags(
return (FALSE);
}
- if (page_compression != fsp_page_compression) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file ahas page_compression %ld\n",
- page_compression, fsp_page_compression);
-
- return (FALSE);
- }
- if (page_compression_level != fsp_page_compression_level) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression_level %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has page_compression_level %ld\n",
- page_compression_level, fsp_page_compression_level);
-
- return (FALSE);
- }
-
- if (atomic_writes != fsp_atomic_writes) {
- fprintf(stderr,
- "InnoDB: Error: table flags has atomic writes %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has atomic_writes %ld\n",
- atomic_writes, fsp_atomic_writes);
-
- return (FALSE);
- }
return(TRUE);
}
/********************************************************************//**
-Extract the page compression level from dict_table_t::flags.
-These flags are in memory, so assert that they are valid.
-@return page compression level, or 0 if not compressed */
-UNIV_INLINE
-ulint
-dict_tf_get_page_compression_level(
-/*===============================*/
- ulint flags) /*!< in: flags */
-{
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags);
-
- ut_ad(page_compression_level <= 9);
-
- return(page_compression_level);
-}
-
-/********************************************************************//**
Check whether the table uses the page compression page format.
@return page compression level, or 0 if not compressed */
UNIV_INLINE
@@ -137,21 +86,8 @@ dict_table_page_compression_level(
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
- ut_ad(dict_tf_get_page_compression(table->flags));
- return(dict_tf_get_page_compression_level(table->flags));
-}
-
-/********************************************************************//**
-Check whether the table uses the page compression page format.
-@return true if page compressed, false if not */
-UNIV_INLINE
-ibool
-dict_tf_get_page_compression(
-/*=========================*/
- ulint flags) /*!< in: flags */
-{
- return(DICT_TF_GET_PAGE_COMPRESSION(flags));
+ return(table->table_options->page_compression_level);
}
/********************************************************************//**
@@ -163,19 +99,9 @@ dict_table_is_page_compressed(
/*==========================*/
const dict_table_t* table) /*!< in: table */
{
- return (dict_tf_get_page_compression(table->flags));
-}
+ ut_ad(table);
-/********************************************************************//**
-Extract the atomic writes flag from table flags.
-@return enumerated value of atomic writes */
-UNIV_INLINE
-atomic_writes_t
-dict_tf_get_atomic_writes(
-/*======================*/
- ulint flags) /*!< in: flags */
-{
- return((atomic_writes_t)DICT_TF_GET_ATOMIC_WRITES(flags));
+ return (table->table_options->page_compressed);
}
/********************************************************************//**
@@ -187,5 +113,7 @@ dict_table_get_atomic_writes(
/*=========================*/
const dict_table_t* table) /*!< in: table */
{
- return ((atomic_writes_t)dict_tf_get_atomic_writes(table->flags));
+ ut_ad(table);
+
+ return (table->table_options->atomic_writes);
}
diff --git a/storage/innobase/include/dict0priv.ic b/storage/innobase/include/dict0priv.ic
index 983218af78a..e2eda1a301f 100644
--- a/storage/innobase/include/dict0priv.ic
+++ b/storage/innobase/include/dict0priv.ic
@@ -58,7 +58,7 @@ dict_table_get_low(
}
if (table == NULL) {
- table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE);
+ table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE, NULL);
}
ut_ad(!table || table->cached);
diff --git a/storage/innobase/include/dict0tableoptions.h b/storage/innobase/include/dict0tableoptions.h
new file mode 100644
index 00000000000..def0e39a01f
--- /dev/null
+++ b/storage/innobase/include/dict0tableoptions.h
@@ -0,0 +1,127 @@
+/*****************************************************************************
+
+Copyright (c) 2016, 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
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**************************************************//**
+@file include/dict0tableoptions.h
+Definitions for the system table SYS_TABLE_OPTIONS
+
+Created 22/01/2006 Jan Lindström
+*******************************************************/
+
+#ifndef dict0tableoptions_h
+#define dict0tableoptions_h
+
+#include "univ.i"
+
+/** Data structure to hold contents of SYS_TABLE_OPTIONS */
+struct dict_tableoptions_t{
+ table_id_t table_id;
+ /* true if table page compressed */
+ bool page_compressed;
+ /* Used compression level if set */
+ ulonglong page_compression_level;
+ /* dict0types.h: ATOMIC_WRITES_DEFAULT, _ON, or _OFF */
+ atomic_writes_t atomic_writes;
+ /* fil0crypt.h: FIL_SPACE_ENCRYPTION_DEFAULT, _ON, or _OFF */
+ fil_encryption_t encryption;
+ /* Used encryption key identifier if set */
+ ulonglong encryption_key_id;
+ /* true if table options need to be stored */
+ bool need_stored;
+};
+
+/********************************************************************//**
+This function parses a SYS_TABLE_OPTIONS record, extracts necessary
+information from the record and returns it to the caller.
+@return error message or NULL if successfull */
+UNIV_INTERN
+const char*
+dict_process_sys_tableoptions(
+/*==========================*/
+ mem_heap_t* heap, /*!< in/out: heap memory */
+ const rec_t* rec, /*!< in: current SYS_TABLE_OPTIONS rec */
+ dict_tableoptions_t* table_options); /*!< out: table options */
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS based on table_id
+@return true if found, false if not found */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ table_id_t table_id, /*!< in: table id */
+ dict_tableoptions_t* options, /*!< out:table options */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS
+@return true if found, false if not found */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ dict_table_t* table, /*!< in/out: table */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Update the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_tableoptions(
+/*=====================*/
+ const dict_table_t* table); /*!< in: table object */
+
+/********************************************************************//**
+Insert record into SYS_TABLE_OPTIONS
+@return DB_SUCCESS if OK, dberr_t if the insert failed */
+UNIV_INTERN
+dberr_t
+dict_insert_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Update the table flags in SYS_TABLES.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_table_flags(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Delete the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_delete_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ trx_t* trx, /*!< in: trx */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+#endif /* dict0tableoptions_h */
+
diff --git a/storage/innobase/include/fil0crypt.ic b/storage/innobase/include/fil0crypt.ic
index 5fafa6cd3f0..71314abb687 100644
--- a/storage/innobase/include/fil0crypt.ic
+++ b/storage/innobase/include/fil0crypt.ic
@@ -17,7 +17,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
*****************************************************************************/
/**************************************************//**
-@file include/fil0fil.h
+@file include/fil0crypt.ic
The low-level file system encryption support functions
Created 04/01/2015 Jan Lindström
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 7fe0cc88618..bc7f31789db 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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 +39,7 @@ Created 10/25/1995 Heikki Tuuri
#include "ibuf0types.h"
#include "log0log.h"
#endif /* !UNIV_HOTBACKUP */
-
+#include "my_crypt.h"
#include <list>
// Forward declaration
@@ -186,6 +186,8 @@ extern fil_addr_t fil_addr_null;
#ifndef UNIV_INNOCHECKSUM
+#include "fil0crypt.h"
+
/* structure containing encryption specification */
typedef struct fil_space_crypt_struct fil_space_crypt_t;
@@ -335,6 +337,7 @@ struct fil_space_t {
fil_space_crypt_t* crypt_data;
ulint file_block_size;/*!< file system block size */
ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
+ void* table_options;
};
/** Value of fil_space_t::magic_n */
@@ -465,12 +468,13 @@ UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- const char* name, /*!< in: space name */
- ulint id, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size, or
- 0 for uncompressed tablespaces */
- ulint purpose, /*!< in: FIL_TABLESPACE, or FIL_LOG if log */
- fil_space_crypt_t* crypt_data); /*!< in: crypt data */
+ const char* name, /*!< in: space name */
+ ulint id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size, or
+ 0 for uncompressed tablespaces */
+ ulint purpose, /*!< in: FIL_TABLESPACE, or FIL_LOG if log */
+ fil_space_crypt_t* crypt_data, /*!< in: crypt data */
+ const void* options); /*!< in: table options */
/*******************************************************************//**
Assigns a new space id for a new single-table tablespace. This works simply by
@@ -814,9 +818,8 @@ fil_create_new_single_table_tablespace(
ulint size, /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
- __attribute__((nonnull, warn_unused_result));
+ const dict_table_t* table) /*!< in: table */
+ __attribute__((warn_unused_result));
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
@@ -850,7 +853,8 @@ fil_open_single_table_tablespace(
const char* tablename, /*!< in: table name in the
databasename/tablename format */
const char* filepath, /*!< in: tablespace filepath */
- dict_table_t* table) /*!< in: table */
+ dict_table_t* table, /*!< in: table or NULL */
+ void* options)/*!< in: table options*/
__attribute__((nonnull(5), warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
@@ -1331,6 +1335,17 @@ fil_space_get_block_size(
ulint offset, /*!< in: page offset */
ulint len); /*!< in: page len */
+/******************************************************************
+Parse a MLOG_FILE_WRITE_FSP_FLAGS log entry
+@return position on log buffer */
+UNIV_INTERN
+byte*
+fil_parse_write_fsp_flags(
+/*======================*/
+ byte* ptr, /*!< in: Log entry start */
+ byte* end_ptr,/*!< in: Log entry end */
+ buf_block_t* block); /*!< in: buffer block */
+
#endif /* UNIV_INNOCHECKSUM */
#ifndef UNIV_INNOCHECKSUM
diff --git a/storage/innobase/include/fil0pagecompress.h b/storage/innobase/include/fil0pagecompress.h
index 8316083d52d..d5bfc934bb8 100644
--- a/storage/innobase/include/fil0pagecompress.h
+++ b/storage/innobase/include/fil0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015 MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -31,41 +31,58 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
***********************************************************************/
/*******************************************************************//**
-Returns the page compression level flag of the space, or 0 if the space
+Returns the page compression level of the space, or 0 if the space
is not compressed. The tablespace must be cached in the memory cache.
-@return page compression level if page compressed, ULINT_UNDEFINED if space not found */
-UNIV_INTERN
+@return page compression level, 0 if space not found */
+UNIV_INLINE
ulint
fil_space_get_page_compression_level(
/*=================================*/
- ulint id); /*!< in: space id */
+ fil_space_t* space); /*!< in: space */
/*******************************************************************//**
-Returns the page compression flag of the space, or false if the space
+Returns the page compression level of the space, or 0 if the space
is not compressed. The tablespace must be cached in the memory cache.
-@return true if page compressed, false if not or space not found */
-UNIV_INTERN
+@return page compression level, 0 if space not found */
+UNIV_INLINE
+ulint
+fil_space_get_page_compression_level(
+/*=================================*/
+ ulint space_id); /*!< in: space id*/
+/*******************************************************************//**
+Extract the page compression from space.
+@return true if space is page compressed, false if space is not found
+or space is not page compressed. */
+UNIV_INLINE
ibool
fil_space_is_page_compressed(
/*=========================*/
- ulint id); /*!< in: space id */
+ ulint space_id); /*!< in: space id*/
/*******************************************************************//**
-Returns the page compression flag of the space, or false if the space
-is not compressed. The tablespace must be cached in the memory cache.
-@return true if page compressed, false if not or space not found */
-UNIV_INTERN
+Extract the page compression from space.
+@return true if space is page compressed, false if space is not found
+or space is not page compressed. */
+UNIV_INLINE
ibool
-fil_space_get_page_compressed(
+fil_space_is_page_compressed(
/*=========================*/
- fil_space_t* space); /*!< in: space id */
+ fil_space_t* space); /*!< in: space */
+
/*******************************************************************//**
-Returns the atomic writes flag of the space, or false if the space
-is not using atomic writes. The tablespace must be cached in the memory cache.
-@return atomic write table option value */
-UNIV_INTERN
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
atomic_writes_t
fil_space_get_atomic_writes(
-/*=========================*/
- ulint id); /*!< in: space id */
+/*========================*/
+ fil_space_t* space); /*!< in: space */
+/*******************************************************************//**
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
+atomic_writes_t
+fil_space_get_atomic_writes(
+/*========================*/
+ ulint space_id); /*!< in: space id*/
/*******************************************************************//**
Find out wheather the page is index page or not
@return true if page type index page, false if not */
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 2bac42eb081..a0c27110372 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -55,22 +55,13 @@ to the two Barracuda row formats COMPRESSED and DYNAMIC. */
/** Width of the DATA_DIR flag. This flag indicates that the tablespace
is found in a remote location, not the default data directory. */
#define FSP_FLAGS_WIDTH_DATA_DIR 1
-/** Number of flag bits used to indicate the page compression and compression level */
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4
-
-/** Number of flag bits used to indicate atomic writes for this tablespace */
-#define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2
/** Width of all the currently known tablespace flags */
#define FSP_FLAGS_WIDTH (FSP_FLAGS_WIDTH_POST_ANTELOPE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE \
- + FSP_FLAGS_WIDTH_DATA_DIR \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES )
+ + FSP_FLAGS_WIDTH_DATA_DIR )
/** A mask of all the known/used bits in tablespace flags */
#define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH))
@@ -83,20 +74,9 @@ is found in a remote location, not the default data directory. */
/** Zero relative shift position of the ATOMIC_BLOBS field */
#define FSP_FLAGS_POS_ATOMIC_BLOBS (FSP_FLAGS_POS_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE)
-/** Note that these need to be before the page size to be compatible with
-dictionary */
-/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
-/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
-/** Zero relative shift position of the ATOMIC_WRITES field */
-#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)
/** Zero relative shift position of the PAGE_SSIZE field */
-#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES)
+#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
/** Zero relative shift position of the start of the UNUSED bits */
#define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE)
@@ -124,18 +104,6 @@ dictionary */
#define FSP_FLAGS_MASK_DATA_DIR \
((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR)) \
<< FSP_FLAGS_POS_DATA_DIR)
-/** Bit mask of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
- ((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \
- << FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \
- ((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \
- << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Bit mask of the ATOMIC_WRITES field */
-#define FSP_FLAGS_MASK_ATOMIC_WRITES \
- ((~(~0 << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \
- << FSP_FLAGS_POS_ATOMIC_WRITES)
/** Return the value of the POST_ANTELOPE field */
#define FSP_FLAGS_GET_POST_ANTELOPE(flags) \
((flags & FSP_FLAGS_MASK_POST_ANTELOPE) \
@@ -160,39 +128,21 @@ dictionary */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)
-/** Return the value of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Return the value of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Return the value of the ATOMIC_WRITES field */
-#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \
- ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \
- >> FSP_FLAGS_POS_ATOMIC_WRITES)
-
/** Set a PAGE_SSIZE into the correct bits in a given
tablespace flags. */
#define FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize) \
(flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE))
-/** Set a PAGE_COMPRESSION into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION(flags, compression) \
- (flags | (compression << FSP_FLAGS_POS_PAGE_COMPRESSION))
-
-/** Set a PAGE_COMPRESSION_LEVEL into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \
- (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL))
-
-/** Set a ATOMIC_WRITES into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \
- (flags | (atomics << FSP_FLAGS_POS_ATOMIC_WRITES))
-
+#define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + 1 + 1 + 4 + 2)
+/** Bit mask of the PAGE_SSIZE field */
+#define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB \
+ ((~(~0 << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \
+ << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB)
+/** Return the value of the PAGE_SSIZE field */
+#define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB) \
+ >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB)
/* @} */
/* @defgroup Tablespace Header Constants (moved from fsp0fsp.c) @{ */
diff --git a/storage/innobase/include/fsp0fsp.ic b/storage/innobase/include/fsp0fsp.ic
index 9f09a9d53e1..7b6fe59bb7b 100644
--- a/storage/innobase/include/fsp0fsp.ic
+++ b/storage/innobase/include/fsp0fsp.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -64,9 +64,6 @@ fsp_flags_is_valid(
ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
ulint unused = FSP_FLAGS_GET_UNUSED(flags);
- ulint page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags);
- ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags);
- ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false););
@@ -120,23 +117,6 @@ fsp_flags_is_valid(
return(false);
}
- /* Page compression level requires page compression and atomic blobs
- to be set */
- if (page_compression_level || page_compression) {
- if (!page_compression || !atomic_blobs) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_compression %lu\n"
- "InnoDB: Error: page_compression_level %lu atomic_blobs %lu\n",
- flags, page_compression, page_compression_level, atomic_blobs);
- return(false);
- }
- }
-
- if (atomic_writes > ATOMIC_WRITES_OFF) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_writes %lu\n",
- flags, atomic_writes);
- return (false);
- }
-
#if UNIV_FORMAT_MAX != UNIV_FORMAT_B
# error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations."
#endif
@@ -195,11 +175,24 @@ fsp_flags_get_page_size(
{
ulint page_size = 0;
ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
+ ulint psize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB(flags);
+
+ if (ssize && UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) {
+ ssize = psize;
+ }
/* Convert from a 'log2 minus 9' to a page size in bytes. */
if (UNIV_UNLIKELY(ssize)) {
page_size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize);
+ if (page_size > UNIV_PAGE_SIZE_MAX) {
+ if (psize) {
+ page_size = ((UNIV_ZIP_SIZE_MIN >> 1) << psize);
+ } else {
+ page_size = UNIV_PAGE_SIZE_ORIG;
+ }
+ }
+
ut_ad(page_size <= UNIV_PAGE_SIZE_MAX);
} else {
/* If the page size was not stored, then it is the
diff --git a/storage/innobase/include/fsp0pagecompress.h b/storage/innobase/include/fsp0pagecompress.h
index 5f943ee2b83..222c79a013f 100644
--- a/storage/innobase/include/fsp0pagecompress.h
+++ b/storage/innobase/include/fsp0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -47,36 +47,6 @@ fsp_header_get_compression_level(
/*=============================*/
const page_t* page); /*!< in: first page of a tablespace */
-/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not compressed */
-UNIV_INLINE
-ibool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags); /*!< in: tablespace flags */
-
-/********************************************************************//**
-Extract the page compression level from tablespace flags.
-A tablespace has only one physical page compression level
-whether that page is compressed or not.
-@return page compression level of the file-per-table tablespace,
-or zero if the table is not compressed. */
-UNIV_INLINE
-ulint
-fsp_flags_get_page_compression_level(
-/*=================================*/
- ulint flags); /*!< in: tablespace flags */
-
-/********************************************************************//**
-Determine the tablespace is using atomic writes from dict_table_t::flags.
-@return true if atomic writes is used, false if not */
-UNIV_INLINE
-atomic_writes_t
-fsp_flags_get_atomic_writes(
-/*========================*/
- ulint flags); /*!< in: tablespace flags */
-
#ifndef UNIV_NONINL
#include "fsp0pagecompress.ic"
#endif
diff --git a/storage/innobase/include/fsp0pagecompress.ic b/storage/innobase/include/fsp0pagecompress.ic
index e879aa2c16e..672dc2c33e8 100644
--- a/storage/innobase/include/fsp0pagecompress.ic
+++ b/storage/innobase/include/fsp0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,42 +25,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@mariadb.com
***********************************************************************/
-/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not page compressed */
-UNIV_INLINE
-ibool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return(FSP_FLAGS_GET_PAGE_COMPRESSION(flags));
-}
-
-/********************************************************************//**
-Determine the tablespace is page compression level from dict_table_t::flags.
-@return page compression level or 0 if not compressed*/
-UNIV_INLINE
-ulint
-fsp_flags_get_page_compression_level(
-/*=================================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return(FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags));
-}
-
-/********************************************************************//**
-Determine the tablespace is using atomic writes from dict_table_t::flags.
-@return true if atomic writes is used, false if not */
-UNIV_INLINE
-atomic_writes_t
-fsp_flags_get_atomic_writes(
-/*========================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return((atomic_writes_t)FSP_FLAGS_GET_ATOMIC_WRITES(flags));
-}
-
/*******************************************************************//**
Find out wheather the page is index page or not
@return true if page type index page, false if not */
@@ -106,20 +70,37 @@ UNIV_INLINE
ulint
fil_space_get_page_compression_level(
/*=================================*/
- ulint id) /*!< in: space id */
+ fil_space_t* space) /*!< in: space */
{
- ulint flags;
+ if (space && space->table_options) {
+ dict_tableoptions_t* options = (dict_tableoptions_t*)space->table_options;
+ return (options->page_compression_level);
+ }
- flags = fil_space_get_flags(id);
+ return(0);
+}
+/*******************************************************************//**
+Returns the page compression level of the space, or 0 if the space
+is not compressed. The tablespace must be cached in the memory cache.
+@return page compression level, 0 if space not found */
+UNIV_INLINE
+ulint
+fil_space_get_page_compression_level(
+/*=================================*/
+ ulint space_id) /*!< in: space id*/
+{
+ fil_space_t* space;
- if (flags && flags != ULINT_UNDEFINED) {
+ fil_system_enter();
+ space = fil_space_get_by_id(space_id);
+ fil_system_exit();
- return(fsp_flags_get_page_compression_level(flags));
+ if (space) {
+ return (fil_space_get_page_compression_level(space));
}
return(0);
}
-
/*******************************************************************//**
Extract the page compression from space.
@return true if space is page compressed, false if space is not found
@@ -128,20 +109,78 @@ UNIV_INLINE
ibool
fil_space_is_page_compressed(
/*=========================*/
- ulint id) /*!< in: space id */
+ fil_space_t* space) /*!< in: space */
{
- ulint flags;
+ if (space && space->table_options) {
+ dict_tableoptions_t* options = (dict_tableoptions_t*)space->table_options;
+ return(options->page_compressed);
+ }
- flags = fil_space_get_flags(id);
+ return(0);
+}
+
+/*******************************************************************//**
+Extract the page compression from space.
+@return true if space is page compressed, false if space is not found
+or space is not page compressed. */
+UNIV_INLINE
+ibool
+fil_space_is_page_compressed(
+/*=========================*/
+ ulint space_id) /*!< in: space id*/
+{
+ fil_space_t* space;
- if (flags && flags != ULINT_UNDEFINED) {
+ fil_system_enter();
+ space = fil_space_get_by_id(space_id);
+ fil_system_exit();
- return(fsp_flags_is_page_compressed(flags));
+ if (space) {
+ return (fil_space_is_page_compressed(space));
}
return(0);
}
+/*******************************************************************//**
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
+atomic_writes_t
+fil_space_get_atomic_writes(
+/*========================*/
+ fil_space_t* space) /*!< in: space */
+{
+ if (space && space->table_options) {
+ dict_tableoptions_t* options = (dict_tableoptions_t*)space->table_options;
+ return(options->atomic_writes);
+ }
+
+ return((atomic_writes_t)0);
+}
+
+/*******************************************************************//**
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
+atomic_writes_t
+fil_space_get_atomic_writes(
+/*========================*/
+ ulint space_id) /*!< in: space id*/
+{
+ fil_space_t* space;
+
+ fil_system_enter();
+ space = fil_space_get_by_id(space_id);
+ fil_system_exit();
+
+ if (space) {
+ return (fil_space_get_atomic_writes(space));
+ }
+
+ return((atomic_writes_t)0);
+}
+
#endif /* UNIV_INNOCHECKSUM */
/****************************************************************//**
@@ -184,28 +223,6 @@ fil_get_compression_alg_name(
#ifndef UNIV_INNOCHECKSUM
/*******************************************************************//**
-Returns the atomic writes flag of the space, or false if the space
-is not using atomic writes. The tablespace must be cached in the memory cache.
-@return atomic writes table option value */
-UNIV_INLINE
-atomic_writes_t
-fil_space_get_atomic_writes(
-/*========================*/
- ulint id) /*!< in: space id */
-{
- ulint flags;
-
- flags = fil_space_get_flags(id);
-
- if (flags && flags != ULINT_UNDEFINED) {
-
- return((atomic_writes_t)fsp_flags_get_atomic_writes(flags));
- }
-
- return((atomic_writes_t)0);
-}
-
-/*******************************************************************//**
Find out wheather the page is page compressed with lzo method
@return true if page is page compressed with lzo method, false if not */
UNIV_INLINE
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 59abb0863d9..b541241fad6 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -643,4 +644,16 @@ ib_push_warning(
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...);
+
+/********************************************************************//**
+Helper function to get default_encryption_key_id from THD
+(trx->mysql_thd).
+@return default_encryption_key_id from THD or
+FIL_DEFAULT_ENCRYPTION_KEY */
+UNIV_INTERN
+ulint
+innobase_get_default_encryption_key_id(
+/*===================================*/
+ trx_t* trx); /*! in: trx */
+
#endif /* HA_INNODB_PROTOTYPES_H */
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index eae981f2fbb..483bd742105 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -193,9 +193,12 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
#define MLOG_FILE_WRITE_CRYPT_DATA ((byte)100) /*!< log record for
writing/updating crypt data of
a tablespace */
-
+#define MLOG_FILE_WRITE_FSP_FLAGS ((byte)101) /*!< log record for
+ writing/updating flags
+ a tablespace */
#define EXTRA_CHECK_MLOG_NUMBER(x) \
- ((x) == MLOG_FILE_WRITE_CRYPT_DATA)
+ ((x) == MLOG_FILE_WRITE_CRYPT_DATA || \
+ (x) == MLOG_FILE_WRITE_FSP_FLAGS)
/* @} */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 7fda64e21b7..ddc061b4bf6 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -387,10 +388,8 @@ row_create_table_for_mysql(
(will be freed, or on DB_SUCCESS
added to the data dictionary cache) */
trx_t* trx, /*!< in/out: transaction */
- bool commit, /*!< in: if true, commit the transaction */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
- __attribute__((nonnull, warn_unused_result));
+ bool commit) /*!< in: if true, commit the transaction */
+ __attribute__((warn_unused_result));
/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
to create an index results in dropping the whole table! This is no problem
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index c84e8277f07..975e8f305a5 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1324,6 +1324,9 @@ recv_parse_or_apply_log_rec_body(
case MLOG_FILE_WRITE_CRYPT_DATA:
ptr = fil_parse_write_crypt_data(ptr, end_ptr, block);
break;
+ case MLOG_FILE_WRITE_FSP_FLAGS:
+ ptr = fil_parse_write_fsp_flags(ptr, end_ptr, block);
+ break;
default:
ptr = NULL;
recv_sys->found_corrupt_log = TRUE;
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 2b9e877e765..8cd894f86b3 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -45,6 +45,8 @@ Created 10/21/1995 Heikki Tuuri
#include "fil0fil.h"
#include "fil0crypt.h"
#include "fsp0fsp.h"
+#include "rem0rec.h"
+#include "dict0tableoptions.h"
#include "fil0pagecompress.h"
#include "buf0buf.h"
#include "srv0mon.h"
diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc
index da08939d78a..3970111bbb9 100644
--- a/storage/innobase/pars/pars0pars.cc
+++ b/storage/innobase/pars/pars0pars.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -860,7 +861,7 @@ pars_retrieve_table_def(
sym_node->token_type = SYM_TABLE_REF_COUNTED;
sym_node->table = dict_table_open_on_name(
- sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
ut_a(sym_node->table != NULL);
}
@@ -2019,8 +2020,7 @@ pars_create_table(
column = static_cast<sym_node_t*>(que_node_get_next(column));
}
- node = tab_create_graph_create(table, pars_sym_tab_global->heap, true,
- FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ node = tab_create_graph_create(table, pars_sym_tab_global->heap, true);
table_sym->resolved = TRUE;
table_sym->token_type = SYM_TABLE;
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 893ffcab3da..28fcfa21104 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, MariaDB Corporation.
+Copyright (c) 2015, 2016, 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
@@ -650,16 +650,6 @@ struct FetchIndexRootPages : public AbstractCallback {
rec_format_t ibd_rec_format;
rec_format_t table_rec_format;
- if (!dict_tf_is_valid(ibd_table_flags)) {
-
- ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- ".ibd file has invlad table flags: %lx",
- ibd_table_flags);
-
- return(DB_CORRUPTION);
- }
-
ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags);
table_rec_format = dict_tf_get_rec_format(m_table->flags);
@@ -3644,7 +3634,7 @@ row_import_for_mysql(
err = fil_open_single_table_tablespace(
true, true, table->space,
dict_tf_to_fsp_flags(table->flags),
- table->name, filepath, table);
+ table->name, filepath, table, table->table_options);
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
err = DB_TABLESPACE_NOT_FOUND;);
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index d3670bcfddd..eb01daed638 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1819,7 +1819,7 @@ row_ins_check_foreign_constraints(
ref_table = dict_table_open_on_name(
foreign->referenced_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
}
if (0 == trx->dict_operation_lock_mode) {
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index cf07362cdbf..bab06ead9d4 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -47,6 +48,7 @@ Created 9/17/2000 Heikki Tuuri
#include "dict0boot.h"
#include "dict0stats.h"
#include "dict0stats_bg.h"
+#include "dict0tableoptions.h"
#include "trx0roll.h"
#include "trx0purge.h"
#include "trx0rec.h"
@@ -2232,9 +2234,7 @@ row_create_table_for_mysql(
(will be freed, or on DB_SUCCESS
added to the data dictionary cache) */
trx_t* trx, /*!< in/out: transaction */
- bool commit, /*!< in: if true, commit the transaction */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ bool commit) /*!< in: if true, commit the transaction */
{
tab_node_t* node;
mem_heap_t* heap;
@@ -2347,7 +2347,7 @@ err_exit:
ut_ad(strstr(table->name, "/FTS_") != NULL);
}
- node = tab_create_graph_create(table, heap, commit, mode, key_id);
+ node = tab_create_graph_create(table, heap, commit);
thr = pars_complete_graph_for_exec(node, trx, heap);
@@ -2395,7 +2395,7 @@ err_exit:
fputs(" because tablespace full\n", stderr);
if (dict_table_open_on_name(table->name, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE)) {
+ DICT_ERR_IGNORE_NONE, NULL)) {
/* Make things easy for the drop table code. */
@@ -2497,7 +2497,7 @@ row_create_index_for_mysql(
is_fts = (index->type == DICT_FTS);
table = dict_table_open_on_name(table_name, TRUE, TRUE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
trx_start_if_not_started_xa(trx);
@@ -2730,7 +2730,7 @@ loop:
}
table = dict_table_open_on_name(drop->table_name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table == NULL) {
/* If for some reason the table has already been dropped
@@ -2909,7 +2909,7 @@ row_discard_tablespace_begin(
dict_table_t* table;
table = dict_table_open_on_name(
- name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ name, TRUE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (table) {
dict_stats_wait_bg_to_stop_using_table(table, trx);
@@ -3491,15 +3491,13 @@ row_truncate_table_for_mysql(
fil_space_crypt_t* crypt_data;
ulint space = table->space;
ulint flags = fil_space_get_flags(space);
- ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
- fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT;
dict_get_and_save_data_dir_path(table, true);
crypt_data = fil_space_get_crypt_data(space);
if (crypt_data) {
- key_id = crypt_data->key_id;
- mode = crypt_data->encryption;
+ table->table_options->encryption_key_id = crypt_data->key_id;
+ table->table_options->encryption = crypt_data->encryption;
}
if (flags != ULINT_UNDEFINED
@@ -3520,7 +3518,7 @@ row_truncate_table_for_mysql(
table->data_dir_path,
flags, table->flags2,
FIL_IBD_FILE_INITIAL_SIZE,
- mode, key_id)
+ table)
!= DB_SUCCESS) {
dict_table_x_unlock_indexes(table);
@@ -3923,7 +3921,8 @@ row_drop_table_for_mysql(
table = dict_table_open_on_name(
name, TRUE, FALSE,
static_cast<dict_err_ignore_t>(
- DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT));
+ DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT),
+ NULL);
if (!table) {
err = DB_TABLE_NOT_FOUND;
@@ -4295,6 +4294,11 @@ row_drop_table_for_mysql(
"END;\n"
, FALSE, trx);
+ /* Delete row from SYS_TABLE_OPTIONS if it exists */
+ if (err == DB_SUCCESS) {
+ err = dict_delete_tableoptions(table, trx, true);
+ }
+
switch (err) {
ibool is_temp;
@@ -4369,7 +4373,7 @@ row_drop_table_for_mysql(
dict_table_remove_from_cache(table);
if (dict_load_table(tablename, TRUE,
- DICT_ERR_IGNORE_NONE) != NULL) {
+ DICT_ERR_IGNORE_NONE, NULL) != NULL) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: not able to remove table ",
stderr);
@@ -4575,7 +4579,7 @@ row_mysql_drop_temp_tables(void)
btr_pcur_store_position(&pcur, &mtr);
btr_pcur_commit_specify_mtr(&pcur, &mtr);
- table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE);
+ table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE, NULL);
if (table) {
row_drop_table_for_mysql(table_name, trx, FALSE);
@@ -4686,7 +4690,7 @@ loop:
table = dict_table_open_on_name(
table_name, TRUE, FALSE, static_cast<dict_err_ignore_t>(
DICT_ERR_IGNORE_INDEX_ROOT
- | DICT_ERR_IGNORE_CORRUPT));
+ | DICT_ERR_IGNORE_CORRUPT), NULL);
if (!table) {
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -4914,7 +4918,7 @@ row_rename_table_for_mysql(
dict_locked = trx->dict_operation_lock_mode == RW_X_LATCH;
table = dict_table_open_on_name(old_name, dict_locked, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (!table) {
err = DB_TABLE_NOT_FOUND;
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index ea2f93dd788..f7543611d95 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -5306,7 +5306,7 @@ row_search_check_if_query_cache_permitted(
}
table = dict_table_open_on_name(norm_name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table == NULL) {
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 0ea4865d15f..5f0c9671332 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -293,7 +293,7 @@ run_again:
ref_table = dict_table_open_on_name(
foreign->foreign_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
}
if (foreign_table) {
@@ -411,7 +411,7 @@ wsrep_row_upd_check_foreign_constraints(
foreign->referenced_table =
dict_table_open_on_name(
foreign->referenced_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
opened = TRUE;
}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index d7b37b5bc1e..29ce93d31a9 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation
+Copyright (c) 2013, 2016, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -675,7 +675,8 @@ create_log_files(
logfilename, SRV_LOG_SPACE_FIRST_ID,
fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
FIL_LOG,
- NULL /* no encryption yet */);
+ NULL /* no encryption yet */,
+ NULL);
ut_a(fil_validate());
logfile0 = fil_node_create(
@@ -1158,9 +1159,12 @@ check_first_page:
ut_a(ret);
if (i == 0) {
+ dict_tableoptions_t options;
+ memset(&options, 0, sizeof(dict_tableoptions_t));
+ options.encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
fil_space_create(name, 0, flags, FIL_TABLESPACE,
- crypt_data);
+ crypt_data, &options);
crypt_data = NULL;
}
@@ -1308,7 +1312,7 @@ srv_undo_tablespace_open(
/* Set the compressed page size to 0 (non-compressed) */
flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
fil_space_create(name, space, flags, FIL_TABLESPACE,
- NULL /* no encryption */);
+ NULL /* no encryption */, NULL);
ut_a(fil_validate());
@@ -1585,6 +1589,7 @@ innobase_start_or_create_for_mysql(void)
char* logfile0 = NULL;
size_t dirnamelen;
bool sys_datafiles_created = false;
+ bool sys_table_options_created = false;
/* This should be initialized early */
ut_init_timer();
@@ -2293,7 +2298,8 @@ innobase_start_or_create_for_mysql(void)
SRV_LOG_SPACE_FIRST_ID,
fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
FIL_LOG,
- NULL /* no encryption yet */);
+ NULL /* no encryption yet */,
+ NULL);
ut_a(fil_validate());
@@ -2315,7 +2321,7 @@ innobase_start_or_create_for_mysql(void)
/* Create the file space object for archived logs. Under
MySQL, no archiving ever done. */
fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
- 0, FIL_LOG);
+ 0, FIL_LOG, NULL, NULL);
#endif /* UNIV_LOG_ARCHIVE */
log_group_init(0, i, srv_log_file_size * UNIV_PAGE_SIZE,
SRV_LOG_SPACE_FIRST_ID,
@@ -2537,7 +2543,16 @@ files_checked:
sys_datafiles_created = true;
- /* This function assumes that SYS_DATAFILES exists */
+ err = dict_create_or_check_sys_table_options();
+
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
+
+ sys_table_options_created = true;
+
+ /* This function assumes that SYS_DATAFILES
+ and SYS_TABLE_OPTIONS exists */
dict_check_tablespaces_and_store_max_id(dict_check);
}
@@ -2747,6 +2762,16 @@ files_checked:
}
}
+ /* Create the SYS_TABLE_OPTIONS system table if we
+ have not done that already on crash recovery. */
+ if (sys_table_options_created == false) {
+ err = dict_create_or_check_sys_table_options();
+
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
+ }
+
srv_is_being_started = FALSE;
ut_a(trx_purge_state() == PURGE_STATE_INIT);
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 8d1bd543d0c..766644a8624 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -391,6 +391,7 @@ SET(INNOBASE_SOURCES
dict/dict0mem.cc
dict/dict0stats.cc
dict/dict0stats_bg.cc
+ dict/dict0tableoptions.cc
dyn/dyn0dyn.cc
eval/eval0eval.cc
eval/eval0proc.cc
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc
index 739ea9f7572..4af32a5819f 100644
--- a/storage/xtradb/api/api0api.cc
+++ b/storage/xtradb/api/api0api.cc
@@ -36,8 +36,9 @@ InnoDB Native API
#include "api0api.h"
#include "api0misc.h"
-#include "srv0start.h"
+#include "dict0tableoptions.h"
#include "dict0dict.h"
+#include "srv0start.h"
#include "btr0pcur.h"
#include "row0ins.h"
#include "row0upd.h"
@@ -270,7 +271,7 @@ ib_open_table_by_name(
dict_table_t* table;
table = dict_table_open_on_name(name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table != NULL && table->ibd_file_missing) {
table = NULL;
@@ -3723,7 +3724,7 @@ ib_table_truncate(
dict_mutex_enter_for_mysql();
table = dict_table_open_on_name(table_name, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table != NULL && dict_table_get_first_index(table)) {
err = ib_create_cursor_with_index_id(&ib_crsr, table, 0,
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 72d078b3139..5020f42776d 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -62,6 +62,7 @@ Created 11/5/1995 Heikki Tuuri
#include "trx0trx.h"
#include "srv0start.h"
#include "ut0byte.h"
+#include "fil0fil.h"
#include "fil0pagecompress.h"
#include "ha_prototypes.h"
@@ -4793,7 +4794,7 @@ corrupt:
"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);
+ bpage->space, bpage->key_version);
if (bpage->space > TRX_SYS_SPACE) {
if (corrupted) {
diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc
index 68cbde8c342..ae9366d500d 100644
--- a/storage/xtradb/dict/dict0crea.cc
+++ b/storage/xtradb/dict/dict0crea.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -310,7 +311,7 @@ dict_build_table_def_step(
dict_tf_to_fsp_flags(table->flags),
table->flags2,
FIL_IBD_FILE_INITIAL_SIZE,
- node->mode, node->key_id);
+ table);
table->space = (unsigned int) space;
@@ -935,10 +936,8 @@ tab_create_graph_create(
dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
mem_heap_t* heap, /*!< in: heap where created */
- bool commit, /*!< in: true if the commit node should be
+ bool commit) /*!< in: true if the commit node should be
added to the query graph */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
{
tab_node_t* node;
@@ -951,8 +950,6 @@ tab_create_graph_create(
node->state = TABLE_BUILD_TABLE_DEF;
node->heap = mem_heap_create(256);
- node->mode = mode;
- node->key_id = key_id;
node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables,
heap);
@@ -1988,3 +1985,112 @@ dict_create_add_tablespace_to_dictionary(
return(error);
}
+
+/****************************************************************//**
+Creates the sys_table_options system tables inside InnoDB
+at server bootstrap or server start if it is not found or is
+not of the right form.
+@return DB_SUCCESS or error code */
+UNIV_INTERN
+dberr_t
+dict_create_or_check_sys_table_options(void)
+/*========================================*/
+{
+ trx_t* trx;
+ my_bool srv_file_per_table_backup;
+ dberr_t err;
+ dberr_t sys_tableoptions_err;
+
+ ut_a(srv_get_active_thread_type() == SRV_NONE);
+
+ /* Note: The master thread has not been started at this point. */
+
+ sys_tableoptions_err = dict_check_if_system_table_exists(
+ "SYS_TABLE_OPTIONS", DICT_NUM_FIELDS__SYS_TABLEOPTIONS + 1, 1);
+
+ if (sys_tableoptions_err == DB_SUCCESS) {
+
+ return(DB_SUCCESS);
+ }
+
+ trx = trx_allocate_for_mysql();
+
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ trx->op_info = "creating table options sys table";
+
+ row_mysql_lock_data_dictionary(trx);
+
+ /* Check which incomplete table definition to drop. */
+
+ if (sys_tableoptions_err == DB_CORRUPTION) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Dropping incompletely created "
+ "SYS_TABLE_OPTIONS table.");
+ row_drop_table_for_mysql("SYS_TABLE_OPTIONS", trx, TRUE);
+ }
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Creating table options system table.");
+
+ /* We always want SYSTEM tables to be created inside the system
+ tablespace. */
+ srv_file_per_table_backup = srv_file_per_table;
+ srv_file_per_table = 0;
+
+ err = que_eval_sql(
+ NULL,
+ "PROCEDURE CREATE_SYS_TABLE_OPTIONS_PROC () IS\n"
+ "BEGIN\n"
+ "CREATE TABLE SYS_TABLE_OPTIONS(\n"
+ " TABLE_ID BIGINT,"
+ " PAGE_COMPRESSED INT,"
+ " PAGE_COMPRESSION_LEVEL INT,"
+ " ATOMIC_WRITES INT,"
+ " ENCRYPTED INT,"
+ " ENCRYPTION_KEY_ID INT"
+ ");\n"
+ "CREATE UNIQUE CLUSTERED INDEX SYS_TABLE_OPTIONS_TABLE_ID"
+ " ON SYS_TABLE_OPTIONS (TABLE_ID);\n"
+ "END;\n",
+ FALSE, trx);
+
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Creation of SYS_TABLE_OPTIONS "
+ "has failed with error %lu. Tablespace is full. "
+ "Dropping incompletely created tables.",
+ (ulong) err);
+
+ ut_a(err == DB_OUT_OF_FILE_SPACE
+ || err == DB_TOO_MANY_CONCURRENT_TRXS);
+
+ row_drop_table_for_mysql("SYS_TABLE_OPTIONS", trx, TRUE);
+
+ if (err == DB_OUT_OF_FILE_SPACE) {
+ err = DB_MUST_GET_MORE_FILE_SPACE;
+ }
+ }
+
+ trx_commit_for_mysql(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ srv_file_per_table = srv_file_per_table_backup;
+
+ if (err == DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Table options system table created.");
+ }
+
+ /* Note: The master thread has not been started at this point. */
+ /* Confirm and move to the non-LRU part of the table LRU list. */
+
+ sys_tableoptions_err = dict_check_if_system_table_exists(
+ "SYS_TABLE_OPTIONS", DICT_NUM_FIELDS__SYS_TABLEOPTIONS + 1, 1);
+ ut_a(sys_tableoptions_err == DB_SUCCESS);
+
+ return(err);
+}
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index f6621473077..7c25b1e4ef1 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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
@@ -1163,8 +1163,10 @@ dict_table_open_on_name(
indexes after an aborted online
index creation */
dict_err_ignore_t
- ignore_err) /*!< in: error to be ignored when
+ ignore_err, /*!< in: error to be ignored when
loading a table definition */
+ dict_tableoptions_t*
+ options) /*!< in: table options */
{
dict_table_t* table;
@@ -1178,7 +1180,7 @@ dict_table_open_on_name(
table = dict_table_check_if_in_cache_low(table_name);
if (table == NULL) {
- table = dict_load_table(table_name, TRUE, ignore_err);
+ table = dict_load_table(table_name, TRUE, ignore_err, options);
}
ut_ad(!table || table->cached);
@@ -1187,6 +1189,16 @@ dict_table_open_on_name(
/* If table is encrypted return table */
if (ignore_err == DICT_ERR_IGNORE_NONE
+ && !table->is_encrypted && options) {
+ if ((options->encryption == FIL_SPACE_ENCRYPTION_ON ||
+ (options->encryption == FIL_SPACE_ENCRYPTION_DEFAULT && srv_encrypt_tables))
+ && !encryption_key_id_exists((unsigned int)options->encryption_key_id)) {
+ table->is_encrypted = true;
+ }
+ }
+
+ /* If table is encrypted return table */
+ if (ignore_err == DICT_ERR_IGNORE_NONE
&& table->is_encrypted) {
/* Make life easy for drop table. */
if (table->can_be_evicted) {
diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc
index d6ed8acb39e..0e0c054687f 100644
--- a/storage/xtradb/dict/dict0load.cc
+++ b/storage/xtradb/dict/dict0load.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2016, 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
@@ -24,6 +25,13 @@ from dictionary tables
Created 4/24/1996 Heikki Tuuri
*******************************************************/
+#include "univ.i"
+#include "dict0dict.h"
+#include "fil0fil.h"
+#include "my_crypt.h"
+#include "fil0crypt.h"
+#include "dict0types.h"
+#include "dict0tableoptions.h"
#include "dict0load.h"
#include "mysql_version.h"
@@ -56,7 +64,8 @@ static const char* SYSTEM_TABLE_NAME[] = {
"SYS_FOREIGN",
"SYS_FOREIGN_COLS",
"SYS_TABLESPACES",
- "SYS_DATAFILES"
+ "SYS_DATAFILES",
+ "SYS_TABLE_OPTIONS"
};
/* If this flag is TRUE, then we will load the cluster index's (and tables')
@@ -1083,6 +1092,11 @@ loop:
discarded = !!(flags2 & DICT_TF2_DISCARDED);
}
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLES__ID, &len);
+ table_id_t table_id = static_cast<table_id_t>(
+ mach_read_from_8(field));
+
if (space_id == 0) {
/* The system tablespace always exists. */
ut_ad(!discarded);
@@ -1148,6 +1162,7 @@ loop:
/* Use the remote filepath if known. */
char* filepath = NULL;
+
if (DICT_TF_HAS_DATA_DIR(flags)) {
filepath = dict_get_first_path(
space_id, name);
@@ -1158,6 +1173,10 @@ loop:
since if it's off we should decrypt a potentially
already encrypted table */
bool read_page_0 = true;
+ dict_tableoptions_t options;
+
+ memset(&options, 0, sizeof(dict_tableoptions_t));
+ dict_get_table_options(table_id, &options, true);
/* We set the 2nd param (fix_dict = true)
here because we already have an x-lock on
@@ -1168,7 +1187,7 @@ loop:
dberr_t err = fil_open_single_table_tablespace(
read_page_0, srv_read_only_mode ? false : true,
space_id, dict_tf_to_fsp_flags(flags),
- name, filepath, NULL);
+ name, filepath, NULL, &options);
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -2281,9 +2300,11 @@ dict_load_table(
const char* name, /*!< in: table name in the
databasename/tablename format */
ibool cached, /*!< in: TRUE=add to cache, FALSE=do not */
- dict_err_ignore_t ignore_err)
+ dict_err_ignore_t ignore_err,
/*!< in: error to be ignored when loading
table and its indexes' definition */
+ dict_tableoptions_t* options)
+ /*!< in: table options */
{
dberr_t err;
dict_table_t* table;
@@ -2366,6 +2387,11 @@ err_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
+ if (table && options) {
+ ut_ad(table->table_options);
+ memcpy(table->table_options, options, sizeof(dict_tableoptions_t));
+ }
+
if (table->space == 0) {
/* The system tablespace is always available. */
} else if (table->flags2 & DICT_TF2_DISCARDED) {
@@ -2413,7 +2439,7 @@ err_exit:
err = fil_open_single_table_tablespace(
true, false, table->space,
dict_tf_to_fsp_flags(table->flags),
- name, filepath, table);
+ name, filepath, table, table->table_options);
if (err != DB_SUCCESS) {
/* We failed to find a sensible
@@ -2635,7 +2661,7 @@ check_rec:
table = dict_load_table(
mem_heap_strdupl(
heap, (char*) field, len),
- TRUE, ignore_err);
+ TRUE, ignore_err, NULL);
}
}
}
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index a4f6cd6c91f..51fc389e6af 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -2,6 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2015, 2016, 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
@@ -85,7 +86,6 @@ dict_mem_table_create(
mem_heap_t* heap;
ut_ad(name);
- ut_a(dict_tf_is_valid(flags));
ut_a(!(flags2 & ~DICT_TF2_BIT_MASK));
heap = mem_heap_create(DICT_HEAP_SIZE);
@@ -95,6 +95,11 @@ dict_mem_table_create(
table->heap = heap;
+ table->table_options = static_cast<dict_tableoptions_t*>(
+ mem_heap_zalloc(heap, sizeof(dict_tableoptions_t)));
+
+ table->table_options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+
table->flags = (unsigned int) flags;
table->flags2 = (unsigned int) flags2;
table->name = static_cast<char*>(ut_malloc(strlen(name) + 1));
diff --git a/storage/xtradb/dict/dict0tableoptions.cc b/storage/xtradb/dict/dict0tableoptions.cc
new file mode 100644
index 00000000000..527c5e356d9
--- /dev/null
+++ b/storage/xtradb/dict/dict0tableoptions.cc
@@ -0,0 +1,482 @@
+/*****************************************************************************
+
+Copyright (c) 2016, 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
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**************************************************//**
+@file dict/dict0tableoptions.cc
+Function implementations for the system table SYS_TABLE_OPTIONS
+
+Created 22/01/2006 Jan Lindström
+*******************************************************/
+
+#include "mysql_version.h"
+#include "btr0pcur.h"
+#include "btr0btr.h"
+#include "page0page.h"
+#include "mach0data.h"
+#include "dict0dict.h"
+#include "dict0boot.h"
+#include "dict0stats.h"
+#include "dict0mem.h"
+#include "rem0cmp.h"
+#include "srv0start.h"
+#include "srv0srv.h"
+#include "dict0crea.h"
+#include "dict0priv.h"
+#include "ha_prototypes.h" /* innobase_casedn_str() */
+#include "fts0priv.h"
+#include "dict0tableoptions.h"
+#include "dict0load.h"
+#include "row0mysql.h"
+
+/********************************************************************//**
+This function parses a SYS_TABLE_OPTIONS record, extracts necessary
+information from the record and returns it to the caller.
+@return error message or NULL if successfull */
+UNIV_INTERN
+const char*
+dict_process_sys_tableoptions(
+/*==========================*/
+ mem_heap_t* heap, /*!< in/out: heap memory */
+ const rec_t* rec, /*!< in: current SYS_TABLE_OPTIONS rec */
+ dict_tableoptions_t* table_options) /*!< out: table options */
+{
+ const byte* field;
+ ulint len=0;
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ return("delete-marked record in SYS_TABLE_OPTIONS");
+ }
+
+ if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLEOPTIONS) {
+ return("wrong number of columns in SYS_TABLE_OPTIONS record");
+ }
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__TABLE_ID, &len);
+ if (len != 8) {
+err_len:
+ return("incorrect column length in SYS_TABLE_OPTIONS");
+ }
+
+ table_options->table_id = mach_read_from_8(field);
+
+ rec_get_nth_field_offs_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__DB_TRX_ID, &len);
+ if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ rec_get_nth_field_offs_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__DB_ROLL_PTR, &len);
+ if (len != DATA_ROLL_PTR_LEN && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSED, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->page_compressed = mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSION_LEVEL, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->page_compression_level = mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__ATOMIC_WRITES, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->atomic_writes = (atomic_writes_t)mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTED, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->encryption = (fil_encryption_t)mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTION_KEY_ID, &len);
+ if (len != 4 && len != UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
+ table_options->encryption_key_id = mach_read_from_4(field);
+
+ return(NULL);
+}
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS based on table_id
+@return true if found, false if not */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ table_id_t table_id, /*!< in: table id */
+ dict_tableoptions_t* options, /*!< out:table options */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ mtr_t mtr;
+ dict_table_t* sys_tableoptions;
+ dict_index_t* sys_index;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ byte* buf;
+ btr_pcur_t pcur;
+ const rec_t* rec;
+ mem_heap_t* heap = mem_heap_create(1024);
+ const char* err=NULL;
+ bool found = false;
+
+ mtr_start(&mtr);
+
+ if (!fixed) {
+ /* We have taken dict_sys on dict_load_table() */
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ mutex_exit(&dict_sys->mutex);
+ rw_lock_x_lock(&dict_operation_lock);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ sys_tableoptions = dict_table_get_low("SYS_TABLE_OPTIONS");
+ sys_index = UT_LIST_GET_FIRST(sys_tableoptions->indexes);
+ ut_ad(!dict_table_is_comp(sys_tableoptions));
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, DICT_FLD__SYS_TABLEOPTIONS__TABLE_ID);
+
+ buf = static_cast<byte*>(mem_heap_alloc(heap, 8));
+ mach_write_to_8(buf, table_id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_SEARCH_LEAF, &pcur, &mtr);
+
+ rec = btr_pcur_get_rec(&pcur);
+
+ /* If the file-per-table tablespace was created with
+ an earlier version of InnoDB, then this record is not
+ in SYS_TABLE_OPTIONS.*/
+
+ memset(options, 0, sizeof(dict_tableoptions_t));
+
+ if (btr_pcur_is_on_user_rec(&pcur)) {
+ err = dict_process_sys_tableoptions(heap, rec, options);
+
+ if (err) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: %s\n", err);
+ } else {
+ found = true;
+ }
+ }
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+ mem_heap_free(heap);
+
+ if (!fixed) {
+ mutex_exit(&(dict_sys->mutex));
+ rw_lock_x_unlock(&dict_operation_lock);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ return(found);
+}
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS
+@return true if found, false if not */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ dict_table_t* table, /*!< in/out: table */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ bool found=false;
+
+ found = dict_get_table_options(table->id, table->table_options, fixed);
+
+ return(found);
+}
+
+/********************************************************************//**
+Update the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_tableoptions(
+/*=====================*/
+ const dict_table_t* table) /*!< in: table object */
+{
+ dberr_t err = DB_SUCCESS;
+ trx_t* trx;
+
+ trx = trx_allocate_for_background();
+ trx->op_info = "update sys_table_options";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+ row_mysql_lock_data_dictionary(trx);
+
+ pars_info_t* info = pars_info_create();
+
+ pars_info_add_ull_literal(info, "tableid", table->id);
+ pars_info_add_int4_literal(info, "pagecomp", (ulint)table->table_options->page_compressed);
+ pars_info_add_int4_literal(info, "level", (ulint)table->table_options->page_compression_level);
+ pars_info_add_int4_literal(info, "awrite", (ulint)table->table_options->atomic_writes);
+ pars_info_add_int4_literal(info, "encrypt", (ulint)table->table_options->encryption);
+ pars_info_add_int4_literal(info, "keyid", (ulint)table->table_options->encryption_key_id);
+
+ err = que_eval_sql(info,
+ "PROCEDURE UPDATE_TABLE_OPTIONS () IS\n"
+ "BEGIN\n"
+ "UPDATE SYS_TABLE_OPTIONS"
+ " SET PAGE_COMPRESSED = :pagecomp,\n"
+ " PAGE_COMPRESSION_LEVEL = :level,\n"
+ " ATOMIC_WRITES = :awrite,\n"
+ " ENCRYPTED = :encrypt,\n"
+ " ENCRYPTION_KEY_ID = : keyid\n"
+ " WHERE TABLE_ID = :tableid;\n"
+ "END;\n", FALSE, trx);
+
+ trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary(trx);
+ trx_free_for_background(trx);
+
+ if (err == DB_SUCCESS) {
+ /* We just updated SYS_TABLE_OPTIONS due to the contents in
+ tablespace or dictionary. Make note of that */
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "The InnoDB data dictionary table SYS_TABLE_OPTIONS "
+ "for table ID %lu name %s was updated to use "
+ "page_compressed %lu compression_level %lu "
+ " atomic_writes %lu encrypted %lu key_id %lu.",
+ table->id, table->name,
+ (ulint)table->table_options->page_compressed,
+ (ulint)table->table_options->page_compression_level,
+ (ulint)table->table_options->atomic_writes,
+ (ulint)table->table_options->encryption,
+ (ulint)table->table_options->encryption_key_id);
+ } else {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem updating InnoDB data dictionary table "
+ "SYS_TABLE_OPTIONS for table ID %lu name %s err %lu.",
+ table->id, table->name, (ulint)err);
+ }
+
+ return(err);
+}
+
+/********************************************************************//**
+Insert record into SYS_TABLE_OPTIONS
+@return DB_SUCCESS if OK, dberr_t if the insert failed */
+UNIV_INTERN
+dberr_t
+dict_insert_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ dberr_t err = DB_SUCCESS;
+ trx_t* trx;
+
+ trx = trx_allocate_for_background();
+ trx->op_info = "insert tableoptions";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ if (!fixed) {
+ /* We have taken dict_sys on dict_load_table() */
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ mutex_exit(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ pars_info_t* info = pars_info_create();
+ pars_info_add_ull_literal(info, "tableid", table->id);
+ pars_info_add_int4_literal(info, "pagecomp", (ulint)table->table_options->page_compressed);
+ pars_info_add_int4_literal(info, "level", (ulint)table->table_options->page_compression_level);
+ pars_info_add_int4_literal(info, "awrite", (ulint)table->table_options->atomic_writes);
+ pars_info_add_int4_literal(info, "encrypt", (ulint)table->table_options->encryption);
+ pars_info_add_int4_literal(info, "keyid", (ulint)table->table_options->encryption_key_id);
+
+ err = que_eval_sql(info,
+ "PROCEDURE INSERT_TABLEOPTIONS () IS\n"
+ "BEGIN\n"
+ "INSERT INTO SYS_TABLE_OPTIONS VALUES"
+ "(:tableid, :pagecomp, :level, :awrite, :encrypt, :keyid);\n"
+ "END;\n",
+ FALSE, trx);
+
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem inserting row to InnoDB data dictionary table SYS_TABLE_OPTIONS "
+ "for table ID %lu name %s "
+ "page_compressed %lu compression_level %lu "
+ " atomic_writes %lu encrypted %lu key_id %lu.",
+ table->id, table->name,
+ (ulint)table->table_options->page_compressed,
+ (ulint)table->table_options->page_compression_level,
+ (ulint)table->table_options->atomic_writes,
+ (ulint)table->table_options->encryption,
+ (ulint)table->table_options->encryption_key_id);
+ }
+
+ trx->op_info = "";
+ trx_commit_for_mysql(trx);
+
+ if (!fixed) {
+ row_mysql_unlock_data_dictionary(trx);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ trx_free_for_background(trx);
+
+ return(err);
+}
+
+/********************************************************************//**
+Update the table flags in SYS_TABLES.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_table_flags(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ dberr_t err = DB_SUCCESS;
+ trx_t* trx;
+
+ trx = trx_allocate_for_background();
+ trx->op_info = "update sys_tables options";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ ulint type = dict_tf_to_sys_tables_type(table->flags);
+
+ if (!fixed) {
+ /* We have taken dict_sys on dict_load_table() */
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ mutex_exit(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ pars_info_t* info = pars_info_create();
+
+ pars_info_add_str_literal(info, "tablename", table->name);
+ pars_info_add_int4_literal(info, "type", type);
+
+ err = que_eval_sql(info,
+ "PROCEDURE UPDATE_TABLE_FLAGS () IS\n"
+ "BEGIN\n"
+ "UPDATE SYS_TABLES"
+ " SET TYPE = :type\n"
+ " WHERE NAME = :tablename;\n"
+ "END;\n", FALSE, trx);
+
+ trx_commit_for_mysql(trx);
+
+ if (!fixed) {
+ row_mysql_unlock_data_dictionary(trx);
+ mutex_enter(&(dict_sys->mutex));
+ }
+
+ trx_free_for_background(trx);
+
+ if (err == DB_SUCCESS) {
+ /* We just updated SYS_TABLES due to the contents in
+ tablespace or dictionary. Make note of that */
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "The InnoDB data dictionary table SYS_TABLES "
+ "for table ID %lu name %s was updated to use "
+ "flags %lu. ",
+ table->id, table->name,
+ (ulint)type);
+ } else {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem updating InnoDB data dictionary table "
+ "SYS_TABLES for table ID %lu name %s err %lu.",
+ table->id, table->name, (ulint)err);
+ }
+
+ return(err);
+}
+
+/********************************************************************//**
+Delete the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_delete_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ trx_t* trx, /*!< in: trx */
+ bool fixed) /*!< in: can we fix the
+ dictionary ? */
+{
+ dberr_t err = DB_SUCCESS;
+
+ trx->op_info = "delete sys_table_options";
+ trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
+
+ if (!fixed) {
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ if (dict_get_table_options((dict_table_t*)table, true)) {
+
+ pars_info_t* info = pars_info_create();
+
+ pars_info_add_ull_literal(info, "tableid", table->id);
+
+ err = que_eval_sql(info,
+ "PROCEDURE DELETE_TABLE_OPTIONS () IS\n"
+ "BEGIN\n"
+ "DELETE FROM SYS_TABLE_OPTIONS"
+ " WHERE TABLE_ID = :tableid;\n"
+ "END;\n", FALSE, trx);
+
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Problem deleting InnoDB data dictionary table "
+ "SYS_TABLE_OPTIONS for table ID %lu name %s err %lu.",
+ table->id, table->name, (ulint)err);
+ }
+ }
+
+ if (!fixed) {
+ row_mysql_unlock_data_dictionary(trx);
+ }
+
+ return(err);
+}
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 65827717230..8bcec4df01e 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +25,8 @@ Created 10/25/1995 Heikki Tuuri
*******************************************************/
#include "fil0fil.h"
+#include "rem0rec.h"
+#include "dict0tableoptions.h"
#include "fil0pagecompress.h"
#include "fsp0pagecompress.h"
#include "fil0crypt.h"
@@ -677,7 +679,6 @@ fil_node_open_file(
flags = fsp_header_get_flags(page);
page_size = fsp_flags_get_page_size(flags);
- atomic_writes = fsp_flags_get_atomic_writes(flags);
ut_free(buf2);
@@ -718,27 +719,6 @@ fil_node_open_file(
ut_error;
}
- if (UNIV_UNLIKELY(space->flags != flags)) {
- fprintf(stderr,
- "InnoDB: Error: table flags are 0x%lx"
- " in the data dictionary\n"
- "InnoDB: but the flags in file %s are 0x%lx!\n",
- space->flags, node->name, flags);
-
- ut_error;
- }
-
- if (UNIV_UNLIKELY(space->flags != flags)) {
- if (!dict_tf_verify_flags(space->flags, flags)) {
- fprintf(stderr,
- "InnoDB: Error: table flags are 0x%lx"
- " in the data dictionary\n"
- "InnoDB: but the flags in file %s are 0x%lx!\n",
- space->flags, node->name, flags);
- ut_error;
- }
- }
-
if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
/* Truncate the size to whole extent size. */
size_bytes = ut_2pow_round(size_bytes,
@@ -760,7 +740,7 @@ add_size:
space->size += node->size;
}
- atomic_writes = fsp_flags_get_atomic_writes(space->flags);
+ atomic_writes = fil_space_get_atomic_writes(space);
/* printf("Opening file %s\n", node->name); */
@@ -1182,11 +1162,12 @@ UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- const char* name, /*!< in: space name */
- 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 */
+ const char* name, /*!< in: space name */
+ 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 */
+ const void *options)/*!< in: table options*/
{
fil_space_t* space;
@@ -1285,6 +1266,13 @@ fil_space_create(
space->crypt_data = crypt_data;
+ if (options) {
+ space->table_options = static_cast<dict_tableoptions_t*>(mem_zalloc(sizeof(dict_tableoptions_t)));
+ memcpy(space->table_options, (dict_tableoptions_t*)options, sizeof(dict_tableoptions_t));
+ } else {
+ space->table_options = NULL;
+ }
+
mutex_exit(&fil_system->mutex);
return(TRUE);
@@ -1421,6 +1409,10 @@ fil_space_free(
fil_space_destroy_crypt_data(&(space->crypt_data));
+ if (space->table_options) {
+ mem_free(space->table_options);
+ }
+
mem_free(space->name);
mem_free(space);
@@ -1960,12 +1952,7 @@ fil_check_first_page(
flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) {
- fprintf(stderr,
- "InnoDB: Error: Current page size %lu != "
- " page size on page %lu\n",
- UNIV_PAGE_SIZE, fsp_flags_get_page_size(flags));
-
- return("innodb-page-size mismatch");
+ return("innodb-page-size mismatch");
}
if (!space_id && !flags) {
@@ -2035,14 +2022,11 @@ fil_read_first_page(
*flags and *space_id as they were read from the first file and
do not validate the first page. */
if (!one_read_already) {
+ check_msg = fil_check_first_page(page);
*flags = fsp_header_get_flags(page);
*space_id = fsp_header_get_space_id(page);
}
- if (!one_read_already) {
- check_msg = fil_check_first_page(page);
- }
-
flushed_lsn = mach_read_from_8(page +
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
@@ -2428,8 +2412,7 @@ fil_op_log_parse_or_replay(
space_id, name, path, flags,
DICT_TF2_USE_TABLESPACE,
FIL_IBD_FILE_INITIAL_SIZE,
- FIL_SPACE_ENCRYPTION_DEFAULT,
- FIL_DEFAULT_ENCRYPTION_KEY) != DB_SUCCESS) {
+ NULL) != DB_SUCCESS) {
ut_error;
}
}
@@ -3371,8 +3354,7 @@ fil_create_new_single_table_tablespace(
ulint size, /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ const dict_table_t* table) /*!< in: table or NULL */
{
os_file_t file;
ibool ret;
@@ -3384,8 +3366,11 @@ fil_create_new_single_table_tablespace(
/* TRUE if a table is created with CREATE TEMPORARY TABLE */
bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY);
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
- ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
+ ulint atomic_writes = table ? table->table_options->atomic_writes :
+ ATOMIC_WRITES_DEFAULT;
fil_space_crypt_t *crypt_data = NULL;
+ fil_encryption_t mode = table ? table->table_options->encryption :
+ FIL_SPACE_ENCRYPTION_DEFAULT;
ut_a(space_id > 0);
ut_ad(!srv_read_only_mode);
@@ -3543,11 +3528,13 @@ fil_create_new_single_table_tablespace(
requested it to remain unencrypted. */
if (mode == FIL_SPACE_ENCRYPTION_ON || mode == FIL_SPACE_ENCRYPTION_OFF ||
srv_encrypt_tables) {
+ uint key_id = table ? table->table_options->encryption_key_id :
+ FIL_DEFAULT_ENCRYPTION_KEY;
crypt_data = fil_space_create_crypt_data(mode, key_id);
}
success = fil_space_create(tablename, space_id, flags, FIL_TABLESPACE,
- crypt_data);
+ crypt_data, table ? table->table_options : NULL);
if (!success || !fil_node_create(path, size, space_id, FALSE)) {
err = DB_ERROR;
@@ -3632,6 +3619,140 @@ fil_report_bad_tablespace(
(ulong) expected_id, (ulong) expected_flags);
}
+/******************************************************************
+Set flags for a tablespace */
+static
+void
+fil_space_set_fsp_flags(
+/*=====================*/
+ ulint id, /*!< in: space id */
+ uint flags) /*!< in: fsp flags */
+{
+ fil_space_t* space;
+
+ ut_ad(fil_system);
+
+ mutex_enter(&fil_system->mutex);
+
+ space = fil_space_get_by_id(id);
+
+ if (space != NULL) {
+ space->flags = flags;
+ }
+
+ mutex_exit(&fil_system->mutex);
+}
+
+/******************************************************************
+Update tablespace (fsp) flags on page 0
+@return true if successfull, false if not */
+static
+void
+fil_update_page0(
+/*=============*/
+ byte* page0, /*!< in: page 0 or NULL */
+ os_file_t data_file, /*!< in: data file */
+ ulint space, /*!< in: space id */
+ ulint flags, /*!< in: old fsp flags */
+ ulint fsp_flags)/*!< in: new fsp flags */
+{
+ ulint psize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB(flags);
+ ulint zip_size = FSP_FLAGS_GET_ZIP_SSIZE(flags);
+
+ if (!psize) {
+ psize = UNIV_PAGE_SIZE_ORIG;
+ }
+
+ fsp_flags = fsp_flags_set_page_size(fsp_flags, psize);
+
+ if (flags != fsp_flags) {
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "InnoDB: Adjusted space_id %lu tablespace flags from %lu to %lu.\n",
+ space, flags, fsp_flags);
+
+ mtr_t mtr;
+ mtr_start(&mtr);
+
+ if (!page0) {
+ buf_block_t* block = buf_page_get_gen(space,
+ zip_size, 0,
+ RW_X_LATCH,
+ NULL,
+ BUF_GET,
+ __FILE__, __LINE__,
+ &mtr);
+ page0 = buf_block_get_frame(block);
+ }
+
+ mlog_write_ulint(page0 + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS,
+ fsp_flags, MLOG_4BYTES, &mtr);
+ /* Redo log this as bytewise update to page 0
+ followed by an MLOG_FILE_WRITE_FSP_FLAGS */
+ byte* log_ptr = mlog_open(&mtr, 11 + 8);
+ if (log_ptr != NULL) {
+ log_ptr = mlog_write_initial_log_record_fast(
+ page0,
+ MLOG_FILE_WRITE_FSP_FLAGS,
+ log_ptr, &mtr);
+ mach_write_to_4(log_ptr, fsp_flags);
+ log_ptr += 4;
+ mach_write_to_4(log_ptr, space);
+ log_ptr += 4;
+ mlog_close(&mtr, log_ptr);
+ }
+
+ mtr_commit(&mtr);
+ lsn_t end_lsn = mtr.end_lsn;
+ buf_flush_init_for_writing(page0, NULL, end_lsn);
+ flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page0);
+ ut_ad(flags == fsp_flags);
+
+ /* Flush dirty page to the storage */
+ ulint n_pages = 0;
+ ulint sum_pages = 0;
+ bool success = false;
+ do {
+ success = buf_flush_list(ULINT_MAX, end_lsn, &n_pages);
+ buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
+ sum_pages += n_pages;
+ } while (!success);
+
+ fil_space_set_fsp_flags(space, fsp_flags);
+ }
+}
+
+/******************************************************************
+Parse a MLOG_FILE_WRITE_FSP_FLAGS log entry
+@return position on log buffer */
+UNIV_INTERN
+byte*
+fil_parse_write_fsp_flags(
+/*======================*/
+ byte* ptr, /*!< in: Log entry start */
+ byte* end_ptr,/*!< in: Log entry end */
+ buf_block_t* block) /*!< in: buffer block */
+{
+ /* check that redo log entry is complete */
+ uint entry_size = 4 + 4; // size of flags + space_id
+
+ if (end_ptr - ptr < entry_size){
+ return NULL;
+ }
+
+ ulint flags = mach_read_from_4(ptr);
+ ptr += 4;
+ ulint space_id = mach_read_from_4(ptr);
+ ptr += 4;
+
+ ut_a(fsp_flags_is_valid(flags));
+
+ /* update fil_space memory cache with flags */
+ fil_space_set_fsp_flags(space_id, flags);
+
+ return ptr;
+}
+
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks that the
space id in it is correct. If this does not succeed, print an error message
@@ -3665,7 +3786,8 @@ fil_open_single_table_tablespace(
const char* tablename, /*!< in: table name in the
databasename/tablename format */
const char* path_in, /*!< in: tablespace filepath */
- dict_table_t* table) /*!< in: table */
+ dict_table_t* table, /*!< in: table or NULL */
+ void* options) /*!< in: table options or NULL*/
{
dberr_t err = DB_SUCCESS;
bool dict_filepath_same_as_default = false;
@@ -3678,6 +3800,8 @@ fil_open_single_table_tablespace(
ulint valid_tablespaces_found = 0;
ulint atomic_writes = 0;
fil_space_crypt_t* crypt_data = NULL;
+ bool fix_flags = false;
+ ulint nflags = 0;
#ifdef UNIV_SYNC_DEBUG
ut_ad(!fix_dict || rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
@@ -3694,7 +3818,7 @@ fil_open_single_table_tablespace(
return(DB_CORRUPTION);
}
- atomic_writes = fsp_flags_get_atomic_writes(flags);
+ atomic_writes = options ? ((dict_tableoptions_t*)options)->atomic_writes : 0;
/* If the tablespace was relocated, we do not
compare the DATA_DIR flag */
@@ -3783,18 +3907,27 @@ fil_open_single_table_tablespace(
table->crypt_data = def.crypt_data;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
- if (def.valid && def.id == id
- && (def.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ /* This could mean that tablespace flags are corrupted
+ or that they are old */
+ if ((def.flags & ~FSP_FLAGS_MASK_DATA_DIR) != mod_flags &&
+ table && options) {
+ fix_flags = true;
valid_tablespaces_found++;
} else {
- def.valid = false;
- /* Do not use this tablespace. */
- fil_report_bad_tablespace(
- def.filepath, def.check_msg, def.id,
- def.flags, id, flags);
+
+ /* Validate this single-table-tablespace with SYS_TABLES,
+ but do not compare the DATA_DIR flag, in case the
+ tablespace was relocated. */
+ if (def.valid && def.id == id
+ && (def.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ valid_tablespaces_found++;
+ } else {
+ def.valid = false;
+ /* Do not use this tablespace. */
+ fil_report_bad_tablespace(
+ def.filepath, def.check_msg, def.id,
+ def.flags, id, flags);
+ }
}
}
@@ -3813,15 +3946,22 @@ fil_open_single_table_tablespace(
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
if (remote.valid && remote.id == id
- && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) != mod_flags &&
+ table && options ) {
+ fix_flags = true;
valid_tablespaces_found++;
} else {
- remote.valid = false;
- /* Do not use this linked tablespace. */
- fil_report_bad_tablespace(
- remote.filepath, remote.check_msg, remote.id,
- remote.flags, id, flags);
- link_file_is_bad = true;
+ if (remote.valid && remote.id == id
+ && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ valid_tablespaces_found++;
+ } else {
+ remote.valid = false;
+ /* Do not use this linked tablespace. */
+ fil_report_bad_tablespace(
+ remote.filepath, remote.check_msg, remote.id,
+ remote.flags, id, flags);
+ link_file_is_bad = true;
+ }
}
}
@@ -3836,18 +3976,27 @@ fil_open_single_table_tablespace(
table->crypt_data = dict.crypt_data;
}
- /* Validate this single-table-tablespace with SYS_TABLES,
- but do not compare the DATA_DIR flag, in case the
- tablespace was relocated. */
- if (dict.valid && dict.id == id
- && (dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ /* This could mean that tablespace flags are corrupted
+ or that they are old */
+ if ((dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) != mod_flags &&
+ table && options ) {
+ fix_flags = true;
valid_tablespaces_found++;
} else {
- dict.valid = false;
- /* Do not use this tablespace. */
- fil_report_bad_tablespace(
- dict.filepath, dict.check_msg, dict.id,
- dict.flags, id, flags);
+
+ /* Validate this single-table-tablespace with SYS_TABLES,
+ but do not compare the DATA_DIR flag, in case the
+ tablespace was relocated. */
+ if (dict.valid && dict.id == id
+ && (dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+ valid_tablespaces_found++;
+ } else {
+ dict.valid = false;
+ /* Do not use this tablespace. */
+ fil_report_bad_tablespace(
+ dict.filepath, dict.check_msg, dict.id,
+ dict.flags, id, flags);
+ }
}
}
@@ -3996,7 +4145,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, options)) {
err = DB_ERROR;
} else {
/* We do not measure the size of the file, that is why
@@ -4009,6 +4158,46 @@ skip_validate:
}
}
+ if (fix_flags) {
+ /* Here we remove PAGE_COMPRESSION, PAGE_COMPRESSION_LEVEL,
+ ATOMIC_WRITES, PAGE_ENCRYPTION and PAGE_ENCRYPTION_KEY
+ values from table flags. */
+ nflags = (DICT_TF_GET_COMPACT(table->flags) << DICT_TF_POS_COMPACT)
+ | (DICT_TF_GET_ZIP_SSIZE(table->flags) << DICT_TF_POS_ZIP_SSIZE)
+ | (DICT_TF_HAS_ATOMIC_BLOBS(table->flags) << DICT_TF_POS_ATOMIC_BLOBS)
+ | (DICT_TF_HAS_DATA_DIR(table->flags) << DICT_TF_POS_DATA_DIR);
+ ulint fsp_flags = dict_tf_to_fsp_flags(nflags);
+
+ if (def.success) {
+ fil_update_page0(NULL, def.file, def.id, def.flags, fsp_flags);
+ } else if (dict.success) {
+ fil_update_page0(NULL, dict.file, dict.id, dict.flags, fsp_flags);
+ } else {
+ fil_update_page0(NULL, remote.file, remote.id, remote.flags, fsp_flags);
+ }
+
+ if (((dict_tableoptions_t*)options)->need_stored) {
+ dict_insert_tableoptions(table, fix_dict);
+ }
+
+ if (def.success) {
+ def.check_msg = fil_read_first_page(
+ def.file, FALSE, &def.flags, &def.id,
+ &def.lsn, &def.lsn, &def.crypt_data);
+ } else if (dict.success) {
+ dict.check_msg = fil_read_first_page(
+ dict.file, FALSE, &dict.flags, &dict.id,
+ &dict.lsn, &dict.lsn, &dict.crypt_data);
+ } else {
+ remote.check_msg = fil_read_first_page(
+ remote.file, FALSE, &remote.flags, &remote.id,
+ &remote.lsn, &remote.lsn, &remote.crypt_data);
+ }
+
+ table->flags = nflags;
+ dict_update_table_flags(table, fix_dict);
+ }
+
cleanup_and_exit:
if (remote.success) {
os_file_close(remote.file);
@@ -4399,6 +4588,7 @@ fil_load_single_table_tablespace(
if (!remote.success) {
os_file_close(remote.file);
mem_free(remote.filepath);
+ remote.filepath = NULL;
}
}
@@ -4602,7 +4792,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, NULL);
if (!file_space_create_success) {
if (srv_force_recovery > 0) {
@@ -4777,14 +4967,15 @@ fil_load_single_table_tablespaces(void)
fil_load_single_table_tablespace(
dbinfo.name, fileinfo.name);
files_read++;
+
if (files_read - files_read_at_last_check >
CHECK_TIME_EVERY_N_FILES) {
ib_time_t cur_time= ut_time();
files_read_at_last_check= files_read;
- double time_elapsed= ut_difftime(cur_time,
+ double time_elapsed= ut_difftime(cur_time,
prev_report_time);
if (time_elapsed > 15) {
- ib_logf(IB_LOG_LEVEL_INFO,
+ ib_logf(IB_LOG_LEVEL_INFO,
"Processed %ld .ibd/.isl files",
files_read);
prev_report_time= cur_time;
diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc
index 4451116337e..347c02bca8d 100644
--- a/storage/xtradb/fil/fil0pagecompress.cc
+++ b/storage/xtradb/fil/fil0pagecompress.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +25,8 @@ Updated 14/02/2015
***********************************************************************/
#include "fil0fil.h"
+#include "rem0rec.h"
+#include "dict0tableoptions.h"
#include "fil0pagecompress.h"
#include <debug_sync.h>
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 7a381f4ca05..bbe863f7b9e 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1489,7 +1489,8 @@ fts_drop_table(
table = dict_table_open_on_name(
table_name, TRUE, FALSE,
static_cast<dict_err_ignore_t>(
- DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT));
+ DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT),
+ NULL);
if (table != 0) {
@@ -1981,7 +1982,13 @@ fts_create_one_index_table(
dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB,
4130048, 0);
- error = row_create_table_for_mysql(new_table, trx, false, FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ /* Get default encryption key id if set */
+ if (new_table && new_table->table_options &&
+ new_table->table_options->encryption_key_id == 0) {
+ new_table->table_options->encryption_key_id = innobase_get_default_encryption_key_id(trx);
+ }
+
+ error = row_create_table_for_mysql(new_table, trx, false);
if (error != DB_SUCCESS) {
trx->error_state = error;
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 2f989a47d86..5c8e0e57a7b 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -5,7 +5,7 @@ Copyright (c) 2013, 2015, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -91,6 +91,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "dict0boot.h"
#include "dict0stats.h"
#include "dict0stats_bg.h"
+#include "dict0tableoptions.h"
#include "ha_prototypes.h"
#include "ut0mem.h"
#include "ut0timer.h"
@@ -5973,6 +5974,43 @@ ha_innobase::innobase_initialize_autoinc()
}
/*****************************************************************//**
+Set up the table options structure based on frm. */
+UNIV_INTERN
+void
+ha_innobase::set_table_options(
+/*===========================*/
+ THD* thd, /*!< in: thd */
+ TABLE* table, /*!< in: table */
+ dict_tableoptions_t* options) /*!< in: table options */
+{
+ ha_table_option_struct* moptions = table->s->option_struct;
+
+ options->page_compressed = moptions->page_compressed;
+ options->page_compression_level = moptions->page_compression_level;
+ options->atomic_writes = (atomic_writes_t)moptions->atomic_writes;
+ options->encryption = (fil_encryption_t)moptions->encryption;
+ options->encryption_key_id = moptions->encryption_key_id;
+
+ if (options->encryption_key_id == 0) {
+ options->encryption_key_id = THDVAR(thd, default_encryption_key_id);
+ }
+
+ if (options->page_compression_level == 0) {
+ options->page_compression_level = page_zip_level;
+ }
+
+ /* Table options should be stored if they are not same as
+ defaults */
+ if (moptions->page_compressed ||
+ (options->atomic_writes == ATOMIC_WRITES_ON ||
+ options->atomic_writes == ATOMIC_WRITES_OFF) ||
+ (options->encryption == FIL_SPACE_ENCRYPTION_OFF ||
+ options->encryption == FIL_SPACE_ENCRYPTION_ON)) {
+ options->need_stored = true;
+ }
+}
+
+/*****************************************************************//**
Creates and opens a handle to a table which already exists in an InnoDB
database.
@return 1 if error, 0 if success */
@@ -5991,6 +6029,7 @@ ha_innobase::open(
ibool par_case_name_set = FALSE;
char par_case_name[FN_REFLEN];
dict_err_ignore_t ignore_err = DICT_ERR_IGNORE_NONE;
+ dict_tableoptions_t table_options;
DBUG_ENTER("ha_innobase::open");
@@ -5999,6 +6038,8 @@ ha_innobase::open(
thd = ha_thd();
+ set_table_options(thd, table, &table_options);
+
/* No-op in XtraDB */
innobase_release_temporary_latches(ht, thd);
@@ -6038,7 +6079,7 @@ ha_innobase::open(
}
/* Get pointer to a table object in InnoDB dictionary cache */
- ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err);
+ ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err, &table_options);
if (ib_table
&& ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)
@@ -6116,7 +6157,7 @@ ha_innobase::open(
ib_table = dict_table_open_on_name(
par_case_name, FALSE, TRUE,
- ignore_err);
+ ignore_err, &table_options);
}
if (ib_table) {
@@ -11031,8 +11072,7 @@ create_table_def(
const char* remote_path, /*!< in: Remote path or zero length-string */
ulint flags, /*!< in: table flags */
ulint flags2, /*!< in: table flags2 */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ dict_tableoptions_t* table_options) /*!< in: table options */
{
THD* thd = trx->mysql_thd;
dict_table_t* table;
@@ -11223,7 +11263,10 @@ err_col:
fts_add_doc_id_column(table, heap);
}
- err = row_create_table_for_mysql(table, trx, false, mode, key_id);
+ /* Copy table options to table */
+ memcpy(table->table_options, table_options, sizeof(dict_tableoptions_t));
+
+ err = row_create_table_for_mysql(table, trx, false);
mem_heap_free(heap);
@@ -11812,16 +11855,11 @@ innobase_table_flags(
enum row_type row_format;
rec_format_t innodb_row_format = REC_FORMAT_COMPACT;
bool use_data_dir;
- ha_table_option_struct *options= form->s->option_struct;
/* Cache the value of innodb_file_format, in case it is
modified by another thread while the table is being created. */
const ulint file_format_allowed = srv_file_format;
- /* Cache the value of innobase_compression_level, in case it is
- modified by another thread while the table is being created. */
- const ulint default_compression_level = page_zip_level;
-
*flags = 0;
*flags2 = 0;
@@ -12027,11 +12065,7 @@ index_bad:
dict_tf_set(flags,
innodb_row_format,
zip_ssize,
- use_data_dir,
- options->page_compressed,
- options->page_compression_level == 0 ?
- default_compression_level : options->page_compression_level,
- options->atomic_writes);
+ use_data_dir);
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) {
*flags2 |= DICT_TF2_TEMPORARY;
@@ -12062,7 +12096,8 @@ ha_innobase::check_table_options(
created table, contains also the
create statement string */
const bool use_tablespace, /*!< in: use file par table */
- const ulint file_format)
+ const ulint file_format, /*!< in: table row format */
+ dict_tableoptions_t* table_options) /*!< out: used table options */
{
enum row_type row_format = table->s->row_type;
ha_table_option_struct *options= table->s->option_struct;
@@ -12132,6 +12167,8 @@ ha_innobase::check_table_options(
" key_block_size");
return "PAGE_COMPRESSED";
}
+
+ table_options->need_stored = true;
}
/* Check page compression level requirements, some of them are
@@ -12155,6 +12192,10 @@ ha_innobase::check_table_options(
options->page_compression_level);
return "PAGE_COMPRESSION_LEVEL";
}
+
+ table_options->need_stored = true;
+ } else if (options->page_compressed) {
+ options->page_compression_level = page_zip_level;
}
/* If encryption is set up make sure that used key_id is found */
@@ -12170,6 +12211,8 @@ ha_innobase::check_table_options(
return "ENCRYPTION_KEY_ID";
}
+
+ table_options->need_stored = true;
}
/* Ignore nondefault key_id if encryption is set off */
@@ -12181,7 +12224,10 @@ ha_innobase::check_table_options(
"InnoDB: Ignored ENCRYPTION_KEY_ID %u when encryption is disabled",
(uint)options->encryption_key_id
);
+
options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+ table_options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+ table_options->need_stored = true;
}
/* If default encryption is used make sure that used kay is found
@@ -12199,6 +12245,8 @@ ha_innobase::check_table_options(
return "ENCRYPTION_KEY_ID";
}
+
+ table_options->need_stored = true;
}
/* Check atomic writes requirements */
@@ -12212,8 +12260,16 @@ ha_innobase::check_table_options(
" innodb_file_per_table.");
return "ATOMIC_WRITES";
}
+
+ table_options->need_stored = true;
}
+ table_options->page_compressed = options->page_compressed;
+ table_options->page_compression_level = options->page_compression_level;
+ table_options->atomic_writes = awrites;
+ table_options->encryption = encrypt;
+ table_options->encryption_key_id = options->encryption_key_id;
+
return 0;
}
@@ -12255,13 +12311,10 @@ ha_innobase::create(
ulint flags;
ulint flags2;
dict_table_t* innobase_table = NULL;
+ dict_tableoptions_t table_options;
const char* stmt;
size_t stmt_len;
- /* Cache table options */
- ha_table_option_struct *options= form->s->option_struct;
- fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
- uint key_id = (uint)options->encryption_key_id;
DBUG_ENTER("ha_innobase::create");
@@ -12276,9 +12329,11 @@ ha_innobase::create(
/* Create the table definition in InnoDB */
+ memset(&table_options, 0, sizeof(dict_tableoptions_t));
+
/* Validate table options not handled by the SQL-parser */
if(check_table_options(thd, form, create_info, use_tablespace,
- file_format)) {
+ file_format, &table_options)) {
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
@@ -12360,7 +12415,8 @@ ha_innobase::create(
row_mysql_lock_data_dictionary(trx);
error = create_table_def(trx, form, norm_name, temp_path,
- remote_path, flags, flags2, encrypt, key_id);
+ remote_path, flags, flags2, &table_options);
+
if (error) {
goto cleanup;
}
@@ -12394,7 +12450,7 @@ ha_innobase::create(
enum fts_doc_id_index_enum ret;
innobase_table = dict_table_open_on_name(
- norm_name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ norm_name, TRUE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
ut_a(innobase_table);
@@ -12516,7 +12572,7 @@ ha_innobase::create(
log_buffer_flush_to_disk();
innobase_table = dict_table_open_on_name(
- norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
DBUG_ASSERT(innobase_table != 0);
@@ -12895,22 +12951,26 @@ ha_innobase::defragment_table(
bool async) /*!< in: whether to wait until finish */
{
char norm_name[FN_REFLEN];
- dict_table_t* table = NULL;
+ dict_table_t* itable = NULL;
dict_index_t* index = NULL;
ibool one_index = (index_name != 0);
int ret = 0;
dberr_t err = DB_SUCCESS;
+ dict_tableoptions_t options;
+ THD* thd;
if (!srv_defragment) {
return ER_FEATURE_DISABLED;
}
normalize_table_name(norm_name, name);
+ thd = ha_thd();
+ set_table_options(thd, table, &options);
- table = dict_table_open_on_name(norm_name, FALSE,
- FALSE, DICT_ERR_IGNORE_NONE);
+ itable = dict_table_open_on_name(norm_name, FALSE,
+ FALSE, DICT_ERR_IGNORE_NONE, &options);
- for (index = dict_table_get_first_index(table); index;
+ for (index = dict_table_get_first_index(itable); index;
index = dict_table_get_next_index(index)) {
if (one_index && strcasecmp(index_name, index->name) != 0) {
@@ -12969,7 +13029,7 @@ ha_innobase::defragment_table(
}
}
- dict_table_close(table, FALSE, FALSE);
+ dict_table_close(itable, FALSE, FALSE);
if (ret == 0 && one_index) {
ret = ER_NO_SUCH_INDEX;
@@ -17366,7 +17426,7 @@ innodb_internal_table_validate(
}
user_table = dict_table_open_on_name(
- table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE);
+ table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE, NULL);
if (user_table) {
if (dict_table_has_fts_index(user_table)) {
@@ -21108,7 +21168,8 @@ i_s_innodb_mutexes,
i_s_innodb_sys_semaphore_waits,
i_s_innodb_tablespaces_encryption,
i_s_innodb_tablespaces_scrubbing,
-i_s_innodb_changed_page_bitmaps
+i_s_innodb_changed_page_bitmaps,
+i_s_innodb_sys_table_options
maria_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
@@ -21769,3 +21830,25 @@ ib_push_warning(
my_free(buf);
va_end(args);
}
+
+/********************************************************************//**
+Helper function to get default_encryption_key_id from THD
+(trx->mysql_thd).
+@return default_encryption_key_id from THD or
+FIL_DEFAULT_ENCRYPTION_KEY */
+UNIV_INTERN
+ulint
+innobase_get_default_encryption_key_id(
+/*===================================*/
+ trx_t* trx) /*! in: trx */
+{
+ ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
+
+ if (trx && trx->mysql_thd) {
+ THD *thd = (THD *)trx->mysql_thd;
+
+ key_id = THDVAR(thd, default_encryption_key_id);
+ }
+
+ return (key_id);
+}
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index 2027a593140..694af5af9e0 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -201,7 +201,9 @@ class ha_innobase: public handler
char* temp_path,
char* remote_path);
const char* check_table_options(THD *thd, TABLE* table,
- HA_CREATE_INFO* create_info, const bool use_tablespace, const ulint file_format);
+ HA_CREATE_INFO* create_info, const bool use_tablespace, const ulint file_format,
+ dict_tableoptions_t* table_options);
+ void set_table_options(THD *thd, TABLE*table, dict_tableoptions_t* table_options);
int create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info);
int truncate();
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 076c4b6c3b6..7df886f76f6 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2828,7 +2828,6 @@ prepare_inplace_alter_table_dict(
to rebuild the table with a temporary name. */
if (new_clustered) {
- fil_space_crypt_t* crypt_data;
const char* new_table_name
= dict_mem_create_temporary_tablename(
ctx->heap,
@@ -2836,15 +2835,6 @@ prepare_inplace_alter_table_dict(
ctx->new_table->id);
ulint n_cols;
dtuple_t* add_cols;
- ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
- fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT;
-
- crypt_data = fil_space_get_crypt_data(ctx->prebuilt->table->space);
-
- if (crypt_data) {
- key_id = crypt_data->key_id;
- mode = crypt_data->encryption;
- }
if (innobase_check_foreigns(
ha_alter_info, altered_table, old_table,
@@ -2976,7 +2966,7 @@ prepare_inplace_alter_table_dict(
}
error = row_create_table_for_mysql(
- ctx->new_table, ctx->trx, false, mode, key_id);
+ ctx->new_table, ctx->trx, false);
switch (error) {
dict_table_t* temp_table;
@@ -2989,7 +2979,7 @@ prepare_inplace_alter_table_dict(
ut_ad(mutex_own(&dict_sys->mutex));
temp_table = dict_table_open_on_name(
ctx->new_table->name, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
ut_a(ctx->new_table == temp_table);
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
@@ -3505,7 +3495,8 @@ ha_innobase::prepare_inplace_alter_table(
user_thd, altered_table,
ha_alter_info->create_info,
prebuilt->table->space != 0,
- srv_file_format)) {
+ srv_file_format,
+ prebuilt->table->table_options)) {
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
table_type(), invalid_tbopt);
goto err_exit_no_heap;
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index e124cb98f99..0581d2786dc 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyrigth (c) 2014, 2015, MariaDB Corporation
+Copyrigth (c) 2014, 2016, 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
@@ -57,6 +57,7 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
#include "ibuf0ibuf.h"
#include "dict0mem.h"
#include "dict0types.h"
+#include "dict0tableoptions.h"
#include "ha_prototypes.h"
#include "srv0start.h"
#include "srv0srv.h"
@@ -2938,7 +2939,7 @@ i_s_fts_deleted_generic_fill(
deleted = fts_doc_ids_create();
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -3336,7 +3337,7 @@ i_s_fts_index_cache_fill(
}
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -3776,7 +3777,7 @@ i_s_fts_index_table_fill(
}
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -3926,7 +3927,7 @@ i_s_fts_config_fill(
fields = table->field;
user_table = dict_table_open_on_name(
- fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (!user_table) {
DBUG_RETURN(0);
@@ -9391,8 +9392,6 @@ static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
END_OF_ST_FIELD_INFO
};
-
-
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS
@return 0 on success */
@@ -9587,3 +9586,229 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_changed_page_bitmaps =
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA),
};
+/** SYS_TABLE_OPTIONS ************************************************/
+/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLE_OPTIONS */
+static ST_FIELD_INFO innodb_sys_tableoptions_fields_info[] =
+{
+ // SYS_TABLE_OPTIONS_TABLE_ID 0
+ {STRUCT_FLD(field_name, "TABLE_ID"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_PAGE_COMPRESSED 1
+ {STRUCT_FLD(field_name, "PAGE_COMPRESSED"),
+ STRUCT_FLD(field_length, 7),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_PAGE_COMPRESSION_LEVEL 2
+ {STRUCT_FLD(field_name, "PAGE_COMPRESSION_LEVEL"),
+ STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_ATOMIC_WRITES 3
+ {STRUCT_FLD(field_name, "ATOMIC_WRITES"),
+ STRUCT_FLD(field_length, 9),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_ENCRYPTED 4
+ {STRUCT_FLD(field_name, "ENCRYPTED"),
+ STRUCT_FLD(field_length, 9),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ // SYS_TABLE_OPTIONS_ENCRYPTION_KEY_ID 5
+ {STRUCT_FLD(field_name, "ENCRYPTION_KEY_ID"),
+ STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+
+/*******************************************************************//**
+Function to go through each record in SYS_TABLE_OPTIONS table, and fill the
+information_schema.innodb_sys_table_options table with related table information
+@return 0 on success */
+static
+int
+i_s_dict_fill_sys_table_options(
+/*============================*/
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ Item* ) /*!< in: condition (not used) */
+{
+ btr_pcur_t pcur;
+ const rec_t* rec;
+ mem_heap_t* heap;
+ mtr_t mtr;
+
+ DBUG_ENTER("i_s_sys_table_options_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
+ /* deny access to user without PROCESS_ACL privilege */
+ if (check_global_access(thd, PROCESS_ACL, true)) {
+ DBUG_RETURN(0);
+ }
+
+ heap = mem_heap_create(1000);
+ mutex_enter(&(dict_sys->mutex));
+ mtr_start(&mtr);
+
+ rec = dict_startscan_system(&pcur, &mtr, SYS_TABLE_OPTIONS);
+
+ while (rec) {
+ const char* err_msg;
+ dict_tableoptions_t options;
+
+ /* Create and populate a dict_tableoptions_t structure with
+ information from SYS_TABLE_OPTIONS row */
+ memset(&options, 0, sizeof(dict_tableoptions_t));
+
+ err_msg = dict_process_sys_tableoptions(
+ heap, rec, &options);
+
+ mtr_commit(&mtr);
+ mutex_exit(&dict_sys->mutex);
+
+ if (!err_msg) {
+ Field** fields = tables->table->field;
+
+ OK(fields[SYS_TABLE_OPTIONS_TABLE_ID]->store((longlong) options.table_id));
+ OK(fields[SYS_TABLE_OPTIONS_PAGE_COMPRESSION_LEVEL]->store((ulint)options.page_compression_level));
+ OK(fields[SYS_TABLE_OPTIONS_ENCRYPTION_KEY_ID]->store((ulint)options.encryption_key_id));
+
+ if (options.page_compressed) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_PAGE_COMPRESSED], "YES"));
+ } else {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_PAGE_COMPRESSED], "NO"));
+ }
+
+ if (options.encryption == FIL_SPACE_ENCRYPTION_DEFAULT) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ENCRYPTED], "DEFAULT"));
+ } else if (options.encryption == FIL_SPACE_ENCRYPTION_ON) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ENCRYPTED], "ON"));
+ } else {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ENCRYPTED], "OFF"));
+ }
+
+ if (options.atomic_writes == ATOMIC_WRITES_DEFAULT) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ATOMIC_WRITES], "DEFAULT"));
+ } else if (options.atomic_writes == ATOMIC_WRITES_ON) {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ATOMIC_WRITES], "ON"));
+ } else {
+ OK(field_store_string(fields[SYS_TABLE_OPTIONS_ATOMIC_WRITES], "OFF"));
+ }
+
+ OK(schema_table_store_record(thd, tables->table));
+
+ } else {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_CANT_FIND_SYSTEM_REC, "%s",
+ err_msg);
+ }
+
+ mem_heap_empty(heap);
+
+ /* Get the next record */
+ mutex_enter(&dict_sys->mutex);
+ mtr_start(&mtr);
+ rec = dict_getnext_system(&pcur, &mtr);
+ }
+
+ mtr_commit(&mtr);
+ mutex_exit(&dict_sys->mutex);
+ mem_heap_free(heap);
+
+ DBUG_RETURN(0);
+}
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLE_OPTIONS
+@return 0 on success */
+static
+int
+innodb_sys_table_options_init(
+/*============================*/
+ void* p) /*!< in/out: table schema object */
+{
+ ST_SCHEMA_TABLE* schema;
+
+ DBUG_ENTER("innodb_sys_table_options_init");
+
+ schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = innodb_sys_tableoptions_fields_info;
+ schema->fill_table = i_s_dict_fill_sys_table_options;
+
+ DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_table_options =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_SYS_TABLE_OPTIONS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, maria_plugin_author),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB SYS_TABLE_OPTIONS"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, innodb_sys_table_options_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ /* unsigned int */
+ STRUCT_FLD(version, INNODB_VERSION_SHORT),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* Maria extension */
+ STRUCT_FLD(version_info, INNODB_VERSION_STR),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA),
+};
diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h
index 55ef6e7ea42..857dfc52817 100644
--- a/storage/xtradb/handler/i_s.h
+++ b/storage/xtradb/handler/i_s.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyrigth (c) 2014, 2015, MariaDB Corporation
+Copyrigth (c) 2014, 2016, 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
@@ -68,6 +68,7 @@ extern struct st_maria_plugin i_s_innodb_tablespaces_encryption;
extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing;
extern struct st_mysql_plugin i_s_innodb_sys_semaphore_waits;
extern struct st_mysql_plugin i_s_innodb_changed_page_bitmaps;
+extern struct st_mysql_plugin i_s_innodb_sys_table_options;
/** maximum number of buffer page info we would cache. */
#define MAX_BUF_INFO_CACHED 10000
@@ -135,6 +136,14 @@ HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
+/** Fields on INFORMATION_SCHEMA.SYS_TABLE_OPTIONS table */
+#define SYS_TABLE_OPTIONS_TABLE_ID 0
+#define SYS_TABLE_OPTIONS_PAGE_COMPRESSED 1
+#define SYS_TABLE_OPTIONS_PAGE_COMPRESSION_LEVEL 2
+#define SYS_TABLE_OPTIONS_ATOMIC_WRITES 3
+#define SYS_TABLE_OPTIONS_ENCRYPTED 4
+#define SYS_TABLE_OPTIONS_ENCRYPTION_KEY_ID 5
+
/*******************************************************************//**
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
If the value is ULINT_UNDEFINED then the field it set to NULL.
diff --git a/storage/xtradb/include/dict0boot.h b/storage/xtradb/include/dict0boot.h
index a994c9d8ff1..cb47f7750a7 100644
--- a/storage/xtradb/include/dict0boot.h
+++ b/storage/xtradb/include/dict0boot.h
@@ -325,6 +325,29 @@ enum dict_fld_sys_datafiles_enum {
DICT_NUM_FIELDS__SYS_DATAFILES = 4
};
+/* The columns in SYS_TABLE_OPTIONS */
+enum dict_col_sys_tableoptions_enum {
+ DICT_COL__SYS_TABLEOPTIONS__TABLE_ID = 0,
+ DICT_COL__SYS_TABLEOPTIONS__PAGE_COMPRESSED = 1,
+ DICT_COL__SYS_TABLEOPTIONS__PAGE_COMPRESSION_LEVEL = 2,
+ DICT_COL__SYS_TABLEOPTIONS__ATOMIC_WRITES = 3,
+ DICT_COL__SYS_TABLEOPTIONS__ENCRYPTED = 4,
+ DICT_COL__SYS_TABLEOPTIONS__ENCRYPTION_KEY_ID = 5,
+ DICT_NUM_COLS__SYS_TABLEOPTIONS = 6
+};
+/* The field numbers in the SYS_TABLE_OPTIONS clustered index */
+enum dict_fld_sys_tableoptions_enum {
+ DICT_FLD__SYS_TABLEOPTIONS__TABLE_ID = 0,
+ DICT_FLD__SYS_TABLEOPTIONS__DB_TRX_ID = 1,
+ DICT_FLD__SYS_TABLEOPTIONS__DB_ROLL_PTR = 2,
+ DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSED = 3,
+ DICT_FLD__SYS_TABLEOPTIONS__PAGE_COMPRESSION_LEVEL = 4,
+ DICT_FLD__SYS_TABLEOPTIONS__ATOMIC_WRITES = 5,
+ DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTED = 6,
+ DICT_FLD__SYS_TABLEOPTIONS__ENCRYPTION_KEY_ID = 7,
+ DICT_NUM_FIELDS__SYS_TABLEOPTIONS = 8
+};
+
/* A number of the columns above occur in multiple tables. These are the
length of thos fields. */
#define DICT_FLD_LEN_SPACE 4
diff --git a/storage/xtradb/include/dict0crea.h b/storage/xtradb/include/dict0crea.h
index 3b746fcf83c..0b3a9f86213 100644
--- a/storage/xtradb/include/dict0crea.h
+++ b/storage/xtradb/include/dict0crea.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -44,10 +45,8 @@ tab_create_graph_create(
dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
mem_heap_t* heap, /*!< in: heap where created */
- bool commit, /*!< in: true if the commit node should be
+ bool commit);/*!< in: true if the commit node should be
added to the query graph */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id);/*!< in: encryption key_id */
/*********************************************************************//**
Creates an index create graph.
@return own: index create node */
@@ -194,6 +193,17 @@ dict_create_add_foreign_to_dictionary(
trx_t* trx) /*!< in/out: dictionary transaction */
__attribute__((nonnull, warn_unused_result));
+/****************************************************************//**
+Creates the sys_table_options system tables inside InnoDB
+at server bootstrap or server start if it is not found or is
+not of the right form.
+@return DB_SUCCESS or error code */
+UNIV_INTERN
+dberr_t
+dict_create_or_check_sys_table_options(void)
+/*========================================*/
+__attribute__((warn_unused_result));
+
/* Table create node structure */
struct tab_node_t{
que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */
@@ -212,8 +222,6 @@ struct tab_node_t{
/* Local storage for this graph node */
ulint state; /*!< node execution state */
ulint col_no; /*!< next column definition to insert */
- ulint key_id; /*!< encryption key_id */
- fil_encryption_t mode; /*!< encryption mode */
mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 2b73efaabc7..d51a1a714d8 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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
@@ -44,6 +44,7 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#include "row0types.h"
#include "fsp0fsp.h"
+#include "dict0tableoptions.h"
#include "dict0pagecompress.h"
extern bool innodb_table_stats_not_found;
@@ -568,9 +569,12 @@ dict_table_open_on_name(
indexes after an aborted online
index creation */
dict_err_ignore_t
- ignore_err) /*!< in: error to be ignored when
+ ignore_err, /*!< in: error to be ignored when
loading the table */
- __attribute__((nonnull, warn_unused_result));
+ dict_tableoptions_t* options)
+ /*!< in: table options */
+
+ __attribute__((warn_unused_result));
/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
@@ -944,15 +948,8 @@ dict_tf_set(
ulint* flags, /*!< in/out: table */
rec_format_t format, /*!< in: file format */
ulint zip_ssize, /*!< in: zip shift size */
- bool remote_path, /*!< in: table uses DATA DIRECTORY
+ bool remote_path); /*!< in: table uses DATA DIRECTORY
*/
- bool page_compressed,/*!< in: table uses page compressed
- pages */
- ulint page_compression_level, /*!< in: table page compression
- level */
- ulint atomic_writes) /*!< in: table atomic
- writes option value*/
- __attribute__((nonnull));
/********************************************************************//**
Convert a 32 bit integer table flags to the 32 bit integer that is
written into the tablespace header at the offset FSP_SPACE_FLAGS and is
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 2f9fc3bcfe6..4fd2430a8bb 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2015, MariaDB
+Copyright (c) 2013, 2016, 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
@@ -538,10 +538,7 @@ dict_tf_is_valid(
ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(flags);
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(flags);
ulint unused = DICT_TF_GET_UNUSED(flags);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags);
ulint data_dir = DICT_TF_HAS_DATA_DIR(flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(flags);
/* Make sure there are no bits that we do not know about. */
if (unused != 0) {
@@ -551,12 +548,9 @@ dict_tf_is_valid(
" in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
unused,
- compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
@@ -573,11 +567,8 @@ dict_tf_is_valid(
" in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- compact, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
+ compact, compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
@@ -591,11 +582,8 @@ dict_tf_is_valid(
" in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- flags, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
+ flags, compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
@@ -614,59 +602,15 @@ dict_tf_is_valid(
"InnoDB: Error: table compact flags are %ld in the data dictionary and are corrupted\n"
"InnoDB: Error: data dictionary flags are\n"
"InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
+ "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n",
flags,
- compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
-
- );
- return(false);
- }
- }
-
- if (page_compression || page_compression_level) {
- /* Page compression format must have compact and
- atomic_blobs and page_compression_level requires
- page_compression */
- if (!compact
- || !page_compression
- || !atomic_blobs) {
-
- fprintf(stderr,
- "InnoDB: Error: table flags are %ld in the data dictionary and are corrupted\n"
- "InnoDB: Error: data dictionary flags are\n"
- "InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- flags, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
+ compact, atomic_blobs, unused, data_dir, zip_ssize
);
return(false);
}
}
- if (atomic_writes) {
-
- if(atomic_writes > ATOMIC_WRITES_OFF) {
-
- fprintf(stderr,
- "InnoDB: Error: table flags are %ld in the data dictionary and are corrupted\n"
- "InnoDB: Error: data dictionary flags are\n"
- "InnoDB: compact %ld atomic_blobs %ld\n"
- "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n"
- "InnoDB: page_compression %ld page_compression_level %ld\n"
- "InnoDB: atomic_writes %ld\n",
- flags, compact, atomic_blobs, unused, data_dir, zip_ssize,
- page_compression, page_compression_level, atomic_writes
- );
- return(false);
- }
- }
-
/* CREATE TABLE ... DATA DIRECTORY is supported for any row format,
so the DATA_DIR flag is compatible with all other table flags. */
@@ -689,11 +633,7 @@ dict_sys_tables_type_validate(
ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(type);
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(type);
ulint unused = DICT_TF_GET_UNUSED(type);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(type);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(type);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(type);
-
- ut_a(atomic_writes <= ATOMIC_WRITES_OFF);
+ ulint unused_mariadb = DICT_TF_GET_UNUSED_MARIADB(type);
/* The low order bit of SYS_TABLES.TYPE is always set to 1.
If the format is UNIV_FORMAT_B or higher, this field is the same
@@ -712,9 +652,12 @@ dict_sys_tables_type_validate(
/* Make sure there are no bits that we do not know about. */
if (unused) {
- fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, unused %lu\n",
- type, unused);
- return(ULINT_UNDEFINED);
+ /* We deal the MariaDB extended dictionary flags at ::open() */
+ if (unused_mariadb) {
+ fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, unused %lu\n",
+ type, unused);
+ return(ULINT_UNDEFINED);
+ }
}
if (atomic_blobs) {
@@ -757,27 +700,6 @@ dict_sys_tables_type_validate(
format, so the DATA_DIR flag is compatible with any other
table flags. However, it is not used with TEMPORARY tables.*/
- if (page_compression || page_compression_level) {
- /* page compressed row format must have low_order_bit and
- atomic_blobs bits set and the DICT_N_COLS_COMPACT flag
- should be in N_COLS, but we already know about the
- low_order_bit and DICT_N_COLS_COMPACT flags. */
-
- if (!atomic_blobs || !page_compression) {
- fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, page_compression %lu page_compression_level %lu\n"
- "InnoDB: Error: atomic_blobs %lu\n",
- type, page_compression, page_compression_level, atomic_blobs);
- return(ULINT_UNDEFINED);
- }
- }
-
- /* Validate that the atomic writes number is within allowed range. */
- if (atomic_writes > ATOMIC_WRITES_OFF) {
- fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, atomic_writes %lu\n",
- type, atomic_writes);
- return(ULINT_UNDEFINED);
- }
-
/* Return the validated SYS_TABLES.TYPE. */
return(type);
}
@@ -850,16 +772,9 @@ dict_tf_set(
ulint* flags, /*!< in/out: table flags */
rec_format_t format, /*!< in: file format */
ulint zip_ssize, /*!< in: zip shift size */
- bool use_data_dir, /*!< in: table uses DATA DIRECTORY
+ bool use_data_dir) /*!< in: table uses DATA DIRECTORY
*/
- bool page_compressed,/*!< in: table uses page compressed
- pages */
- ulint page_compression_level, /*!< in: table page compression
- level */
- ulint atomic_writes) /*!< in: table atomic writes setup */
{
- atomic_writes_t awrites = (atomic_writes_t)atomic_writes;
-
switch (format) {
case REC_FORMAT_REDUNDANT:
*flags = 0;
@@ -884,19 +799,6 @@ dict_tf_set(
if (use_data_dir) {
*flags |= (1 << DICT_TF_POS_DATA_DIR);
}
-
- if (page_compressed) {
- *flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
- | (1 << DICT_TF_POS_PAGE_COMPRESSION)
- | (page_compression_level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL);
-
- ut_ad(zip_ssize == 0);
- ut_ad(dict_tf_get_page_compression(*flags) == TRUE);
- ut_ad(dict_tf_get_page_compression_level(*flags) == page_compression_level);
- }
-
- *flags |= (atomic_writes << DICT_TF_POS_ATOMIC_WRITES);
- ut_a(dict_tf_get_atomic_writes(*flags) == awrites);
}
/********************************************************************//**
@@ -917,9 +819,6 @@ dict_tf_to_fsp_flags(
ulint table_flags) /*!< in: dict_table_t::flags */
{
ulint fsp_flags;
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
return(ULINT_UNDEFINED););
@@ -938,18 +837,6 @@ dict_tf_to_fsp_flags(
fsp_flags |= DICT_TF_HAS_DATA_DIR(table_flags)
? FSP_FLAGS_MASK_DATA_DIR : 0;
- /* In addition, tablespace flags also contain if the page
- compression is used for this table. */
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(fsp_flags, page_compression);
-
- /* In addition, tablespace flags also contain page compression level
- if page compression is used for this table. */
- fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level);
-
- /* In addition, tablespace flags also contain flag if atomic writes
- is used for this table */
- fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes);
-
ut_a(fsp_flags_is_valid(fsp_flags));
ut_a(dict_tf_verify_flags(table_flags, fsp_flags));
@@ -984,10 +871,6 @@ dict_sys_tables_type_to_tf(
flags |= type & (DICT_TF_MASK_ZIP_SSIZE
| DICT_TF_MASK_ATOMIC_BLOBS
| DICT_TF_MASK_DATA_DIR
- | DICT_TF_MASK_PAGE_COMPRESSION
- | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL
- | DICT_TF_MASK_ATOMIC_WRITES
-
);
return(flags);
@@ -1016,14 +899,10 @@ dict_tf_to_sys_tables_type(
/* Adjust bit zero. It is always 1 in SYS_TABLES.TYPE */
type = 1;
- /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION,
- PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES are the same. */
+ /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR are the same. */
type |= flags & (DICT_TF_MASK_ZIP_SSIZE
| DICT_TF_MASK_ATOMIC_BLOBS
- | DICT_TF_MASK_DATA_DIR
- | DICT_TF_MASK_PAGE_COMPRESSION
- | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL
- | DICT_TF_MASK_ATOMIC_WRITES);
+ | DICT_TF_MASK_DATA_DIR);
return(type);
}
diff --git a/storage/xtradb/include/dict0load.h b/storage/xtradb/include/dict0load.h
index 030190b1a8e..1b67f054e55 100644
--- a/storage/xtradb/include/dict0load.h
+++ b/storage/xtradb/include/dict0load.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -44,6 +45,7 @@ enum dict_system_id_t {
SYS_FOREIGN_COLS,
SYS_TABLESPACES,
SYS_DATAFILES,
+ SYS_TABLE_OPTIONS,
/* This must be last item. Defines the number of system tables. */
SYS_NUM_SYSTEM_TABLES
@@ -201,9 +203,11 @@ dict_load_table(
const char* name, /*!< in: table name in the
databasename/tablename format */
ibool cached, /*!< in: TRUE=add to cache, FALSE=do not */
- dict_err_ignore_t ignore_err);
+ dict_err_ignore_t ignore_err,
/*!< in: error to be ignored when loading
table and its indexes' definition */
+ dict_tableoptions_t* options);
+ /*!< in: table options */
/***********************************************************************//**
Loads a table object based on the table id.
@return table; NULL if table does not exist */
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 9c43829cecf..f069ed31ced 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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
@@ -61,6 +61,7 @@ Created 1/8/1996 Heikki Tuuri
/* Forward declaration. */
struct ib_rbt_t;
+struct dict_tableoptions_t;
/** Type flags of an index: OR'ing of the flags is allowed to define a
combination of types */
@@ -134,34 +135,11 @@ This flag prevents older engines from attempting to open the table and
allows InnoDB to update_create_info() accordingly. */
#define DICT_TF_WIDTH_DATA_DIR 1
-/**
-Width of the page compression flag
-*/
-#define DICT_TF_WIDTH_PAGE_COMPRESSION 1
-#define DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL 4
-
-/**
-Width of the page encryption flag
-*/
-#define DICT_TF_WIDTH_PAGE_ENCRYPTION 1
-#define DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY 8
-
-/**
-Width of atomic writes flag
-DEFAULT=0, ON = 1, OFF = 2
-*/
-#define DICT_TF_WIDTH_ATOMIC_WRITES 2
-
/** Width of all the currently known table flags */
#define DICT_TF_BITS (DICT_TF_WIDTH_COMPACT \
+ DICT_TF_WIDTH_ZIP_SSIZE \
+ DICT_TF_WIDTH_ATOMIC_BLOBS \
- + DICT_TF_WIDTH_DATA_DIR \
- + DICT_TF_WIDTH_PAGE_COMPRESSION \
- + DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL \
- + DICT_TF_WIDTH_ATOMIC_WRITES \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)
+ + DICT_TF_WIDTH_DATA_DIR)
/** A mask of all the known/used bits in table flags */
#define DICT_TF_BIT_MASK (~(~0 << DICT_TF_BITS))
@@ -177,26 +155,13 @@ DEFAULT=0, ON = 1, OFF = 2
/** Zero relative shift position of the DATA_DIR field */
#define DICT_TF_POS_DATA_DIR (DICT_TF_POS_ATOMIC_BLOBS \
+ DICT_TF_WIDTH_ATOMIC_BLOBS)
-/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define DICT_TF_POS_PAGE_COMPRESSION (DICT_TF_POS_DATA_DIR \
- + DICT_TF_WIDTH_DATA_DIR)
-/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
-#define DICT_TF_POS_PAGE_COMPRESSION_LEVEL (DICT_TF_POS_PAGE_COMPRESSION \
- + DICT_TF_WIDTH_PAGE_COMPRESSION)
-/** Zero relative shift position of the ATOMIC_WRITES field */
-#define DICT_TF_POS_ATOMIC_WRITES (DICT_TF_POS_PAGE_COMPRESSION_LEVEL \
- + DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL)
-
-/** Zero relative shift position of the PAGE_ENCRYPTION field */
-#define DICT_TF_POS_PAGE_ENCRYPTION (DICT_TF_POS_ATOMIC_WRITES \
- + DICT_TF_WIDTH_ATOMIC_WRITES)
-/** Zero relative shift position of the PAGE_ENCRYPTION_KEY field */
-#define DICT_TF_POS_PAGE_ENCRYPTION_KEY (DICT_TF_POS_PAGE_ENCRYPTION \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION)
/** Zero relative shift position of the start of the UNUSED bits */
-#define DICT_TF_POS_UNUSED (DICT_TF_POS_PAGE_ENCRYPTION_KEY \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)
+#define DICT_TF_POS_UNUSED (DICT_TF_POS_DATA_DIR \
+ + DICT_TF_WIDTH_DATA_DIR)
+/** Zero relative shift position of the start of the UNUSED bits */
+#define DICT_TF_POS_UNUSED_MARIADB (DICT_TF_POS_DATA_DIR \
+ + 1 + 1 + 4 + 1 + 8 + 2)
/** Bit mask of the COMPACT field */
#define DICT_TF_MASK_COMPACT \
((~(~0 << DICT_TF_WIDTH_COMPACT)) \
@@ -213,27 +178,6 @@ DEFAULT=0, ON = 1, OFF = 2
#define DICT_TF_MASK_DATA_DIR \
((~(~0 << DICT_TF_WIDTH_DATA_DIR)) \
<< DICT_TF_POS_DATA_DIR)
-/** Bit mask of the PAGE_COMPRESSION field */
-#define DICT_TF_MASK_PAGE_COMPRESSION \
- ((~(~0 << DICT_TF_WIDTH_PAGE_COMPRESSION)) \
- << DICT_TF_POS_PAGE_COMPRESSION)
-/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
-#define DICT_TF_MASK_PAGE_COMPRESSION_LEVEL \
- ((~(~0 << DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL)) \
- << DICT_TF_POS_PAGE_COMPRESSION_LEVEL)
-/** Bit mask of the ATOMIC_WRITES field */
-#define DICT_TF_MASK_ATOMIC_WRITES \
- ((~(~0 << DICT_TF_WIDTH_ATOMIC_WRITES)) \
- << DICT_TF_POS_ATOMIC_WRITES)
-/** Bit mask of the PAGE_ENCRYPTION field */
-#define DICT_TF_MASK_PAGE_ENCRYPTION \
- ((~(~0L << DICT_TF_WIDTH_PAGE_ENCRYPTION)) \
- << DICT_TF_POS_PAGE_ENCRYPTION)
-/** Bit mask of the PAGE_ENCRYPTION_KEY field */
-#define DICT_TF_MASK_PAGE_ENCRYPTION_KEY \
- ((~(~0L << DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)) \
- << DICT_TF_POS_PAGE_ENCRYPTION_KEY)
-
/** Return the value of the COMPACT field */
#define DICT_TF_GET_COMPACT(flags) \
((flags & DICT_TF_MASK_COMPACT) \
@@ -246,37 +190,17 @@ DEFAULT=0, ON = 1, OFF = 2
#define DICT_TF_HAS_ATOMIC_BLOBS(flags) \
((flags & DICT_TF_MASK_ATOMIC_BLOBS) \
>> DICT_TF_POS_ATOMIC_BLOBS)
-/** Return the value of the ATOMIC_BLOBS field */
+/** Return the value of the HAS_DATA_DIR field */
#define DICT_TF_HAS_DATA_DIR(flags) \
((flags & DICT_TF_MASK_DATA_DIR) \
>> DICT_TF_POS_DATA_DIR)
-
-/** Return the contents of the PAGE_ENCRYPTION field */
-#define DICT_TF_GET_PAGE_ENCRYPTION(flags) \
- ((flags & DICT_TF_MASK_PAGE_ENCRYPTION) \
- >> DICT_TF_POS_PAGE_ENCRYPTION)
-/** Return the contents of the PAGE_ENCRYPTION KEY field */
-#define DICT_TF_GET_PAGE_ENCRYPTION_KEY(flags) \
- ((flags & DICT_TF_MASK_PAGE_ENCRYPTION_KEY) \
- >> DICT_TF_POS_PAGE_ENCRYPTION_KEY)
-
-
/** Return the contents of the UNUSED bits */
#define DICT_TF_GET_UNUSED(flags) \
(flags >> DICT_TF_POS_UNUSED)
+/** Return the contents of the UNUSED bits */
+#define DICT_TF_GET_UNUSED_MARIADB(flags) \
+ (flags >> DICT_TF_POS_UNUSED_MARIADB)
-/** Return the value of the PAGE_COMPRESSION field */
-#define DICT_TF_GET_PAGE_COMPRESSION(flags) \
- ((flags & DICT_TF_MASK_PAGE_COMPRESSION) \
- >> DICT_TF_POS_PAGE_COMPRESSION)
-/** Return the value of the PAGE_COMPRESSION_LEVEL field */
-#define DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags) \
- ((flags & DICT_TF_MASK_PAGE_COMPRESSION_LEVEL) \
- >> DICT_TF_POS_PAGE_COMPRESSION_LEVEL)
-/** Return the value of the ATOMIC_WRITES field */
-#define DICT_TF_GET_ATOMIC_WRITES(flags) \
- ((flags & DICT_TF_MASK_ATOMIC_WRITES) \
- >> DICT_TF_POS_ATOMIC_WRITES)
/* @} */
#ifndef UNIV_INNOCHECKSUM
@@ -1035,6 +959,7 @@ struct dict_table_t{
char* name; /*!< table name */
void* thd; /*!< thd */
fil_space_crypt_t *crypt_data; /*!< crypt data if present */
+ dict_tableoptions_t* table_options; /*!< table options */
const char* dir_path_of_temp_table;/*!< NULL or the directory path
where a TEMPORARY table that was explicitly
created by a user should be placed if
diff --git a/storage/xtradb/include/dict0pagecompress.h b/storage/xtradb/include/dict0pagecompress.h
index 19a2a6c52f3..16678c938a9 100644
--- a/storage/xtradb/include/dict0pagecompress.h
+++ b/storage/xtradb/include/dict0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (C) 2013,2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,25 +28,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
#define dict0pagecompress_h
/********************************************************************//**
-Extract the page compression level from table flags.
-@return page compression level, or 0 if not compressed */
-UNIV_INLINE
-ulint
-dict_tf_get_page_compression_level(
-/*===============================*/
- ulint flags) /*!< in: flags */
- __attribute__((const));
-/********************************************************************//**
-Extract the page compression flag from table flags
-@return page compression flag, or false if not compressed */
-UNIV_INLINE
-ibool
-dict_tf_get_page_compression(
-/*==========================*/
- ulint flags) /*!< in: flags */
- __attribute__((const));
-
-/********************************************************************//**
Check whether the table uses the page compressed page format.
@return page compression level, or 0 if not compressed */
UNIV_INLINE
@@ -68,16 +49,6 @@ dict_tf_verify_flags(
__attribute__((const));
/********************************************************************//**
-Extract the atomic writes flag from table flags.
-@return true if atomic writes are used, false if not used */
-UNIV_INLINE
-atomic_writes_t
-dict_tf_get_atomic_writes(
-/*======================*/
- ulint flags) /*!< in: flags */
- __attribute__((const));
-
-/********************************************************************//**
Check whether the table uses the atomic writes.
@return true if atomic writes is used, false if not */
UNIV_INLINE
diff --git a/storage/xtradb/include/dict0pagecompress.ic b/storage/xtradb/include/dict0pagecompress.ic
index 811976434a8..935af5e7c2b 100644
--- a/storage/xtradb/include/dict0pagecompress.ic
+++ b/storage/xtradb/include/dict0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
+Copyright (C) 2013,2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -39,17 +39,11 @@ dict_tf_verify_flags(
ulint ssize = DICT_TF_GET_ZIP_SSIZE(table_flags);
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table_flags);
ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags);
- ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
- ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags);
ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags);
ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags);
ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags);
- ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
- ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
- ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags);
DBUG_EXECUTE_IF("dict_tf_verify_flags_failure",
return(ULINT_UNDEFINED););
@@ -78,56 +72,11 @@ dict_tf_verify_flags(
return (FALSE);
}
- if (page_compression != fsp_page_compression) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file ahas page_compression %ld\n",
- page_compression, fsp_page_compression);
-
- return (FALSE);
- }
- if (page_compression_level != fsp_page_compression_level) {
- fprintf(stderr,
- "InnoDB: Error: table flags has page_compression_level %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has page_compression_level %ld\n",
- page_compression_level, fsp_page_compression_level);
-
- return (FALSE);
- }
-
- if (atomic_writes != fsp_atomic_writes) {
- fprintf(stderr,
- "InnoDB: Error: table flags has atomic writes %ld"
- " in the data dictionary\n"
- "InnoDB: but the flags in file has atomic_writes %ld\n",
- atomic_writes, fsp_atomic_writes);
-
- return (FALSE);
- }
return(TRUE);
}
/********************************************************************//**
-Extract the page compression level from dict_table_t::flags.
-These flags are in memory, so assert that they are valid.
-@return page compression level, or 0 if not compressed */
-UNIV_INLINE
-ulint
-dict_tf_get_page_compression_level(
-/*===============================*/
- ulint flags) /*!< in: flags */
-{
- ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags);
-
- ut_ad(page_compression_level <= 9);
-
- return(page_compression_level);
-}
-
-/********************************************************************//**
Check whether the table uses the page compression page format.
@return page compression level, or 0 if not compressed */
UNIV_INLINE
@@ -137,21 +86,8 @@ dict_table_page_compression_level(
const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
- ut_ad(dict_tf_get_page_compression(table->flags));
- return(dict_tf_get_page_compression_level(table->flags));
-}
-
-/********************************************************************//**
-Check whether the table uses the page compression page format.
-@return true if page compressed, false if not */
-UNIV_INLINE
-ibool
-dict_tf_get_page_compression(
-/*=========================*/
- ulint flags) /*!< in: flags */
-{
- return(DICT_TF_GET_PAGE_COMPRESSION(flags));
+ return(table->table_options->page_compression_level);
}
/********************************************************************//**
@@ -163,19 +99,9 @@ dict_table_is_page_compressed(
/*==========================*/
const dict_table_t* table) /*!< in: table */
{
- return (dict_tf_get_page_compression(table->flags));
-}
+ ut_ad(table);
-/********************************************************************//**
-Extract the atomic writes flag from table flags.
-@return enumerated value of atomic writes */
-UNIV_INLINE
-atomic_writes_t
-dict_tf_get_atomic_writes(
-/*======================*/
- ulint flags) /*!< in: flags */
-{
- return((atomic_writes_t)DICT_TF_GET_ATOMIC_WRITES(flags));
+ return (table->table_options->page_compressed);
}
/********************************************************************//**
@@ -187,5 +113,7 @@ dict_table_get_atomic_writes(
/*=========================*/
const dict_table_t* table) /*!< in: table */
{
- return ((atomic_writes_t)dict_tf_get_atomic_writes(table->flags));
+ ut_ad(table);
+
+ return (table->table_options->atomic_writes);
}
diff --git a/storage/xtradb/include/dict0priv.ic b/storage/xtradb/include/dict0priv.ic
index 983218af78a..e2eda1a301f 100644
--- a/storage/xtradb/include/dict0priv.ic
+++ b/storage/xtradb/include/dict0priv.ic
@@ -58,7 +58,7 @@ dict_table_get_low(
}
if (table == NULL) {
- table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE);
+ table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE, NULL);
}
ut_ad(!table || table->cached);
diff --git a/storage/xtradb/include/dict0tableoptions.h b/storage/xtradb/include/dict0tableoptions.h
new file mode 100644
index 00000000000..def0e39a01f
--- /dev/null
+++ b/storage/xtradb/include/dict0tableoptions.h
@@ -0,0 +1,127 @@
+/*****************************************************************************
+
+Copyright (c) 2016, 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
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**************************************************//**
+@file include/dict0tableoptions.h
+Definitions for the system table SYS_TABLE_OPTIONS
+
+Created 22/01/2006 Jan Lindström
+*******************************************************/
+
+#ifndef dict0tableoptions_h
+#define dict0tableoptions_h
+
+#include "univ.i"
+
+/** Data structure to hold contents of SYS_TABLE_OPTIONS */
+struct dict_tableoptions_t{
+ table_id_t table_id;
+ /* true if table page compressed */
+ bool page_compressed;
+ /* Used compression level if set */
+ ulonglong page_compression_level;
+ /* dict0types.h: ATOMIC_WRITES_DEFAULT, _ON, or _OFF */
+ atomic_writes_t atomic_writes;
+ /* fil0crypt.h: FIL_SPACE_ENCRYPTION_DEFAULT, _ON, or _OFF */
+ fil_encryption_t encryption;
+ /* Used encryption key identifier if set */
+ ulonglong encryption_key_id;
+ /* true if table options need to be stored */
+ bool need_stored;
+};
+
+/********************************************************************//**
+This function parses a SYS_TABLE_OPTIONS record, extracts necessary
+information from the record and returns it to the caller.
+@return error message or NULL if successfull */
+UNIV_INTERN
+const char*
+dict_process_sys_tableoptions(
+/*==========================*/
+ mem_heap_t* heap, /*!< in/out: heap memory */
+ const rec_t* rec, /*!< in: current SYS_TABLE_OPTIONS rec */
+ dict_tableoptions_t* table_options); /*!< out: table options */
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS based on table_id
+@return true if found, false if not found */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ table_id_t table_id, /*!< in: table id */
+ dict_tableoptions_t* options, /*!< out:table options */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Gets the table options from SYS_TABLE_OPTIONS
+@return true if found, false if not found */
+UNIV_INTERN
+bool
+dict_get_table_options(
+/*===================*/
+ dict_table_t* table, /*!< in/out: table */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Update the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_tableoptions(
+/*=====================*/
+ const dict_table_t* table); /*!< in: table object */
+
+/********************************************************************//**
+Insert record into SYS_TABLE_OPTIONS
+@return DB_SUCCESS if OK, dberr_t if the insert failed */
+UNIV_INTERN
+dberr_t
+dict_insert_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Update the table flags in SYS_TABLES.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_update_table_flags(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+/********************************************************************//**
+Delete the record in SYS_TABLE_OPTIONS.
+@return DB_SUCCESS if OK, dberr_t if the update failed */
+UNIV_INTERN
+dberr_t
+dict_delete_tableoptions(
+/*=====================*/
+ const dict_table_t* table, /*!< in: table object */
+ trx_t* trx, /*!< in: trx */
+ bool fixed); /*!< in: can we fix the
+ dictionary ? */
+
+#endif /* dict0tableoptions_h */
+
diff --git a/storage/xtradb/include/fil0crypt.ic b/storage/xtradb/include/fil0crypt.ic
index 0a1a60dfab8..56a3075ae7f 100644
--- a/storage/xtradb/include/fil0crypt.ic
+++ b/storage/xtradb/include/fil0crypt.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2015, MariaDB Corporation.
+Copyright (c) 2015, 2016, 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
@@ -17,7 +17,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
*****************************************************************************/
/**************************************************//**
-@file include/fil0fil.h
+@file include/fil0crypt.ic
The low-level file system encryption support functions
Created 04/01/2015 Jan Lindström
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 2a3995519a7..b1b3e0c1bcb 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, 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,6 +40,7 @@ Created 10/25/1995 Heikki Tuuri
#include "log0log.h"
#endif /* !UNIV_HOTBACKUP */
#include "trx0types.h"
+#include "my_crypt.h"
#include <list>
@@ -182,6 +183,8 @@ extern fil_addr_t fil_addr_null;
#define FIL_LOG 502 /*!< redo log */
/* @} */
+#include "fil0crypt.h"
+
/* structure containing encryption specification */
typedef struct fil_space_crypt_struct fil_space_crypt_t;
@@ -329,6 +332,7 @@ struct fil_space_t {
fil_space_crypt_t* crypt_data;
ulint file_block_size;/*!< file system block size */
ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
+ void* table_options;
};
/** Value of fil_space_t::magic_n */
@@ -466,12 +470,13 @@ UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- const char* name, /*!< in: space name */
- ulint id, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size, or
- 0 for uncompressed tablespaces */
- ulint purpose, /*!< in: FIL_TABLESPACE, or FIL_LOG if log */
- fil_space_crypt_t* crypt_data); /*!< in: crypt data */
+ const char* name, /*!< in: space name */
+ ulint id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size, or
+ 0 for uncompressed tablespaces */
+ ulint purpose, /*!< in: FIL_TABLESPACE, or FIL_LOG if log */
+ fil_space_crypt_t* crypt_data, /*!< in: crypt data */
+ const void* options); /*!< in: table options */
/*******************************************************************//**
Assigns a new space id for a new single-table tablespace. This works simply by
@@ -794,9 +799,8 @@ fil_create_new_single_table_tablespace(
ulint size, /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
- __attribute__((nonnull, warn_unused_result));
+ const dict_table_t* table) /*!< in: table */
+ __attribute__((warn_unused_result));
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
@@ -830,7 +834,8 @@ fil_open_single_table_tablespace(
const char* tablename, /*!< in: table name in the
databasename/tablename format */
const char* filepath, /*!< in: tablespace filepath */
- dict_table_t* table) /*!< in: table */
+ dict_table_t* table, /*!< in: table or NULL */
+ void* options)/*!< in: table options*/
__attribute__((nonnull(5), warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
@@ -1365,6 +1370,17 @@ fil_get_page_type_name(
/*===================*/
ulint page_type); /*!< in: FIL_PAGE_TYPE */
+/******************************************************************
+Parse a MLOG_FILE_WRITE_FSP_FLAGS log entry
+@return position on log buffer */
+UNIV_INTERN
+byte*
+fil_parse_write_fsp_flags(
+/*======================*/
+ byte* ptr, /*!< in: Log entry start */
+ byte* end_ptr,/*!< in: Log entry end */
+ buf_block_t* block); /*!< in: buffer block */
+
#ifndef UNIV_NONINL
#include "fil0fil.ic"
#endif
diff --git a/storage/xtradb/include/fil0pagecompress.h b/storage/xtradb/include/fil0pagecompress.h
index 8316083d52d..d5bfc934bb8 100644
--- a/storage/xtradb/include/fil0pagecompress.h
+++ b/storage/xtradb/include/fil0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015 MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -31,41 +31,58 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
***********************************************************************/
/*******************************************************************//**
-Returns the page compression level flag of the space, or 0 if the space
+Returns the page compression level of the space, or 0 if the space
is not compressed. The tablespace must be cached in the memory cache.
-@return page compression level if page compressed, ULINT_UNDEFINED if space not found */
-UNIV_INTERN
+@return page compression level, 0 if space not found */
+UNIV_INLINE
ulint
fil_space_get_page_compression_level(
/*=================================*/
- ulint id); /*!< in: space id */
+ fil_space_t* space); /*!< in: space */
/*******************************************************************//**
-Returns the page compression flag of the space, or false if the space
+Returns the page compression level of the space, or 0 if the space
is not compressed. The tablespace must be cached in the memory cache.
-@return true if page compressed, false if not or space not found */
-UNIV_INTERN
+@return page compression level, 0 if space not found */
+UNIV_INLINE
+ulint
+fil_space_get_page_compression_level(
+/*=================================*/
+ ulint space_id); /*!< in: space id*/
+/*******************************************************************//**
+Extract the page compression from space.
+@return true if space is page compressed, false if space is not found
+or space is not page compressed. */
+UNIV_INLINE
ibool
fil_space_is_page_compressed(
/*=========================*/
- ulint id); /*!< in: space id */
+ ulint space_id); /*!< in: space id*/
/*******************************************************************//**
-Returns the page compression flag of the space, or false if the space
-is not compressed. The tablespace must be cached in the memory cache.
-@return true if page compressed, false if not or space not found */
-UNIV_INTERN
+Extract the page compression from space.
+@return true if space is page compressed, false if space is not found
+or space is not page compressed. */
+UNIV_INLINE
ibool
-fil_space_get_page_compressed(
+fil_space_is_page_compressed(
/*=========================*/
- fil_space_t* space); /*!< in: space id */
+ fil_space_t* space); /*!< in: space */
+
/*******************************************************************//**
-Returns the atomic writes flag of the space, or false if the space
-is not using atomic writes. The tablespace must be cached in the memory cache.
-@return atomic write table option value */
-UNIV_INTERN
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
atomic_writes_t
fil_space_get_atomic_writes(
-/*=========================*/
- ulint id); /*!< in: space id */
+/*========================*/
+ fil_space_t* space); /*!< in: space */
+/*******************************************************************//**
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
+atomic_writes_t
+fil_space_get_atomic_writes(
+/*========================*/
+ ulint space_id); /*!< in: space id*/
/*******************************************************************//**
Find out wheather the page is index page or not
@return true if page type index page, false if not */
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index 8fdacc51277..9b306565080 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -54,22 +54,13 @@ to the two Barracuda row formats COMPRESSED and DYNAMIC. */
/** Width of the DATA_DIR flag. This flag indicates that the tablespace
is found in a remote location, not the default data directory. */
#define FSP_FLAGS_WIDTH_DATA_DIR 1
-/** Number of flag bits used to indicate the page compression and compression level */
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
-#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4
-
-/** Number of flag bits used to indicate atomic writes for this tablespace */
-#define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2
/** Width of all the currently known tablespace flags */
#define FSP_FLAGS_WIDTH (FSP_FLAGS_WIDTH_POST_ANTELOPE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE \
- + FSP_FLAGS_WIDTH_DATA_DIR \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES )
+ + FSP_FLAGS_WIDTH_DATA_DIR )
/** A mask of all the known/used bits in tablespace flags */
#define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH))
@@ -82,26 +73,29 @@ is found in a remote location, not the default data directory. */
/** Zero relative shift position of the ATOMIC_BLOBS field */
#define FSP_FLAGS_POS_ATOMIC_BLOBS (FSP_FLAGS_POS_ZIP_SSIZE \
+ FSP_FLAGS_WIDTH_ZIP_SSIZE)
-/** Note that these need to be before the page size to be compatible with
-dictionary */
-/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ATOMIC_BLOBS \
- + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
-/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
-/** Zero relative shift position of the ATOMIC_WRITES field */
-#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)
/** Zero relative shift position of the PAGE_SSIZE field */
-#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \
- + FSP_FLAGS_WIDTH_ATOMIC_WRITES)
+#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
/** Zero relative shift position of the start of the DATA DIR bits */
#define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE)
/** Zero relative shift position of the start of the UNUSED bits */
#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_DATA_DIR\
- + FSP_FLAGS_WIDTH_DATA_DIR)
+ + FSP_FLAGS_WIDTH_DATA_DIR)
+
+/** These are used only to set up the SYS_TABLE_OPTIONS */
+
+/** Zero relative shift position of the PAGE_SSIZE field */
+#define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ + 1 + 1 + 4 + 2)
+/** Bit mask of the PAGE_SSIZE field */
+#define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB \
+ ((~(~0 << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \
+ << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB)
+/** Return the value of the PAGE_SSIZE field */
+#define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB(flags) \
+ ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB) \
+ >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB)
/** Bit mask of the POST_ANTELOPE field */
#define FSP_FLAGS_MASK_POST_ANTELOPE \
@@ -123,18 +117,6 @@ dictionary */
#define FSP_FLAGS_MASK_DATA_DIR \
((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR)) \
<< FSP_FLAGS_POS_DATA_DIR)
-/** Bit mask of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
- ((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \
- << FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \
- ((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \
- << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Bit mask of the ATOMIC_WRITES field */
-#define FSP_FLAGS_MASK_ATOMIC_WRITES \
- ((~(~0 << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \
- << FSP_FLAGS_POS_ATOMIC_WRITES)
/** Return the value of the POST_ANTELOPE field */
#define FSP_FLAGS_GET_POST_ANTELOPE(flags) \
@@ -159,39 +141,11 @@ dictionary */
/** Return the contents of the UNUSED bits */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)
-/** Return the value of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION)
-/** Return the value of the PAGE_COMPRESSION_LEVEL field */
-#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \
- ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL) \
- >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)
-/** Return the value of the ATOMIC_WRITES field */
-#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \
- ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \
- >> FSP_FLAGS_POS_ATOMIC_WRITES)
/** Set a PAGE_SSIZE into the correct bits in a given
tablespace flags. */
#define FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize) \
(flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE))
-
-/** Set a PAGE_COMPRESSION into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION(flags, compression) \
- (flags | (compression << FSP_FLAGS_POS_PAGE_COMPRESSION))
-
-/** Set a PAGE_COMPRESSION_LEVEL into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \
- (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL))
-
-/** Set a ATOMIC_WRITES into the correct bits in a given
-tablespace flags. */
-#define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \
- (flags | (atomics << FSP_FLAGS_POS_ATOMIC_WRITES))
-
/* @} */
/* @defgroup Tablespace Header Constants (moved from fsp0fsp.c) @{ */
diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic
index ddcb87b0e57..193339c78e8 100644
--- a/storage/xtradb/include/fsp0fsp.ic
+++ b/storage/xtradb/include/fsp0fsp.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -64,9 +64,6 @@ fsp_flags_is_valid(
ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
ulint unused = FSP_FLAGS_GET_UNUSED(flags);
- ulint page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags);
- ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags);
- ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false););
@@ -124,23 +121,6 @@ fsp_flags_is_valid(
# error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations."
#endif
- /* Page compression level requires page compression and atomic blobs
- to be set */
- if (page_compression_level || page_compression) {
- if (!page_compression || !atomic_blobs) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_compression %lu\n"
- "InnoDB: Error: page_compression_level %lu atomic_blobs %lu\n",
- flags, page_compression, page_compression_level, atomic_blobs);
- return(false);
- }
- }
-
- if (atomic_writes > ATOMIC_WRITES_OFF) {
- fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_writes %lu\n",
- flags, atomic_writes);
- return (false);
- }
-
/* The DATA_DIR field can be used for any row type so there is
nothing here to validate. */
@@ -195,11 +175,24 @@ fsp_flags_get_page_size(
{
ulint page_size = 0;
ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
+ ulint psize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB(flags);
+
+ if (ssize && UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) {
+ ssize = psize;
+ }
/* Convert from a 'log2 minus 9' to a page size in bytes. */
if (UNIV_UNLIKELY(ssize)) {
page_size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize);
+ if (page_size > UNIV_PAGE_SIZE_MAX) {
+ if (psize) {
+ page_size = ((UNIV_ZIP_SIZE_MIN >> 1) << psize);
+ } else {
+ page_size = UNIV_PAGE_SIZE_ORIG;
+ }
+ }
+
ut_ad(page_size <= UNIV_PAGE_SIZE_MAX);
} else {
/* If the page size was not stored, then it is the
diff --git a/storage/xtradb/include/fsp0pagecompress.h b/storage/xtradb/include/fsp0pagecompress.h
index 5f943ee2b83..222c79a013f 100644
--- a/storage/xtradb/include/fsp0pagecompress.h
+++ b/storage/xtradb/include/fsp0pagecompress.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -47,36 +47,6 @@ fsp_header_get_compression_level(
/*=============================*/
const page_t* page); /*!< in: first page of a tablespace */
-/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not compressed */
-UNIV_INLINE
-ibool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags); /*!< in: tablespace flags */
-
-/********************************************************************//**
-Extract the page compression level from tablespace flags.
-A tablespace has only one physical page compression level
-whether that page is compressed or not.
-@return page compression level of the file-per-table tablespace,
-or zero if the table is not compressed. */
-UNIV_INLINE
-ulint
-fsp_flags_get_page_compression_level(
-/*=================================*/
- ulint flags); /*!< in: tablespace flags */
-
-/********************************************************************//**
-Determine the tablespace is using atomic writes from dict_table_t::flags.
-@return true if atomic writes is used, false if not */
-UNIV_INLINE
-atomic_writes_t
-fsp_flags_get_atomic_writes(
-/*========================*/
- ulint flags); /*!< in: tablespace flags */
-
#ifndef UNIV_NONINL
#include "fsp0pagecompress.ic"
#endif
diff --git a/storage/xtradb/include/fsp0pagecompress.ic b/storage/xtradb/include/fsp0pagecompress.ic
index e879aa2c16e..672dc2c33e8 100644
--- a/storage/xtradb/include/fsp0pagecompress.ic
+++ b/storage/xtradb/include/fsp0pagecompress.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,42 +25,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@mariadb.com
***********************************************************************/
-/********************************************************************//**
-Determine if the tablespace is page compressed from dict_table_t::flags.
-@return TRUE if page compressed, FALSE if not page compressed */
-UNIV_INLINE
-ibool
-fsp_flags_is_page_compressed(
-/*=========================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return(FSP_FLAGS_GET_PAGE_COMPRESSION(flags));
-}
-
-/********************************************************************//**
-Determine the tablespace is page compression level from dict_table_t::flags.
-@return page compression level or 0 if not compressed*/
-UNIV_INLINE
-ulint
-fsp_flags_get_page_compression_level(
-/*=================================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return(FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags));
-}
-
-/********************************************************************//**
-Determine the tablespace is using atomic writes from dict_table_t::flags.
-@return true if atomic writes is used, false if not */
-UNIV_INLINE
-atomic_writes_t
-fsp_flags_get_atomic_writes(
-/*========================*/
- ulint flags) /*!< in: tablespace flags */
-{
- return((atomic_writes_t)FSP_FLAGS_GET_ATOMIC_WRITES(flags));
-}
-
/*******************************************************************//**
Find out wheather the page is index page or not
@return true if page type index page, false if not */
@@ -106,20 +70,37 @@ UNIV_INLINE
ulint
fil_space_get_page_compression_level(
/*=================================*/
- ulint id) /*!< in: space id */
+ fil_space_t* space) /*!< in: space */
{
- ulint flags;
+ if (space && space->table_options) {
+ dict_tableoptions_t* options = (dict_tableoptions_t*)space->table_options;
+ return (options->page_compression_level);
+ }
- flags = fil_space_get_flags(id);
+ return(0);
+}
+/*******************************************************************//**
+Returns the page compression level of the space, or 0 if the space
+is not compressed. The tablespace must be cached in the memory cache.
+@return page compression level, 0 if space not found */
+UNIV_INLINE
+ulint
+fil_space_get_page_compression_level(
+/*=================================*/
+ ulint space_id) /*!< in: space id*/
+{
+ fil_space_t* space;
- if (flags && flags != ULINT_UNDEFINED) {
+ fil_system_enter();
+ space = fil_space_get_by_id(space_id);
+ fil_system_exit();
- return(fsp_flags_get_page_compression_level(flags));
+ if (space) {
+ return (fil_space_get_page_compression_level(space));
}
return(0);
}
-
/*******************************************************************//**
Extract the page compression from space.
@return true if space is page compressed, false if space is not found
@@ -128,20 +109,78 @@ UNIV_INLINE
ibool
fil_space_is_page_compressed(
/*=========================*/
- ulint id) /*!< in: space id */
+ fil_space_t* space) /*!< in: space */
{
- ulint flags;
+ if (space && space->table_options) {
+ dict_tableoptions_t* options = (dict_tableoptions_t*)space->table_options;
+ return(options->page_compressed);
+ }
- flags = fil_space_get_flags(id);
+ return(0);
+}
+
+/*******************************************************************//**
+Extract the page compression from space.
+@return true if space is page compressed, false if space is not found
+or space is not page compressed. */
+UNIV_INLINE
+ibool
+fil_space_is_page_compressed(
+/*=========================*/
+ ulint space_id) /*!< in: space id*/
+{
+ fil_space_t* space;
- if (flags && flags != ULINT_UNDEFINED) {
+ fil_system_enter();
+ space = fil_space_get_by_id(space_id);
+ fil_system_exit();
- return(fsp_flags_is_page_compressed(flags));
+ if (space) {
+ return (fil_space_is_page_compressed(space));
}
return(0);
}
+/*******************************************************************//**
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
+atomic_writes_t
+fil_space_get_atomic_writes(
+/*========================*/
+ fil_space_t* space) /*!< in: space */
+{
+ if (space && space->table_options) {
+ dict_tableoptions_t* options = (dict_tableoptions_t*)space->table_options;
+ return(options->atomic_writes);
+ }
+
+ return((atomic_writes_t)0);
+}
+
+/*******************************************************************//**
+Extract the atomic writes option from space.
+@return atomic_writes option */
+UNIV_INLINE
+atomic_writes_t
+fil_space_get_atomic_writes(
+/*========================*/
+ ulint space_id) /*!< in: space id*/
+{
+ fil_space_t* space;
+
+ fil_system_enter();
+ space = fil_space_get_by_id(space_id);
+ fil_system_exit();
+
+ if (space) {
+ return (fil_space_get_atomic_writes(space));
+ }
+
+ return((atomic_writes_t)0);
+}
+
#endif /* UNIV_INNOCHECKSUM */
/****************************************************************//**
@@ -184,28 +223,6 @@ fil_get_compression_alg_name(
#ifndef UNIV_INNOCHECKSUM
/*******************************************************************//**
-Returns the atomic writes flag of the space, or false if the space
-is not using atomic writes. The tablespace must be cached in the memory cache.
-@return atomic writes table option value */
-UNIV_INLINE
-atomic_writes_t
-fil_space_get_atomic_writes(
-/*========================*/
- ulint id) /*!< in: space id */
-{
- ulint flags;
-
- flags = fil_space_get_flags(id);
-
- if (flags && flags != ULINT_UNDEFINED) {
-
- return((atomic_writes_t)fsp_flags_get_atomic_writes(flags));
- }
-
- return((atomic_writes_t)0);
-}
-
-/*******************************************************************//**
Find out wheather the page is page compressed with lzo method
@return true if page is page compressed with lzo method, false if not */
UNIV_INLINE
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 9ec6a7ff4b4..7b7a1faf32e 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -655,4 +656,16 @@ ib_push_warning(
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...);
+
+/********************************************************************//**
+Helper function to get default_encryption_key_id from THD
+(trx->mysql_thd).
+@return default_encryption_key_id from THD or
+FIL_DEFAULT_ENCRYPTION_KEY */
+UNIV_INTERN
+ulint
+innobase_get_default_encryption_key_id(
+/*===================================*/
+ trx_t* trx); /*! in: trx */
+
#endif /* HA_INNODB_PROTOTYPES_H */
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index c9199153138..ae706f085b1 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2015, 2016, 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
@@ -193,9 +194,12 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
#define MLOG_FILE_WRITE_CRYPT_DATA ((byte)100) /*!< log record for
writing/updating crypt data of
a tablespace */
-
+#define MLOG_FILE_WRITE_FSP_FLAGS ((byte)101) /*!< log record for
+ writing/updating flags
+ a tablespace */
#define EXTRA_CHECK_MLOG_NUMBER(x) \
- ((x) == MLOG_FILE_WRITE_CRYPT_DATA)
+ ((x) == MLOG_FILE_WRITE_CRYPT_DATA || \
+ (x) == MLOG_FILE_WRITE_FSP_FLAGS)
/* @} */
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index a0ff6cdad15..be367ff9a5d 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -387,10 +388,8 @@ row_create_table_for_mysql(
(will be freed, or on DB_SUCCESS
added to the data dictionary cache) */
trx_t* trx, /*!< in/out: transaction */
- bool commit, /*!< in: if true, commit the transaction */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
- __attribute__((nonnull, warn_unused_result));
+ bool commit) /*!< in: if true, commit the transaction */
+ __attribute__((warn_unused_result));
/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
to create an index results in dropping the whole table! This is no problem
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index b0e69107723..8d5f15ab3de 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1386,6 +1386,9 @@ recv_parse_or_apply_log_rec_body(
case MLOG_FILE_WRITE_CRYPT_DATA:
ptr = fil_parse_write_crypt_data(ptr, end_ptr, block);
break;
+ case MLOG_FILE_WRITE_FSP_FLAGS:
+ ptr = fil_parse_write_fsp_flags(ptr, end_ptr, block);
+ break;
default:
ptr = NULL;
recv_sys->found_corrupt_log = TRUE;
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 7f13c1656ee..38604111bba 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -44,6 +44,8 @@ Created 10/21/1995 Heikki Tuuri
#include "srv0start.h"
#include "fil0fil.h"
#include "fsp0fsp.h"
+#include "rem0rec.h"
+#include "dict0tableoptions.h"
#include "fil0pagecompress.h"
#include "buf0buf.h"
#include "btr0types.h"
diff --git a/storage/xtradb/pars/pars0pars.cc b/storage/xtradb/pars/pars0pars.cc
index da08939d78a..3970111bbb9 100644
--- a/storage/xtradb/pars/pars0pars.cc
+++ b/storage/xtradb/pars/pars0pars.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -860,7 +861,7 @@ pars_retrieve_table_def(
sym_node->token_type = SYM_TABLE_REF_COUNTED;
sym_node->table = dict_table_open_on_name(
- sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
ut_a(sym_node->table != NULL);
}
@@ -2019,8 +2020,7 @@ pars_create_table(
column = static_cast<sym_node_t*>(que_node_get_next(column));
}
- node = tab_create_graph_create(table, pars_sym_tab_global->heap, true,
- FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ node = tab_create_graph_create(table, pars_sym_tab_global->heap, true);
table_sym->resolved = TRUE;
table_sym->token_type = SYM_TABLE;
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index ac6380e5a27..cc0001b9620 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, MariaDB Corporation.
+Copyright (c) 2015, 2016, 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
@@ -650,16 +650,6 @@ struct FetchIndexRootPages : public AbstractCallback {
rec_format_t ibd_rec_format;
rec_format_t table_rec_format;
- if (!dict_tf_is_valid(ibd_table_flags)) {
-
- ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- ".ibd file has invlad table flags: %lx",
- ibd_table_flags);
-
- return(DB_CORRUPTION);
- }
-
ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags);
table_rec_format = dict_tf_get_rec_format(m_table->flags);
@@ -3632,7 +3622,7 @@ row_import_for_mysql(
err = fil_open_single_table_tablespace(
true, true, table->space,
dict_tf_to_fsp_flags(table->flags),
- table->name, filepath, table);
+ table->name, filepath, table, table->table_options);
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
err = DB_TABLESPACE_NOT_FOUND;);
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index d02e1796f8a..1f49effa904 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1837,7 +1837,7 @@ row_ins_check_foreign_constraints(
ref_table = dict_table_open_on_name(
foreign->referenced_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
}
if (0 == trx->dict_operation_lock_mode) {
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 55e685ac19c..57492734de6 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -47,6 +48,7 @@ Created 9/17/2000 Heikki Tuuri
#include "dict0boot.h"
#include "dict0stats.h"
#include "dict0stats_bg.h"
+#include "dict0tableoptions.h"
#include "trx0roll.h"
#include "trx0purge.h"
#include "trx0rec.h"
@@ -2246,9 +2248,7 @@ row_create_table_for_mysql(
(will be freed, or on DB_SUCCESS
added to the data dictionary cache) */
trx_t* trx, /*!< in/out: transaction */
- bool commit, /*!< in: if true, commit the transaction */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ bool commit) /*!< in: if true, commit the transaction */
{
tab_node_t* node;
mem_heap_t* heap;
@@ -2361,7 +2361,7 @@ err_exit:
ut_ad(strstr(table->name, "/FTS_") != NULL);
}
- node = tab_create_graph_create(table, heap, commit, mode, key_id);
+ node = tab_create_graph_create(table, heap, commit);
thr = pars_complete_graph_for_exec(node, trx, heap);
@@ -2409,7 +2409,7 @@ err_exit:
fputs(" because tablespace full\n", stderr);
if (dict_table_open_on_name(table->name, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE)) {
+ DICT_ERR_IGNORE_NONE, NULL)) {
/* Make things easy for the drop table code. */
@@ -2511,7 +2511,7 @@ row_create_index_for_mysql(
is_fts = (index->type == DICT_FTS);
table = dict_table_open_on_name(table_name, TRUE, TRUE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
trx_start_if_not_started_xa(trx);
@@ -2744,7 +2744,7 @@ loop:
}
table = dict_table_open_on_name(drop->table_name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table == NULL) {
/* If for some reason the table has already been dropped
@@ -2923,7 +2923,7 @@ row_discard_tablespace_begin(
dict_table_t* table;
table = dict_table_open_on_name(
- name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ name, TRUE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
if (table) {
dict_stats_wait_bg_to_stop_using_table(table, trx);
@@ -3505,15 +3505,13 @@ row_truncate_table_for_mysql(
fil_space_crypt_t* crypt_data;
ulint space = table->space;
ulint flags = fil_space_get_flags(space);
- ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
- fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT;
dict_get_and_save_data_dir_path(table, true);
crypt_data = fil_space_get_crypt_data(space);
if (crypt_data) {
- key_id = crypt_data->key_id;
- mode = crypt_data->encryption;
+ table->table_options->encryption_key_id = crypt_data->key_id;
+ table->table_options->encryption = crypt_data->encryption;
}
if (flags != ULINT_UNDEFINED
@@ -3534,7 +3532,7 @@ row_truncate_table_for_mysql(
table->data_dir_path,
flags, table->flags2,
FIL_IBD_FILE_INITIAL_SIZE,
- mode, key_id)
+ table)
!= DB_SUCCESS) {
dict_table_x_unlock_indexes(table);
@@ -3937,7 +3935,8 @@ row_drop_table_for_mysql(
table = dict_table_open_on_name(
name, TRUE, FALSE,
static_cast<dict_err_ignore_t>(
- DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT));
+ DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT),
+ NULL);
if (!table) {
err = DB_TABLE_NOT_FOUND;
@@ -4309,6 +4308,11 @@ row_drop_table_for_mysql(
"END;\n"
, FALSE, trx);
+ /* Delete row from SYS_TABLE_OPTIONS if it exists */
+ if (err == DB_SUCCESS) {
+ err = dict_delete_tableoptions(table, trx, true);
+ }
+
switch (err) {
ibool is_temp;
@@ -4383,7 +4387,7 @@ row_drop_table_for_mysql(
dict_table_remove_from_cache(table);
if (dict_load_table(tablename, TRUE,
- DICT_ERR_IGNORE_NONE) != NULL) {
+ DICT_ERR_IGNORE_NONE, NULL) != NULL) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: not able to remove table ",
stderr);
@@ -4701,7 +4705,7 @@ loop:
table = dict_table_open_on_name(
table_name, TRUE, FALSE, static_cast<dict_err_ignore_t>(
DICT_ERR_IGNORE_INDEX_ROOT
- | DICT_ERR_IGNORE_CORRUPT));
+ | DICT_ERR_IGNORE_CORRUPT), NULL);
if (!table) {
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -4929,7 +4933,7 @@ row_rename_table_for_mysql(
dict_locked = trx->dict_operation_lock_mode == RW_X_LATCH;
table = dict_table_open_on_name(old_name, dict_locked, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (!table) {
err = DB_TABLE_NOT_FOUND;
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index 35719391fae..52775466508 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -5326,7 +5326,7 @@ row_search_check_if_query_cache_permitted(
}
table = dict_table_open_on_name(norm_name, FALSE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_NONE, NULL);
if (table == NULL) {
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 725ba6f990b..f42fe85837b 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -295,7 +295,7 @@ run_again:
ref_table = dict_table_open_on_name(
foreign->foreign_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
}
if (foreign_table) {
@@ -414,7 +414,7 @@ wsrep_row_upd_check_foreign_constraints(
foreign->referenced_table =
dict_table_open_on_name(
foreign->referenced_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE, NULL);
opened = TRUE;
}
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index e0f9bde63fa..847698e251c 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation
+Copyright (c) 2013, 2016, MariaDB Corporation
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -702,7 +702,8 @@ create_log_files(
logfilename, SRV_LOG_SPACE_FIRST_ID,
fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
FIL_LOG,
- NULL /* no encryption yet */);
+ NULL /* no encryption yet */,
+ NULL);
ut_a(fil_validate());
logfile0 = fil_node_create(
@@ -724,7 +725,7 @@ create_log_files(
#ifdef UNIV_LOG_ARCHIVE
/* Create the file space object for archived logs. */
fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
- 0, FIL_LOG, NULL /* no encryption yet */);
+ 0, FIL_LOG, NULL /* no encryption yet */, NULL);
#endif
log_group_init(0, srv_n_log_files,
srv_log_file_size * UNIV_PAGE_SIZE,
@@ -1183,9 +1184,12 @@ check_first_page:
ut_a(ret);
if (i == 0) {
+ dict_tableoptions_t options;
+ memset(&options, 0, sizeof(dict_tableoptions_t));
+ options.encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
fil_space_create(name, 0, flags, FIL_TABLESPACE,
- crypt_data);
+ crypt_data, &options);
crypt_data = NULL;
}
@@ -1333,7 +1337,7 @@ srv_undo_tablespace_open(
/* Set the compressed page size to 0 (non-compressed) */
flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE);
fil_space_create(name, space, flags, FIL_TABLESPACE,
- NULL /* no encryption */);
+ NULL /* no encryption */, NULL);
ut_a(fil_validate());
@@ -1634,6 +1638,7 @@ innobase_start_or_create_for_mysql(void)
char* logfile0 = NULL;
size_t dirnamelen;
bool sys_datafiles_created = false;
+ bool sys_table_options_created = false;
/* This should be initialized early */
ut_init_timer();
@@ -2362,7 +2367,8 @@ innobase_start_or_create_for_mysql(void)
SRV_LOG_SPACE_FIRST_ID,
fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
FIL_LOG,
- NULL /* no encryption yet */);
+ NULL /* no encryption yet */,
+ NULL);
ut_a(fil_validate());
@@ -2384,7 +2390,7 @@ innobase_start_or_create_for_mysql(void)
/* Create the file space object for archived logs. Under
MySQL, no archiving ever done. */
fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
- 0, FIL_LOG, NULL /* no encryption yet */);
+ 0, FIL_LOG, NULL /* no encryption yet */, NULL);
#endif /* UNIV_LOG_ARCHIVE */
log_group_init(0, i, srv_log_file_size * UNIV_PAGE_SIZE,
SRV_LOG_SPACE_FIRST_ID,
@@ -2609,7 +2615,16 @@ files_checked:
sys_datafiles_created = true;
- /* This function assumes that SYS_DATAFILES exists */
+ err = dict_create_or_check_sys_table_options();
+
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
+
+ sys_table_options_created = true;
+
+ /* This function assumes that SYS_DATAFILES
+ and SYS_TABLE_OPTIONS exists */
dict_check_tablespaces_and_store_max_id(dict_check);
}
@@ -2828,6 +2843,16 @@ files_checked:
}
}
+ /* Create the SYS_TABLE_OPTIONS system table if we
+ have not done that already on crash recovery. */
+ if (sys_table_options_created == false) {
+ err = dict_create_or_check_sys_table_options();
+
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
+ }
+
srv_is_being_started = FALSE;
ut_a(trx_purge_state() == PURGE_STATE_INIT);