diff options
author | unknown <davi@mysql.com/endora.local> | 2007-12-12 19:44:14 -0200 |
---|---|---|
committer | unknown <davi@mysql.com/endora.local> | 2007-12-12 19:44:14 -0200 |
commit | e5a397e28f7db0b356d1eddd669591b76fa1c1f8 (patch) | |
tree | 77edf95e44bc644261fab601d8279ffa8c28a4ff /sql/ha_ndbcluster.cc | |
parent | ede6f50a6a92aef2bf1105d4da98796ca309c3bd (diff) | |
download | mariadb-git-e5a397e28f7db0b356d1eddd669591b76fa1c1f8.tar.gz |
Bug#32395 Alter table under a impending global read lock causes a server crash
The problem is that some DDL statements (ALTER TABLE, CREATE
TRIGGER, FLUSH TABLES, ...) when under LOCK TABLES need to
momentarily drop the lock, reopen the table and grab the write
lock again (using reopen_tables). When grabbing the lock again,
reopen_tables doesn't pass a flag to mysql_lock_tables in
order to ignore the impending global read lock, which causes a
assertion because LOCK_open is being hold. Also dropping the
lock must not signal to any threads that the table has been
relinquished (related to the locking/flushing protocol).
The solution is to correct the way the table is reopenned
and the locks grabbed. When reopening the table and under
LOCK TABLES, the table version should be set to 0 so other
threads have to wait for the table. When grabbing the lock,
any other flush should be ignored because it's theoretically
a atomic operation. The chosen solution also fixes a potential
discrepancy between binlog and GRL (global read lock) because
table placeholders were being ignored, now a FLUSH TABLES WITH
READ LOCK will properly for table with open placeholders.
It's also important to mention that this patch doesn't fix
a potential deadlock if one uses two GRLs under LOCK TABLES
concurrently.
mysql-test/r/lock_multi.result:
Add test case result for Bug#32395
mysql-test/r/trigger_notembedded.result:
Add test case result for Bug#32395
mysql-test/t/lock_multi.test:
Add test case for Bug#32395
mysql-test/t/trigger_notembedded.test:
Enable test case for Bug#32395
sql/ha_ndbcluster.cc:
Update close_cached_tables usage.
sql/ha_ndbcluster_binlog.cc:
Update close_cached_tables usage.
sql/mysql_priv.h:
Update close_cache_tables prototype.
sql/set_var.cc:
Update close_cached_tables usage and set flag to wait for
tables with placeholders. This is one of the places where
a GRL can be obtained.
sql/sql_base.cc:
Preserve old version for write locked tables and ignore
pending flushes and update close_cache_tables to take
into account name locked tables.
sql/sql_parse.cc:
Update close_cached_tables usage and pass flag so that
name locked tables are waited for.
sql/sql_table.cc:
Protect the table against a impending GRL if under LOCK TABLES.
Diffstat (limited to 'sql/ha_ndbcluster.cc')
-rw-r--r-- | sql/ha_ndbcluster.cc | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index bf2b19bfc9c..2555bb23825 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -577,7 +577,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans) bzero((char*) &table_list,sizeof(table_list)); table_list.db= m_dbname; table_list.alias= table_list.table_name= m_tabname; - close_cached_tables(thd, 0, &table_list); + close_cached_tables(thd, &table_list, FALSE, FALSE, FALSE); break; } default: @@ -8064,7 +8064,7 @@ int handle_trailing_share(NDB_SHARE *share) table_list.db= share->db; table_list.alias= table_list.table_name= share->table_name; safe_mutex_assert_owner(&LOCK_open); - close_cached_tables(thd, 0, &table_list, TRUE); + close_cached_tables(thd, &table_list, TRUE, FALSE, FALSE); pthread_mutex_lock(&ndbcluster_mutex); /* ndb_share reference temporary free */ |