mirror of
https://github.com/MariaDB/server.git
synced 2026-05-12 10:00:09 +02:00
Merge branch 'merge-innodb-5.6' into 10.0
This commit is contained in:
commit
c8fcaf8aec
22 changed files with 705 additions and 158 deletions
|
|
@ -505,6 +505,71 @@ ib_cb_t innodb_api_cb[] = {
|
|||
(ib_cb_t) ib_trx_read_only
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Test a file path whether it is same as mysql data directory path.
|
||||
|
||||
@param path null terminated character string
|
||||
|
||||
@return
|
||||
@retval TRUE The path is different from mysql data directory.
|
||||
@retval FALSE The path is same as mysql data directory.
|
||||
*/
|
||||
static bool is_mysql_datadir_path(const char *path)
|
||||
{
|
||||
if (path == NULL)
|
||||
return false;
|
||||
|
||||
char mysql_data_dir[FN_REFLEN], path_dir[FN_REFLEN];
|
||||
convert_dirname(path_dir, path, NullS);
|
||||
convert_dirname(mysql_data_dir, mysql_unpacked_real_data_home, NullS);
|
||||
size_t mysql_data_home_len= dirname_length(mysql_data_dir);
|
||||
size_t path_len = dirname_length(path_dir);
|
||||
|
||||
if (path_len < mysql_data_home_len)
|
||||
return true;
|
||||
|
||||
if (!lower_case_file_system)
|
||||
return(memcmp(mysql_data_dir, path_dir, mysql_data_home_len));
|
||||
|
||||
return(files_charset_info->coll->strnncoll(files_charset_info,
|
||||
(uchar *) path_dir, path_len,
|
||||
(uchar *) mysql_data_dir,
|
||||
mysql_data_home_len,
|
||||
TRUE));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int mysql_tmpfile_path(const char *path, const char *prefix)
|
||||
{
|
||||
DBUG_ASSERT(path != NULL);
|
||||
DBUG_ASSERT((strlen(path) + strlen(prefix)) <= FN_REFLEN);
|
||||
|
||||
char filename[FN_REFLEN];
|
||||
File fd = create_temp_file(filename, path, prefix,
|
||||
#ifdef __WIN__
|
||||
O_BINARY | O_TRUNC | O_SEQUENTIAL |
|
||||
O_SHORT_LIVED |
|
||||
#endif /* __WIN__ */
|
||||
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
|
||||
MYF(MY_WME));
|
||||
if (fd >= 0) {
|
||||
#ifndef __WIN__
|
||||
/*
|
||||
This can be removed once the following bug is fixed:
|
||||
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
|
||||
(file not removed) (Unix)
|
||||
*/
|
||||
unlink(filename);
|
||||
#endif /* !__WIN__ */
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************//**
|
||||
Check whether valid argument given to innodb_ft_*_stopword_table.
|
||||
This function is registered as a callback with MySQL.
|
||||
|
|
@ -520,6 +585,108 @@ innodb_stopword_table_validate(
|
|||
for update function */
|
||||
struct st_mysql_value* value); /*!< in: incoming string */
|
||||
|
||||
/** Validate passed-in "value" is a valid directory name.
|
||||
This function is registered as a callback with MySQL.
|
||||
@param[in,out] thd thread handle
|
||||
@param[in] var pointer to system variable
|
||||
@param[out] save immediate result for update
|
||||
@param[in] value incoming string
|
||||
@return 0 for valid name */
|
||||
static
|
||||
int
|
||||
innodb_tmpdir_validate(
|
||||
THD* thd,
|
||||
struct st_mysql_sys_var* var,
|
||||
void* save,
|
||||
struct st_mysql_value* value)
|
||||
{
|
||||
|
||||
char* alter_tmp_dir;
|
||||
char* innodb_tmp_dir;
|
||||
char buff[OS_FILE_MAX_PATH];
|
||||
int len = sizeof(buff);
|
||||
char tmp_abs_path[FN_REFLEN + 2];
|
||||
|
||||
ut_ad(save != NULL);
|
||||
ut_ad(value != NULL);
|
||||
|
||||
if (check_global_access(thd, FILE_ACL)) {
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"InnoDB: FILE Permissions required");
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
alter_tmp_dir = (char*) value->val_str(value, buff, &len);
|
||||
|
||||
if (!alter_tmp_dir) {
|
||||
*static_cast<const char**>(save) = alter_tmp_dir;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (strlen(alter_tmp_dir) > FN_REFLEN) {
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"Path length should not exceed %d bytes", FN_REFLEN);
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
my_realpath(tmp_abs_path, alter_tmp_dir, 0);
|
||||
size_t tmp_abs_len = strlen(tmp_abs_path);
|
||||
|
||||
if (my_access(tmp_abs_path, F_OK)) {
|
||||
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"InnoDB: Path doesn't exist.");
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
} else if (my_access(tmp_abs_path, R_OK | W_OK)) {
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"InnoDB: Server doesn't have permission in "
|
||||
"the given location.");
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
MY_STAT stat_info_dir;
|
||||
|
||||
if (my_stat(tmp_abs_path, &stat_info_dir, MYF(0))) {
|
||||
if ((stat_info_dir.st_mode & S_IFDIR) != S_IFDIR) {
|
||||
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"Given path is not a directory. ");
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_mysql_datadir_path(tmp_abs_path)) {
|
||||
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"InnoDB: Path Location should not be same as "
|
||||
"mysql data directory location.");
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
innodb_tmp_dir = static_cast<char*>(
|
||||
thd_memdup(thd, tmp_abs_path, tmp_abs_len + 1));
|
||||
*static_cast<const char**>(save) = innodb_tmp_dir;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/** "GEN_CLUST_INDEX" is the name reserved for InnoDB default
|
||||
system clustered index when there is no primary key. */
|
||||
const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX";
|
||||
|
|
@ -572,6 +739,11 @@ static MYSQL_THDVAR_STR(ft_user_stopword_table,
|
|||
"User supplied stopword table name, effective in the session level.",
|
||||
innodb_stopword_table_validate, NULL, NULL);
|
||||
|
||||
static MYSQL_THDVAR_STR(tmpdir,
|
||||
PLUGIN_VAR_OPCMDARG|PLUGIN_VAR_MEMALLOC,
|
||||
"Directory for temporary non-tablespace files.",
|
||||
innodb_tmpdir_validate, NULL, NULL);
|
||||
|
||||
static SHOW_VAR innodb_status_variables[]= {
|
||||
{"buffer_pool_dump_status",
|
||||
(char*) &export_vars.innodb_buffer_pool_dump_status, SHOW_CHAR},
|
||||
|
|
@ -1306,6 +1478,26 @@ thd_supports_xa(
|
|||
return(THDVAR(thd, support_xa));
|
||||
}
|
||||
|
||||
/** Get the value of innodb_tmpdir.
|
||||
@param[in] thd thread handle, or NULL to query
|
||||
the global innodb_tmpdir.
|
||||
@retval NULL if innodb_tmpdir="" */
|
||||
UNIV_INTERN
|
||||
const char*
|
||||
thd_innodb_tmpdir(
|
||||
THD* thd)
|
||||
{
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!sync_thread_levels_nonempty_trx(false));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
const char* tmp_dir = THDVAR(thd, tmpdir);
|
||||
if (tmp_dir != NULL && *tmp_dir == '\0') {
|
||||
tmp_dir = NULL;
|
||||
}
|
||||
|
||||
return(tmp_dir);
|
||||
}
|
||||
/******************************************************************//**
|
||||
Returns the lock wait timeout for the current connection.
|
||||
@return the lock wait timeout, in seconds */
|
||||
|
|
@ -1833,13 +2025,14 @@ innobase_get_lower_case_table_names(void)
|
|||
return(lower_case_table_names);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Creates a temporary file.
|
||||
/** Create a temporary file in the location specified by the parameter
|
||||
path. If the path is null, then it will be created in tmpdir.
|
||||
@param[in] path location for creating temporary file
|
||||
@return temporary file descriptor, or < 0 on error */
|
||||
UNIV_INTERN
|
||||
int
|
||||
innobase_mysql_tmpfile(void)
|
||||
/*========================*/
|
||||
innobase_mysql_tmpfile(
|
||||
const char* path)
|
||||
{
|
||||
int fd2 = -1;
|
||||
File fd;
|
||||
|
|
@ -1849,7 +2042,11 @@ innobase_mysql_tmpfile(void)
|
|||
return(-1);
|
||||
);
|
||||
|
||||
fd = mysql_tmpfile("ib");
|
||||
if (path == NULL) {
|
||||
fd = mysql_tmpfile("ib");
|
||||
} else {
|
||||
fd = mysql_tmpfile_path(path, "ib");
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
/* Copy the file descriptor, so that the additional resources
|
||||
|
|
@ -2776,6 +2973,13 @@ ha_innobase::reset_template(void)
|
|||
ut_ad(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED);
|
||||
ut_ad(prebuilt->magic_n2 == prebuilt->magic_n);
|
||||
|
||||
/* Force table to be freed in close_thread_table(). */
|
||||
DBUG_EXECUTE_IF("free_table_in_fts_query",
|
||||
if (prebuilt->in_fts_query) {
|
||||
table->m_needs_reopen = true;
|
||||
}
|
||||
);
|
||||
|
||||
prebuilt->keep_other_fields_on_keyread = 0;
|
||||
prebuilt->read_just_key = 0;
|
||||
prebuilt->in_fts_query = 0;
|
||||
|
|
@ -15774,15 +15978,12 @@ innobase_fts_close_ranking(
|
|||
{
|
||||
fts_result_t* result;
|
||||
|
||||
((NEW_FT_INFO*) fts_hdl)->ft_prebuilt->in_fts_query = false;
|
||||
|
||||
result = ((NEW_FT_INFO*) fts_hdl)->ft_result;
|
||||
|
||||
fts_query_free_result(result);
|
||||
|
||||
my_free((uchar*) fts_hdl);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -17103,6 +17304,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(sync_array_size),
|
||||
MYSQL_SYSVAR(compression_failure_threshold_pct),
|
||||
MYSQL_SYSVAR(compression_pad_pct_max),
|
||||
MYSQL_SYSVAR(simulate_comp_failures),
|
||||
#ifdef UNIV_DEBUG
|
||||
MYSQL_SYSVAR(trx_rseg_n_slots_debug),
|
||||
MYSQL_SYSVAR(limit_optimistic_insert_debug),
|
||||
|
|
@ -17110,7 +17312,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(fil_make_page_dirty_debug),
|
||||
MYSQL_SYSVAR(saved_page_number_debug),
|
||||
#endif /* UNIV_DEBUG */
|
||||
MYSQL_SYSVAR(simulate_comp_failures),
|
||||
MYSQL_SYSVAR(tmpdir),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2712,6 +2712,10 @@ prepare_inplace_alter_table_dict(
|
|||
|
||||
ctx->num_to_add_index = ha_alter_info->index_add_count;
|
||||
|
||||
ut_ad(ctx->prebuilt->trx->mysql_thd != NULL);
|
||||
const char* path = thd_innodb_tmpdir(
|
||||
ctx->prebuilt->trx->mysql_thd);
|
||||
|
||||
index_defs = innobase_create_key_defs(
|
||||
ctx->heap, ha_alter_info, altered_table, ctx->num_to_add_index,
|
||||
num_fts_index,
|
||||
|
|
@ -3054,8 +3058,10 @@ prepare_inplace_alter_table_dict(
|
|||
error = DB_OUT_OF_MEMORY;
|
||||
goto error_handling;);
|
||||
rw_lock_x_lock(&ctx->add_index[a]->lock);
|
||||
|
||||
bool ok = row_log_allocate(ctx->add_index[a],
|
||||
NULL, true, NULL, NULL);
|
||||
NULL, true, NULL,
|
||||
NULL, path);
|
||||
rw_lock_x_unlock(&ctx->add_index[a]->lock);
|
||||
|
||||
if (!ok) {
|
||||
|
|
@ -3081,7 +3087,7 @@ prepare_inplace_alter_table_dict(
|
|||
clust_index, ctx->new_table,
|
||||
!(ha_alter_info->handler_flags
|
||||
& Alter_inplace_info::ADD_PK_INDEX),
|
||||
ctx->add_cols, ctx->col_map);
|
||||
ctx->add_cols, ctx->col_map, path);
|
||||
rw_lock_x_unlock(&clust_index->lock);
|
||||
|
||||
if (!ok) {
|
||||
|
|
@ -4058,6 +4064,7 @@ ok_exit:
|
|||
files and merge sort. */
|
||||
DBUG_EXECUTE_IF("innodb_OOM_inplace_alter",
|
||||
error = DB_OUT_OF_MEMORY; goto oom;);
|
||||
|
||||
error = row_merge_build_indexes(
|
||||
prebuilt->trx,
|
||||
prebuilt->table, ctx->new_table,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue