Bug#25721

  "Concurrent ALTER/CREATE SERVER can lead to deadlock"
  Deadlock caused by inconsistant use of mutexes in sql_server.cc
  One mutex has been removed to resolve deadlock.
  Many functions were made private which should not be exported.
  Unused variables and function removed.
parent 32da2907
...@@ -189,6 +189,31 @@ drop user guest_select@localhost; ...@@ -189,6 +189,31 @@ drop user guest_select@localhost;
drop table federated.t1; drop table federated.t1;
drop server 's1'; drop server 's1';
# End of 5.1 tests # End of 5.1 tests
use test;
create procedure p1 ()
begin
DECLARE v INT DEFAULT 0;
DECLARE e INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET e = e + 1;
WHILE v < 10000 do
CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
ALTER SERVER s OPTIONS (USER 'Remote');
DROP SERVER s;
SET v = v + 1;
END WHILE;
SELECT e > 0;
END//
use test;
call p1();
call p1();
e > 0
1
e > 0
1
drop procedure p1;
drop server if exists s;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated; DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
......
...@@ -234,4 +234,39 @@ drop server 's1'; ...@@ -234,4 +234,39 @@ drop server 's1';
--echo # End of 5.1 tests --echo # End of 5.1 tests
#
# Bug#25721 - deadlock with ALTER/CREATE SERVER
#
connect (other,localhost,root,,);
connection master;
use test;
delimiter //;
create procedure p1 ()
begin
DECLARE v INT DEFAULT 0;
DECLARE e INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET e = e + 1;
WHILE v < 10000 do
CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
ALTER SERVER s OPTIONS (USER 'Remote');
DROP SERVER s;
SET v = v + 1;
END WHILE;
SELECT e > 0;
END//
delimiter ;//
connection other;
use test;
send call p1();
connection master;
call p1();
connection other;
reap;
drop procedure p1;
drop server if exists s;
source include/federated_cleanup.inc; source include/federated_cleanup.inc;
...@@ -4320,7 +4320,7 @@ mysql_execute_command(THD *thd) ...@@ -4320,7 +4320,7 @@ mysql_execute_command(THD *thd)
if ((err_code= drop_server(thd, &lex->server_options))) if ((err_code= drop_server(thd, &lex->server_options)))
{ {
if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_EXISTS) if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
{ {
DBUG_PRINT("info", ("problem dropping server %s", DBUG_PRINT("info", ("problem dropping server %s",
lex->server_options.server_name)); lex->server_options.server_name));
......
This diff is collapsed.
...@@ -25,40 +25,18 @@ typedef struct st_federated_server ...@@ -25,40 +25,18 @@ typedef struct st_federated_server
} FOREIGN_SERVER; } FOREIGN_SERVER;
/* cache handlers */ /* cache handlers */
my_bool servers_init(bool dont_read_server_table); bool servers_init(bool dont_read_server_table);
my_bool servers_reload(THD *thd); bool servers_reload(THD *thd);
my_bool get_server_from_table_to_cache(TABLE *table);
void servers_free(bool end=0); void servers_free(bool end=0);
/* insert functions */ /* insert functions */
int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options); int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options);
int insert_server(THD *thd, FOREIGN_SERVER *server_options);
int insert_server_record(TABLE *table, FOREIGN_SERVER *server);
int insert_server_record_into_cache(FOREIGN_SERVER *server);
void store_server_fields_for_insert(TABLE *table, FOREIGN_SERVER *server);
void store_server_fields_for_insert(TABLE *table,
FOREIGN_SERVER *existing,
FOREIGN_SERVER *altered);
int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
FOREIGN_SERVER *server);
/* drop functions */ /* drop functions */
int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options); int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options);
int delete_server_record(TABLE *table,
char *server_name,
int server_name_length);
int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options);
/* update functions */ /* update functions */
int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options); int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options);
int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options,
FOREIGN_SERVER *existing, /* lookup functions */
FOREIGN_SERVER *altered);
int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered);
int update_server_record(TABLE *table, FOREIGN_SERVER *server);
int update_server_record_in_cache(FOREIGN_SERVER *existing,
FOREIGN_SERVER *altered);
/* utility functions */
void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to);
FOREIGN_SERVER *get_server_by_name(const char *server_name); FOREIGN_SERVER *get_server_by_name(const char *server_name);
my_bool server_exists_in_table(THD *thd, char *server_name);
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