mirror of
https://github.com/MariaDB/server.git
synced 2026-04-24 09:15:30 +02:00
Merge branch 'merge-innodb-5.6' into 10.0
5.6.26
This commit is contained in:
commit
ab7b672983
18 changed files with 278 additions and 251 deletions
|
|
@ -1773,8 +1773,8 @@ ALTER TABLE tm1 DROP INDEX im3;
|
|||
affected rows: 2
|
||||
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||
ALTER TABLE ti1 DROP COLUMN d2;
|
||||
affected rows: 2
|
||||
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
ALTER TABLE tm1 DROP COLUMN d2;
|
||||
affected rows: 2
|
||||
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
if (`select plugin_auth_version < "5.6.26" from information_schema.plugins where plugin_name='innodb'`)
|
||||
{
|
||||
--skip Not fixed in XtraDB below 5.6.26
|
||||
}
|
||||
--source include/have_innodb.inc
|
||||
#
|
||||
# Test of alter table
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ ib_open_table_by_id(
|
|||
dict_mutex_enter_for_mysql();
|
||||
}
|
||||
|
||||
table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
|
||||
table = dict_table_open_on_id(table_id, TRUE, DICT_TABLE_OP_NORMAL);
|
||||
|
||||
if (table != NULL && table->ibd_file_missing) {
|
||||
table = NULL;
|
||||
|
|
@ -2116,6 +2116,10 @@ ib_cursor_moveto(
|
|||
|
||||
n_fields = dict_index_get_n_ordering_defined_by_user(prebuilt->index);
|
||||
|
||||
if (n_fields > dtuple_get_n_fields(tuple->ptr)) {
|
||||
n_fields = dtuple_get_n_fields(tuple->ptr);
|
||||
}
|
||||
|
||||
dtuple_set_n_fields(search_tuple, n_fields);
|
||||
dtuple_set_n_fields_cmp(search_tuple, n_fields);
|
||||
|
||||
|
|
@ -3753,14 +3757,14 @@ ib_table_truncate(
|
|||
if (trunc_err == DB_SUCCESS) {
|
||||
ut_a(ib_trx_state(ib_trx) == static_cast<ib_trx_state_t>(
|
||||
TRX_STATE_NOT_STARTED));
|
||||
|
||||
err = ib_trx_release(ib_trx);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
} else {
|
||||
err = ib_trx_rollback(ib_trx);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
}
|
||||
|
||||
err = ib_trx_release(ib_trx);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
|
||||
/* Set the memcached_sync_count back. */
|
||||
if (table != NULL && memcached_sync != 0) {
|
||||
dict_mutex_enter_for_mysql();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1995, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
@ -938,11 +938,11 @@ buf_flush_write_block_low(
|
|||
break;
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
frame = bpage->zip.data;
|
||||
mach_write_to_8(frame + FIL_PAGE_LSN,
|
||||
bpage->newest_modification);
|
||||
|
||||
ut_a(page_zip_verify_checksum(frame, zip_size));
|
||||
|
||||
mach_write_to_8(frame + FIL_PAGE_LSN,
|
||||
bpage->newest_modification);
|
||||
memset(frame + FIL_PAGE_FILE_FLUSH_LSN, 0, 8);
|
||||
break;
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
|
|
|
|||
|
|
@ -3271,71 +3271,6 @@ dict_table_is_referenced_by_foreign_key(
|
|||
return(!table->referenced_set.empty());
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Check if the index is referenced by a foreign key, if TRUE return foreign
|
||||
else return NULL
|
||||
@return pointer to foreign key struct if index is defined for foreign
|
||||
key, otherwise NULL */
|
||||
UNIV_INTERN
|
||||
dict_foreign_t*
|
||||
dict_table_get_referenced_constraint(
|
||||
/*=================================*/
|
||||
dict_table_t* table, /*!< in: InnoDB table */
|
||||
dict_index_t* index) /*!< in: InnoDB index */
|
||||
{
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(table != NULL);
|
||||
|
||||
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||
it != table->referenced_set.end();
|
||||
++it) {
|
||||
|
||||
foreign = *it;
|
||||
|
||||
if (foreign->referenced_index == index) {
|
||||
|
||||
return(foreign);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Checks if a index is defined for a foreign key constraint. Index is a part
|
||||
of a foreign key constraint if the index is referenced by foreign key
|
||||
or index is a foreign key index.
|
||||
@return pointer to foreign key struct if index is defined for foreign
|
||||
key, otherwise NULL */
|
||||
UNIV_INTERN
|
||||
dict_foreign_t*
|
||||
dict_table_get_foreign_constraint(
|
||||
/*==============================*/
|
||||
dict_table_t* table, /*!< in: InnoDB table */
|
||||
dict_index_t* index) /*!< in: InnoDB index */
|
||||
{
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(table != NULL);
|
||||
|
||||
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||
it != table->foreign_set.end();
|
||||
++it) {
|
||||
|
||||
foreign = *it;
|
||||
|
||||
if (foreign->foreign_index == index) {
|
||||
|
||||
return(foreign);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Removes a foreign constraint struct from the dictionary cache. */
|
||||
UNIV_INTERN
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1995, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
@ -5451,9 +5451,10 @@ fil_io(
|
|||
|
||||
space = fil_space_get_by_id(space_id);
|
||||
|
||||
/* If we are deleting a tablespace we don't allow any read
|
||||
operations on that. However, we do allow write operations. */
|
||||
if (space == 0 || (type == OS_FILE_READ && space->stop_new_ops)) {
|
||||
/* If we are deleting a tablespace we don't allow async read operations
|
||||
on that. However, we do allow write and sync read operations */
|
||||
if (space == 0
|
||||
|| (type == OS_FILE_READ && !sync && space->stop_new_ops)) {
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
|
|
|
|||
|
|
@ -8941,7 +8941,8 @@ create_table_def(
|
|||
|
||||
/* MySQL does the name length check. But we do additional check
|
||||
on the name length here */
|
||||
if (strlen(table_name) > MAX_FULL_NAME_LEN) {
|
||||
const size_t table_name_len = strlen(table_name);
|
||||
if (table_name_len > MAX_FULL_NAME_LEN) {
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TABLE_NAME,
|
||||
|
|
@ -8950,6 +8951,15 @@ create_table_def(
|
|||
DBUG_RETURN(ER_TABLE_NAME);
|
||||
}
|
||||
|
||||
if (table_name[table_name_len - 1] == '/') {
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TABLE_NAME,
|
||||
"InnoDB: Table name is empty");
|
||||
|
||||
DBUG_RETURN(ER_WRONG_TABLE_NAME);
|
||||
}
|
||||
|
||||
n_cols = form->s->fields;
|
||||
|
||||
/* Check whether there already exists a FTS_DOC_ID column */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2005, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
@ -29,6 +29,7 @@ Smart ALTER TABLE
|
|||
#include <innodb_priv.h>
|
||||
#include <sql_alter.h>
|
||||
#include <sql_class.h>
|
||||
#include <sql_table.h>
|
||||
|
||||
#include "dict0crea.h"
|
||||
#include "dict0dict.h"
|
||||
|
|
@ -528,12 +529,9 @@ ha_innobase::check_if_supported_inplace_alter(
|
|||
} else if (((ha_alter_info->handler_flags
|
||||
& Alter_inplace_info::ADD_PK_INDEX)
|
||||
|| innobase_need_rebuild(ha_alter_info))
|
||||
&& (innobase_fulltext_exist(altered_table)
|
||||
|| (prebuilt->table->flags2
|
||||
& DICT_TF2_FTS_HAS_DOC_ID))) {
|
||||
&& (innobase_fulltext_exist(altered_table))) {
|
||||
/* Refuse to rebuild the table online, if
|
||||
fulltext indexes are to survive the rebuild,
|
||||
or if the table contains a hidden FTS_DOC_ID column. */
|
||||
fulltext indexes are to survive the rebuild. */
|
||||
online = false;
|
||||
/* If the table already contains fulltext indexes,
|
||||
refuse to rebuild the table natively altogether. */
|
||||
|
|
@ -891,10 +889,8 @@ innobase_get_foreign_key_info(
|
|||
char* tbl_namep = NULL;
|
||||
ulint db_name_len = 0;
|
||||
ulint tbl_name_len = 0;
|
||||
#ifdef __WIN__
|
||||
char db_name[MAX_DATABASE_NAME_LEN];
|
||||
char tbl_name[MAX_TABLE_NAME_LEN];
|
||||
#endif
|
||||
|
||||
fk_key = static_cast<Foreign_key*>(key);
|
||||
|
||||
|
|
@ -947,24 +943,29 @@ innobase_get_foreign_key_info(
|
|||
add_fk[num_fk] = dict_mem_foreign_create();
|
||||
|
||||
#ifndef __WIN__
|
||||
tbl_namep = fk_key->ref_table.str;
|
||||
tbl_name_len = fk_key->ref_table.length;
|
||||
db_namep = fk_key->ref_db.str;
|
||||
db_name_len = fk_key->ref_db.length;
|
||||
if(fk_key->ref_db.str) {
|
||||
tablename_to_filename(fk_key->ref_db.str, db_name,
|
||||
MAX_DATABASE_NAME_LEN);
|
||||
db_namep = db_name;
|
||||
db_name_len = strlen(db_name);
|
||||
}
|
||||
if (fk_key->ref_table.str) {
|
||||
tablename_to_filename(fk_key->ref_table.str, tbl_name,
|
||||
MAX_TABLE_NAME_LEN);
|
||||
tbl_namep = tbl_name;
|
||||
tbl_name_len = strlen(tbl_name);
|
||||
}
|
||||
#else
|
||||
ut_ad(fk_key->ref_table.str);
|
||||
|
||||
memcpy(tbl_name, fk_key->ref_table.str,
|
||||
fk_key->ref_table.length);
|
||||
tbl_name[fk_key->ref_table.length] = 0;
|
||||
tablename_to_filename(fk_key->ref_table.str, tbl_name,
|
||||
MAX_TABLE_NAME_LEN);
|
||||
innobase_casedn_str(tbl_name);
|
||||
tbl_name_len = strlen(tbl_name);
|
||||
tbl_namep = &tbl_name[0];
|
||||
|
||||
if (fk_key->ref_db.str != NULL) {
|
||||
memcpy(db_name, fk_key->ref_db.str,
|
||||
fk_key->ref_db.length);
|
||||
db_name[fk_key->ref_db.length] = 0;
|
||||
tablename_to_filename(fk_key->ref_db.str, db_name,
|
||||
MAX_DATABASE_NAME_LEN);
|
||||
innobase_casedn_str(db_name);
|
||||
db_name_len = strlen(db_name);
|
||||
db_namep = &db_name[0];
|
||||
|
|
@ -3303,58 +3304,72 @@ innobase_check_foreign_key_index(
|
|||
ulint n_drop_fk) /*!< in: Number of foreign keys
|
||||
to drop */
|
||||
{
|
||||
dict_foreign_t* foreign;
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(indexed_table != NULL);
|
||||
|
||||
/* Check if the index is referenced. */
|
||||
foreign = dict_table_get_referenced_constraint(indexed_table, index);
|
||||
const dict_foreign_set* fks = &indexed_table->referenced_set;
|
||||
|
||||
ut_ad(!foreign || indexed_table
|
||||
== foreign->referenced_table);
|
||||
/* Check for all FK references from other tables to the index. */
|
||||
for (dict_foreign_set::const_iterator it = fks->begin();
|
||||
it != fks->end(); ++it) {
|
||||
|
||||
if (foreign
|
||||
&& !dict_foreign_find_index(
|
||||
indexed_table, col_names,
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields, index,
|
||||
/*check_charsets=*/TRUE,
|
||||
/*check_null=*/FALSE)
|
||||
&& !innobase_find_equiv_index(
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields,
|
||||
ha_alter_info->key_info_buffer,
|
||||
ha_alter_info->index_add_buffer,
|
||||
ha_alter_info->index_add_count)
|
||||
) {
|
||||
trx->error_info = index;
|
||||
return(true);
|
||||
dict_foreign_t* foreign = *it;
|
||||
if (foreign->referenced_index != index) {
|
||||
continue;
|
||||
}
|
||||
ut_ad(indexed_table == foreign->referenced_table);
|
||||
|
||||
if (NULL == dict_foreign_find_index(
|
||||
indexed_table, col_names,
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields, index,
|
||||
/*check_charsets=*/TRUE,
|
||||
/*check_null=*/FALSE)
|
||||
&& NULL == innobase_find_equiv_index(
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields,
|
||||
ha_alter_info->key_info_buffer,
|
||||
ha_alter_info->index_add_buffer,
|
||||
ha_alter_info->index_add_count)) {
|
||||
|
||||
/* Index cannot be dropped. */
|
||||
trx->error_info = index;
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if this index references some
|
||||
other table */
|
||||
foreign = dict_table_get_foreign_constraint(
|
||||
indexed_table, index);
|
||||
fks = &indexed_table->foreign_set;
|
||||
|
||||
ut_ad(!foreign || indexed_table
|
||||
== foreign->foreign_table);
|
||||
/* Check for all FK references in current table using the index. */
|
||||
for (dict_foreign_set::const_iterator it = fks->begin();
|
||||
it != fks->end(); ++it) {
|
||||
|
||||
if (foreign
|
||||
&& !innobase_dropping_foreign(
|
||||
foreign, drop_fk, n_drop_fk)
|
||||
&& !dict_foreign_find_index(
|
||||
indexed_table, col_names,
|
||||
foreign->foreign_col_names,
|
||||
foreign->n_fields, index,
|
||||
/*check_charsets=*/TRUE,
|
||||
/*check_null=*/FALSE)
|
||||
&& !innobase_find_equiv_index(
|
||||
foreign->foreign_col_names,
|
||||
foreign->n_fields,
|
||||
ha_alter_info->key_info_buffer,
|
||||
ha_alter_info->index_add_buffer,
|
||||
ha_alter_info->index_add_count)
|
||||
) {
|
||||
trx->error_info = index;
|
||||
return(true);
|
||||
dict_foreign_t* foreign = *it;
|
||||
if (foreign->foreign_index != index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ut_ad(indexed_table == foreign->foreign_table);
|
||||
|
||||
if (!innobase_dropping_foreign(
|
||||
foreign, drop_fk, n_drop_fk)
|
||||
&& NULL == dict_foreign_find_index(
|
||||
indexed_table, col_names,
|
||||
foreign->foreign_col_names,
|
||||
foreign->n_fields, index,
|
||||
/*check_charsets=*/TRUE,
|
||||
/*check_null=*/FALSE)
|
||||
&& NULL == innobase_find_equiv_index(
|
||||
foreign->foreign_col_names,
|
||||
foreign->n_fields,
|
||||
ha_alter_info->key_info_buffer,
|
||||
ha_alter_info->index_add_buffer,
|
||||
ha_alter_info->index_add_count)) {
|
||||
|
||||
/* Index cannot be dropped. */
|
||||
trx->error_info = index;
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
return(false);
|
||||
|
|
@ -3573,6 +3588,19 @@ check_if_ok_to_rename:
|
|||
if (index->type & DICT_FTS) {
|
||||
DBUG_ASSERT(index->type == DICT_FTS
|
||||
|| (index->type & DICT_CORRUPT));
|
||||
|
||||
/* We need to drop any corrupted fts indexes
|
||||
before we add a new fts index. */
|
||||
if (add_fts_idx && index->type & DICT_CORRUPT) {
|
||||
ib_errf(user_thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_INNODB_INDEX_CORRUPT,
|
||||
"Fulltext index '%s' is corrupt. "
|
||||
"you should drop this index first.",
|
||||
index->name);
|
||||
|
||||
goto err_exit_no_heap;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
|
|
@ -433,18 +433,6 @@ dict_foreign_add_to_cache(
|
|||
/*!< in: error to be ignored */
|
||||
__attribute__((nonnull(1), warn_unused_result));
|
||||
/*********************************************************************//**
|
||||
Check if the index is referenced by a foreign key, if TRUE return the
|
||||
matching instance NULL otherwise.
|
||||
@return pointer to foreign key struct if index is defined for foreign
|
||||
key, otherwise NULL */
|
||||
UNIV_INTERN
|
||||
dict_foreign_t*
|
||||
dict_table_get_referenced_constraint(
|
||||
/*=================================*/
|
||||
dict_table_t* table, /*!< in: InnoDB table */
|
||||
dict_index_t* index) /*!< in: InnoDB index */
|
||||
__attribute__((nonnull, warn_unused_result));
|
||||
/*********************************************************************//**
|
||||
Checks if a table is referenced by foreign keys.
|
||||
@return TRUE if table is referenced by a foreign key */
|
||||
UNIV_INTERN
|
||||
|
|
@ -479,19 +467,6 @@ dict_str_starts_with_keyword(
|
|||
const char* keyword) /*!< in: keyword to look for */
|
||||
__attribute__((nonnull, warn_unused_result));
|
||||
/*********************************************************************//**
|
||||
Checks if a index is defined for a foreign key constraint. Index is a part
|
||||
of a foreign key constraint if the index is referenced by foreign key
|
||||
or index is a foreign key index
|
||||
@return pointer to foreign key struct if index is defined for foreign
|
||||
key, otherwise NULL */
|
||||
UNIV_INTERN
|
||||
dict_foreign_t*
|
||||
dict_table_get_foreign_constraint(
|
||||
/*==============================*/
|
||||
dict_table_t* table, /*!< in: InnoDB table */
|
||||
dict_index_t* index) /*!< in: InnoDB index */
|
||||
__attribute__((nonnull, warn_unused_result));
|
||||
/*********************************************************************//**
|
||||
Scans a table create SQL string and adds to the data dictionary
|
||||
the foreign key constraints declared in the string. This function
|
||||
should be called after the indexes for a table have been created.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2011, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1997, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
@ -119,6 +119,16 @@ struct purge_node_t{
|
|||
clustered index record */
|
||||
ibool done; /* Debug flag */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/***********************************************************//**
|
||||
Validate the persisent cursor. The purge node has two references
|
||||
to the clustered index record - one via the ref member, and the
|
||||
other via the persistent cursor. These two references must match
|
||||
each other if the found_clust flag is set.
|
||||
@return true if the persistent cursor is consistent with
|
||||
the ref member.*/
|
||||
bool validate_pcur();
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Created 1/20/1994 Heikki Tuuri
|
|||
|
||||
#define INNODB_VERSION_MAJOR 5
|
||||
#define INNODB_VERSION_MINOR 6
|
||||
#define INNODB_VERSION_BUGFIX 25
|
||||
#define INNODB_VERSION_BUGFIX 26
|
||||
|
||||
/* The following is the InnoDB version as shown in
|
||||
SELECT plugin_version FROM information_schema.plugins;
|
||||
|
|
|
|||
|
|
@ -1383,6 +1383,7 @@ os_file_create_simple_no_error_handling_func(
|
|||
*success = (file != INVALID_HANDLE_VALUE);
|
||||
#else /* __WIN__ */
|
||||
int create_flag;
|
||||
const char* mode_str = NULL;
|
||||
|
||||
ut_a(name);
|
||||
|
||||
|
|
@ -1391,6 +1392,8 @@ os_file_create_simple_no_error_handling_func(
|
|||
|
||||
if (create_mode == OS_FILE_OPEN) {
|
||||
|
||||
mode_str = "OPEN";
|
||||
|
||||
if (access_type == OS_FILE_READ_ONLY) {
|
||||
|
||||
create_flag = O_RDONLY;
|
||||
|
|
@ -1409,10 +1412,14 @@ os_file_create_simple_no_error_handling_func(
|
|||
|
||||
} else if (srv_read_only_mode) {
|
||||
|
||||
mode_str = "OPEN";
|
||||
|
||||
create_flag = O_RDONLY;
|
||||
|
||||
} else if (create_mode == OS_FILE_CREATE) {
|
||||
|
||||
mode_str = "CREATE";
|
||||
|
||||
create_flag = O_RDWR | O_CREAT | O_EXCL;
|
||||
|
||||
} else {
|
||||
|
|
@ -1427,6 +1434,17 @@ os_file_create_simple_no_error_handling_func(
|
|||
|
||||
*success = file == -1 ? FALSE : TRUE;
|
||||
|
||||
/* This function is always called for data files, we should disable
|
||||
OS caching (O_DIRECT) here as we do in os_file_create_func(), so
|
||||
we open the same file in the same mode, see man page of open(2). */
|
||||
if (!srv_read_only_mode
|
||||
&& *success
|
||||
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|
||||
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) {
|
||||
|
||||
os_file_set_nocache(file, name, mode_str);
|
||||
}
|
||||
|
||||
#ifdef USE_FILE_LOCK
|
||||
if (!srv_read_only_mode
|
||||
&& *success
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2012, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
@ -138,14 +138,6 @@ struct row_import {
|
|||
@return ULINT_UNDEFINED if not found. */
|
||||
ulint find_col(const char* name) const UNIV_NOTHROW;
|
||||
|
||||
/**
|
||||
Find the index field entry in in the cfg indexes fields.
|
||||
@name - of the index to look for
|
||||
@return instance if found else 0. */
|
||||
const dict_field_t* find_field(
|
||||
const row_index_t* cfg_index,
|
||||
const char* name) const UNIV_NOTHROW;
|
||||
|
||||
/**
|
||||
Get the number of rows for which purge failed during the convert phase.
|
||||
@param name - index name
|
||||
|
|
@ -1140,30 +1132,6 @@ row_import::find_col(
|
|||
return(ULINT_UNDEFINED);
|
||||
}
|
||||
|
||||
/**
|
||||
Find the index field entry in in the cfg indexes fields.
|
||||
@name - of the index to look for
|
||||
@return instance if found else 0. */
|
||||
const dict_field_t*
|
||||
row_import::find_field(
|
||||
const row_index_t* cfg_index,
|
||||
const char* name) const UNIV_NOTHROW
|
||||
{
|
||||
const dict_field_t* field = cfg_index->m_fields;
|
||||
|
||||
for (ulint i = 0; i < cfg_index->m_n_fields; ++i, ++field) {
|
||||
const char* field_name;
|
||||
|
||||
field_name = reinterpret_cast<const char*>(field->name);
|
||||
|
||||
if (strcmp(field_name, name) == 0) {
|
||||
return(field);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the index schema that was read from the .cfg file matches the
|
||||
in memory index definition.
|
||||
|
|
@ -1187,51 +1155,60 @@ row_import::match_index_columns(
|
|||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (cfg_index->m_n_fields != index->n_fields) {
|
||||
|
||||
ib_errf(thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_TABLE_SCHEMA_MISMATCH,
|
||||
"Index field count %lu doesn't match"
|
||||
" tablespace metadata file value %lu",
|
||||
(ulong) index->n_fields,
|
||||
(ulong) cfg_index->m_n_fields);
|
||||
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
cfg_index->m_srv_index = index;
|
||||
|
||||
const dict_field_t* field = index->fields;
|
||||
const dict_field_t* cfg_field = cfg_index->m_fields;
|
||||
|
||||
for (ulint i = 0; i < index->n_fields; ++i, ++field) {
|
||||
for (ulint i = 0; i < index->n_fields; ++i, ++field, ++cfg_field) {
|
||||
|
||||
const dict_field_t* cfg_field;
|
||||
|
||||
cfg_field = find_field(cfg_index, field->name);
|
||||
|
||||
if (cfg_field == 0) {
|
||||
if (strcmp(field->name, cfg_field->name) != 0) {
|
||||
ib_errf(thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_TABLE_SCHEMA_MISMATCH,
|
||||
"Index %s field %s not found in tablespace "
|
||||
"meta-data file.",
|
||||
index->name, field->name);
|
||||
"Index field name %s doesn't match"
|
||||
" tablespace metadata field name %s"
|
||||
" for field position %lu",
|
||||
field->name, cfg_field->name, (ulong) i);
|
||||
|
||||
err = DB_ERROR;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (cfg_field->prefix_len != field->prefix_len) {
|
||||
ib_errf(thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_TABLE_SCHEMA_MISMATCH,
|
||||
"Index %s field %s prefix len %lu "
|
||||
"doesn't match meta-data file value "
|
||||
"%lu",
|
||||
index->name, field->name,
|
||||
(ulong) field->prefix_len,
|
||||
(ulong) cfg_field->prefix_len);
|
||||
if (cfg_field->prefix_len != field->prefix_len) {
|
||||
ib_errf(thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_TABLE_SCHEMA_MISMATCH,
|
||||
"Index %s field %s prefix len %lu"
|
||||
" doesn't match metadata file value"
|
||||
" %lu",
|
||||
index->name, field->name,
|
||||
(ulong) field->prefix_len,
|
||||
(ulong) cfg_field->prefix_len);
|
||||
|
||||
err = DB_ERROR;
|
||||
}
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
||||
if (cfg_field->fixed_len != field->fixed_len) {
|
||||
ib_errf(thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_TABLE_SCHEMA_MISMATCH,
|
||||
"Index %s field %s fixed len %lu "
|
||||
"doesn't match meta-data file value "
|
||||
"%lu",
|
||||
index->name, field->name,
|
||||
(ulong) field->fixed_len,
|
||||
(ulong) cfg_field->fixed_len);
|
||||
if (cfg_field->fixed_len != field->fixed_len) {
|
||||
ib_errf(thd, IB_LOG_LEVEL_ERROR,
|
||||
ER_TABLE_SCHEMA_MISMATCH,
|
||||
"Index %s field %s fixed len %lu"
|
||||
" doesn't match metadata file value"
|
||||
" %lu",
|
||||
index->name, field->name,
|
||||
(ulong) field->fixed_len,
|
||||
(ulong) cfg_field->fixed_len);
|
||||
|
||||
err = DB_ERROR;
|
||||
}
|
||||
err = DB_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1997, 2015, Oracle and/or its affiliates. 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
|
||||
|
|
@ -84,7 +84,7 @@ row_purge_node_create(
|
|||
|
||||
/***********************************************************//**
|
||||
Repositions the pcur in the purge node on the clustered index record,
|
||||
if found.
|
||||
if found. If the record is not found, close pcur.
|
||||
@return TRUE if the record was found */
|
||||
static
|
||||
ibool
|
||||
|
|
@ -95,11 +95,10 @@ row_purge_reposition_pcur(
|
|||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
if (node->found_clust) {
|
||||
ibool found;
|
||||
ut_ad(node->validate_pcur());
|
||||
|
||||
found = btr_pcur_restore_position(mode, &node->pcur, mtr);
|
||||
node->found_clust = btr_pcur_restore_position(mode, &node->pcur, mtr);
|
||||
|
||||
return(found);
|
||||
} else {
|
||||
node->found_clust = row_search_on_row_ref(
|
||||
&node->pcur, mode, node->table, node->ref, mtr);
|
||||
|
|
@ -109,6 +108,11 @@ row_purge_reposition_pcur(
|
|||
}
|
||||
}
|
||||
|
||||
/* Close the current cursor if we fail to position it correctly. */
|
||||
if (!node->found_clust) {
|
||||
btr_pcur_close(&node->pcur);
|
||||
}
|
||||
|
||||
return(node->found_clust);
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +186,12 @@ func_exit:
|
|||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
btr_pcur_commit_specify_mtr(&node->pcur, &mtr);
|
||||
/* Persistent cursor is closed if reposition fails. */
|
||||
if (node->found_clust) {
|
||||
btr_pcur_commit_specify_mtr(&node->pcur, &mtr);
|
||||
} else {
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
return(success);
|
||||
}
|
||||
|
|
@ -251,7 +260,12 @@ row_purge_poss_sec(
|
|||
btr_pcur_get_rec(&node->pcur),
|
||||
&mtr, index, entry);
|
||||
|
||||
btr_pcur_commit_specify_mtr(&node->pcur, &mtr);
|
||||
/* Persistent cursor is closed if reposition fails. */
|
||||
if (node->found_clust) {
|
||||
btr_pcur_commit_specify_mtr(&node->pcur, &mtr);
|
||||
} else {
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
return(can_delete);
|
||||
}
|
||||
|
|
@ -831,6 +845,8 @@ row_purge_record_func(
|
|||
dict_index_t* clust_index;
|
||||
bool purged = true;
|
||||
|
||||
ut_ad(!node->found_clust);
|
||||
|
||||
clust_index = dict_table_get_first_index(node->table);
|
||||
|
||||
node->index = dict_table_get_next_index(clust_index);
|
||||
|
|
@ -986,3 +1002,52 @@ row_purge_step(
|
|||
|
||||
return(thr);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/***********************************************************//**
|
||||
Validate the persisent cursor. The purge node has two references
|
||||
to the clustered index record - one via the ref member, and the
|
||||
other via the persistent cursor. These two references must match
|
||||
each other if the found_clust flag is set.
|
||||
@return true if the stored copy of persistent cursor is consistent
|
||||
with the ref member.*/
|
||||
bool
|
||||
purge_node_t::validate_pcur()
|
||||
{
|
||||
if (!found_clust) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
if (index == NULL) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
if (index->type == DICT_FTS) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
if (pcur.old_stored != BTR_PCUR_OLD_STORED) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
dict_index_t* clust_index = pcur.btr_cur.index;
|
||||
|
||||
ulint* offsets = rec_get_offsets(
|
||||
pcur.old_rec, clust_index, NULL, pcur.old_n_fields, &heap);
|
||||
|
||||
/* Here we are comparing the purge ref record and the stored initial
|
||||
part in persistent cursor. Both cases we store n_uniq fields of the
|
||||
cluster index and so it is fine to do the comparison. We note this
|
||||
dependency here as pcur and ref belong to different modules. */
|
||||
int st = cmp_dtuple_rec(ref, pcur.old_rec, offsets);
|
||||
|
||||
if (st != 0) {
|
||||
fprintf(stderr, "Purge node pcur validation failed\n");
|
||||
dtuple_print(stderr, ref);
|
||||
rec_print(stderr, pcur.old_rec, clust_index);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue