diff options
author | unknown <ingo@mysql.com> | 2004-09-18 20:33:39 +0200 |
---|---|---|
committer | unknown <ingo@mysql.com> | 2004-09-18 20:33:39 +0200 |
commit | a7919a11fcb3a52246158aba3193d0128baff344 (patch) | |
tree | f3658d5151d0eec668e2a6a6702b3ad26c908d15 /sql/ha_myisam.cc | |
parent | c36356b6a4ac740f61f2a82a04f87213b06f40f5 (diff) | |
download | mariadb-git-a7919a11fcb3a52246158aba3193d0128baff344.tar.gz |
bug#2831 - --extenral-locking does not fully work with --myisam-recover.
Changed the semantics of open_count so that it is decremented
at every unlock (if it was incremented due to data changes).
So it indicates a crash, if it is non-zero after a lock.
The table will then be repaired.
myisam/mi_close.c:
bug#2831 - --extenral-locking does not fully work with --myisam-recover.
To avoid flushing the open_count at every unlock,
we need to do so at close at least.
myisam/mi_locking.c:
bug#2831 - --extenral-locking does not fully work with --myisam-recover.
open_count is now decremented at unlock (from a writelock) with
mi_unlock_open_count(). After every new lock the state is read
from the index file and the open_count checked. If not zero,
another server must have crashed, so the table is marked as crashed.
In certain situations the decremented open_count mut be flushed to
the index file. I tried to keep these extra flushes as seldom as possible.
sql/ha_myisam.cc:
bug#2831 - --extenral-locking does not fully work with --myisam-recover.
Added code to repair the table, if it is marked crashed after
successful locking and the --myisam-recover option is set.
sql/sql_table.cc:
This does not really belong to the bugfix for #2831.
But it was detected during fixing the external locking.
Diffstat (limited to 'sql/ha_myisam.cc')
-rw-r--r-- | sql/ha_myisam.cc | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index d5bbf9b5a92..2b7b8f436b1 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1000,9 +1000,27 @@ int ha_myisam::delete_table(const char *name) int ha_myisam::external_lock(THD *thd, int lock_type) { - return mi_lock_database(file, !table->tmp_table ? - lock_type : ((lock_type == F_UNLCK) ? - F_UNLCK : F_EXTRA_LCK)); + int rc; + + while ((! (rc= mi_lock_database(file, !table->tmp_table ? + lock_type : ((lock_type == F_UNLCK) ? + F_UNLCK : F_EXTRA_LCK)))) && + mi_is_crashed(file) && (myisam_recover_options != HA_RECOVER_NONE)) + { + /* + check_and_repair() implicitly write locks the table, unless a + LOCK TABLES is in effect. It should be safer to always write lock here. + The implicit lock by check_and_repair() will then be a no-op. + check_and_repair() does not restore the original lock, but unlocks the + table. So we have to get the requested lock type again. And then to + check, if the table has been crashed again meanwhile by another server. + If anything fails, we break. + */ + if (((lock_type != F_WRLCK) && (rc= mi_lock_database(file, F_WRLCK))) || + (rc= check_and_repair(thd))) + break; + } + return rc; } |