diff options
author | monty@mysql.com <> | 2004-09-06 15:14:10 +0300 |
---|---|---|
committer | monty@mysql.com <> | 2004-09-06 15:14:10 +0300 |
commit | 31122efde725e9b472e467a7cb1807100b7e6b1e (patch) | |
tree | d9ef905036723648a1d354d0523ef8124e4dee76 /innobase | |
parent | 32594c99899edd6de0053609c087f04dc21fbbfd (diff) | |
parent | 5d71817c7049e9db5c22e1667a41f57cf558d8ed (diff) | |
download | mariadb-git-31122efde725e9b472e467a7cb1807100b7e6b1e.tar.gz |
Merge with 4.1
(Includes merge of arena code in 4.1 and 5.0)
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/buf/buf0flu.c | 65 | ||||
-rw-r--r-- | innobase/buf/buf0rea.c | 2 | ||||
-rw-r--r-- | innobase/dict/dict0crea.c | 1 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 1 | ||||
-rw-r--r-- | innobase/fil/fil0fil.c | 2 | ||||
-rw-r--r-- | innobase/include/dyn0dyn.h | 3 | ||||
-rw-r--r-- | innobase/include/mtr0log.h | 3 | ||||
-rw-r--r-- | innobase/include/mtr0log.ic | 3 | ||||
-rw-r--r-- | innobase/include/os0file.h | 4 | ||||
-rw-r--r-- | innobase/include/page0page.ic | 15 | ||||
-rw-r--r-- | innobase/include/srv0srv.h | 3 | ||||
-rw-r--r-- | innobase/include/srv0start.h | 6 | ||||
-rw-r--r-- | innobase/include/ut0dbg.h | 34 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 1 | ||||
-rw-r--r-- | innobase/log/log0recv.c | 3 | ||||
-rw-r--r-- | innobase/os/os0file.c | 69 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 40 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 92 | ||||
-rw-r--r-- | innobase/srv/srv0srv.c | 7 | ||||
-rw-r--r-- | innobase/srv/srv0start.c | 64 | ||||
-rw-r--r-- | innobase/ut/ut0dbg.c | 7 | ||||
-rw-r--r-- | innobase/ut/ut0mem.c | 6 |
22 files changed, 367 insertions, 64 deletions
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 6cefdb60956..964c396dd08 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -217,7 +217,9 @@ buf_flush_buffered_writes(void) /*===========================*/ { buf_block_t* block; + byte* write_buf; ulint len; + ulint len2; ulint i; if (trx_doublewrite == NULL) { @@ -244,6 +246,16 @@ buf_flush_buffered_writes(void) block = trx_doublewrite->buf_block_arr[i]; ut_a(block->state == BUF_BLOCK_FILE_PAGE); + if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4) + != mach_read_from_4(block->frame + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: The page to be written seems corrupt!\n" +"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n" +"InnoDB: before posting to the doublewrite buffer.\n"); + } + if (block->check_index_page_at_flush && !page_simple_validate(block->frame)) { @@ -272,6 +284,19 @@ buf_flush_buffered_writes(void) trx_doublewrite->block1, 0, len, (void*)trx_doublewrite->write_buf, NULL); + write_buf = trx_doublewrite->write_buf; + + for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; len2 += UNIV_PAGE_SIZE) { + if (mach_read_from_4(write_buf + len2 + FIL_PAGE_LSN + 4) + != mach_read_from_4(write_buf + len2 + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: The page to be written seems corrupt!\n" +"InnoDB: The lsn fields do not match! Noticed in the doublewrite block1.\n"); + } + } + if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { len = (trx_doublewrite->first_free - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE; @@ -282,6 +307,22 @@ buf_flush_buffered_writes(void) (void*)(trx_doublewrite->write_buf + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE), NULL); + + write_buf = trx_doublewrite->write_buf + + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; + for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; + len2 += UNIV_PAGE_SIZE) { + if (mach_read_from_4(write_buf + len2 + + FIL_PAGE_LSN + 4) + != mach_read_from_4(write_buf + len2 + + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: The page to be written seems corrupt!\n" +"InnoDB: The lsn fields do not match! Noticed in the doublewrite block2.\n"); + } + } } /* Now flush the doublewrite buffer data to disk */ @@ -295,6 +336,18 @@ buf_flush_buffered_writes(void) for (i = 0; i < trx_doublewrite->first_free; i++) { block = trx_doublewrite->buf_block_arr[i]; + if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4) + != mach_read_from_4(block->frame + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: The page to be written seems corrupt!\n" +"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n" +"InnoDB: after posting and flushing the doublewrite buffer.\n" +"InnoDB: Page buf fix count %lu, io fix %lu, state %lu\n", + (ulong)block->buf_fix_count, (ulong)block->io_fix, + (ulong)block->state); + } ut_a(block->state == BUF_BLOCK_FILE_PAGE); fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, @@ -412,6 +465,9 @@ buf_flush_write_block_low( /*======================*/ buf_block_t* block) /* in: buffer block to write */ { +#ifdef UNIV_LOG_DEBUG + static ibool univ_log_debug_warned; +#endif /* UNIV_LOG_DEBUG */ ut_a(block->state == BUF_BLOCK_FILE_PAGE); #ifdef UNIV_IBUF_DEBUG @@ -420,8 +476,13 @@ buf_flush_write_block_low( ut_ad(!ut_dulint_is_zero(block->newest_modification)); #ifdef UNIV_LOG_DEBUG - fputs("Warning: cannot force log to disk in the log debug version!\n", - stderr); + if (!univ_log_debug_warned) { + univ_log_debug_warned = TRUE; + fputs( + "Warning: cannot force log to disk if UNIV_LOG_DEBUG is defined!\n" + "Crash recovery will not work!\n", + stderr); + } #else /* Force the log to the disk before writing the modified block */ log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE); diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index 71e885ff439..11107d777c8 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -629,6 +629,8 @@ buf_read_ibuf_merge_pages( } } + os_aio_simulated_wake_handler_threads(); + /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index fd8e02585ae..1e4d906b7b5 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -32,6 +32,7 @@ static dtuple_t* dict_create_sys_tables_tuple( /*=========================*/ + /* out: the tuple which should be inserted */ dict_table_t* table, /* in: table */ mem_heap_t* heap) /* in: memory heap from which the memory for the built tuple is allocated */ diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 71cf908db4e..eeefd7bf1ae 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -682,6 +682,7 @@ dict_init(void) rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION); dict_foreign_err_file = os_file_create_tmpfile(); + ut_a(dict_foreign_err_file); mutex_create(&dict_foreign_err_mutex); mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH); } diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 59fbd6f785d..885738deae2 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1513,6 +1513,8 @@ fil_decr_pending_ibuf_merges( mutex_exit(&(system->mutex)); } +/************************************************************ +Creates the database directory for a table if it does not exist yet. */ static void fil_create_directory_for_tablename( diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h index 501fde05e90..abee62300e3 100644 --- a/innobase/include/dyn0dyn.h +++ b/innobase/include/dyn0dyn.h @@ -47,7 +47,8 @@ dyn_array_open( /*===========*/ /* out: pointer to the buffer */ dyn_array_t* arr, /* in: dynamic array */ - ulint size); /* in: size in bytes of the buffer */ + ulint size); /* in: size in bytes of the buffer; MUST be + smaller than DYN_ARRAY_DATA_SIZE! */ /************************************************************************* Closes the buffer returned by dyn_array_open. */ UNIV_INLINE diff --git a/innobase/include/mtr0log.h b/innobase/include/mtr0log.h index 41be168a371..9c9c6f696e8 100644 --- a/innobase/include/mtr0log.h +++ b/innobase/include/mtr0log.h @@ -111,7 +111,8 @@ mlog_open( /*======*/ /* out: buffer, NULL if log mode MTR_LOG_NONE */ mtr_t* mtr, /* in: mtr */ - ulint size); /* in: buffer size in bytes */ + ulint size); /* in: buffer size in bytes; MUST be + smaller than DYN_ARRAY_DATA_SIZE! */ /************************************************************ Closes a buffer opened to mlog. */ UNIV_INLINE diff --git a/innobase/include/mtr0log.ic b/innobase/include/mtr0log.ic index aa3f945c202..08d9a6448eb 100644 --- a/innobase/include/mtr0log.ic +++ b/innobase/include/mtr0log.ic @@ -18,7 +18,8 @@ mlog_open( /*======*/ /* out: buffer, NULL if log mode MTR_LOG_NONE */ mtr_t* mtr, /* in: mtr */ - ulint size) /* in: buffer size in bytes */ + ulint size) /* in: buffer size in bytes; MUST be + smaller than DYN_ARRAY_DATA_SIZE! */ { dyn_array_t* mlog; diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 6549a3748df..f1647c47bce 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -169,12 +169,12 @@ void os_io_init_simple(void); /*===================*/ /*************************************************************************** -Creates a temporary file. In case of error, causes abnormal termination. */ +Creates a temporary file. */ FILE* os_file_create_tmpfile(void); /*========================*/ - /* out: temporary file handle (never NULL) */ + /* out: temporary file handle (never NULL) */ /*************************************************************************** The os_file_opendir() function opens a directory stream corresponding to the directory named by the dirname argument. The directory stream is positioned diff --git a/innobase/include/page0page.ic b/innobase/include/page0page.ic index e7c0f8ee07c..3d2bf3b090e 100644 --- a/innobase/include/page0page.ic +++ b/innobase/include/page0page.ic @@ -479,7 +479,20 @@ page_rec_get_next( offs = rec_get_next_offs(rec); - ut_a(offs < UNIV_PAGE_SIZE); + if (offs >= UNIV_PAGE_SIZE) { + fprintf(stderr, +"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n", + (ulong)offs, (ulong)(rec - page)); + fprintf(stderr, +"\nInnoDB: rec address %lx, first buffer frame %lx\n" +"InnoDB: buffer pool high end %lx, buf fix count %lu\n", + (ulong)rec, (ulong)buf_pool->frame_zero, + (ulong)buf_pool->high_end, + (ulong)buf_block_align(rec)->buf_fix_count); + buf_page_print(page); + + ut_a(0); + } if (offs == 0) { diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index c7ba39aaaf1..2e42c2f5036 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -42,6 +42,7 @@ extern char* srv_arch_dir; #endif /* UNIV_LOG_ARCHIVE */ extern ibool srv_file_per_table; +extern ibool srv_locks_unsafe_for_binlog; extern ulint srv_n_data_files; extern char** srv_data_file_names; @@ -98,6 +99,8 @@ extern lint srv_conc_n_threads; extern ibool srv_fast_shutdown; +extern ibool srv_innodb_status; + extern ibool srv_use_doublewrite_buf; extern ibool srv_set_thread_priorities; diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index 0074de537c3..75af1a212b4 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -64,15 +64,17 @@ innobase_start_or_create_for_mysql(void); /* out: DB_SUCCESS or error code */ /******************************************************************** Shuts down the Innobase database. */ - int innobase_shutdown_for_mysql(void); /*=============================*/ /* out: DB_SUCCESS or error code */ - extern dulint srv_shutdown_lsn; extern dulint srv_start_lsn; +#ifdef __NETWARE__ +void set_panic_flag_for_netware(void); +#endif + extern ulint srv_sizeof_trx_t_in_ha_innodb_cc; extern ibool srv_is_being_started; diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h index a155f68bd12..5f30a894874 100644 --- a/innobase/include/ut0dbg.h +++ b/innobase/include/ut0dbg.h @@ -22,7 +22,38 @@ extern ulint* ut_dbg_null_ptr; extern const char* ut_dbg_msg_assert_fail; extern const char* ut_dbg_msg_trap; extern const char* ut_dbg_msg_stop; - +/* Have a graceful exit on NetWare rather than a segfault to avoid abends */ +#ifdef __NETWARE__ +extern ibool panic_shutdown; +#define ut_a(EXPR) do {\ + if (!((ulint)(EXPR) + ut_dbg_zero)) {\ + ut_print_timestamp(stderr);\ + fprintf(stderr, ut_dbg_msg_assert_fail,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__,\ + (ulint)__LINE__);\ + fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\ + fputs(ut_dbg_msg_trap, stderr);\ + ut_dbg_stop_threads = TRUE;\ + if (ut_dbg_stop_threads) {\ + fprintf(stderr, ut_dbg_msg_stop,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\ + }\ + if(!panic_shutdown){\ + panic_shutdown = TRUE;\ + innobase_shutdown_for_mysql();}\ + exit(1);\ + }\ +} while (0) +#define ut_error do {\ + ut_print_timestamp(stderr);\ + fprintf(stderr, ut_dbg_msg_assert_fail,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\ + fprintf(stderr, ut_dbg_msg_trap);\ + ut_dbg_stop_threads = TRUE;\ + if(!panic_shutdown){panic_shutdown = TRUE;\ + innobase_shutdown_for_mysql();}\ +} while (0) +#else #define ut_a(EXPR) do {\ if (!((ulint)(EXPR) + ut_dbg_zero)) {\ ut_print_timestamp(stderr);\ @@ -49,6 +80,7 @@ extern const char* ut_dbg_msg_stop; ut_dbg_stop_threads = TRUE;\ if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\ } while (0) +#endif #ifdef UNIV_DEBUG #define ut_ad(EXPR) ut_a(EXPR) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 92e8f224dea..c9c0cd109a9 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -509,6 +509,7 @@ lock_sys_create( /* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */ lock_latest_err_file = os_file_create_tmpfile(); + ut_a(lock_latest_err_file); } /************************************************************************* diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 7e57efcf9e1..e5b0300239a 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -628,6 +628,9 @@ log_block_checksum_is_ok_or_old_format( format of InnoDB version < 3.23.52 */ byte* block) /* in: pointer to a log block */ { +#ifdef UNIV_LOG_DEBUG + return(TRUE); +#endif /* UNIV_LOG_DEBUG */ if (log_block_calc_checksum(block) == log_block_get_checksum(block)) { return(TRUE); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index d5ca8f927c6..392580eb570 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -478,22 +478,72 @@ os_io_init_simple(void) } } +#ifndef UNIV_HOTBACKUP +/************************************************************************* +Creates a temporary file. This function is defined in ha_innodb.cc. */ + +int +innobase_mysql_tmpfile(void); +/*========================*/ + /* out: temporary file descriptor, or < 0 on error */ +#endif /* !UNIV_HOTBACKUP */ + /*************************************************************************** -Creates a temporary file. In case of error, causes abnormal termination. */ +Creates a temporary file. */ FILE* os_file_create_tmpfile(void) /*========================*/ - /* out: temporary file handle (never NULL) */ + /* out: temporary file handle, or NULL on error */ { - FILE* file = tmpfile(); - if (file == NULL) { + FILE* file = NULL; + int fd = -1; +#ifdef UNIV_HOTBACKUP + int tries; + for (tries = 10; tries--; ) { + char* name = tempnam(fil_path_to_mysql_datadir, "ib"); + if (!name) { + break; + } + + fd = open(name, +# ifdef __WIN__ + O_SEQUENTIAL | O_SHORT_LIVED | O_TEMPORARY | +# endif /* __WIN__ */ + O_CREAT | O_EXCL | O_RDWR, + S_IREAD | S_IWRITE); + if (fd >= 0) { +# ifndef __WIN__ + unlink(name); +# endif /* !__WIN__ */ + free(name); + break; + } + ut_print_timestamp(stderr); - fputs(" InnoDB: Error: unable to create temporary file\n", - stderr); - os_file_handle_error(NULL, "tmpfile"); - ut_error; + fprintf(stderr, " InnoDB: Warning: " + "unable to create temporary file %s, retrying\n", + name); + free(name); + } +#else /* UNIV_HOTBACKUP */ + fd = innobase_mysql_tmpfile(); +#endif /* UNIV_HOTBACKUP */ + + if (fd >= 0) { + file = fdopen(fd, "w+b"); + } + + if (!file) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: unable to create temporary file;" + " errno: %d\n", errno); + if (fd >= 0) { + close(fd); + } } + return(file); } @@ -3623,6 +3673,9 @@ consecutive_loop: ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: ERROR: The page to be written seems corrupt!\n"); + fprintf(stderr, +"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n", + (ulong)total_len, (ulong)len2); buf_page_print(combined_buf + len2); fprintf(stderr, "InnoDB: ERROR: The page to be written seems corrupt!\n"); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 556c80c948d..2e8c3adf94f 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2284,7 +2284,6 @@ row_drop_table_for_mysql( "COMMIT WORK;\n" "END;\n"; - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(name != NULL); if (srv_created_new_raw) { @@ -2338,21 +2337,6 @@ row_drop_table_for_mysql( srv_print_innodb_table_monitor = FALSE; } - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - ut_a(name != NULL); - - if (srv_created_new_raw) { - fputs( - "InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" - "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", - stderr); - - return(DB_ERROR); - } - quoted_name = mem_strdupq(name, '\''); namelen = strlen(quoted_name); sql = mem_alloc((sizeof str1) + (sizeof str2) - 2 + 1 + namelen); @@ -3011,6 +2995,30 @@ row_rename_table_for_mysql( NULL); trx->error_state = DB_SUCCESS; } + } else { + err = dict_load_foreigns(new_name); + + if (err != DB_SUCCESS) { + + ut_print_timestamp(stderr); + + fputs( + " InnoDB: Error: in RENAME TABLE table ", + stderr); + ut_print_name(stderr, new_name); + fputs("\n" + "InnoDB: is referenced in foreign key constraints\n" + "InnoDB: which are not compatible with the new table definition.\n", + stderr); + + ut_a(dict_table_rename_in_cache(table, + old_name, FALSE)); + + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, FALSE, + NULL); + trx->error_state = DB_SUCCESS; + } } } funct_exit: diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 9e8e9b82f2d..dc6694fc18c 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -631,10 +631,24 @@ row_sel_get_clust_rec( if (!node->read_view) { /* Try to place a lock on the index record */ - + + /* If innodb_locks_unsafe_for_binlog option is used, + we lock only the record, i.e. next-key locking is + not used. + */ + if ( srv_locks_unsafe_for_binlog ) + { + err = lock_clust_rec_read_check_and_lock(0, clust_rec, + index,node->row_lock_mode, LOCK_REC_NOT_GAP, thr); + } + else + { err = lock_clust_rec_read_check_and_lock(0, clust_rec, index, node->row_lock_mode, LOCK_ORDINARY, thr); - if (err != DB_SUCCESS) { + + } + + if (err != DB_SUCCESS) { return(err); } @@ -1184,9 +1198,23 @@ rec_loop: search result set, resulting in the phantom problem. */ if (!consistent_read) { + + /* If innodb_locks_unsafe_for_binlog option is used, + we lock only the record, i.e. next-key locking is + not used. + */ + + if ( srv_locks_unsafe_for_binlog ) + { + err = sel_set_rec_lock(page_rec_get_next(rec), index, + node->row_lock_mode, LOCK_REC_NOT_GAP, thr); + } + else + { err = sel_set_rec_lock(page_rec_get_next(rec), index, node->row_lock_mode, LOCK_ORDINARY, thr); - if (err != DB_SUCCESS) { + } + if (err != DB_SUCCESS) { /* Note that in this case we will store in pcur the PREDECESSOR of the record we are waiting the lock for */ @@ -1211,8 +1239,22 @@ rec_loop: if (!consistent_read) { /* Try to place a lock on the index record */ - err = sel_set_rec_lock(rec, index, node->row_lock_mode, + /* If innodb_locks_unsafe_for_binlog option is used, + we lock only the record, i.e. next-key locking is + not used. + */ + + if ( srv_locks_unsafe_for_binlog ) + { + err = sel_set_rec_lock(rec, index, node->row_lock_mode, + LOCK_REC_NOT_GAP, thr); + } + else + { + err = sel_set_rec_lock(rec, index, node->row_lock_mode, LOCK_ORDINARY, thr); + } + if (err != DB_SUCCESS) { goto lock_wait_or_error; @@ -3169,10 +3211,24 @@ rec_loop: /* Try to place a lock on the index record */ - err = sel_set_rec_lock(rec, index, + /* If innodb_locks_unsafe_for_binlog option is used, + we lock only the record, i.e. next-key locking is + not used. + */ + if ( srv_locks_unsafe_for_binlog ) + { + err = sel_set_rec_lock(rec, index, + prebuilt->select_lock_type, + LOCK_REC_NOT_GAP, thr); + } + else + { + err = sel_set_rec_lock(rec, index, prebuilt->select_lock_type, LOCK_ORDINARY, thr); - if (err != DB_SUCCESS) { + } + + if (err != DB_SUCCESS) { goto lock_wait_or_error; } @@ -3193,8 +3249,15 @@ rec_loop: if (srv_force_recovery == 0 || moves_up == FALSE) { ut_print_timestamp(stderr); + buf_page_print(buf_frame_align(rec)); + fprintf(stderr, +"\nInnoDB: rec address %lx, first buffer frame %lx\n" +"InnoDB: buffer pool high end %lx, buf block fix count %lu\n", + (ulong)rec, (ulong)buf_pool->frame_zero, + (ulong)buf_pool->high_end, + (ulong)buf_block_align(rec)->buf_fix_count); fprintf(stderr, -" InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n" +"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n" "InnoDB: ", (ulong) (rec - buf_frame_align(rec)), (ulong) next_offs, @@ -3325,9 +3388,22 @@ rec_loop: prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr); } else { - err = sel_set_rec_lock(rec, index, + /* If innodb_locks_unsafe_for_binlog option is used, + we lock only the record, i.e. next-key locking is + not used. + */ + if ( srv_locks_unsafe_for_binlog ) + { + err = sel_set_rec_lock(rec, index, + prebuilt->select_lock_type, + LOCK_REC_NOT_GAP, thr); + } + else + { + err = sel_set_rec_lock(rec, index, prebuilt->select_lock_type, LOCK_ORDINARY, thr); + } } if (err != DB_SUCCESS) { diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 4bc5b0dc795..389cd5b779d 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -77,6 +77,10 @@ ibool srv_file_per_table = FALSE; /* store to its own file each table created by an user; data dictionary tables are in the system tablespace 0 */ +ibool srv_locks_unsafe_for_binlog = FALSE; /* Place locks to records only + i.e. do not use next-key locking + except on duplicate key checking and + foreign key checking */ ulint srv_n_data_files = 0; char** srv_data_file_names = NULL; ulint* srv_data_file_sizes = NULL; /* size in database pages */ @@ -238,6 +242,9 @@ merge to completion before shutdown */ ibool srv_fast_shutdown = FALSE; +/* Generate a innodb_status.<pid> file */ +ibool srv_innodb_status = FALSE; + ibool srv_use_doublewrite_buf = TRUE; ibool srv_set_thread_priorities = TRUE; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 74dd23e4252..4a0335086f0 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1112,16 +1112,24 @@ NetWare. */ mutex_create(&srv_monitor_file_mutex); mutex_set_level(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK); - srv_monitor_file_name = mem_alloc( - strlen(fil_path_to_mysql_datadir) + - 20 + sizeof "/innodb_status."); - sprintf(srv_monitor_file_name, "%s/innodb_status.%lu", - fil_path_to_mysql_datadir, os_proc_get_number()); - srv_monitor_file = fopen(srv_monitor_file_name, "w+"); - if (!srv_monitor_file) { - fprintf(stderr, "InnoDB: unable to create %s: %s\n", - srv_monitor_file_name, strerror(errno)); - return(DB_ERROR); + if (srv_innodb_status) { + srv_monitor_file_name = mem_alloc( + strlen(fil_path_to_mysql_datadir) + + 20 + sizeof "/innodb_status."); + sprintf(srv_monitor_file_name, "%s/innodb_status.%lu", + fil_path_to_mysql_datadir, os_proc_get_number()); + srv_monitor_file = fopen(srv_monitor_file_name, "w+"); + if (!srv_monitor_file) { + fprintf(stderr, "InnoDB: unable to create %s: %s\n", + srv_monitor_file_name, strerror(errno)); + return(DB_ERROR); + } + } else { + srv_monitor_file_name = NULL; + srv_monitor_file = os_file_create_tmpfile(); + if (!srv_monitor_file) { + return(DB_ERROR); + } } /* Restrict the maximum number of file i/o threads */ @@ -1177,6 +1185,7 @@ NetWare. */ for (i = 0; i < srv_n_file_io_threads; i++) { n[i] = i; + os_thread_create(io_handler_thread, n + i, thread_ids + i); } @@ -1578,9 +1587,10 @@ NetWare. */ fprintf(stderr, "InnoDB: You have now successfully upgraded to the multiple tablespaces\n" -"InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\n" -"InnoDB: InnoDB! But if you absolutely need to downgrade, see section 4.6 of\n" -"InnoDB: http://www.innodb.com/ibman.php for instructions.\n"); +"InnoDB: format. You should NOT DOWNGRADE to an earlier version of\n" +"InnoDB: InnoDB! But if you absolutely need to downgrade, see\n" +"InnoDB: http://dev.mysql.com/doc/mysql/en/Multiple_tablespaces.html\n" +"InnoDB: for instructions.\n"); } if (srv_force_recovery == 0) { @@ -1606,7 +1616,9 @@ innobase_shutdown_for_mysql(void) /* out: DB_SUCCESS or error code */ { ulint i; - +#ifdef __NETWARE__ + extern ibool panic_shutdown; +#endif if (!srv_was_started) { if (srv_is_being_started) { ut_print_timestamp(stderr); @@ -1623,8 +1635,11 @@ innobase_shutdown_for_mysql(void) The step 1 is the real InnoDB shutdown. The remaining steps 2 - ... just free data structures after the shutdown. */ +#ifdef __NETWARE__ + if(!panic_shutdown) +#endif logs_empty_and_mark_files_at_shutdown(); - + if (srv_conc_n_threads != 0) { fprintf(stderr, "InnoDB: Warning: query counter shows %ld queries still\n" @@ -1687,15 +1702,16 @@ innobase_shutdown_for_mysql(void) if (srv_monitor_file) { fclose(srv_monitor_file); srv_monitor_file = 0; - unlink(srv_monitor_file_name); - mem_free(srv_monitor_file_name); + if (srv_monitor_file_name) { + unlink(srv_monitor_file_name); + mem_free(srv_monitor_file_name); + } } - + mutex_free(&srv_monitor_file_mutex); /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ - sync_close(); /* 4. Free the os_conc_mutex and all os_events and os_mutexes */ @@ -1706,7 +1722,7 @@ innobase_shutdown_for_mysql(void) /* 5. Free all allocated memory and the os_fast_mutex created in ut0mem.c */ - ut_free_all_mem(); + ut_free_all_mem(); if (os_thread_count != 0 || os_event_count != 0 @@ -1736,3 +1752,11 @@ innobase_shutdown_for_mysql(void) return((int) DB_SUCCESS); } + +#ifdef __NETWARE__ +void set_panic_flag_for_netware() +{ + extern ibool panic_shutdown; + panic_shutdown = TRUE; +} +#endif diff --git a/innobase/ut/ut0dbg.c b/innobase/ut/ut0dbg.c index 65703ec1c86..2a0cfe1f13a 100644 --- a/innobase/ut/ut0dbg.c +++ b/innobase/ut/ut0dbg.c @@ -14,7 +14,12 @@ ulint ut_dbg_zero = 0; /* If this is set to TRUE all threads will stop into the next assertion and assert */ ibool ut_dbg_stop_threads = FALSE; - +#ifdef __NETWARE__ +ibool panic_shutdown = FALSE; /* This is set to TRUE when on NetWare there + happens an InnoDB assertion failure or other + fatal error condition that requires an + immediate shutdown. */ +#endif /* Null pointer used to generate memory trap */ ulint* ut_dbg_null_ptr = NULL; diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 9a591df9f77..09410e348c2 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -107,7 +107,13 @@ ut_malloc_low( /* Make an intentional seg fault so that we get a stack trace */ + /* Intentional segfault on NetWare causes an abend. Avoid this + by graceful exit handling in ut_a(). */ +#if (!defined __NETWARE__) if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; +#else + ut_a(0); +#endif } if (set_to_zero) { |