From 2a64e9a2e89456c412ba1d53026a92a53d28940c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 1 Sep 2005 16:52:59 +0400 Subject: Fix for bug #12423 "Deadlock when doing FLUSH PRIVILEGES and GRANT in multi-threaded environment". To avoid deadlocks between several simultaneously run account management commands (particularly between FLUSH PRIVILEGES/SET PASSWORD and GRANT commands) we should always take table and internal locks during their execution in the same order. In other words we should first open and lock privilege tables and only then obtain acl_cache::lock/LOCK_grant locks. mysql-test/r/grant2.result: Added test for bug #12423 "Deadlock when doing FLUSH PRIVILEGES and GRANT in multi-threaded environment". mysql-test/t/grant2.test: Added test for bug #12423 "Deadlock when doing FLUSH PRIVILEGES and GRANT in multi-threaded environment". sql/mysqld.cc: acl_init/grant_init() are now used only at server start up so they always allocate temporary THD object and don't need argument for passing pointer to it. sql/sql_acl.cc: To avoid deadlocks between several simultaneously run account management commands (particularly between FLUSH PRIVILEGES/SET PASSWORD and GRANT commands) we should always take table and internal locks during their execution in the same order. In other words we should first open and lock privilege tables and only then obtain acl_cache::lock/LOCK_grant locks. Changed acl_reload()/grant_reload() and change_password()/update_user_table() in such way that they obey this principle. Now in acl_reload()/grant_reload()/ change_password() we open and lock privilege tables, then obtain internal locks and then call acl_load()/grant_load()/update_user_table() functions to do actual loading or updating. sql/sql_acl.h: acl_init/grant_init() are now used only at server start up so they always allocate temporary THD object and don't need argument for passing pointer to it. acl_reload()/grant_reload() now are able to report about their success or failure through return value. sql/sql_parse.cc: If reload_acl_and_cache() is called from SIGHUP handler we have to allocate temporary THD for execution of acl_reload()/grant_reload(). --- sql/sql_acl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sql/sql_acl.h') diff --git a/sql/sql_acl.h b/sql/sql_acl.h index dc1b04c063a..256101ec7d8 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -134,8 +134,8 @@ public: /* prototypes */ bool hostname_requires_resolving(const char *hostname); -my_bool acl_init(THD *thd, bool dont_read_acl_tables); -void acl_reload(THD *thd); +my_bool acl_init(bool dont_read_acl_tables); +my_bool acl_reload(THD *thd); void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *user, const char *db, my_bool db_is_pattern); @@ -151,9 +151,9 @@ int mysql_grant(THD *thd, const char *db, List &user_list, int mysql_table_grant(THD *thd, TABLE_LIST *table, List &user_list, List &column_list, ulong rights, bool revoke); -my_bool grant_init(THD *thd); +my_bool grant_init(); void grant_free(void); -void grant_reload(THD *thd); +my_bool grant_reload(THD *thd); bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, uint show_command, uint number, bool dont_print_error); bool check_grant_column (THD *thd,TABLE *table, const char *name, uint length, -- cgit v1.2.1