Commit 91599701 authored by Sergei Golubchik's avatar Sergei Golubchik

Bug#29363867: LOST CONNECTION TO MYSQL SERVER DURING QUERY

plugin variables in SET  only locked the plugin till the end of the
statement. If SET with a plugin variable was prepared, it was possible
to uninstall the plugin before EXECUTE. Then EXECUTE would crash,
trying to resolve a now-invalid pointer to a disappeared variable.

Fix: keep plugins locked until the prepared statement is closed.
parent 4f63b6cf
......@@ -30,3 +30,38 @@ disconnect con2;
USE test;
DROP PROCEDURE p_install;
DROP PROCEDURE p_show_vars;
#
# Bug#29363867: LOST CONNECTION TO MYSQL SERVER DURING QUERY
#
## prepared SET with a plugin variable prevents uninstall
install plugin query_response_time soname 'query_response_time';
prepare s from 'set global query_response_time_range_base=16';
select plugin_status from information_schema.plugins where plugin_name='query_response_time';
plugin_status
ACTIVE
uninstall plugin query_response_time;
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
execute s;
execute s;
select plugin_status from information_schema.plugins where plugin_name='query_response_time';
plugin_status
DELETED
deallocate prepare s;
select plugin_status from information_schema.plugins where plugin_name='query_response_time';
plugin_status
## prepared SET mentioning a plugin otherwise does not prevent uninstall
install plugin archive soname 'ha_archive';
create table t1 (a int) engine=archive;
insert t1 values (1),(2),(3);
prepare s from 'set session auto_increment_increment=(select count(*) from t1)';
flush tables;
select plugin_status from information_schema.plugins where plugin_name='archive';
plugin_status
ACTIVE
uninstall plugin archive;
select plugin_status from information_schema.plugins where plugin_name='archive';
plugin_status
execute s;
ERROR 42000: Unknown storage engine 'ARCHIVE'
drop table t1;
if (!$QUERY_RESPONSE_TIME_SO) {
skip Needs query_response_time loadable plugin;
}
if (!$HA_ARCHIVE_SO) {
skip Needs Archive loadable plugin;
}
--echo #
--echo # MDEV-5345 - Deadlock between mysql_change_user(), SHOW VARIABLES and
--echo # INSTALL PLUGIN
......@@ -54,3 +61,31 @@ disconnect con2;
USE test;
DROP PROCEDURE p_install;
DROP PROCEDURE p_show_vars;
--echo #
--echo # Bug#29363867: LOST CONNECTION TO MYSQL SERVER DURING QUERY
--echo #
--echo ## prepared SET with a plugin variable prevents uninstall
install plugin query_response_time soname 'query_response_time';
prepare s from 'set global query_response_time_range_base=16';
select plugin_status from information_schema.plugins where plugin_name='query_response_time';
uninstall plugin query_response_time;
execute s;
execute s;
select plugin_status from information_schema.plugins where plugin_name='query_response_time';
deallocate prepare s;
select plugin_status from information_schema.plugins where plugin_name='query_response_time';
--echo ## prepared SET mentioning a plugin otherwise does not prevent uninstall
install plugin archive soname 'ha_archive';
create table t1 (a int) engine=archive;
insert t1 values (1),(2),(3);
prepare s from 'set session auto_increment_increment=(select count(*) from t1)';
flush tables;
select plugin_status from information_schema.plugins where plugin_name='archive';
uninstall plugin archive;
select plugin_status from information_schema.plugins where plugin_name='archive';
--error ER_UNKNOWN_STORAGE_ENGINE
execute s;
drop table t1;
......@@ -765,15 +765,15 @@ void lex_end(LEX *lex)
DBUG_ENTER("lex_end");
DBUG_PRINT("enter", ("lex: %p", lex));
lex_end_stage1(lex);
lex_end_stage2(lex);
lex_unlock_plugins(lex);
lex_end_nops(lex);
DBUG_VOID_RETURN;
}
void lex_end_stage1(LEX *lex)
void lex_unlock_plugins(LEX *lex)
{
DBUG_ENTER("lex_end_stage1");
DBUG_ENTER("lex_unlock_plugins");
/* release used plugins */
if (lex->plugins.elements) /* No function call and no mutex if no plugins. */
......@@ -782,33 +782,23 @@ void lex_end_stage1(LEX *lex)
lex->plugins.elements);
}
reset_dynamic(&lex->plugins);
DBUG_VOID_RETURN;
}
if (lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE)
{
/*
/*
Don't delete lex->sphead, it'll be needed for EXECUTE.
Note that of all statements that populate lex->sphead
only SQLCOM_COMPOUND can be PREPAREd
*/
DBUG_ASSERT(lex->sphead == 0 || lex->sql_command == SQLCOM_COMPOUND);
}
else
{
sp_head::destroy(lex->sphead);
lex->sphead= NULL;
}
DBUG_VOID_RETURN;
}
/*
MASTER INFO parameters (or state) is normally cleared towards the end
of a statement. But in case of PS, the state needs to be preserved during
its lifetime and should only be cleared on PS close or deallocation.
*/
void lex_end_stage2(LEX *lex)
void lex_end_nops(LEX *lex)
{
DBUG_ENTER("lex_end_stage2");
DBUG_ENTER("lex_end_nops");
sp_head::destroy(lex->sphead);
lex->sphead= NULL;
/* Reset LEX_MASTER_INFO */
lex->mi.reset(lex->sql_command == SQLCOM_CHANGE_MASTER);
......
......@@ -3412,8 +3412,8 @@ extern void lex_init(void);
extern void lex_free(void);
extern void lex_start(THD *thd);
extern void lex_end(LEX *lex);
extern void lex_end_stage1(LEX *lex);
extern void lex_end_stage2(LEX *lex);
extern void lex_end_nops(LEX *lex);
extern void lex_unlock_plugins(LEX *lex);
void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex);
int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex);
extern int MYSQLlex(union YYSTYPE *yylval, THD *thd);
......
......@@ -4307,8 +4307,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
thd->release_transactional_locks();
}
/* Preserve CHANGE MASTER attributes */
lex_end_stage1(lex);
/* Preserve locked plugins for SET */
if (lex->sql_command != SQLCOM_SET_OPTION)
lex_unlock_plugins(lex);
cleanup_stmt();
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= old_stmt_arena;
......@@ -5189,7 +5191,7 @@ void Prepared_statement::deallocate_immediate()
status_var_increment(thd->status_var.com_stmt_close);
/* It should now be safe to reset CHANGE MASTER parameters */
lex_end_stage2(lex);
lex_end(lex);
}
......
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