diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-05-03 20:53:29 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-05-03 21:35:41 +0300 |
commit | 5dd0c77e9239217457cf795d6380bdd3bf0808ad (patch) | |
tree | aa118e213bd34b417169a1348bdde71056711142 | |
parent | 80da57cc4f0c717ee3e01ac5abccc859b88a2fbf (diff) | |
download | mariadb-git-5dd0c77e9239217457cf795d6380bdd3bf0808ad.tar.gz |
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.
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 19 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 57 | ||||
-rw-r--r-- | storage/innobase/include/fsp0fsp.h | 12 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0load.cc | 19 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.cc | 59 | ||||
-rw-r--r-- | 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 d8bd0a66ade..ce5b10a623c 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 @@ err_exit: } /* 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 22abf592adc..4458315b014 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 2bac42eb081..296dfd8d841 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 d6ed8acb39e..3d3a35e5c8e 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 @@ err_exit: } /* 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 2da234ad094..80312d97e01 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 8fdacc51277..839aed80418 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) |