diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c index 260e8d4c27601b345c948cbb621eb10fec878b26..35fdfce16a614f24c0fda329f04a3fcb35ecd754 100644 --- a/innobase/dict/dict0boot.c +++ b/innobase/dict/dict0boot.c @@ -313,6 +313,11 @@ dict_boot(void) mtr_commit(&mtr); /*-------------------------*/ + + /* Initialize the insert buffer table and index for each tablespace */ + + ibuf_init_at_db_start(); + /* Load definitions of other indexes on system tables */ dict_load_sys_table(dict_sys->sys_tables); @@ -320,10 +325,6 @@ dict_boot(void) dict_load_sys_table(dict_sys->sys_indexes); dict_load_sys_table(dict_sys->sys_fields); - /* Initialize the insert buffer table and index for each tablespace */ - - ibuf_init_at_db_start(); - mutex_exit(&(dict_sys->mutex)); } diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index 82cc55dfba547709865f383a902866a2e34996c6..101fb5f3ba0d47f74e3079805f6ad014f3ea77c4 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -2536,6 +2536,10 @@ fseg_free_page( seg_inode = fseg_inode_get(seg_header, mtr); fseg_free_page_low(seg_inode, space, page, mtr); + +#ifdef UNIV_DEBUG_FILE_ACCESSES + buf_page_set_file_page_was_freed(space, page); +#endif } /************************************************************************** @@ -2599,6 +2603,14 @@ fseg_free_extent( } fsp_free_extent(space, page, mtr); + +#ifdef UNIV_DEBUG_FILE_ACCESSES + for (i = 0; i < FSP_EXTENT_SIZE; i++) { + + buf_page_set_file_page_was_freed(space, + first_page_in_extent + i); + } +#endif } /************************************************************************** diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 7227b54e71eca3b28af2cde49e3c197ef6a7938a..171c6169927700767d0833a0e16f1eb2ed7d111f 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -1382,6 +1382,9 @@ ibuf_remove_free_page( fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, space, page_no, &mtr); +#ifdef UNIV_DEBUG_FILE_ACCESSES + buf_page_reset_file_page_was_freed(space, page_no); +#endif ibuf_enter(); mutex_enter(&ibuf_mutex); @@ -1413,6 +1416,9 @@ ibuf_remove_free_page( ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, FALSE, &mtr); +#ifdef UNIV_DEBUG_FILE_ACCESSES + buf_page_set_file_page_was_freed(space, page_no); +#endif mtr_commit(&mtr); mutex_exit(&ibuf_mutex); @@ -2431,6 +2437,8 @@ ibuf_merge_or_delete_for_page( block = buf_block_align(page); rw_lock_x_lock_move_ownership(&(block->lock)); + + ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX); } n_inserts = 0; diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index e93cd3f0364bab4ee3cef4e058a22f629783fcbe..d16085a2d6fbbc7d47708abf39b8b2fbbb04622c 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -944,9 +944,9 @@ recv_read_in_area( } buf_read_recv_pages(FALSE, space, page_nos, n); - - /* printf("Recv pages at %lu n %lu\n", page_nos[0], n); */ - + /* + printf("Recv pages at %lu n %lu\n", page_nos[0], n); + */ return(n); } diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index fa0c266a82aa08b53b35f9a30fe610c4679709fb..668d74d75b55f70dcbc20865286bb1b2e424c7d0 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -11,6 +11,7 @@ Created 10/21/1995 Heikki Tuuri #include "ut0mem.h" #include "srv0srv.h" +#undef HAVE_FDATASYNC #ifdef POSIX_ASYNC_IO /* We assume in this case that the OS has standard Posix aio (at least SunOS @@ -562,6 +563,11 @@ os_file_flush( return(TRUE); } + fprintf(stderr, + "InnoDB: Error: the OS said file flush did not succeed\n"); + + os_file_handle_error(file, NULL); + return(FALSE); #endif } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index aa5259cbaf83791dfe7050e8b139e24f4f4a2184..8e1a584f6675c3b7b8845bcef3d9c16801ceabba 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -824,7 +824,11 @@ row_create_table_for_mysql( } else { assert(err == DB_DUPLICATE_KEY); fprintf(stderr, - "Innobase: error: table %s already exists in Innobase data dictionary\n", + "InnoDB: Error: table %s already exists in InnoDB internal\n" + "InnoDB: data dictionary. Have you deleted the .frm file\n" + "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n" + "InnoDB: for InnoDB tables in MySQL version <= 3.23.39?\n" + "InnoDB: See the Restrictions section of the InnoDB manual.\n", table->name); } diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 70cf0fe5a32dcc98e5ba432d724f641f6a46c7c2..c8db428bade54ff2b2b05d8025c505125fc2055d 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -361,6 +361,7 @@ row_undo_mod_del_unmark_sec( btr_cur_t* btr_cur; ulint err; ibool found; + char* err_buf; UT_NOT_USED(node); @@ -369,13 +370,31 @@ row_undo_mod_del_unmark_sec( found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, &mtr); - ut_a(found); + if (!found) { + err_buf = mem_alloc(1000); + dtuple_sprintf(err_buf, 900, entry); - btr_cur = btr_pcur_get_btr_cur(&pcur); + fprintf(stderr, "InnoDB: error in sec index entry del undo in\n" + "InnoDB: index %s table %s\n", index->name, + index->table->name); + fprintf(stderr, "InnoDB: tuple %s\n", err_buf); + + rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur)); + fprintf(stderr, "InnoDB: record %s\n", err_buf); + + fprintf(stderr, "InnoDB: Make a detailed bug report and send it\n"); + fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + + mem_free(err_buf); - err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, + } else { + + btr_cur = btr_pcur_get_btr_cur(&pcur); + + err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, FALSE, thr, &mtr); - ut_ad(err == DB_SUCCESS); + ut_ad(err == DB_SUCCESS); + } btr_pcur_close(&pcur); mtr_commit(&mtr); diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 10dd64b8b1a56cba6fe349c14d0a1919c200a879..5bca2a24c01f1e010ce350343ed16bbe37c9ff3b 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -750,6 +750,7 @@ row_upd_sec_index_entry( btr_cur_t* btr_cur; mem_heap_t* heap; rec_t* rec; + char* err_buf; ulint err = DB_SUCCESS; index = node->index; @@ -764,18 +765,37 @@ row_upd_sec_index_entry( found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, &mtr); - ut_ad(found); - btr_cur = btr_pcur_get_btr_cur(&pcur); rec = btr_cur_get_rec(btr_cur); - /* Delete mark the old index record; it can already be delete marked if - we return after a lock wait in row_ins_index_entry below */ + if (!found) { + + err_buf = mem_alloc(1000); + dtuple_sprintf(err_buf, 900, entry); + + fprintf(stderr, "InnoDB: error in sec index entry update in\n" + "InnoDB: index %s table %s\n", index->name, + index->table->name); + fprintf(stderr, "InnoDB: tuple %s\n", err_buf); + + rec_sprintf(err_buf, 900, rec); + fprintf(stderr, "InnoDB: record %s\n", err_buf); + + fprintf(stderr, "InnoDB: Make a detailed bug report and send it\n"); + fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + + mem_free(err_buf); + } else { + + /* Delete mark the old index record; it can already be + delete marked if we return after a lock wait in + row_ins_index_entry below */ - if (!rec_get_deleted_flag(rec)) { + if (!rec_get_deleted_flag(rec)) { err = btr_cur_del_mark_set_sec_rec(0, btr_cur, TRUE, thr, &mtr); + } } btr_pcur_close(&pcur); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index b584b663e43b5d30353add5c84389c2bc05ddb28..e121f50926665762f9f1408f4203cded99d4c1a8 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -56,6 +56,7 @@ Created 2/16/1996 Heikki Tuuri #include "srv0start.h" #include "que0que.h" +ibool srv_startup_is_before_trx_rollback_phase = FALSE; ibool srv_is_being_started = FALSE; ibool srv_was_started = FALSE; @@ -531,6 +532,7 @@ innobase_start_or_create_for_mysql(void) /* yydebug = TRUE; */ srv_is_being_started = TRUE; + srv_startup_is_before_trx_rollback_phase = TRUE; if (0 == ut_strcmp(srv_unix_file_flush_method_str, "fdatasync")) { srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; @@ -548,6 +550,8 @@ innobase_start_or_create_for_mysql(void) return(DB_ERROR); } + printf("srv_unix set to %lu\n", srv_unix_file_flush_method); + os_aio_use_native_aio = srv_use_native_aio; err = srv_boot(); @@ -728,6 +732,7 @@ innobase_start_or_create_for_mysql(void) trx_sys_create(); dict_create(); + srv_startup_is_before_trx_rollback_phase = FALSE; } else if (srv_archive_recovery) { fprintf(stderr, @@ -742,9 +747,15 @@ innobase_start_or_create_for_mysql(void) return(DB_ERROR); } - trx_sys_init_at_db_start(); + /* Since ibuf init is in dict_boot, and ibuf is needed + in any disk i/o, first call dict_boot */ + dict_boot(); + + trx_sys_init_at_db_start(); + srv_startup_is_before_trx_rollback_phase = FALSE; + recv_recovery_from_archive_finish(); } else { /* We always try to do a recovery, even if the database had @@ -759,12 +770,15 @@ innobase_start_or_create_for_mysql(void) return(DB_ERROR); } - trx_sys_init_at_db_start(); + /* Since ibuf init is in dict_boot, and ibuf is needed + in any disk i/o, first call dict_boot */ dict_boot(); + trx_sys_init_at_db_start(); /* The following needs trx lists which are initialized in trx_sys_init_at_db_start */ - + + srv_startup_is_before_trx_rollback_phase = FALSE; recv_recovery_from_checkpoint_finish(); } diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 7153355d2a921f644c6cad3ad02a701dd2504383..c3a1ac3b47fc1a96c2555f99568d4c8166cdddbe 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -166,6 +166,46 @@ struct sync_level_struct{ ulint level; /* level of the latch in the latching order */ }; + +#if defined(__GNUC__) && defined(UNIV_INTEL_X86) + +ulint +sync_gnuc_intelx86_test_and_set( + /* out: old value of the lock word */ + ulint* lw) /* in: pointer to the lock word */ +{ + ulint res; + + /* In assembly we use the so-called AT & T syntax where + the order of operands is inverted compared to the ordinary Intel + syntax. The 'l' after the mnemonics denotes a 32-bit operation. + The line after the code tells which values come out of the asm + code, and the second line tells the input to the asm code. */ + + asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" : + "=eax" (res), "=m" (*lw) : + "ecx" (lw)); + return(res); +} + +void +sync_gnuc_intelx86_reset( + ulint* lw) /* in: pointer to the lock word */ +{ + /* In assembly we use the so-called AT & T syntax where + the order of operands is inverted compared to the ordinary Intel + syntax. The 'l' after the mnemonics denotes a 32-bit operation. */ + + asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" : + "=m" (*lw) : + "ecx" (lw) : + "eax"); /* gcc does not seem to understand + that our asm code resets eax: tell it + explicitly that after the third ':' */ +} + +#endif + /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory location (which must be appropriately aligned). The mutex is initialized diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c index efee02c4cad486a62c912f3a9b470074346fd775..1f40842858268699075b18770c08140ca780f9af 100644 --- a/innobase/trx/trx0undo.c +++ b/innobase/trx/trx0undo.c @@ -613,6 +613,10 @@ trx_undo_insert_header_reuse( /* Insert undo data is not needed after commit: we may free all the space on the page */ + ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + + TRX_UNDO_PAGE_TYPE) + == TRX_UNDO_INSERT); + mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free); @@ -800,7 +804,7 @@ trx_undo_free_page( ulint hist_size; UT_NOT_USED(hdr_offset); - ut_ad(hdr_page_no != page_no); + ut_a(hdr_page_no != page_no); ut_ad(!mutex_own(&kernel_mutex)); ut_ad(mutex_own(&(rseg->mutex))); @@ -1411,6 +1415,10 @@ trx_undo_reuse_cached( if (type == TRX_UNDO_INSERT) { offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr); } else { + ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + + TRX_UNDO_PAGE_TYPE) + == TRX_UNDO_UPDATE); + offset = trx_undo_header_create(undo_page, trx_id, mtr); }