summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <guilhem@mysql.com>2004-12-02 23:02:38 +0100
committerunknown <guilhem@mysql.com>2004-12-02 23:02:38 +0100
commit75fa4c00ef6eaacfd0ce3381627269ea415ac0eb (patch)
treefa1a5fa41aa9adfc6fb1b42cb9b732f551625e0f /sql
parentd967118ff655ce9e220e92c30b83e79740af7dda (diff)
downloadmariadb-git-75fa4c00ef6eaacfd0ce3381627269ea415ac0eb.tar.gz
Making FLUSH TABLES WITH READ LOCK killable while it's waiting for running commits to finish. Normally this step is not long but it's still nice to be killable
(especially in case of bug like BUG#6732 "FLUSH TABLES WITH READ LOCK + COMMIT makes next FLUSH...LOCK hang forever"). sql/lock.cc: making FLUSH TABLES WITH READ LOCK killable while it's waiting for running commits to finish sql/mysql_priv.h: prototype change sql/sql_parse.cc: now it's possible that make_global_read_lock_block_commit fails (killed)
Diffstat (limited to 'sql')
-rw-r--r--sql/lock.cc24
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/sql_parse.cc7
3 files changed, 26 insertions, 7 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index c4f1d681b76..3367c6a2900 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -840,19 +840,33 @@ void start_waiting_global_read_lock(THD *thd)
}
-void make_global_read_lock_block_commit(THD *thd)
+bool make_global_read_lock_block_commit(THD *thd)
{
+ bool error;
+ const char *old_message;
+ DBUG_ENTER("make_global_read_lock_block_commit");
/*
If we didn't succeed lock_global_read_lock(), or if we already suceeded
make_global_read_lock_block_commit(), do nothing.
*/
if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
- return;
+ DBUG_RETURN(1);
pthread_mutex_lock(&LOCK_open);
/* increment this BEFORE waiting on cond (otherwise race cond) */
global_read_lock_blocks_commit++;
- while (protect_against_global_read_lock)
+ /* For testing we set up some blocking, to see if we can be killed */
+ DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
+ protect_against_global_read_lock++;);
+ old_message= thd->enter_cond(&COND_refresh, &LOCK_open,
+ "Waiting for all running commits to finish");
+ while (protect_against_global_read_lock && !thd->killed)
pthread_cond_wait(&COND_refresh, &LOCK_open);
- pthread_mutex_unlock(&LOCK_open);
- thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
+ DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
+ protect_against_global_read_lock--;);
+ if (error= thd->killed)
+ global_read_lock_blocks_commit--; // undo what we did
+ else
+ thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
+ thd->exit_cond(old_message);
+ DBUG_RETURN(error);
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index babb0c1aa6f..09bec0a9323 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1096,7 +1096,7 @@ void unlock_global_read_lock(THD *thd);
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
bool is_not_commit);
void start_waiting_global_read_lock(THD *thd);
-void make_global_read_lock_block_commit(THD *thd);
+bool make_global_read_lock_block_commit(THD *thd);
/* Lock based on name */
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c04312f6ded..e27cd20e15e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5746,7 +5746,12 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
return 1;
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
tables);
- make_global_read_lock_block_commit(thd);
+ if (make_global_read_lock_block_commit(thd))
+ {
+ /* Don't leave things in a half-locked state */
+ unlock_global_read_lock(thd);
+ return 1;
+ }
}
else
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);