summaryrefslogtreecommitdiff
path: root/innobase/fil
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-12-27 04:10:25 +0200
committerunknown <heikki@hundin.mysql.fi>2004-12-27 04:10:25 +0200
commit708eebea8aec579f71e086057063b1f8a7695df1 (patch)
treeedc9436d7606b90f03beba7251499fb1e63afa5e /innobase/fil
parentf2a9080c707363197956e55f73ceec598be8da07 (diff)
downloadmariadb-git-708eebea8aec579f71e086057063b1f8a7695df1.tar.gz
Many files:
Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/buf/buf0rea.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/include/dict0load.h: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/include/fil0fil.h: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/include/row0mysql.h: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/include/trx0trx.h: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/dict/dict0load.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/fil/fil0fil.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/row/row0ins.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/row/row0mysql.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/row/row0sel.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/srv/srv0start.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 innobase/trx/trx0trx.c: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1 sql/ha_innodb.cc: Fix InnoDB critical bug #7496; we scan the InnoDB data dictionary also at a normal mysqld startup, and create the spaces, so that we know the mapping space id -> .ibd file name; fix an infinite loop if DISCARD TABLESPACE coincides with INSERT or some other table operation; fix a potential crash if DISCARD TABLESPACE coincides with a cascaded FOREIGN KEY operation in the same table; do not allow DISCARD TABLESPACE of a referenced table if FOREIGN_KEY_CHECKS=1
Diffstat (limited to 'innobase/fil')
-rw-r--r--innobase/fil/fil0fil.c93
1 files changed, 78 insertions, 15 deletions
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index de528355182..89648b3feca 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -466,6 +466,10 @@ fil_node_open_file(
ulint size_low;
ulint size_high;
ibool ret;
+ byte* buf2;
+ byte* page;
+ ibool success;
+ ulint space_id;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(system->mutex)));
@@ -494,6 +498,8 @@ fil_node_open_file(
system->n_open++;
if (node->size == 0) {
+ ut_a(space->purpose != FIL_LOG);
+
os_file_get_size(node->handle, &size_low, &size_high);
size_bytes = (((ib_longlong)size_high) << 32)
@@ -507,6 +513,46 @@ fil_node_open_file(
ut_a(space->id != 0);
+ if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
+ fprintf(stderr,
+"InnoDB: Error: the size of single-table tablespace file %s\n"
+"InnoDB: is only %lu %lu, should be at least %lu!", node->name,
+ (ulong) size_high,
+ (ulong) size_low, (ulong) (4 * UNIV_PAGE_SIZE));
+
+ ut_a(0);
+ }
+
+ /* Read the first page of the tablespace */
+
+ buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
+ /* Align the memory for file i/o if we might have O_DIRECT
+ set */
+ page = ut_align(buf2, UNIV_PAGE_SIZE);
+
+ success = os_file_read(node->handle, page, 0, 0,
+ UNIV_PAGE_SIZE);
+ space_id = fsp_header_get_space_id(page);
+
+ ut_free(buf2);
+
+ if (space_id == ULINT_UNDEFINED || space_id == 0) {
+ fprintf(stderr,
+"InnoDB: Error: tablespace id %lu in file %s is not sensible\n",
+ (ulong) space_id,
+ node->name);
+
+ ut_a(0);
+ }
+
+ if (space_id != space->id) {
+ fprintf(stderr,
+"InnoDB: Error: tablespace id is %lu in the data dictionary\n"
+"InnoDB: but in file %s it is %lu!\n", space->id, node->name, space_id);
+
+ ut_a(0);
+ }
+
if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
node->size = (ulint) ((size_bytes / (1024 * 1024))
* ((1024 * 1024) / UNIV_PAGE_SIZE));
@@ -2487,21 +2533,29 @@ func_exit:
}
/************************************************************************
-Tries to open a single-table tablespace and checks the space id is right in
-it. If does not succeed, prints an error message to the .err log. This
-function is used to open the tablespace when we load a table definition
-to the dictionary cache. NOTE that we assume this operation is used under the
-protection of the dictionary mutex, so that two users cannot race here. This
-operation does not leave the file associated with the tablespace open, but
-closes it after we have looked at the space id in it. */
+Tries to open a single-table tablespace and optionally checks the space id is
+right in it. If does not succeed, prints an error message to the .err log. This
+function is used to open a tablespace when we start up mysqld, and also in
+IMPORT TABLESPACE.
+NOTE that we assume this operation is used either at the database startup
+or under the protection of the dictionary mutex, so that two users cannot
+race here. This operation does not leave the file associated with the
+tablespace open, but closes it after we have looked at the space id in it. */
ibool
fil_open_single_table_tablespace(
/*=============================*/
- /* out: TRUE if success */
- ulint id, /* in: space id */
- const char* name) /* in: table name in the
- databasename/tablename format */
+ /* out: TRUE if success */
+ ibool check_space_id, /* in: should we check that the space
+ id in the file is right; we assume
+ that this function runs much faster
+ if no check is made, since accessing
+ the file inode probably is much
+ faster (the OS caches them) than
+ accessing the first page of the file */
+ ulint id, /* in: space id */
+ const char* name) /* in: table name in the
+ databasename/tablename format */
{
os_file_t file;
char* filepath;
@@ -2540,6 +2594,12 @@ fil_open_single_table_tablespace(
return(FALSE);
}
+ if (!check_space_id) {
+ space_id = id;
+
+ goto skip_check;
+ }
+
/* Read the first page of the tablespace */
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
@@ -2552,6 +2612,8 @@ fil_open_single_table_tablespace(
space_id = fsp_header_get_space_id(page);
+ ut_free(buf2);
+
if (space_id != id) {
ut_print_timestamp(stderr);
@@ -2572,6 +2634,7 @@ fil_open_single_table_tablespace(
goto func_exit;
}
+skip_check:
success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
if (!success) {
@@ -2584,7 +2647,6 @@ fil_open_single_table_tablespace(
fil_node_create(filepath, 0, space_id, FALSE);
func_exit:
os_file_close(file);
- ut_free(buf2);
mem_free(filepath);
return(ret);
@@ -2651,7 +2713,7 @@ fil_load_single_table_tablespace(
fprintf(stderr,
"InnoDB: Error: could not open single-table tablespace file\n"
"InnoDB: %s!\n"
-"InnoDB: We do not continue crash recovery, because the table will become\n"
+"InnoDB: We do not continue the crash recovery, because the table may become\n"
"InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.\n"
"InnoDB: To fix the problem and start mysqld:\n"
"InnoDB: 1) If there is a permission problem in the file and mysqld cannot\n"
@@ -2822,8 +2884,9 @@ fil_load_single_table_tablespace(
goto func_exit;
}
- /* We do not measure the size of the file, that is why we pass the 0
- below */
+ /* We do not use the size information we have about the file, because
+ the rounding formulat for extents and pages is somewhat complex; we
+ let fil_node_open() do that task. */
fil_node_create(filepath, 0, space_id, FALSE);
func_exit: