mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge 10.1 into 10.2
Rewrite the MDEV-13818 fix to prevent heap-use-after-free. Add a test case for MDEV-18272.
This commit is contained in:
@ -86,3 +86,11 @@ int main (int argc __attribute__((unused)),
|
||||
return 0;
|
||||
#endif /* DBUG_OFF */
|
||||
}
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
/* Disable LeakSanitizer in this executable */
|
||||
const char* __asan_default_options()
|
||||
{
|
||||
return "detect_leaks=0";
|
||||
}
|
||||
#endif
|
||||
|
@ -693,8 +693,12 @@ extern void my_mutex_end(void);
|
||||
We need to have at least 256K stack to handle calls to myisamchk_init()
|
||||
with the current number of keys and key parts.
|
||||
*/
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define DEFAULT_THREAD_STACK (364*1024L)
|
||||
#else
|
||||
#define DEFAULT_THREAD_STACK (292*1024L)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MY_PTHREAD_LOCK_READ 0
|
||||
#define MY_PTHREAD_LOCK_WRITE 1
|
||||
|
@ -13,7 +13,7 @@ set sql_mode=ansi_quotes;
|
||||
set global div_precision_increment=5;
|
||||
|
||||
--replace_regex /^\/\S+/PATH/
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT 372736 299008
|
||||
select * from information_schema.system_variables
|
||||
where variable_name not like 'aria%' and
|
||||
variable_name not like 'debug%' and
|
||||
|
@ -1,17 +1,17 @@
|
||||
#
|
||||
# only global
|
||||
#
|
||||
--replace_result 196608 262144
|
||||
--replace_result 372736 299008
|
||||
select @@global.thread_stack;
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
select @@session.thread_stack;
|
||||
--replace_result 196608 262144
|
||||
--replace_result 372736 299008
|
||||
show global variables like 'thread_stack';
|
||||
--replace_result 196608 262144
|
||||
--replace_result 372736 299008
|
||||
show session variables like 'thread_stack';
|
||||
--replace_result 196608 262144
|
||||
--replace_result 372736 299008
|
||||
select * from information_schema.global_variables where variable_name='thread_stack';
|
||||
--replace_result 196608 262144
|
||||
--replace_result 372736 299008
|
||||
select * from information_schema.session_variables where variable_name='thread_stack';
|
||||
|
||||
#
|
||||
|
@ -57,7 +57,7 @@ perl;
|
||||
# fixes for 32-bit
|
||||
s/\b4294967295\b/18446744073709551615/;
|
||||
s/\b2146435072\b/9223372036853727232/;
|
||||
s/\b196608\b/262144/;
|
||||
s/\b372736\b/299008/;
|
||||
s/\b4294963200\b/18446744073709547520/;
|
||||
foreach $var (@env) { s/\Q$ENV{$var}\E/$var/ }
|
||||
next if /use --skip-(use-)?symbolic-links to disable/; # for valgrind, again
|
||||
|
@ -6198,23 +6198,16 @@ dict_ind_free()
|
||||
/** Get an index by name.
|
||||
@param[in] table the table where to look for the index
|
||||
@param[in] name the index name to look for
|
||||
@param[in] committed true=search for committed,
|
||||
false=search for uncommitted
|
||||
@return index, NULL if does not exist */
|
||||
dict_index_t*
|
||||
dict_table_get_index_on_name(
|
||||
dict_table_t* table,
|
||||
const char* name,
|
||||
bool committed)
|
||||
dict_table_get_index_on_name(dict_table_t* table, const char* name)
|
||||
{
|
||||
dict_index_t* index;
|
||||
|
||||
index = dict_table_get_first_index(table);
|
||||
|
||||
while (index != NULL) {
|
||||
if (index->is_committed() == committed
|
||||
&& strcmp(index->name, name) == 0) {
|
||||
|
||||
if (index->is_committed() && !strcmp(index->name, name)) {
|
||||
return(index);
|
||||
}
|
||||
|
||||
|
@ -4860,8 +4860,7 @@ new_clustered_failed:
|
||||
|
||||
/* Create the indexes in SYS_INDEXES and load into dictionary. */
|
||||
|
||||
for (int a = 0; a < ctx->num_to_add_index; a++) {
|
||||
|
||||
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
|
||||
if (index_defs[a].ind_type & DICT_VIRTUAL
|
||||
&& ctx->num_to_drop_vcol > 0 && !new_clustered) {
|
||||
innodb_v_adjust_idx_col(ha_alter_info, old_table,
|
||||
@ -4869,17 +4868,23 @@ new_clustered_failed:
|
||||
&index_defs[a]);
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
"create_index_metadata_fail",
|
||||
if (a + 1 == ctx->num_to_add_index) {
|
||||
ctx->trx->error_state = DB_OUT_OF_FILE_SPACE;
|
||||
ctx->add_index[a] = NULL;
|
||||
goto index_created;
|
||||
});
|
||||
ctx->add_index[a] = row_merge_create_index(
|
||||
ctx->trx, ctx->new_table, &index_defs[a], add_v);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
index_created:
|
||||
#endif
|
||||
add_key_nums[a] = index_defs[a].key_number;
|
||||
|
||||
if (!ctx->add_index[a]) {
|
||||
error = ctx->trx->error_state;
|
||||
DBUG_ASSERT(error != DB_SUCCESS);
|
||||
while (--a >= 0) {
|
||||
dict_mem_index_free(ctx->add_index[a]);
|
||||
}
|
||||
goto error_handling;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2013, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
|
||||
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
|
||||
@ -1599,31 +1599,21 @@ dict_tables_have_same_db(
|
||||
/** Get an index by name.
|
||||
@param[in] table the table where to look for the index
|
||||
@param[in] name the index name to look for
|
||||
@param[in] committed true=search for committed,
|
||||
false=search for uncommitted
|
||||
@return index, NULL if does not exist */
|
||||
dict_index_t*
|
||||
dict_table_get_index_on_name(
|
||||
dict_table_t* table,
|
||||
const char* name,
|
||||
bool committed=true)
|
||||
dict_table_get_index_on_name(dict_table_t* table, const char* name)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Get an index by name.
|
||||
@param[in] table the table where to look for the index
|
||||
@param[in] name the index name to look for
|
||||
@param[in] committed true=search for committed,
|
||||
false=search for uncommitted
|
||||
@return index, NULL if does not exist */
|
||||
inline
|
||||
const dict_index_t*
|
||||
dict_table_get_index_on_name(
|
||||
const dict_table_t* table,
|
||||
const char* name,
|
||||
bool committed=true)
|
||||
dict_table_get_index_on_name(const dict_table_t* table, const char* name)
|
||||
{
|
||||
return(dict_table_get_index_on_name(
|
||||
const_cast<dict_table_t*>(table), name, committed));
|
||||
return dict_table_get_index_on_name(const_cast<dict_table_t*>(table),
|
||||
name);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2019, MariaDB Corporation.
|
||||
|
||||
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
|
||||
@ -4310,7 +4310,7 @@ dberr_t
|
||||
row_merge_create_index_graph(
|
||||
trx_t* trx,
|
||||
dict_table_t* table,
|
||||
dict_index_t* index,
|
||||
dict_index_t*& index,
|
||||
const dict_add_v_col_t* add_v)
|
||||
{
|
||||
ind_node_t* node; /*!< Index creation node */
|
||||
@ -4337,6 +4337,8 @@ row_merge_create_index_graph(
|
||||
|
||||
err = trx->error_state;
|
||||
|
||||
index = node->index;
|
||||
|
||||
que_graph_free((que_t*) que_node_get_parent(thr));
|
||||
|
||||
DBUG_RETURN(err);
|
||||
@ -4400,25 +4402,23 @@ row_merge_create_index(
|
||||
dict_mem_index_add_field(index, name, ifield->prefix_len);
|
||||
}
|
||||
|
||||
ut_d(const dict_index_t* const index_template = index);
|
||||
/* Add the index to SYS_INDEXES, using the index prototype. */
|
||||
err = row_merge_create_index_graph(trx, table, index, add_v);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
|
||||
index = dict_table_get_index_on_name(table, index_def->name,
|
||||
index_def->rebuild);
|
||||
|
||||
ut_a(index);
|
||||
|
||||
ut_ad(index != index_template);
|
||||
index->parser = index_def->parser;
|
||||
index->has_new_v_col = has_new_v_col;
|
||||
|
||||
/* Note the id of the transaction that created this
|
||||
index, we use it to restrict readers from accessing
|
||||
this index, to ensure read consistency. */
|
||||
ut_ad(index->trx_id == trx->id);
|
||||
} else {
|
||||
dict_mem_index_free(index);
|
||||
ut_ad(!index || index == index_template);
|
||||
if (index) {
|
||||
dict_mem_index_free(index);
|
||||
}
|
||||
index = NULL;
|
||||
}
|
||||
|
||||
|
@ -706,8 +706,7 @@ handle_new_error:
|
||||
switch (err) {
|
||||
case DB_LOCK_WAIT_TIMEOUT:
|
||||
if (row_rollback_on_timeout) {
|
||||
trx_rollback_to_savepoint(trx, NULL);
|
||||
break;
|
||||
goto rollback;
|
||||
}
|
||||
/* fall through */
|
||||
case DB_DUPLICATE_KEY:
|
||||
@ -726,6 +725,7 @@ handle_new_error:
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
case DB_DECRYPTION_FAILED:
|
||||
case DB_COMPUTE_VALUE_FAILED:
|
||||
rollback_to_savept:
|
||||
DBUG_EXECUTE_IF("row_mysql_crash_if_error", {
|
||||
log_buffer_flush_to_disk();
|
||||
DBUG_SUICIDE(); });
|
||||
@ -752,6 +752,7 @@ handle_new_error:
|
||||
|
||||
case DB_DEADLOCK:
|
||||
case DB_LOCK_TABLE_FULL:
|
||||
rollback:
|
||||
/* Roll back the whole transaction; this resolution was added
|
||||
to version 3.23.43 */
|
||||
|
||||
@ -773,13 +774,13 @@ handle_new_error:
|
||||
" tablespace. If the mysqld server crashes after"
|
||||
" the startup or when you dump the tables. "
|
||||
<< FORCE_RECOVERY_MSG;
|
||||
break;
|
||||
goto rollback_to_savept;
|
||||
case DB_FOREIGN_EXCEED_MAX_CASCADE:
|
||||
ib::error() << "Cannot delete/update rows with cascading"
|
||||
" foreign key constraints that exceed max depth of "
|
||||
<< FK_MAX_CASCADE_DEL << ". Please drop excessive"
|
||||
" foreign constraints and try again";
|
||||
break;
|
||||
goto rollback_to_savept;
|
||||
default:
|
||||
ib::fatal() << "Unknown error code " << err << ": "
|
||||
<< ut_strerr(err);
|
||||
|
@ -3097,10 +3097,18 @@ prepare_inplace_alter_table_dict(
|
||||
/* Create the indexes in SYS_INDEXES and load into dictionary. */
|
||||
|
||||
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
"create_index_metadata_fail",
|
||||
if (a + 1 == ctx->num_to_add_index) {
|
||||
ctx->trx->error_state = DB_OUT_OF_FILE_SPACE;
|
||||
ctx->add_index[a] = NULL;
|
||||
goto index_created;
|
||||
});
|
||||
ctx->add_index[a] = row_merge_create_index(
|
||||
ctx->trx, ctx->new_table, &index_defs[a]);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
index_created:
|
||||
#endif
|
||||
add_key_nums[a] = index_defs[a].key_number;
|
||||
|
||||
if (!ctx->add_index[a]) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
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 +85,7 @@ ut_dbg_assertion_failed(
|
||||
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
|
||||
#define ut_ad(EXPR) ut_a(EXPR)
|
||||
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
|
||||
#define ut_d(EXPR) do {EXPR;} while (0)
|
||||
#define ut_d(EXPR) EXPR
|
||||
#else
|
||||
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
|
||||
#define ut_ad(EXPR)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2019, MariaDB Corporation.
|
||||
|
||||
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
|
||||
@ -3705,7 +3705,7 @@ row_merge_create_index_graph(
|
||||
/*=========================*/
|
||||
trx_t* trx, /*!< in: trx */
|
||||
dict_table_t* table, /*!< in: table */
|
||||
dict_index_t* index) /*!< in: index */
|
||||
dict_index_t*& index) /*!< in,out: index */
|
||||
{
|
||||
ind_node_t* node; /*!< Index creation node */
|
||||
mem_heap_t* heap; /*!< Memory heap */
|
||||
@ -3729,6 +3729,8 @@ row_merge_create_index_graph(
|
||||
|
||||
err = trx->error_state;
|
||||
|
||||
index = node->index;
|
||||
|
||||
que_graph_free((que_t*) que_node_get_parent(thr));
|
||||
|
||||
return(err);
|
||||
@ -3770,20 +3772,21 @@ row_merge_create_index(
|
||||
ifield->prefix_len);
|
||||
}
|
||||
|
||||
ut_d(const dict_index_t* const index_template = index);
|
||||
/* Add the index to SYS_INDEXES, using the index prototype. */
|
||||
err = row_merge_create_index_graph(trx, table, index);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
|
||||
index = dict_table_get_index_on_name(table, index_def->name);
|
||||
|
||||
ut_a(index);
|
||||
|
||||
ut_ad(index != index_template);
|
||||
/* Note the id of the transaction that created this
|
||||
index, we use it to restrict readers from accessing
|
||||
this index, to ensure read consistency. */
|
||||
ut_ad(index->trx_id == trx->id);
|
||||
} else {
|
||||
ut_ad(!index || index == index_template);
|
||||
if (index) {
|
||||
dict_mem_index_free(index);
|
||||
}
|
||||
index = NULL;
|
||||
}
|
||||
|
||||
|
@ -615,8 +615,7 @@ handle_new_error:
|
||||
switch (err) {
|
||||
case DB_LOCK_WAIT_TIMEOUT:
|
||||
if (row_rollback_on_timeout) {
|
||||
trx_rollback_to_savepoint(trx, NULL);
|
||||
break;
|
||||
goto rollback;
|
||||
}
|
||||
/* fall through */
|
||||
case DB_DUPLICATE_KEY:
|
||||
@ -635,6 +634,7 @@ handle_new_error:
|
||||
case DB_DICT_CHANGED:
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
case DB_DECRYPTION_FAILED:
|
||||
rollback_to_savept:
|
||||
if (savept) {
|
||||
/* Roll back the latest, possibly incomplete insertion
|
||||
or update */
|
||||
@ -658,6 +658,7 @@ handle_new_error:
|
||||
|
||||
case DB_DEADLOCK:
|
||||
case DB_LOCK_TABLE_FULL:
|
||||
rollback:
|
||||
/* Roll back the whole transaction; this resolution was added
|
||||
to version 3.23.43 */
|
||||
|
||||
@ -687,14 +688,14 @@ handle_new_error:
|
||||
"InnoDB: you dump the tables, look at\n"
|
||||
"InnoDB: " REFMAN "forcing-innodb-recovery.html"
|
||||
" for help.\n", stderr);
|
||||
break;
|
||||
goto rollback_to_savept;
|
||||
case DB_FOREIGN_EXCEED_MAX_CASCADE:
|
||||
fprintf(stderr, "InnoDB: Cannot delete/update rows with"
|
||||
" cascading foreign key constraints that exceed max"
|
||||
" depth of %lu\n"
|
||||
"Please drop excessive foreign constraints"
|
||||
" and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD);
|
||||
break;
|
||||
goto rollback_to_savept;
|
||||
default:
|
||||
fprintf(stderr, "InnoDB: unknown error code %lu\n",
|
||||
(ulong) err);
|
||||
|
Reference in New Issue
Block a user