[Commits] 6630a6e: MDEV-9362: InnoDB tables using DATA_DIRECTORY created using

Jan Lindström jan.lindstrom at mariadb.com
Tue May 3 20:56:32 EEST 2016


revision-id: 6630a6e2f6f643c16c5846f5aefc64041df10320 (mariadb-10.1.13-22-g6630a6e)
parent(s): 037b78e5ec2e28d0d4573605f7dc8d5e2b36a66f
committer: Jan Lindström
timestamp: 2016-05-03 20:53:29 +0300
message:

MDEV-9362: InnoDB tables using DATA_DIRECTORY created using
MySQL 5.6 do not work with MariaDB 10.1

Analysis: Problem is that tablespace flags bit DATA_DIR
is on different position on MySQL 5.6 compared to
MariaDB 10.1.

Fix: If we detect that there is difference between dictionary
flags and tablespace flags we remove DATA_DIR flag and compare
again. Remote tablespace is tried to locate even in case
when DATA_DIR flag is not set.

---
 storage/innobase/dict/dict0load.cc | 19 ++++++------
 storage/innobase/fil/fil0fil.cc    | 57 +++++++++++++++++++++++++++++-------
 storage/innobase/include/fsp0fsp.h | 12 +++++++-
 storage/xtradb/dict/dict0load.cc   | 19 ++++++------
 storage/xtradb/fil/fil0fil.cc      | 59 ++++++++++++++++++++++++++++++--------
 storage/xtradb/include/fsp0fsp.h   | 12 +++++++-
 6 files changed, 135 insertions(+), 43 deletions(-)

diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index d8bd0a6..ce5b10a 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
@@ -2241,8 +2242,9 @@ dict_get_and_save_data_dir_path(
 	bool		dict_mutex_own)	/*!< in: true if dict_sys->mutex
 					is owned already */
 {
-	if (DICT_TF_HAS_DATA_DIR(table->flags)
-	    && (!table->data_dir_path)) {
+	bool is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY);
+
+	if (!is_temp && !table->data_dir_path && table->space) {
 		char*	path = fil_space_get_first_path(table->space);
 
 		if (!dict_mutex_own) {
@@ -2254,6 +2256,7 @@ dict_get_and_save_data_dir_path(
 		}
 
 		if (path) {
+			table->flags |= (1 << DICT_TF_POS_DATA_DIR);
 			dict_save_data_dir_path(table, path);
 			mem_free(path);
 		}
@@ -2394,16 +2397,14 @@ dict_load_table(
 			}
 
 			/* Use the remote filepath if needed. */
-			if (DICT_TF_HAS_DATA_DIR(table->flags)) {
-				/* This needs to be added to the table
-				from SYS_DATAFILES */
-				dict_get_and_save_data_dir_path(table, true);
+			/* This needs to be added to the tablex1
+			from SYS_DATAFILES */
+			dict_get_and_save_data_dir_path(table, true);
 
-				if (table->data_dir_path) {
-					filepath = os_file_make_remote_pathname(
+			if (table->data_dir_path) {
+				filepath = os_file_make_remote_pathname(
 						table->data_dir_path,
 						table->name, "ibd");
-				}
 			}
 
 			/* Try to open the tablespace.  We set the
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 22abf59..4458315 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -717,16 +717,23 @@ fil_node_open_file(
 		}
 
 		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);
+			ulint sflags = (space->flags & ~FSP_FLAGS_MASK_DATA_DIR);
+			ulint fflags = (flags & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
 
-			ut_error;
-		}
+			/* DATA_DIR option is on different place on MariaDB
+			compared to MySQL. If this is the difference. Fix
+			it. */
+
+			if (sflags == fflags) {
+				fprintf(stderr,
+					"InnoDB: Warning: Table flags 0x%lx"
+					" in the data dictionary but in file %s are 0x%lx!\n"
+					" Temporally corrected because DATA_DIR option to 0x%lx.\n",
+					space->flags, node->name, flags, space->flags);
+
+				flags = space->flags;
+			}
 
-		if (UNIV_UNLIKELY(space->flags != flags)) {
 			if (!dict_tf_verify_flags(space->flags, flags)) {
 				fprintf(stderr,
 					"InnoDB: Error: table flags are 0x%lx"
@@ -3797,8 +3804,18 @@ fil_open_single_table_tablespace(
 		/* Validate this single-table-tablespace with SYS_TABLES,
 		but do not compare the DATA_DIR flag, in case the
 		tablespace was relocated. */
+
+		ulint newf = def.flags;
+		if (newf != mod_flags) {
+			if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
+			} else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
+			}
+		}
+
 		if (def.valid && def.id == id
-		    && (def.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+		    && newf == mod_flags) {
 			valid_tablespaces_found++;
 		} else {
 			def.valid = false;
@@ -3826,8 +3843,17 @@ fil_open_single_table_tablespace(
 		/* Validate this single-table-tablespace with SYS_TABLES,
 		but do not compare the DATA_DIR flag, in case the
 		tablespace was relocated. */
+		ulint newf = remote.flags;
+		if (newf != mod_flags) {
+			if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
+			} else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
+			}
+		}
+
 		if (remote.valid && remote.id == id
-		    && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+		    && newf == mod_flags) {
 			valid_tablespaces_found++;
 		} else {
 			remote.valid = false;
@@ -3856,8 +3882,17 @@ fil_open_single_table_tablespace(
 		/* Validate this single-table-tablespace with SYS_TABLES,
 		but do not compare the DATA_DIR flag, in case the
 		tablespace was relocated. */
+		ulint newf = dict.flags;
+		if (newf != mod_flags) {
+			if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
+			} else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
+			}
+		}
+
 		if (dict.valid && dict.id == id
-		    && (dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+		    && newf == mod_flags) {
 			valid_tablespaces_found++;
 		} else {
 			dict.valid = false;
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 2bac42e..296dfd8 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
@@ -100,6 +100,9 @@ dictionary */
 /** 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)
+#define FSP_FLAGS_POS_DATA_DIR_ORACLE	(FSP_FLAGS_POS_ATOMIC_BLOBS	\
+					+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS  \
+					+ 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)
@@ -124,6 +127,10 @@ dictionary */
 #define FSP_FLAGS_MASK_DATA_DIR					\
 		((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR))		\
 		<< FSP_FLAGS_POS_DATA_DIR)
+/** Bit mask of the DATA_DIR field */
+#define FSP_FLAGS_MASK_DATA_DIR_ORACLE				\
+		((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR))		\
+		<< FSP_FLAGS_POS_DATA_DIR_ORACLE)
 /** Bit mask of the PAGE_COMPRESSION field */
 #define FSP_FLAGS_MASK_PAGE_COMPRESSION			\
 		((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION))	\
@@ -156,6 +163,9 @@ dictionary */
 #define FSP_FLAGS_HAS_DATA_DIR(flags)				\
 		((flags & FSP_FLAGS_MASK_DATA_DIR)		\
 		>> FSP_FLAGS_POS_DATA_DIR)
+#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags)			\
+		((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE)	\
+		>> FSP_FLAGS_POS_DATA_DIR_ORACLE)
 /** Return the contents of the UNUSED bits */
 #define FSP_FLAGS_GET_UNUSED(flags)				\
 		(flags >> FSP_FLAGS_POS_UNUSED)
diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc
index d6ed8ac..3d3a35e 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
@@ -2242,8 +2243,9 @@ dict_get_and_save_data_dir_path(
 	bool		dict_mutex_own)	/*!< in: true if dict_sys->mutex
 					is owned already */
 {
-	if (DICT_TF_HAS_DATA_DIR(table->flags)
-	    && (!table->data_dir_path)) {
+	bool is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY);
+
+	if (!is_temp && !table->data_dir_path && table->space) {
 		char*	path = fil_space_get_first_path(table->space);
 
 		if (!dict_mutex_own) {
@@ -2255,6 +2257,7 @@ dict_get_and_save_data_dir_path(
 		}
 
 		if (path) {
+			table->flags |= (1 << DICT_TF_POS_DATA_DIR);
 			dict_save_data_dir_path(table, path);
 			mem_free(path);
 		}
@@ -2395,16 +2398,14 @@ dict_load_table(
 			}
 
 			/* Use the remote filepath if needed. */
-			if (DICT_TF_HAS_DATA_DIR(table->flags)) {
-				/* This needs to be added to the table
-				from SYS_DATAFILES */
-				dict_get_and_save_data_dir_path(table, true);
+			/* This needs to be added to the table
+			from SYS_DATAFILES */
+			dict_get_and_save_data_dir_path(table, true);
 
-				if (table->data_dir_path) {
-					filepath = os_file_make_remote_pathname(
+			if (table->data_dir_path) {
+				filepath = os_file_make_remote_pathname(
 						table->data_dir_path,
 						table->name, "ibd");
-				}
 			}
 
 			/* Try to open the tablespace.  We set the
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 2da234a..80312d9 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
@@ -719,16 +719,23 @@ fil_node_open_file(
 		}
 
 		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);
+			ulint sflags = (space->flags & ~FSP_FLAGS_MASK_DATA_DIR);
+			ulint fflags = (flags & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
 
-			ut_error;
-		}
+			/* DATA_DIR option is on different place on MariaDB
+			compared to MySQL. If this is the difference. Fix
+			it. */
+
+			if (sflags == fflags) {
+				fprintf(stderr,
+					"InnoDB: Warning: Table flags 0x%lx"
+					" in the data dictionary but in file %s are 0x%lx!\n"
+					" Temporally corrected because DATA_DIR option to 0x%lx.\n",
+					space->flags, node->name, flags, space->flags);
+
+				flags = space->flags;
+			}
 
-		if (UNIV_UNLIKELY(space->flags != flags)) {
 			if (!dict_tf_verify_flags(space->flags, flags)) {
 				fprintf(stderr,
 					"InnoDB: Error: table flags are 0x%lx"
@@ -3829,8 +3836,18 @@ fil_open_single_table_tablespace(
 		/* Validate this single-table-tablespace with SYS_TABLES,
 		but do not compare the DATA_DIR flag, in case the
 		tablespace was relocated. */
+
+		ulint newf = def.flags;
+		if (newf != mod_flags) {
+			if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
+			} else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
+			}
+		}
+
 		if (def.valid && def.id == id
-		    && (def.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+		    && newf == mod_flags) {
 			valid_tablespaces_found++;
 		} else {
 			def.valid = false;
@@ -3855,8 +3872,17 @@ fil_open_single_table_tablespace(
 		/* Validate this single-table-tablespace with SYS_TABLES,
 		but do not compare the DATA_DIR flag, in case the
 		tablespace was relocated. */
+		ulint newf = remote.flags;
+		if (newf != mod_flags) {
+			if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
+			} else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
+			}
+		}
+
 		if (remote.valid && remote.id == id
-		    && (remote.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+		    && newf == mod_flags) {
 			valid_tablespaces_found++;
 		} else {
 			remote.valid = false;
@@ -3882,8 +3908,17 @@ fil_open_single_table_tablespace(
 		/* Validate this single-table-tablespace with SYS_TABLES,
 		but do not compare the DATA_DIR flag, in case the
 		tablespace was relocated. */
+		ulint newf = dict.flags;
+		if (newf != mod_flags) {
+			if (FSP_FLAGS_HAS_DATA_DIR(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR);
+			} else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) {
+				newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE);
+			}
+		}
+
 		if (dict.valid && dict.id == id
-		    && (dict.flags & ~FSP_FLAGS_MASK_DATA_DIR) == mod_flags) {
+		    && newf == mod_flags) {
 			valid_tablespaces_found++;
 		} else {
 			dict.valid = false;
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index 8fdacc5..839aed8 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
@@ -99,6 +99,9 @@ dictionary */
 /** 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)
+#define FSP_FLAGS_POS_DATA_DIR_ORACLE	(FSP_FLAGS_POS_ATOMIC_BLOBS	\
+					+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS  \
+					+ 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)
@@ -123,6 +126,10 @@ dictionary */
 #define FSP_FLAGS_MASK_DATA_DIR					\
 		((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR))		\
 		<< FSP_FLAGS_POS_DATA_DIR)
+/** Bit mask of the DATA_DIR field */
+#define FSP_FLAGS_MASK_DATA_DIR_ORACLE				\
+		((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR))		\
+		<< FSP_FLAGS_POS_DATA_DIR_ORACLE)
 /** Bit mask of the PAGE_COMPRESSION field */
 #define FSP_FLAGS_MASK_PAGE_COMPRESSION				\
 		((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION))	\
@@ -156,6 +163,9 @@ dictionary */
 #define FSP_FLAGS_HAS_DATA_DIR(flags)				\
 		((flags & FSP_FLAGS_MASK_DATA_DIR)		\
 		>> FSP_FLAGS_POS_DATA_DIR)
+#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags)			\
+		((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE)	\
+		>> FSP_FLAGS_POS_DATA_DIR_ORACLE)
 /** Return the contents of the UNUSED bits */
 #define FSP_FLAGS_GET_UNUSED(flags)				\
 		(flags >> FSP_FLAGS_POS_UNUSED)


More information about the commits mailing list