diff --git a/ChangeLog b/ChangeLog index 0a4b01ef4062cdd31c1651822f6ce71ed2f4ce04..060747550b10ea3814ede999730b3569083ae211 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-26 The InnoDB Team + + * row/row0merge.c (row_merge_drop_temp_indexes): + Replace the WHILE 1 with WHILE 1=1 in the SQL procedure, so that + the loop will actually be entered and temporary indexes be dropped + during crash recovery. + 2008-10-31 The InnoDB Team * dict/dict0mem.c, include/dict0mem.h, include/lock0lock.h, diff --git a/handler/win_delay_loader.cc b/handler/win_delay_loader.cc index 7cee5cf3f3667f41bb6b6946e2c086067a0b92f2..8b69f4a6e51270853250070b34686a6e4ba3beb7 100644 --- a/handler/win_delay_loader.cc +++ b/handler/win_delay_loader.cc @@ -263,6 +263,11 @@ wdl_load_mapfile( char* func_addr; ulint load_addr = 0; ibool valid_load_addr = FALSE; +#ifdef _WIN64 + const char* tmp_string = " Preferred load address is %16llx"; +#else + const char* tmp_string = " Preferred load address is %08x"; +#endif fp = fopen(filename, "r"); if (fp == NULL) { @@ -285,8 +290,7 @@ wdl_load_mapfile( /* Search start of symbol list and get the preferred load address */ while (fgets(tmp_buf, sizeof(tmp_buf), fp)) { - if (sscanf(tmp_buf, " Preferred load address is %16X", - &load_addr) == 1) { + if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) { valid_load_addr = TRUE; } @@ -338,7 +342,7 @@ wdl_load_mapfile( chain_header = map_cell; map_cell->symbol = strdup(func_name); - map_cell->value = strtoul(tmp_buf, NULL, 0) + map_cell->value = (ulint) strtoull(tmp_buf, NULL, 0) - load_addr; map_fold = ut_fold_string(map_cell->symbol); diff --git a/include/row0uins.h b/include/row0uins.h index 3d56cb68f37fe20cd7d2b33d8b675f1e42f75ba5..91052505aad461b3a14b34f794edb8a5731b26ed 100644 --- a/include/row0uins.h +++ b/include/row0uins.h @@ -20,7 +20,9 @@ Created 2/25/1997 Heikki Tuuri /*************************************************************** Undoes a fresh insert of a row to a table. A fresh insert means that the same clustered index unique key did not have any record, even delete -marked, at the time of the insert. */ +marked, at the time of the insert. InnoDB is eager in a rollback: +if it figures out that an index record will be removed in the purge +anyway, it will remove it in the rollback. */ UNIV_INTERN ulint row_undo_ins( diff --git a/row/row0merge.c b/row/row0merge.c index 634119b811e8ac1b5da4ebb3daf38c0ff0c77f31..6d9dfa9feb40694021e77054fdfca37804ee6132 100644 --- a/row/row0merge.c +++ b/row/row0merge.c @@ -1842,7 +1842,7 @@ row_merge_drop_temp_indexes(void) "WHERE SUBSTR(NAME,0,1)='\377' FOR UPDATE;\n" "BEGIN\n" "\tOPEN c;\n" - "\tWHILE 1 LOOP\n" + "\tWHILE 1=1 LOOP\n" "\t\tFETCH c INTO indexid;\n" "\t\tIF (SQL % NOTFOUND) THEN\n" "\t\t\tEXIT;\n" diff --git a/row/row0purge.c b/row/row0purge.c index 703ea904ffa26a2ae3d4de95821fd77d7cf6c4dd..90017fdc0099eb4f6fb6cfe304c4ebd1df4c3132 100644 --- a/row/row0purge.c +++ b/row/row0purge.c @@ -230,7 +230,15 @@ row_purge_remove_sec_if_poss_low_nonbuffered( switch (search_result) { case ROW_NOT_FOUND: - /* Not found */ + /* Not found. This is a legitimate condition. In a + rollback, InnoDB will remove secondary recs that would + be purged anyway. Then the actual purge will not find + the secondary index record. Also, the purge itself is + eager: if it comes to consider a secondary index + record, and notices it does not need to exist in the + index, it will remove it. Then if/when the purge + comes to consider the secondary index record a second + time, it will not exist any more in the index. */ /* fputs("PURGE:........sec entry not found\n", stderr); */ /* dtuple_print(stderr, entry); */ diff --git a/row/row0uins.c b/row/row0uins.c index 75b46769c8cb5805208b59749db106f8d5fd7e47..846a897694ce09b6e83bd8a1ce70abe033ce0b41 100644 --- a/row/row0uins.c +++ b/row/row0uins.c @@ -277,7 +277,9 @@ row_undo_ins_parse_undo_rec( /*************************************************************** Undoes a fresh insert of a row to a table. A fresh insert means that the same clustered index unique key did not have any record, even delete -marked, at the time of the insert. */ +marked, at the time of the insert. InnoDB is eager in a rollback: +if it figures out that an index record will be removed in the purge +anyway, it will remove it in the rollback. */ UNIV_INTERN ulint row_undo_ins( diff --git a/row/row0umod.c b/row/row0umod.c index 65e72bc01a0798cd231465a84da8e2b465d79cd9..56aa1e98d187e1b09d721edee3e04cd7acf17dcc 100644 --- a/row/row0umod.c +++ b/row/row0umod.c @@ -314,8 +314,35 @@ row_undo_mod_del_mark_or_remove_sec_low( search_result = row_search_index_entry(index, entry, mode, &pcur, &mtr); - switch (search_result) { + switch (UNIV_EXPECT(search_result, ROW_FOUND)) { + trx_t* trx; case ROW_NOT_FOUND: + /* In crash recovery, the secondary index record may + be missing if the UPDATE did not have time to insert + the secondary index records before the crash. When we + are undoing that UPDATE in crash recovery, the record + may be missing. In normal processing, the record + SHOULD exist. */ + + trx = thr_get_trx(thr); + + if (!trx_is_recv(trx)) { + fputs("InnoDB: error in sec index entry del undo in\n" + "InnoDB: ", stderr); + dict_index_name_print(stderr, trx, index); + fputs("\n" + "InnoDB: tuple ", stderr); + dtuple_print(stderr, entry); + fputs("\n" + "InnoDB: record ", stderr); + rec_print(stderr, btr_pcur_get_rec(&pcur), index); + putc('\n', stderr); + trx_print(stderr, trx, 0); + fputs("\n" + "InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", stderr); + } + err = DB_SUCCESS; goto func_exit; case ROW_FOUND: diff --git a/win-plugin/win-plugin.diff b/win-plugin/win-plugin.diff index 760b184a8fe1f94a960d81f2407a5f0ae109938b..a9e067c6ee5f0d77a278e2d32cbac24e742f19d8 100644 --- a/win-plugin/win-plugin.diff +++ b/win-plugin/win-plugin.diff @@ -1,18 +1,7 @@ diff -Nur CMakeLists.txt.orig CMakeLists.txt --- CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00 +++ CMakeLists.txt 2008-09-26 17:32:51 -05:00 -@@ -97,6 +97,10 @@ - IF(CYBOZU) - ADD_DEFINITIONS(-DCYBOZU) - ENDIF(CYBOZU) -+# Checks for 32-bit version. And always use 32-bit time_t for compatibility -+IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 4) -+ ADD_DEFINITIONS(-D_USE_32BIT_TIME_T) -+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 4) - - # in some places we use DBUG_OFF - SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF") -@@ -246,9 +250,9 @@ +@@ -244,9 +244,9 @@ IF(WITH_FEDERATED_STORAGE_ENGINE) ADD_SUBDIRECTORY(storage/federated) ENDIF(WITH_FEDERATED_STORAGE_ENGINE) @@ -149,7 +138,7 @@ diff -Nur sql/mysqld.def.orig sql/mysqld.def + localtime_r + my_strdup -diff -Nur ../old/sql/mysqld_x64.def.orig ./sql/mysqld_x64.def +diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def --- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00 +++ sql/mysqld_x64.def 2008-10-31 02:22:04 -05:00 @@ -0,0 +1,99 @@