summaryrefslogtreecommitdiff
path: root/sql/sql_trigger.cc
diff options
context:
space:
mode:
authorunknown <thek@adventure.(none)>2007-07-02 19:14:48 +0200
committerunknown <thek@adventure.(none)>2007-07-02 19:14:48 +0200
commit289cc26c646f5a45e2c9fc6c0bb75f6f61d301a1 (patch)
tree6ae98744dc3b93525f63eb7f5c0c84bcbf702b47 /sql/sql_trigger.cc
parent0484d44eebff70ef5a2c328c7a9d50ac07a89409 (diff)
downloadmariadb-git-289cc26c646f5a45e2c9fc6c0bb75f6f61d301a1.tar.gz
Bug#21074 Large query_cache freezes mysql server sporadically under heavy load
Invaldating a subset of a sufficiently large query cache can take a long time. During this time the server is efficiently frozen and no other operation can be executed. This patch addresses this problem by moving the locks which cause the freezing and also by temporarily disable the query cache while the invalidation takes place. sql/ha_ndbcluster.cc: - mysql_rm_table_part2 has a new parameter to indicate if OPEN_lock mutex protection is needed. sql/lock.cc: - Added function for acquiring table name exclusive locks. - Added function for asserting that table name lock is acquired. sql/mysql_priv.h: - Added function for acquiring table name exclusive locks. - Added function for asserting that table name lock is acquired. - Added parameter to mysql_rm_table_part2 to indicate whether OPEN_lock mutex protection is needed or not. sql/sql_cache.cc: - Changed flush_in_progress-flag into a state and added a function, is_flushing() to reflect on this state. A new state was needed to indicate that a partial invalidation was in progress. - An unused parameter 'under_guard' was removed. - The Query_cache mutex structural_guard was pushed down into one invalidate_table function to avoid multiple entry points which makes maintainens more difficult. - Instead of keeping the structural_guard mutex during the entire invalidation we set the query cache status state to TABLE_FLUSH_IN_PROGRESS to temporarily disable the cache and avoid locking other threads needing the Query_cache resource. sql/sql_cache.h: - Changed flush_in_progress-flag into a state and added a function, is_flushing() to reflect on this state. A new state was needed to indicate that a partial invalidation was in progress. - An unused parameter 'under_guard' was removed. - The Query_cache mutex structural_guard was pushed down into one invalidate_table function to avoid multiple entry points which makes maintainens more difficult. - Instead of keeping the structural_guard mutex during the entire invalidation we set the query cache status state to TABLE_FLUSH_IN_PROGRESS to temporarily disable the cache and avoid locking other threads needing the the Query_cache resource. sql/sql_db.cc: - mysql_rm_table_part2_with_lock is redundant and replaced with mysql_rm_table_part2. sql/sql_parse.cc: - Function query_cache_invalidate3 isn't protect by a lock and we have a race condition. - Moving this function into mysql_rename_tables and make sure it is protected by a exclusive table name lock. sql/sql_rename.cc: - Function query_cache_invalidation3 isn't protect by a lock and we have a race condition. - Moving this function into mysql_rename_tables and make sure it is protected by a exclusive table name lock. - Instead of using LOCK_open mutex, which excludes all other threads, the lock is changed into exclusive table name locks instead. This prevents us from locking the server if a query cache invalidation would take a long time to complete. sql/sql_table.cc: - Instead of using LOCK_open mutex, which excludes all other threads, the lock is changed into exclusive table name locks instead. This prevents us from locking the server if a query cache invalidation would take a long time to complete. - Added new parameter to mysql_rm_table_part2 to control whether OPEN_lock mutex needs to be aquired or not. This is currently needed by the NDB implemenation. sql/sql_trigger.cc: - Table_triggers don't need to be protexted by LOCK_open mutex. This patch cancel this restriction. - Refactored comments to doxygen style.
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r--sql/sql_trigger.cc40
1 files changed, 24 insertions, 16 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index e15003ab243..16159150e66 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1268,8 +1268,6 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
bzero(&table, sizeof(table));
init_alloc_root(&table.mem_root, 8192, 0);
- safe_mutex_assert_owner(&LOCK_open);
-
if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
{
result= 1;
@@ -1431,26 +1429,24 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
}
-/*
- Update .TRG and .TRN files after renaming triggers' subject table.
+/**
+ @brief Update .TRG and .TRN files after renaming triggers' subject table.
- SYNOPSIS
- change_table_name()
- thd Thread context
- db Old database of subject table
- old_table Old name of subject table
- new_db New database for subject table
- new_table New name of subject table
+ @param[in,out] thd Thread context
+ @param[in] db Old database of subject table
+ @param[in] old_table Old name of subject table
+ @param[in] new_db New database for subject table
+ @param[in] new_table New name of subject table
- NOTE
+ @note
This method tries to leave trigger related files in consistent state,
i.e. it either will complete successfully, or will fail leaving files
in their initial state.
Also this method assumes that subject table is not renamed to itself.
+ This method needs to be called under an exclusive table name lock.
- RETURN VALUE
- FALSE Success
- TRUE Error
+ @retval FALSE Success
+ @retval TRUE Error
*/
bool Table_triggers_list::change_table_name(THD *thd, const char *db,
@@ -1466,7 +1462,19 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
bzero(&table, sizeof(table));
init_alloc_root(&table.mem_root, 8192, 0);
- safe_mutex_assert_owner(&LOCK_open);
+ uchar key[MAX_DBKEY_LENGTH];
+ uint key_length= (uint) (strmov(strmov((char*)&key[0], db)+1,
+ old_table)-(char*)&key[0])+1;
+
+ /*
+ This method interfaces the mysql server code protected by
+ either LOCK_open mutex or with an exclusive table name lock.
+ In the future, only an exclusive table name lock will be enough.
+ */
+#ifndef DBUG_OFF
+ if (!is_table_name_exclusively_locked_by_this_thread(thd, key, key_length))
+ safe_mutex_assert_owner(&LOCK_open);
+#endif
DBUG_ASSERT(my_strcasecmp(table_alias_charset, db, new_db) ||
my_strcasecmp(table_alias_charset, old_table, new_table));