diff options
Diffstat (limited to 'storage/innobase/fil/fil0fil.cc')
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 131 |
1 files changed, 86 insertions, 45 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 22abf592adc..e9e164e5e1a 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. Copyright (c) 2013, 2016, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -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" @@ -1802,7 +1809,7 @@ fil_set_max_space_id_if_bigger( Writes the flushed lsn and the latest archived log number to the page header of the first page of a data file of the system tablespace (space 0), which is uncompressed. */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) dberr_t fil_write_lsn_and_arch_no_to_file( /*==============================*/ @@ -1810,7 +1817,7 @@ fil_write_lsn_and_arch_no_to_file( ulint sum_of_sizes, /*!< in: combined size of previous files in space, in database pages */ lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no __attribute__((unused))) + ulint arch_log_no MY_ATTRIBUTE((unused))) /*!< in: archived log number to write */ { byte* buf1; @@ -1898,7 +1905,7 @@ Checks the consistency of the first data page of a tablespace at database startup. @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) const char* fil_check_first_page( /*=================*/ @@ -3186,8 +3193,6 @@ fil_create_link_file( const char* tablename, /*!< in: tablename */ const char* filepath) /*!< in: pathname of tablespace */ { - os_file_t file; - ibool success; dberr_t err = DB_SUCCESS; char* link_filepath; char* prev_filepath = fil_read_link_file(tablename); @@ -3205,16 +3210,25 @@ fil_create_link_file( } link_filepath = fil_make_isl_name(tablename); - /* Note that OS_FILE_READ_WRITE_CACHED used here to avoid - unnecessary errors on O_DIRECT, link files are not really - a data files. */ - file = os_file_create_simple_no_error_handling( - innodb_file_data_key, link_filepath, - OS_FILE_CREATE, OS_FILE_READ_WRITE_CACHED, &success, 0); - if (!success) { - /* The following call will print an error message */ - ulint error = os_file_get_last_error(true); + /** Check if the file already exists. */ + FILE* file = NULL; + ibool exists; + os_file_type_t ftype; + + bool success = os_file_status(link_filepath, &exists, &ftype); + + ulint error = 0; + if (success && !exists) { + file = fopen(link_filepath, "w"); + if (file == NULL) { + /* This call will print its own error message */ + error = os_file_get_last_error(true); + } + } else { + error = OS_FILE_ALREADY_EXISTS; + } + if (error != 0) { ut_print_timestamp(stderr); fputs(" InnoDB: Cannot create file ", stderr); @@ -3239,13 +3253,17 @@ fil_create_link_file( return(err); } - if (!os_file_write(link_filepath, file, filepath, 0, - strlen(filepath))) { + ulint rbytes = fwrite(filepath, 1, strlen(filepath), file); + if (rbytes != strlen(filepath)) { + os_file_get_last_error(true); + ib_logf(IB_LOG_LEVEL_ERROR, + "cannot write link file " + "%s",filepath); err = DB_ERROR; } /* Close the file, we only need it at startup */ - os_file_close(file); + fclose(file); mem_free(link_filepath); @@ -3797,8 +3815,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 +3854,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 +3893,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; @@ -5262,12 +5308,15 @@ retry: os_offset_t offset = ((os_offset_t) (start_page_no - file_start_page_no)) * page_size; + + const char* name = node->name == NULL ? space->name : node->name; + #ifdef UNIV_HOTBACKUP - success = os_file_write(node->name, node->handle, buf, + success = os_file_write(name, node->handle, buf, offset, page_size * n_pages); #else success = os_aio(OS_FILE_WRITE, 0, OS_AIO_SYNC, - node->name, node->handle, buf, + name, node->handle, buf, offset, page_size * n_pages, page_size, node, NULL, 0); #endif /* UNIV_HOTBACKUP */ @@ -5904,30 +5953,22 @@ fil_io( ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0); + const char* name = node->name == NULL ? space->name : node->name; + #ifdef UNIV_HOTBACKUP /* In mysqlbackup do normal i/o, not aio */ if (type == OS_FILE_READ) { ret = os_file_read(node->handle, buf, offset, len); } else { ut_ad(!srv_read_only_mode); - ret = os_file_write(node->name, node->handle, buf, + ret = os_file_write(name, node->handle, buf, offset, len); } #else /* Queue the aio request */ - ret = os_aio( - type, - is_log, - mode | wake_later, - node->name, - node->handle, - buf, - offset, - len, - zip_size ? zip_size : UNIV_PAGE_SIZE, - node, - message, - write_size); + ret = os_aio(type, is_log, mode | wake_later, name, node->handle, buf, + offset, len, zip_size ? zip_size : UNIV_PAGE_SIZE, node, + message, write_size); #endif /* UNIV_HOTBACKUP */ |