summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2004-09-18 20:34:49 +0200
committerunknown <ingo@mysql.com>2004-09-18 20:34:49 +0200
commit9dbd8179559870500c42587ef3d593626ca9617b (patch)
tree47924b4ccdb07c2f05329745d8ece6b1026b347c /sql
parentd7281b331a79d1e2e3f026bbf71660006ee6df0b (diff)
parenta7919a11fcb3a52246158aba3193d0128baff344 (diff)
downloadmariadb-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.cc24
-rw-r--r--sql/sql_table.cc12
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);
}