diff options
author | unknown <ingo@mysql.com> | 2004-09-18 20:34:49 +0200 |
---|---|---|
committer | unknown <ingo@mysql.com> | 2004-09-18 20:34:49 +0200 |
commit | 9dbd8179559870500c42587ef3d593626ca9617b (patch) | |
tree | 47924b4ccdb07c2f05329745d8ece6b1026b347c /sql | |
parent | d7281b331a79d1e2e3f026bbf71660006ee6df0b (diff) | |
parent | a7919a11fcb3a52246158aba3193d0128baff344 (diff) | |
download | mariadb-git-9dbd8179559870500c42587ef3d593626ca9617b.tar.gz |
Merge mysql.com:/home/mydev/mysql-4.0
into mysql.com:/home/mydev/mysql-4.0-bug2831
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_myisam.cc | 24 | ||||
-rw-r--r-- | sql/sql_table.cc | 12 |
2 files changed, 30 insertions, 6 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; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e2e186abb0d..0dd5c65bf79 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2208,7 +2208,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (!(copy= new Copy_field[to->fields])) DBUG_RETURN(-1); /* purecov: inspected */ - to->file->external_lock(thd,F_WRLCK); + if (to->file->external_lock(thd, F_WRLCK)) + { + /* We must always unlock, even when lock failed. */ + (void) to->file->external_lock(thd, F_UNLCK); + DBUG_RETURN(-1); + } to->file->extra(HA_EXTRA_WRITE_CACHE); from->file->info(HA_STATUS_VARIABLE); to->file->deactivate_non_unique_index(from->file->records); @@ -2308,11 +2313,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, error=1; if (ha_commit(thd)) error=1; - if (to->file->external_lock(thd,F_UNLCK)) - error=1; err: free_io_cache(from); *copied= found_count; *deleted=delete_count; + /* we must always unlock the table on return. */ + if (to->file->external_lock(thd,F_UNLCK)) + error=1; DBUG_RETURN(error > 0 ? -1 : 0); } |