diff options
author | unknown <istruewing@stella.local> | 2007-12-11 15:32:10 +0100 |
---|---|---|
committer | unknown <istruewing@stella.local> | 2007-12-11 15:32:10 +0100 |
commit | e223c32077788ca9d398efa23f2431eba4b3e7fc (patch) | |
tree | 054e17b510562830f2d34196b59efb038128cd68 /sql/handler.h | |
parent | 0fdc16bd13bca09abe4026d892d71eccb99fd121 (diff) | |
download | mariadb-git-e223c32077788ca9d398efa23f2431eba4b3e7fc.tar.gz |
Bug#30273 - merge tables: Can't lock file (errno: 155)
The patch for Bug 26379 (Combination of FLUSH TABLE and
REPAIR TABLE corrupts a MERGE table) fixed this bug too.
However it revealed a new bug that crashed the server.
Flushing a merge table at the moment when it is between open
and attach of children crashed the server.
The flushing thread wants to abort locks on the flushed table.
It calls ha_myisammrg::lock_count() and ha_myisammrg::store_lock()
on the TABLE object of the other thread.
Changed ha_myisammrg::lock_count() and ha_myisammrg::store_lock()
to accept non-attached children. ha_myisammrg::lock_count() returns
the number of MyISAM tables in the MERGE table so that the memory
allocation done by get_lock_data() is done correctly, even if the
children become attached before ha_myisammrg::store_lock() is
called. ha_myisammrg::store_lock() will not return any lock if the
children are not attached.
This is however a change in the handler interface. lock_count()
can now return a higher number than store_lock() stores locks.
This is more safe than the reverse implementation would be.
get_lock_data() in the SQL layer is adjusted accordingly. It sets
MYSQL_LOCK::lock_count based on the number of locks returned by
the handler::store_lock() calls, not based on the numbers returned
by the handler::lock_count() calls. The latter are only used for
allocation of memory now.
No test case. The test suite cannot reliably run FLUSH between
lock_count() and store_lock() of another thread. The bug report
contains a program that can repeat the problem with some
probability.
include/myisammrg.h:
Bug#30273 - merge tables: Can't lock file (errno: 155)
Added mutex to struct st_myrg_info (MYRG_INFO).
sql/handler.h:
Bug#30273 - merge tables: Can't lock file (errno: 155)
Extended comments for handler::lock_count() and
handler::store_lock().
sql/lock.cc:
Bug#30273 - merge tables: Can't lock file (errno: 155)
Changed get_lock_data() so that the final lock_count is taken
from the number of locks returned from handler::store_lock()
instead of from handler::lock_count().
sql/sql_base.cc:
Fixed a purecov comment. (unrelated to the rest of the changeset)
storage/myisammrg/ha_myisammrg.cc:
Bug#30273 - merge tables: Can't lock file (errno: 155)
Changed ha_myisammrg::lock_count() and ha_myisammrg::store_lock()
to accept non-attached children.
Protected ha_myisammrg::store_lock() by MYRG_INFO::mutex.
storage/myisammrg/myrg_close.c:
Bug#30273 - merge tables: Can't lock file (errno: 155)
Added MYRG_INFO::mutex destruction to myrg_parent_close().
storage/myisammrg/myrg_open.c:
Bug#30273 - merge tables: Can't lock file (errno: 155)
Added MYRG_INFO::mutex initialization to myrg_parent_open().
Protected myrg_attach_children() and myrg_detach_children()
by MYRG_INFO::mutex.
Fixed a purecov comment. (unrelated to the rest of the changeset)
Diffstat (limited to 'sql/handler.h')
-rw-r--r-- | sql/handler.h | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/sql/handler.h b/sql/handler.h index b91d8a39b88..140b44704a9 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1637,13 +1637,22 @@ public: virtual int repair_partitions(THD *thd) { return HA_ERR_WRONG_COMMAND; } - /* lock_count() can be more than one if the table is a MERGE */ + /** + @note lock_count() can return > 1 if the table is MERGE or partitioned. + */ virtual uint lock_count(void) const { return 1; } /** Is not invoked for non-transactional temporary tables. + @note store_lock() can return more than one lock if the table is MERGE + or partitioned. + @note that one can NOT rely on table->in_use in store_lock(). It may refer to a different thread if called from mysql_lock_abort_for_thread(). + + @note If the table is MERGE, store_lock() can return less locks + than lock_count() claimed. This can happen when the MERGE children + are not attached when this is called from another thread. */ virtual THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, |