Skip to content

Commit 6ac84d9

Browse files
committed
5.6.35
1 parent 31d8c92 commit 6ac84d9

File tree

12 files changed

+188
-60
lines changed

12 files changed

+188
-60
lines changed

storage/innobase/dict/dict0stats.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 2009, 2015, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -1095,7 +1095,8 @@ dict_stats_analyze_index_level(
10951095
them away) which brings non-determinism. We skip only
10961096
leaf-level delete marks because delete marks on
10971097
non-leaf level do not make sense. */
1098-
if (level == 0 &&
1098+
1099+
if (level == 0 && srv_stats_include_delete_marked? 0:
10991100
rec_get_deleted_flag(
11001101
rec,
11011102
page_is_comp(btr_pcur_get_page(&pcur)))) {
@@ -1281,8 +1282,12 @@ enum page_scan_method_t {
12811282
the given page and count the number of
12821283
distinct ones, also ignore delete marked
12831284
records */
1284-
QUIT_ON_FIRST_NON_BORING/* quit when the first record that differs
1285+
QUIT_ON_FIRST_NON_BORING,/* quit when the first record that differs
12851286
from its right neighbor is found */
1287+
COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED/* scan all records on
1288+
the given page and count the number of
1289+
distinct ones, include delete marked
1290+
records */
12861291
};
12871292
/* @} */
12881293

@@ -1558,6 +1563,8 @@ dict_stats_analyze_index_below_cur(
15581563

15591564
offsets_rec = dict_stats_scan_page(
15601565
&rec, offsets1, offsets2, index, page, n_prefix,
1566+
srv_stats_include_delete_marked ?
1567+
COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED:
15611568
COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED, n_diff,
15621569
n_external_pages);
15631570

storage/innobase/fts/fts0opt.cc

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,6 @@ fts_zip_read_word(
578578
fts_zip_t* zip,/*!< in: Zip state + data */
579579
fts_string_t* word)/*!< out: uncompressed word */
580580
{
581-
#ifdef UNIV_DEBUG
582-
ulint i;
583-
#endif
584581
shortlen = 0;
585582
void* null = NULL;
586583
byte* ptr = word->f_str;
@@ -655,10 +652,9 @@ fts_zip_read_word(
655652
}
656653
}
657654

658-
#ifdef UNIV_DEBUG
659655
/* All blocks must be freed at end of inflate. */
660656
if (zip->status != Z_OK) {
661-
for (i = 0; i < ib_vector_size(zip->blocks); ++i) {
657+
for (ulint i = 0; i < ib_vector_size(zip->blocks); ++i) {
662658
if (ib_vector_getp(zip->blocks, i)) {
663659
ut_free(ib_vector_getp(zip->blocks, i));
664660
ib_vector_set(zip->blocks, i, &null);
@@ -669,7 +665,6 @@ fts_zip_read_word(
669665
if (ptr != NULL) {
670666
ut_ad(word->f_len == strlen((char*) ptr));
671667
}
672-
#endif /* UNIV_DEBUG */
673668

674669
return(zip->status == Z_OK || zip->status == Z_STREAM_END ? ptr : NULL);
675670
}

storage/innobase/handler/ha_innodb.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13359,6 +13359,37 @@ ha_innobase::get_auto_increment(
1335913359
ulonglong col_max_value = innobase_get_int_col_max_value(
1336013360
table->next_number_field);
1336113361

13362+
/** The following logic is needed to avoid duplicate key error
13363+
for autoincrement column.
13364+
13365+
(1) InnoDB gives the current autoincrement value with respect
13366+
to increment and offset value.
13367+
13368+
(2) Basically it does compute_next_insert_id() logic inside InnoDB
13369+
to avoid the current auto increment value changed by handler layer.
13370+
13371+
(3) It is restricted only for insert operations. */
13372+
13373+
if (increment > 1 && thd_sql_command(user_thd) != SQLCOM_ALTER_TABLE
13374+
&& autoinc < col_max_value) {
13375+
13376+
ulonglong prev_auto_inc = autoinc;
13377+
13378+
autoinc = ((autoinc - 1) + increment - offset)/ increment;
13379+
13380+
autoinc = autoinc * increment + offset;
13381+
13382+
/* If autoinc exceeds the col_max_value then reset
13383+
to old autoinc value. Because in case of non-strict
13384+
sql mode, boundary value is not considered as error. */
13385+
13386+
if (autoinc >= col_max_value) {
13387+
autoinc = prev_auto_inc;
13388+
}
13389+
13390+
ut_ad(autoinc > 0);
13391+
}
13392+
1336213393
/* Called for the first time ? */
1336313394
if (trx->n_autoinc_rows == 0) {
1336413395

@@ -15880,6 +15911,12 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
1588015911
"Disable with --skip-innodb-doublewrite.",
1588115912
NULL, NULL, TRUE);
1588215913

15914+
static MYSQL_SYSVAR_BOOL(stats_include_delete_marked,
15915+
srv_stats_include_delete_marked,
15916+
PLUGIN_VAR_OPCMDARG,
15917+
"Scan delete marked records for persistent stat",
15918+
NULL, NULL, FALSE);
15919+
1588315920
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
1588415921
PLUGIN_VAR_RQCMDARG,
1588515922
"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[]= {
1668116718
MYSQL_SYSVAR(data_file_path),
1668216719
MYSQL_SYSVAR(data_home_dir),
1668316720
MYSQL_SYSVAR(doublewrite),
16721+
MYSQL_SYSVAR(stats_include_delete_marked),
1668416722
MYSQL_SYSVAR(api_enable_binlog),
1668516723
MYSQL_SYSVAR(api_enable_mdl),
1668616724
MYSQL_SYSVAR(api_disable_rowlock),

storage/innobase/handler/handler0alter.cc

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,7 @@ innobase_fts_check_doc_id_index_in_def(
17091709

17101710
return(FTS_NOT_EXIST_DOC_ID_INDEX);
17111711
}
1712+
17121713
/*******************************************************************//**
17131714
Create an index table where indexes are ordered as follows:
17141715
@@ -1775,26 +1776,11 @@ innobase_create_key_defs(
17751776
(only prefix/part of the column is indexed), MySQL will treat the
17761777
index as a PRIMARY KEY unless the table already has one. */
17771778

1778-
if (n_add > 0 && !new_primary && got_default_clust
1779-
&& (key_info[*add].flags & HA_NOSAME)
1780-
&& !(key_info[*add].flags & HA_KEY_HAS_PART_KEY_SEG)) {
1781-
uint key_part = key_info[*add].user_defined_key_parts;
1782-
1783-
new_primary = true;
1779+
ut_ad(altered_table->s->primary_key == 0
1780+
|| altered_table->s->primary_key == MAX_KEY);
17841781

1785-
while (key_part--) {
1786-
const uint maybe_null
1787-
= key_info[*add].key_part[key_part].key_type
1788-
& FIELDFLAG_MAYBE_NULL;
1789-
DBUG_ASSERT(!maybe_null
1790-
== !key_info[*add].key_part[key_part].
1791-
field->real_maybe_null());
1792-
1793-
if (maybe_null) {
1794-
new_primary = false;
1795-
break;
1796-
}
1797-
}
1782+
if (got_default_clust && !new_primary) {
1783+
new_primary = (altered_table->s->primary_key != MAX_KEY);
17981784
}
17991785

18001786
const bool rebuild = new_primary || add_fts_doc_id
@@ -1812,8 +1798,14 @@ innobase_create_key_defs(
18121798
ulint primary_key_number;
18131799

18141800
if (new_primary) {
1815-
DBUG_ASSERT(n_add > 0);
1816-
primary_key_number = *add;
1801+
if (n_add == 0) {
1802+
DBUG_ASSERT(got_default_clust);
1803+
DBUG_ASSERT(altered_table->s->primary_key
1804+
== 0);
1805+
primary_key_number = 0;
1806+
} else {
1807+
primary_key_number = *add;
1808+
}
18171809
} else if (got_default_clust) {
18181810
/* Create the GEN_CLUST_INDEX */
18191811
index_def_t* index = indexdef++;
@@ -2900,6 +2892,8 @@ prepare_inplace_alter_table_dict(
29002892
ctx->add_cols = add_cols;
29012893
} else {
29022894
DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info));
2895+
DBUG_ASSERT(old_table->s->primary_key
2896+
== altered_table->s->primary_key);
29032897

29042898
if (!ctx->new_table->fts
29052899
&& innobase_fulltext_exist(altered_table)) {
@@ -3892,6 +3886,27 @@ ha_innobase::prepare_inplace_alter_table(
38923886
add_fts_doc_id_idx));
38933887
}
38943888

3889+
/** Get the name of an erroneous key.
3890+
@param[in] error_key_num InnoDB number of the erroneus key
3891+
@param[in] ha_alter_info changes that were being performed
3892+
@param[in] table InnoDB table
3893+
@return the name of the erroneous key */
3894+
static
3895+
const char*
3896+
get_error_key_name(
3897+
ulint error_key_num,
3898+
const Alter_inplace_info* ha_alter_info,
3899+
const dict_table_t* table)
3900+
{
3901+
if (error_key_num == ULINT_UNDEFINED) {
3902+
return(FTS_DOC_ID_INDEX_NAME);
3903+
} else if (ha_alter_info->key_count == 0) {
3904+
return(dict_table_get_first_index(table)->name);
3905+
} else {
3906+
return(ha_alter_info->key_info_buffer[error_key_num].name);
3907+
}
3908+
}
3909+
38953910
/** Alter the table structure in-place with operations
38963911
specified using Alter_inplace_info.
38973912
The level of concurrency allowed during this operation depends
@@ -4009,17 +4024,13 @@ ha_innobase::inplace_alter_table(
40094024
case DB_ONLINE_LOG_TOO_BIG:
40104025
DBUG_ASSERT(ctx->online);
40114026
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
4012-
(prebuilt->trx->error_key_num == ULINT_UNDEFINED)
4013-
? FTS_DOC_ID_INDEX_NAME
4014-
: ha_alter_info->key_info_buffer[
4015-
prebuilt->trx->error_key_num].name);
4027+
get_error_key_name(prebuilt->trx->error_key_num,
4028+
ha_alter_info, prebuilt->table));
40164029
break;
40174030
case DB_INDEX_CORRUPT:
40184031
my_error(ER_INDEX_CORRUPT, MYF(0),
4019-
(prebuilt->trx->error_key_num == ULINT_UNDEFINED)
4020-
? FTS_DOC_ID_INDEX_NAME
4021-
: ha_alter_info->key_info_buffer[
4022-
prebuilt->trx->error_key_num].name);
4032+
get_error_key_name(prebuilt->trx->error_key_num,
4033+
ha_alter_info, prebuilt->table));
40234034
break;
40244035
default:
40254036
my_error_innodb(error,
@@ -4829,7 +4840,6 @@ innobase_update_foreign_cache(
48294840
"Foreign key constraints for table '%s'"
48304841
" are loaded with charset check off",
48314842
user_table->name);
4832-
48334843
}
48344844
}
48354845

@@ -4929,14 +4939,13 @@ commit_try_rebuild(
49294939
DBUG_RETURN(true);
49304940
case DB_ONLINE_LOG_TOO_BIG:
49314941
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
4932-
ha_alter_info->key_info_buffer[0].name);
4942+
get_error_key_name(err_key, ha_alter_info,
4943+
rebuilt_table));
49334944
DBUG_RETURN(true);
49344945
case DB_INDEX_CORRUPT:
49354946
my_error(ER_INDEX_CORRUPT, MYF(0),
4936-
(err_key == ULINT_UNDEFINED)
4937-
? FTS_DOC_ID_INDEX_NAME
4938-
: ha_alter_info->key_info_buffer[err_key]
4939-
.name);
4947+
get_error_key_name(err_key, ha_alter_info,
4948+
rebuilt_table));
49404949
DBUG_RETURN(true);
49414950
default:
49424951
my_error_innodb(error, table_name, user_table->flags);

storage/innobase/include/os0thread.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,25 @@ os_thread_create_func(
117117
os_thread_id_t*thread_id);/*!< out: id of the created
118118
thread, or NULL */
119119

120+
/** Waits until the specified thread completes and joins it.
121+
Its return value is ignored.
122+
@param[in,out] thread thread to join */
123+
UNIV_INTERN
124+
void
125+
os_thread_join(
126+
os_thread_tthread);
127+
120128
/*****************************************************************//**
121129
Exits the current thread. */
122130
UNIV_INTERN
123131
void
124132
os_thread_exit(
125133
/*===========*/
126-
void*exit_value)/*!< in: exit value; in Windows this void*
134+
void*exit_value,/*!< in: exit value; in Windows this void*
127135
is cast as a DWORD */
136+
booldetach = true)/*!< in: if true, the thread will be detached
137+
right before exiting. If false, another thread
138+
is responsible for joining this thread. */
128139
UNIV_COLD MY_ATTRIBUTE((noreturn));
129140
/*****************************************************************//**
130141
Returns the thread identifier of current thread.

storage/innobase/include/srv0srv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ extern unsigned long long srv_stats_transient_sample_pages;
347347
extern my_boolsrv_stats_persistent;
348348
extern unsigned long longsrv_stats_persistent_sample_pages;
349349
extern my_boolsrv_stats_auto_recalc;
350+
extern my_boolsrv_stats_include_delete_marked;
350351

351352
extern iboolsrv_use_doublewrite_buf;
352353
extern ulongsrv_doublewrite_batch_size;

storage/innobase/mach/mach0data.cc

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -55,40 +55,71 @@ mach_parse_compressed(
5555
if (flag < 0x80UL) {
5656
*val = flag;
5757
return(ptr + 1);
58+
}
59+
60+
/* Workaround GCC bug
61+
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
62+
the compiler moves mach_read_from_4 right to the beginning of the
63+
function, causing and out-of-bounds read if we are reading a short
64+
integer close to the end of buffer. */
65+
#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
66+
#define DEPLOY_FENCE
67+
#endif
68+
69+
#ifdef DEPLOY_FENCE
70+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
71+
#endif
5872

59-
} else if (flag < 0xC0UL) {
73+
if (flag < 0xC0UL) {
6074
if (end_ptr < ptr + 2) {
6175
return(NULL);
6276
}
6377

6478
*val = mach_read_from_2(ptr) & 0x7FFFUL;
6579

6680
return(ptr + 2);
81+
}
82+
83+
#ifdef DEPLOY_FENCE
84+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
85+
#endif
6786

68-
} else if (flag < 0xE0UL) {
87+
if (flag < 0xE0UL) {
6988
if (end_ptr < ptr + 3) {
7089
return(NULL);
7190
}
7291

7392
*val = mach_read_from_3(ptr) & 0x3FFFFFUL;
7493

7594
return(ptr + 3);
76-
} else if (flag < 0xF0UL) {
95+
}
96+
97+
#ifdef DEPLOY_FENCE
98+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
99+
#endif
100+
101+
if (flag < 0xF0UL) {
77102
if (end_ptr < ptr + 4) {
78103
return(NULL);
79104
}
80105

81106
*val = mach_read_from_4(ptr) & 0x1FFFFFFFUL;
82107

83108
return(ptr + 4);
84-
} else {
85-
ut_ad(flag == 0xF0UL);
109+
}
86110

87-
if (end_ptr < ptr + 5) {
88-
return(NULL);
89-
}
111+
#ifdef DEPLOY_FENCE
112+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
113+
#endif
114+
115+
#undef DEPLOY_FENCE
116+
117+
ut_ad(flag == 0xF0UL);
90118

91-
*val = mach_read_from_4(ptr + 1);
92-
return(ptr + 5);
119+
if (end_ptr < ptr + 5) {
120+
return(NULL);
93121
}
122+
123+
*val = mach_read_from_4(ptr + 1);
124+
return(ptr + 5);
94125
}

0 commit comments

Comments
 (0)