mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug #38816: kill + flush tables with read lock + stored
procedures causes crashes! The problem of that bugreport was mostly fixed by the patch for bug 38691. However, attached test case focused on another crash or valgrind warning problem: SHOW PROCESSLIST query accesses freed memory of SP instruction that run in a parallel connection. Changes of thd->query/thd->query_length in dangerous places have been guarded with the per-thread LOCK_thd_data mutex (the THD::LOCK_delete mutex has been renamed to THD::LOCK_thd_data).
This commit is contained in:
@ -835,22 +835,16 @@ public:
|
||||
we need to declare it char * because all table handlers are written
|
||||
in C and need to point to it.
|
||||
|
||||
Note that (A) if we set query = NULL, we must at the same time set
|
||||
query_length = 0, and protect the whole operation with the
|
||||
LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a
|
||||
non-NULL value if its previous value is NULL. We do not need to protect
|
||||
operation (B) with any mutex. To avoid crashes in races, if we do not
|
||||
know that thd->query cannot change at the moment, one should print
|
||||
Note that if we set query = NULL, we must at the same time set
|
||||
query_length = 0, and protect the whole operation with
|
||||
LOCK_thd_data mutex. To avoid crashes in races, if we do not
|
||||
know that thd->query cannot change at the moment, we should print
|
||||
thd->query like this:
|
||||
(1) reserve the LOCK_thread_count mutex;
|
||||
(2) check if thd->query is NULL;
|
||||
(3) if not NULL, then print at most thd->query_length characters from
|
||||
it. We will see the query_length field as either 0, or the right value
|
||||
for it.
|
||||
Assuming that the write and read of an n-bit memory field in an n-bit
|
||||
computer is atomic, we can avoid races in the above way.
|
||||
This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB
|
||||
STATUS.
|
||||
(1) reserve the LOCK_thd_data mutex;
|
||||
(2) print or copy the value of query and query_length
|
||||
(3) release LOCK_thd_data mutex.
|
||||
This printing is needed at least in SHOW PROCESSLIST and SHOW
|
||||
ENGINE INNODB STATUS.
|
||||
*/
|
||||
char *query;
|
||||
uint32 query_length; // current query length
|
||||
@ -866,7 +860,7 @@ public:
|
||||
virtual ~Statement();
|
||||
|
||||
/* Assign execution context (note: not all members) of given stmt to self */
|
||||
void set_statement(Statement *stmt);
|
||||
virtual void set_statement(Statement *stmt);
|
||||
void set_n_backup_statement(Statement *stmt, Statement *backup);
|
||||
void restore_backup_statement(Statement *stmt, Statement *backup);
|
||||
/* return class type */
|
||||
@ -1229,7 +1223,15 @@ public:
|
||||
THR_LOCK_OWNER main_lock_id; // To use for conventional queries
|
||||
THR_LOCK_OWNER *lock_id; // If not main_lock_id, points to
|
||||
// the lock_id of a cursor.
|
||||
pthread_mutex_t LOCK_delete; // Locked before thd is deleted
|
||||
/**
|
||||
Protects THD data accessed from other threads:
|
||||
- thd->query and thd->query_length (used by SHOW ENGINE
|
||||
INNODB STATUS and SHOW PROCESSLIST
|
||||
- thd->mysys_var (used by KILL statement and shutdown).
|
||||
Is locked when THD is deleted.
|
||||
*/
|
||||
pthread_mutex_t LOCK_thd_data;
|
||||
|
||||
/* all prepared statements and cursors of this connection */
|
||||
Statement_map stmt_map;
|
||||
/*
|
||||
@ -1637,15 +1639,15 @@ public:
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
inline void set_active_vio(Vio* vio)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_delete);
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
active_vio = vio;
|
||||
pthread_mutex_unlock(&LOCK_delete);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
inline void clear_active_vio()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_delete);
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
active_vio = 0;
|
||||
pthread_mutex_unlock(&LOCK_delete);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
void close_active_vio();
|
||||
#endif
|
||||
@ -1882,6 +1884,14 @@ public:
|
||||
*/
|
||||
void pop_internal_handler();
|
||||
|
||||
/** Overloaded to guard query/query_length fields */
|
||||
virtual void set_statement(Statement *stmt);
|
||||
|
||||
/**
|
||||
Assign a new value to thd->query.
|
||||
Protected with LOCK_thd_data mutex.
|
||||
*/
|
||||
void set_query(char *query_arg, uint32 query_length_arg);
|
||||
private:
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
Internal_error_handler *m_internal_handler;
|
||||
|
Reference in New Issue
Block a user