Below is the list of changes that have just been committed into a local
6.0 repository of rafal. When rafal does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-15 12:51:25+01:00, rafal@quant.(none) +1 -0
This patch fixes some problems in the locking thread implementation.
sql/backup/be_thread.cc@stripped, 2008-02-15 12:51:21+01:00, rafal@quant.(none) +25 -17
1. Protect the section which locks tables with THR_LOCK_caller to avoid race conditions
with kill_locking_thread().
2. Setup Locking_thread_st::thd_name before spawning locking thread, as it refers to it
internally.
3. Set "lock error" proc info for the main thread, not inside the locking thread.
diff -Nrup a/sql/backup/be_thread.cc b/sql/backup/be_thread.cc
--- a/sql/backup/be_thread.cc 2008-02-15 04:51:17 +01:00
+++ b/sql/backup/be_thread.cc 2008-02-15 12:51:21 +01:00
@@ -122,58 +122,63 @@ pthread_handler_t backup_thread_for_lock
DBUG_PRINT("info",("Online backup creating THD struct for thread"));
THD *thd= create_new_thd();
+ if (thd == 0 || thd->killed)
+ {
+ locking_thd->lock_state= LOCK_ERROR;
+ goto end2;
+ }
+
THD_SET_PROC_INFO(thd, "Locking thread started");
thd->query= locking_thd->thd_name.c_ptr();
thd->query_length= locking_thd->thd_name.length();
pthread_detach_this_thread();
locking_thd->lock_thd= thd;
- if (thd == 0)
- {
- THD_SET_PROC_INFO(thd, "lock error");
- locking_thd->lock_state= LOCK_ERROR;
- goto end2;
- }
- if (thd->killed)
- {
- THD_SET_PROC_INFO(thd, "lock error");
- locking_thd->lock_state= LOCK_ERROR;
- goto end2;
- }
/*
Now open and lock the tables.
*/
+
DBUG_PRINT("info",("Online backup open tables in thread"));
if (!locking_thd->tables_in_backup)
{
DBUG_PRINT("info",("Online backup locking error no tables to lock"));
- THD_SET_PROC_INFO(thd, "lock error");
locking_thd->lock_state= LOCK_ERROR;
goto end2;
}
+ pthread_mutex_lock(&locking_thd->THR_LOCK_caller);
+
+ if (thd->killed)
+ {
+ locking_thd->lock_state= LOCK_ERROR;
+ pthread_mutex_unlock(&locking_thd->THR_LOCK_caller);
+ goto end;
+ }
+
/*
As locking tables can be a long operation, we need to support
killing the thread. In this case, we need to close the tables
and exit.
*/
- if (!thd->killed && open_and_lock_tables(thd, locking_thd->tables_in_backup))
+ if (open_and_lock_tables(thd, locking_thd->tables_in_backup))
{
DBUG_PRINT("info",("Online backup locking thread dying"));
- THD_SET_PROC_INFO(thd, "lock error");
locking_thd->lock_state= LOCK_ERROR;
+ pthread_mutex_unlock(&locking_thd->THR_LOCK_caller);
goto end;
}
if (thd->killed)
{
- THD_SET_PROC_INFO(thd, "lock error");
locking_thd->lock_state= LOCK_ERROR;
+ pthread_mutex_unlock(&locking_thd->THR_LOCK_caller);
goto end;
}
+ pthread_mutex_unlock(&locking_thd->THR_LOCK_caller);
+
/*
Part of work is done. Rest until woken up.
We wait if the thread is not killed and the driver has not signaled us.
@@ -286,10 +291,10 @@ result_t Locking_thread_st::start_lockin
{
DBUG_ENTER("Locking_thread_st::start_locking_thread");
pthread_t th;
+ thd_name.append(tname);
if (pthread_create(&th, &connection_attrib,
backup_thread_for_locking, this))
SET_STATE_TO_ERROR_AND_DBUG_RETURN;
- thd_name.append(tname);
DBUG_RETURN(backup::OK);
}
@@ -304,6 +309,9 @@ void Locking_thread_st::kill_locking_thr
{
DBUG_ENTER("Locking_thread_st::kill_locking_thread");
pthread_mutex_lock(&THR_LOCK_caller);
+ if (lock_state == LOCK_ERROR)
+ THD_SET_PROC_INFO(m_thd, "lock error");
+
if (lock_thd && (lock_state != LOCK_DONE) && (lock_state != LOCK_SIGNAL))
{
lock_state= LOCK_SIGNAL;
| Thread |
|---|
| • bk commit into 6.0 tree (rafal:1.2562) | rsomla | 15 Feb |