Commit 6ac84d98 authored by vicentiu's avatar vicentiu

5.6.35

parent 31d8c922
/*****************************************************************************
Copyright (c) 2009, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, 2016, 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
......@@ -1095,7 +1095,8 @@ dict_stats_analyze_index_level(
them away) which brings non-determinism. We skip only
leaf-level delete marks because delete marks on
non-leaf level do not make sense. */
if (level == 0 &&
if (level == 0 && srv_stats_include_delete_marked? 0:
rec_get_deleted_flag(
rec,
page_is_comp(btr_pcur_get_page(&pcur)))) {
......@@ -1281,8 +1282,12 @@ enum page_scan_method_t {
the given page and count the number of
distinct ones, also ignore delete marked
records */
QUIT_ON_FIRST_NON_BORING/* quit when the first record that differs
QUIT_ON_FIRST_NON_BORING,/* quit when the first record that differs
from its right neighbor is found */
COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED/* scan all records on
the given page and count the number of
distinct ones, include delete marked
records */
};
/* @} */
......@@ -1558,6 +1563,8 @@ dict_stats_analyze_index_below_cur(
offsets_rec = dict_stats_scan_page(
&rec, offsets1, offsets2, index, page, n_prefix,
srv_stats_include_delete_marked ?
COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED:
COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED, n_diff,
n_external_pages);
......
......@@ -578,9 +578,6 @@ fts_zip_read_word(
fts_zip_t* zip, /*!< in: Zip state + data */
fts_string_t* word) /*!< out: uncompressed word */
{
#ifdef UNIV_DEBUG
ulint i;
#endif
short len = 0;
void* null = NULL;
byte* ptr = word->f_str;
......@@ -655,10 +652,9 @@ fts_zip_read_word(
}
}
#ifdef UNIV_DEBUG
/* All blocks must be freed at end of inflate. */
if (zip->status != Z_OK) {
for (i = 0; i < ib_vector_size(zip->blocks); ++i) {
for (ulint i = 0; i < ib_vector_size(zip->blocks); ++i) {
if (ib_vector_getp(zip->blocks, i)) {
ut_free(ib_vector_getp(zip->blocks, i));
ib_vector_set(zip->blocks, i, &null);
......@@ -669,7 +665,6 @@ fts_zip_read_word(
if (ptr != NULL) {
ut_ad(word->f_len == strlen((char*) ptr));
}
#endif /* UNIV_DEBUG */
return(zip->status == Z_OK || zip->status == Z_STREAM_END ? ptr : NULL);
}
......
......@@ -13359,6 +13359,37 @@ ha_innobase::get_auto_increment(
ulonglong col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
/** The following logic is needed to avoid duplicate key error
for autoincrement column.
(1) InnoDB gives the current autoincrement value with respect
to increment and offset value.
(2) Basically it does compute_next_insert_id() logic inside InnoDB
to avoid the current auto increment value changed by handler layer.
(3) It is restricted only for insert operations. */
if (increment > 1 && thd_sql_command(user_thd) != SQLCOM_ALTER_TABLE
&& autoinc < col_max_value) {
ulonglong prev_auto_inc = autoinc;
autoinc = ((autoinc - 1) + increment - offset)/ increment;
autoinc = autoinc * increment + offset;
/* If autoinc exceeds the col_max_value then reset
to old autoinc value. Because in case of non-strict
sql mode, boundary value is not considered as error. */
if (autoinc >= col_max_value) {
autoinc = prev_auto_inc;
}
ut_ad(autoinc > 0);
}
/* Called for the first time ? */
if (trx->n_autoinc_rows == 0) {
......@@ -15880,6 +15911,12 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE);
static MYSQL_SYSVAR_BOOL(stats_include_delete_marked,
srv_stats_include_delete_marked,
PLUGIN_VAR_OPCMDARG,
"Scan delete marked records for persistent stat",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG,
"Number of IOPs the server can do. Tunes the background IO rate",
......@@ -16681,6 +16718,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(stats_include_delete_marked),
MYSQL_SYSVAR(api_enable_binlog),
MYSQL_SYSVAR(api_enable_mdl),
MYSQL_SYSVAR(api_disable_rowlock),
......
......@@ -1709,6 +1709,7 @@ innobase_fts_check_doc_id_index_in_def(
return(FTS_NOT_EXIST_DOC_ID_INDEX);
}
/*******************************************************************//**
Create an index table where indexes are ordered as follows:
......@@ -1775,26 +1776,11 @@ innobase_create_key_defs(
(only prefix/part of the column is indexed), MySQL will treat the
index as a PRIMARY KEY unless the table already has one. */
if (n_add > 0 && !new_primary && got_default_clust
&& (key_info[*add].flags & HA_NOSAME)
&& !(key_info[*add].flags & HA_KEY_HAS_PART_KEY_SEG)) {
uint key_part = key_info[*add].user_defined_key_parts;
new_primary = true;
while (key_part--) {
const uint maybe_null
= key_info[*add].key_part[key_part].key_type
& FIELDFLAG_MAYBE_NULL;
DBUG_ASSERT(!maybe_null
== !key_info[*add].key_part[key_part].
field->real_maybe_null());
ut_ad(altered_table->s->primary_key == 0
|| altered_table->s->primary_key == MAX_KEY);
if (maybe_null) {
new_primary = false;
break;
}
}
if (got_default_clust && !new_primary) {
new_primary = (altered_table->s->primary_key != MAX_KEY);
}
const bool rebuild = new_primary || add_fts_doc_id
......@@ -1812,8 +1798,14 @@ innobase_create_key_defs(
ulint primary_key_number;
if (new_primary) {
DBUG_ASSERT(n_add > 0);
if (n_add == 0) {
DBUG_ASSERT(got_default_clust);
DBUG_ASSERT(altered_table->s->primary_key
== 0);
primary_key_number = 0;
} else {
primary_key_number = *add;
}
} else if (got_default_clust) {
/* Create the GEN_CLUST_INDEX */
index_def_t* index = indexdef++;
......@@ -2900,6 +2892,8 @@ prepare_inplace_alter_table_dict(
ctx->add_cols = add_cols;
} else {
DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info));
DBUG_ASSERT(old_table->s->primary_key
== altered_table->s->primary_key);
if (!ctx->new_table->fts
&& innobase_fulltext_exist(altered_table)) {
......@@ -3892,6 +3886,27 @@ ha_innobase::prepare_inplace_alter_table(
add_fts_doc_id_idx));
}
/** Get the name of an erroneous key.
@param[in] error_key_num InnoDB number of the erroneus key
@param[in] ha_alter_info changes that were being performed
@param[in] table InnoDB table
@return the name of the erroneous key */
static
const char*
get_error_key_name(
ulint error_key_num,
const Alter_inplace_info* ha_alter_info,
const dict_table_t* table)
{
if (error_key_num == ULINT_UNDEFINED) {
return(FTS_DOC_ID_INDEX_NAME);
} else if (ha_alter_info->key_count == 0) {
return(dict_table_get_first_index(table)->name);
} else {
return(ha_alter_info->key_info_buffer[error_key_num].name);
}
}
/** Alter the table structure in-place with operations
specified using Alter_inplace_info.
The level of concurrency allowed during this operation depends
......@@ -4009,17 +4024,13 @@ ha_innobase::inplace_alter_table(
case DB_ONLINE_LOG_TOO_BIG:
DBUG_ASSERT(ctx->online);
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
(prebuilt->trx->error_key_num == ULINT_UNDEFINED)
? FTS_DOC_ID_INDEX_NAME
: ha_alter_info->key_info_buffer[
prebuilt->trx->error_key_num].name);
get_error_key_name(prebuilt->trx->error_key_num,
ha_alter_info, prebuilt->table));
break;
case DB_INDEX_CORRUPT:
my_error(ER_INDEX_CORRUPT, MYF(0),
(prebuilt->trx->error_key_num == ULINT_UNDEFINED)
? FTS_DOC_ID_INDEX_NAME
: ha_alter_info->key_info_buffer[
prebuilt->trx->error_key_num].name);
get_error_key_name(prebuilt->trx->error_key_num,
ha_alter_info, prebuilt->table));
break;
default:
my_error_innodb(error,
......@@ -4829,7 +4840,6 @@ innobase_update_foreign_cache(
"Foreign key constraints for table '%s'"
" are loaded with charset check off",
user_table->name);
}
}
......@@ -4929,14 +4939,13 @@ commit_try_rebuild(
DBUG_RETURN(true);
case DB_ONLINE_LOG_TOO_BIG:
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
ha_alter_info->key_info_buffer[0].name);
get_error_key_name(err_key, ha_alter_info,
rebuilt_table));
DBUG_RETURN(true);
case DB_INDEX_CORRUPT:
my_error(ER_INDEX_CORRUPT, MYF(0),
(err_key == ULINT_UNDEFINED)
? FTS_DOC_ID_INDEX_NAME
: ha_alter_info->key_info_buffer[err_key]
.name);
get_error_key_name(err_key, ha_alter_info,
rebuilt_table));
DBUG_RETURN(true);
default:
my_error_innodb(error, table_name, user_table->flags);
......
......@@ -117,14 +117,25 @@ os_thread_create_func(
os_thread_id_t* thread_id); /*!< out: id of the created
thread, or NULL */
/** Waits until the specified thread completes and joins it.
Its return value is ignored.
@param[in,out] thread thread to join */
UNIV_INTERN
void
os_thread_join(
os_thread_t thread);
/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
void* exit_value) /*!< in: exit value; in Windows this void*
void* exit_value, /*!< in: exit value; in Windows this void*
is cast as a DWORD */
bool detach = true) /*!< in: if true, the thread will be detached
right before exiting. If false, another thread
is responsible for joining this thread. */
UNIV_COLD MY_ATTRIBUTE((noreturn));
/*****************************************************************//**
Returns the thread identifier of current thread.
......
......@@ -347,6 +347,7 @@ extern unsigned long long srv_stats_transient_sample_pages;
extern my_bool srv_stats_persistent;
extern unsigned long long srv_stats_persistent_sample_pages;
extern my_bool srv_stats_auto_recalc;
extern my_bool srv_stats_include_delete_marked;
extern ibool srv_use_doublewrite_buf;
extern ulong srv_doublewrite_batch_size;
......
/*****************************************************************************
Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2016, 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
......@@ -55,8 +55,22 @@ mach_parse_compressed(
if (flag < 0x80UL) {
*val = flag;
return(ptr + 1);
}
/* Workaround GCC bug
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
the compiler moves mach_read_from_4 right to the beginning of the
function, causing and out-of-bounds read if we are reading a short
integer close to the end of buffer. */
#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
#define DEPLOY_FENCE
#endif
#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif
} else if (flag < 0xC0UL) {
if (flag < 0xC0UL) {
if (end_ptr < ptr + 2) {
return(NULL);
}
......@@ -64,8 +78,13 @@ mach_parse_compressed(
*val = mach_read_from_2(ptr) & 0x7FFFUL;
return(ptr + 2);
}
#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif
} else if (flag < 0xE0UL) {
if (flag < 0xE0UL) {
if (end_ptr < ptr + 3) {
return(NULL);
}
......@@ -73,7 +92,13 @@ mach_parse_compressed(
*val = mach_read_from_3(ptr) & 0x3FFFFFUL;
return(ptr + 3);
} else if (flag < 0xF0UL) {
}
#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif
if (flag < 0xF0UL) {
if (end_ptr < ptr + 4) {
return(NULL);
}
......@@ -81,7 +106,14 @@ mach_parse_compressed(
*val = mach_read_from_4(ptr) & 0x1FFFFFFFUL;
return(ptr + 4);
} else {
}
#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif
#undef DEPLOY_FENCE
ut_ad(flag == 0xF0UL);
if (end_ptr < ptr + 5) {
......@@ -90,5 +122,4 @@ mach_parse_compressed(
*val = mach_read_from_4(ptr + 1);
return(ptr + 5);
}
}
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2016, 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
......@@ -191,14 +191,38 @@ os_thread_create_func(
#endif
}
/** Waits until the specified thread completes and joins it.
Its return value is ignored.
@param[in,out] thread thread to join */
UNIV_INTERN
void
os_thread_join(
os_thread_t thread)
{
#ifdef __WIN__
/* Do nothing. */
#else
#ifdef UNIV_DEBUG
const int ret =
#endif /* UNIV_DEBUG */
pthread_join(thread, NULL);
/* Waiting on already-quit threads is allowed. */
ut_ad(ret == 0 || ret == ESRCH);
#endif /* __WIN__ */
}
/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
void* exit_value) /*!< in: exit value; in Windows this void*
void* exit_value, /*!< in: exit value; in Windows this void*
is cast as a DWORD */
bool detach) /*!< in: if true, the thread will be detached
right before exiting. If false, another thread
is responsible for joining this thread. */
{
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Thread exits, id %lu\n",
......@@ -216,7 +240,9 @@ os_thread_exit(
#ifdef __WIN__
ExitThread((DWORD) exit_value);
#else
if (detach) {
pthread_detach(pthread_self());
}
pthread_exit(exit_value);
#endif
}
......
......@@ -957,7 +957,7 @@ fts_parallel_merge(
CloseHandle(psort_info->thread_hdl);
#endif /*__WIN__ */
os_thread_exit(NULL);
os_thread_exit(NULL, false);
OS_THREAD_DUMMY_RETURN;
}
......
......@@ -3774,6 +3774,13 @@ row_merge_build_indexes(
" exited when creating FTS"
" index '%s'",
indexes[i]->name);
} else {
for (j = 0; j < FTS_NUM_AUX_INDEX;
j++) {
os_thread_join(merge_info[j]
.thread_hdl);
}
}
} else {
/* This cannot report duplicates; an
......
......@@ -1362,6 +1362,8 @@ row_insert_for_mysql(
row_ins_step(thr);
DEBUG_SYNC_C("ib_after_row_insert_step");
err = trx->error_state;
if (err != DB_SUCCESS) {
......
......@@ -340,6 +340,7 @@ this many index pages, there are 2 ways to calculate statistics:
table/index are not found in the innodb database */
UNIV_INTERN unsigned long long srv_stats_transient_sample_pages = 8;
UNIV_INTERN my_bool srv_stats_persistent = TRUE;
UNIV_INTERN my_bool srv_stats_include_delete_marked = FALSE;
UNIV_INTERN unsigned long long srv_stats_persistent_sample_pages = 20;
UNIV_INTERN my_bool srv_stats_auto_recalc = TRUE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment