Commit 545e596e authored by monty@work.mysql.com's avatar monty@work.mysql.com

merge

parents fb58572c b976c48f
...@@ -17,7 +17,7 @@ sasha@mysql.sashanet.com ...@@ -17,7 +17,7 @@ sasha@mysql.sashanet.com
serg@serg.mysql.com serg@serg.mysql.com
tim@hundin.mysql.fi tim@hundin.mysql.fi
tim@threads.polyesthetic.msg tim@threads.polyesthetic.msg
tim@white.box
tim@work.mysql.com tim@work.mysql.com
tonu@hundin.mysql.fi tonu@hundin.mysql.fi
tonu@x3.internalnet tonu@x3.internalnet
tim@white.box
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -246,6 +246,12 @@ btr_pcur_restore_position( ...@@ -246,6 +246,12 @@ btr_pcur_restore_position(
&& btr_pcur_is_on_user_rec(cursor, mtr) && btr_pcur_is_on_user_rec(cursor, mtr)
&& (0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor)))) { && (0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor)))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! */
cursor->modify_clock = buf_frame_get_modify_clock(
buf_frame_align(
btr_pcur_get_rec(cursor)));
mem_heap_free(heap); mem_heap_free(heap);
return(TRUE); return(TRUE);
......
...@@ -241,6 +241,8 @@ buf_block_init( ...@@ -241,6 +241,8 @@ buf_block_init(
block->modify_clock = ut_dulint_zero; block->modify_clock = ut_dulint_zero;
block->file_page_was_freed = FALSE;
rw_lock_create(&(block->lock)); rw_lock_create(&(block->lock));
ut_ad(rw_lock_validate(&(block->lock))); ut_ad(rw_lock_validate(&(block->lock)));
...@@ -542,6 +544,64 @@ buf_page_peek( ...@@ -542,6 +544,64 @@ buf_page_peek(
return(FALSE); return(FALSE);
} }
/************************************************************************
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_set_file_page_was_freed(
/*=============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
buf_block_t* block;
mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset);
if (block) {
block->file_page_was_freed = TRUE;
}
mutex_exit(&(buf_pool->mutex));
return(block);
}
/************************************************************************
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
buf_block_t* block;
mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset);
if (block) {
block->file_page_was_freed = FALSE;
}
mutex_exit(&(buf_pool->mutex));
return(block);
}
/************************************************************************ /************************************************************************
This is the general function used to get access to a database page. */ This is the general function used to get access to a database page. */
...@@ -646,6 +706,9 @@ loop: ...@@ -646,6 +706,9 @@ loop:
block->accessed = TRUE; block->accessed = TRUE;
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -842,6 +905,9 @@ buf_page_optimistic_get_func( ...@@ -842,6 +905,9 @@ buf_page_optimistic_get_func(
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
ut_ad(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
if (!accessed) { if (!accessed) {
/* In the case of a first access, try to apply linear /* In the case of a first access, try to apply linear
read-ahead */ read-ahead */
...@@ -949,6 +1015,9 @@ buf_page_get_known_nowait( ...@@ -949,6 +1015,9 @@ buf_page_get_known_nowait(
#endif #endif
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
ut_ad(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a((mode == BUF_KEEP_OLD) ut_a((mode == BUF_KEEP_OLD)
...@@ -996,6 +1065,8 @@ buf_page_init( ...@@ -996,6 +1065,8 @@ buf_page_init(
block->n_hash_helps = 0; block->n_hash_helps = 0;
block->is_hashed = FALSE; block->is_hashed = FALSE;
block->file_page_was_freed = FALSE;
} }
/************************************************************************ /************************************************************************
...@@ -1126,6 +1197,8 @@ buf_page_create( ...@@ -1126,6 +1197,8 @@ buf_page_create(
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a(ibuf_count_get(block->space, block->offset) == 0); ut_a(ibuf_count_get(block->space, block->offset) == 0);
#endif #endif
block->file_page_was_freed = FALSE;
/* Page can be found in buf_pool */ /* Page can be found in buf_pool */
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
......
...@@ -182,7 +182,7 @@ buf_flush_write_complete( ...@@ -182,7 +182,7 @@ buf_flush_write_complete(
buf_pool->LRU_flush_ended++; buf_pool->LRU_flush_ended++;
} }
/* printf("n pending flush %lu\n", /* printf("n pending flush %lu\n",
buf_pool->n_flush[block->flush_type]); */ buf_pool->n_flush[block->flush_type]); */
if ((buf_pool->n_flush[block->flush_type] == 0) if ((buf_pool->n_flush[block->flush_type] == 0)
...@@ -421,6 +421,8 @@ buf_flush_try_neighbors( ...@@ -421,6 +421,8 @@ buf_flush_try_neighbors(
/* In simulated aio we wake up the i/o-handler threads now that /* In simulated aio we wake up the i/o-handler threads now that
we have posted a batch of writes: */ we have posted a batch of writes: */
/* printf("Flush count %lu ; Waking i/o handlers\n", count); */
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
return(count); return(count);
......
...@@ -260,9 +260,9 @@ loop: ...@@ -260,9 +260,9 @@ loop:
*/ */
if (n_iterations > 30) { if (n_iterations > 30) {
fprintf(stderr, fprintf(stderr,
"Innobase: Warning: difficult to find free blocks from\n" "InnoDB: Warning: difficult to find free blocks from\n"
"Innobase: the buffer pool! Consider increasing the\n" "InnoDB: the buffer pool (%lu search iterations)! Consider\n"
"Innobase: buffer pool size.\n"); "InnoDB: increasing the buffer pool size.\n", n_iterations);
} }
} }
......
...@@ -18,6 +18,7 @@ Created 11/5/1995 Heikki Tuuri ...@@ -18,6 +18,7 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h" #include "log0recv.h"
#include "trx0sys.h" #include "trx0sys.h"
#include "os0file.h" #include "os0file.h"
#include "srv0start.h"
/* The size in blocks of the area where the random read-ahead algorithm counts /* The size in blocks of the area where the random read-ahead algorithm counts
the accessed pages when deciding whether to read-ahead */ the accessed pages when deciding whether to read-ahead */
...@@ -132,10 +133,16 @@ buf_read_ahead_random( ...@@ -132,10 +133,16 @@ buf_read_ahead_random(
ulint low, high; ulint low, high;
ulint i; ulint i;
if (ibuf_bitmap_page(offset)) { if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */
return(0);
}
/* If it is an ibuf bitmap page, we do no read-ahead, as if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {
that could break the ibuf page access order */
/* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access
order */
return(0); return(0);
} }
...@@ -301,9 +308,16 @@ buf_read_ahead_linear( ...@@ -301,9 +308,16 @@ buf_read_ahead_linear(
ulint low, high; ulint low, high;
ulint i; ulint i;
if (ibuf_bitmap_page(offset)) { if (srv_startup_is_before_trx_rollback_phase) {
/* If it is an ibuf bitmap page, we do no read-ahead, as /* No read-ahead to avoid thread deadlocks */
that could break the ibuf page access order */ return(0);
}
if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {
/* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access
order */
return(0); return(0);
} }
......
...@@ -313,6 +313,11 @@ dict_boot(void) ...@@ -313,6 +313,11 @@ dict_boot(void)
mtr_commit(&mtr); 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 */ /* Load definitions of other indexes on system tables */
dict_load_sys_table(dict_sys->sys_tables); dict_load_sys_table(dict_sys->sys_tables);
...@@ -320,10 +325,6 @@ dict_boot(void) ...@@ -320,10 +325,6 @@ dict_boot(void)
dict_load_sys_table(dict_sys->sys_indexes); dict_load_sys_table(dict_sys->sys_indexes);
dict_load_sys_table(dict_sys->sys_fields); 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)); mutex_exit(&(dict_sys->mutex));
} }
......
...@@ -127,11 +127,9 @@ typedef byte fseg_inode_t; ...@@ -127,11 +127,9 @@ typedef byte fseg_inode_t;
page number within space, FIL_NULL page number within space, FIL_NULL
means that the slot is not in use */ means that the slot is not in use */
/*-------------------------------------*/ /*-------------------------------------*/
#define FSEG_INODE_SIZE (16 + 3 * FLST_BASE_NODE_SIZE +\ #define FSEG_INODE_SIZE (16 + 3 * FLST_BASE_NODE_SIZE + FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
#define FSP_SEG_INODES_PER_PAGE ((UNIV_PAGE_SIZE - FSEG_ARR_OFFSET - 10)\ #define FSP_SEG_INODES_PER_PAGE ((UNIV_PAGE_SIZE - FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
/ FSEG_INODE_SIZE)
/* Number of segment inodes which fit on a /* Number of segment inodes which fit on a
single page */ single page */
...@@ -198,8 +196,7 @@ the extent are free and which contain old tuple version to clean. */ ...@@ -198,8 +196,7 @@ the extent are free and which contain old tuple version to clean. */
/* File extent data structure size in bytes. The "+ 7 ) / 8" part in the /* File extent data structure size in bytes. The "+ 7 ) / 8" part in the
definition rounds the number of bytes upward. */ definition rounds the number of bytes upward. */
#define XDES_SIZE (XDES_BITMAP +\ #define XDES_SIZE (XDES_BITMAP + (FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE + 7) / 8)
(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE + 7) / 8)
/* Offset of the descriptor array on a descriptor page */ /* Offset of the descriptor array on a descriptor page */
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
...@@ -2539,6 +2536,10 @@ fseg_free_page( ...@@ -2539,6 +2536,10 @@ fseg_free_page(
seg_inode = fseg_inode_get(seg_header, mtr); seg_inode = fseg_inode_get(seg_header, mtr);
fseg_free_page_low(seg_inode, space, page, 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
} }
/************************************************************************** /**************************************************************************
...@@ -2602,6 +2603,14 @@ fseg_free_extent( ...@@ -2602,6 +2603,14 @@ fseg_free_extent(
} }
fsp_free_extent(space, page, mtr); 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
} }
/************************************************************************** /**************************************************************************
...@@ -2633,6 +2642,14 @@ fseg_free_step( ...@@ -2633,6 +2642,14 @@ fseg_free_step(
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
mtr_x_lock(fil_space_get_latch(space), mtr); mtr_x_lock(fil_space_get_latch(space), mtr);
descr = xdes_get_descriptor(space, buf_frame_get_page_no(header), mtr);
/* Check that the header resides on a page which has not been
freed yet */
ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
% FSP_EXTENT_SIZE, mtr) == FALSE);
inode = fseg_inode_get(header, mtr); inode = fseg_inode_get(header, mtr);
descr = fseg_get_first_extent(inode, mtr); descr = fseg_get_first_extent(inode, mtr);
...@@ -2647,7 +2664,6 @@ fseg_free_step( ...@@ -2647,7 +2664,6 @@ fseg_free_step(
} }
/* Free a frag page */ /* Free a frag page */
n = fseg_find_last_used_frag_page_slot(inode, mtr); n = fseg_find_last_used_frag_page_slot(inode, mtr);
if (n == ULINT_UNDEFINED) { if (n == ULINT_UNDEFINED) {
...@@ -2659,6 +2675,16 @@ fseg_free_step( ...@@ -2659,6 +2675,16 @@ fseg_free_step(
fseg_free_page_low(inode, space, fseg_free_page_low(inode, space,
fseg_get_nth_frag_page_no(inode, n, mtr), mtr); fseg_get_nth_frag_page_no(inode, n, mtr), mtr);
n = fseg_find_last_used_frag_page_slot(inode, mtr);
if (n == ULINT_UNDEFINED) {
/* Freeing completed: free the segment inode */
fsp_free_seg_inode(space, inode, mtr);
return(TRUE);
}
return(FALSE); return(FALSE);
} }
......
...@@ -1382,6 +1382,9 @@ ibuf_remove_free_page( ...@@ -1382,6 +1382,9 @@ ibuf_remove_free_page(
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
space, page_no, &mtr); space, page_no, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_reset_file_page_was_freed(space, page_no);
#endif
ibuf_enter(); ibuf_enter();
mutex_enter(&ibuf_mutex); mutex_enter(&ibuf_mutex);
...@@ -1413,6 +1416,9 @@ ibuf_remove_free_page( ...@@ -1413,6 +1416,9 @@ ibuf_remove_free_page(
ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
FALSE, &mtr); FALSE, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_set_file_page_was_freed(space, page_no);
#endif
mtr_commit(&mtr); mtr_commit(&mtr);
mutex_exit(&ibuf_mutex); mutex_exit(&ibuf_mutex);
...@@ -2431,6 +2437,8 @@ ibuf_merge_or_delete_for_page( ...@@ -2431,6 +2437,8 @@ ibuf_merge_or_delete_for_page(
block = buf_block_align(page); block = buf_block_align(page);
rw_lock_x_lock_move_ownership(&(block->lock)); rw_lock_x_lock_move_ownership(&(block->lock));
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
} }
n_inserts = 0; n_inserts = 0;
......
...@@ -293,6 +293,32 @@ buf_page_peek_block( ...@@ -293,6 +293,32 @@ buf_page_peek_block(
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset);/* in: page number */ ulint offset);/* in: page number */
/************************************************************************ /************************************************************************
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_set_file_page_was_freed(
/*=============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset); /* in: page number */
/************************************************************************
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset); /* in: page number */
/************************************************************************
Recommends a move of a block to the start of the LRU list if there is danger Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool of dropping from the buffer pool. NOTE: does not reserve the buffer pool
mutex. */ mutex. */
...@@ -706,6 +732,9 @@ struct buf_block_struct{ ...@@ -706,6 +732,9 @@ struct buf_block_struct{
which bufferfixes the block acquires which bufferfixes the block acquires
an s-latch here; so we can use the an s-latch here; so we can use the
debug utilities in sync0rw */ debug utilities in sync0rw */
ibool file_page_was_freed;
/* this is set to TRUE when fsp
frees a page in buffer pool */
}; };
/* The buffer pool structure. NOTE! The definition appears here only for /* The buffer pool structure. NOTE! The definition appears here only for
......
...@@ -28,4 +28,7 @@ int ...@@ -28,4 +28,7 @@ int
innobase_shutdown_for_mysql(void); innobase_shutdown_for_mysql(void);
/*=============================*/ /*=============================*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
extern ibool srv_startup_is_before_trx_rollback_phase;
#endif #endif
...@@ -86,7 +86,7 @@ mutex_test_and_set( ...@@ -86,7 +86,7 @@ mutex_test_and_set(
/* mutex_fence(); */ /* mutex_fence(); */
return(res); return(res);
#elif defined(__GNUC__) && defined(UNIV_INTEL_X86) #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
ulint* lw; ulint* lw;
ulint res; ulint res;
...@@ -134,7 +134,7 @@ mutex_reset_lock_word( ...@@ -134,7 +134,7 @@ mutex_reset_lock_word(
__asm MOV EDX, 0 __asm MOV EDX, 0
__asm MOV ECX, lw __asm MOV ECX, lw
__asm XCHG EDX, DWORD PTR [ECX] __asm XCHG EDX, DWORD PTR [ECX]
#elif defined(__GNUC__) && defined(UNIV_INTEL_X86) #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
ulint* lw; ulint* lw;
lw = &(mutex->lock_word); lw = &(mutex->lock_word);
......
...@@ -74,6 +74,8 @@ subdirectory of 'mysql'. */ ...@@ -74,6 +74,8 @@ subdirectory of 'mysql'. */
#define UNIV_SYNC_PERF_STAT #define UNIV_SYNC_PERF_STAT
#define UNIV_SEARCH_PERF_STAT #define UNIV_SEARCH_PERF_STAT
#define UNIV_DEBUG_FILE_ACCESSES
*/ */
#define UNIV_LIGHT_MEM_DEBUG #define UNIV_LIGHT_MEM_DEBUG
......
...@@ -944,9 +944,9 @@ recv_read_in_area( ...@@ -944,9 +944,9 @@ recv_read_in_area(
} }
buf_read_recv_pages(FALSE, space, page_nos, n); 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); return(n);
} }
......
...@@ -11,6 +11,7 @@ Created 10/21/1995 Heikki Tuuri ...@@ -11,6 +11,7 @@ Created 10/21/1995 Heikki Tuuri
#include "ut0mem.h" #include "ut0mem.h"
#include "srv0srv.h" #include "srv0srv.h"
#undef HAVE_FDATASYNC
#ifdef POSIX_ASYNC_IO #ifdef POSIX_ASYNC_IO
/* We assume in this case that the OS has standard Posix aio (at least SunOS /* We assume in this case that the OS has standard Posix aio (at least SunOS
...@@ -562,6 +563,11 @@ os_file_flush( ...@@ -562,6 +563,11 @@ os_file_flush(
return(TRUE); return(TRUE);
} }
fprintf(stderr,
"InnoDB: Error: the OS said file flush did not succeed\n");
os_file_handle_error(file, NULL);
return(FALSE); return(FALSE);
#endif #endif
} }
......
...@@ -824,7 +824,11 @@ row_create_table_for_mysql( ...@@ -824,7 +824,11 @@ row_create_table_for_mysql(
} else { } else {
assert(err == DB_DUPLICATE_KEY); assert(err == DB_DUPLICATE_KEY);
fprintf(stderr, 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); table->name);
} }
......
...@@ -361,6 +361,7 @@ row_undo_mod_del_unmark_sec( ...@@ -361,6 +361,7 @@ row_undo_mod_del_unmark_sec(
btr_cur_t* btr_cur; btr_cur_t* btr_cur;
ulint err; ulint err;
ibool found; ibool found;
char* err_buf;
UT_NOT_USED(node); UT_NOT_USED(node);
...@@ -369,13 +370,31 @@ row_undo_mod_del_unmark_sec( ...@@ -369,13 +370,31 @@ row_undo_mod_del_unmark_sec(
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
&mtr); &mtr);
ut_a(found); if (!found) {
err_buf = mem_alloc(1000);
dtuple_sprintf(err_buf, 900, entry);
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);
} else {
btr_cur = btr_pcur_get_btr_cur(&pcur); btr_cur = btr_pcur_get_btr_cur(&pcur);
err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
btr_cur, FALSE, thr, &mtr); btr_cur, FALSE, thr, &mtr);
ut_ad(err == DB_SUCCESS); ut_ad(err == DB_SUCCESS);
}
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
......
...@@ -750,6 +750,7 @@ row_upd_sec_index_entry( ...@@ -750,6 +750,7 @@ row_upd_sec_index_entry(
btr_cur_t* btr_cur; btr_cur_t* btr_cur;
mem_heap_t* heap; mem_heap_t* heap;
rec_t* rec; rec_t* rec;
char* err_buf;
ulint err = DB_SUCCESS; ulint err = DB_SUCCESS;
index = node->index; index = node->index;
...@@ -764,19 +765,38 @@ row_upd_sec_index_entry( ...@@ -764,19 +765,38 @@ row_upd_sec_index_entry(
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
&mtr); &mtr);
ut_ad(found);
btr_cur = btr_pcur_get_btr_cur(&pcur); btr_cur = btr_pcur_get_btr_cur(&pcur);
rec = btr_cur_get_rec(btr_cur); rec = btr_cur_get_rec(btr_cur);
/* Delete mark the old index record; it can already be delete marked if if (!found) {
we return after a lock wait in row_ins_index_entry below */
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, err = btr_cur_del_mark_set_sec_rec(0, btr_cur, TRUE, thr,
&mtr); &mtr);
} }
}
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
......
...@@ -56,6 +56,7 @@ Created 2/16/1996 Heikki Tuuri ...@@ -56,6 +56,7 @@ Created 2/16/1996 Heikki Tuuri
#include "srv0start.h" #include "srv0start.h"
#include "que0que.h" #include "que0que.h"
ibool srv_startup_is_before_trx_rollback_phase = FALSE;
ibool srv_is_being_started = FALSE; ibool srv_is_being_started = FALSE;
ibool srv_was_started = FALSE; ibool srv_was_started = FALSE;
...@@ -531,6 +532,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -531,6 +532,7 @@ innobase_start_or_create_for_mysql(void)
/* yydebug = TRUE; */ /* yydebug = TRUE; */
srv_is_being_started = 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")) { if (0 == ut_strcmp(srv_unix_file_flush_method_str, "fdatasync")) {
srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
...@@ -548,6 +550,9 @@ innobase_start_or_create_for_mysql(void) ...@@ -548,6 +550,9 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR); return(DB_ERROR);
} }
/*
printf("srv_unix set to %lu\n", srv_unix_file_flush_method);
*/
os_aio_use_native_aio = srv_use_native_aio; os_aio_use_native_aio = srv_use_native_aio;
err = srv_boot(); err = srv_boot();
...@@ -728,6 +733,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -728,6 +733,7 @@ innobase_start_or_create_for_mysql(void)
trx_sys_create(); trx_sys_create();
dict_create(); dict_create();
srv_startup_is_before_trx_rollback_phase = FALSE;
} else if (srv_archive_recovery) { } else if (srv_archive_recovery) {
fprintf(stderr, fprintf(stderr,
...@@ -742,9 +748,15 @@ innobase_start_or_create_for_mysql(void) ...@@ -742,9 +748,15 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR); 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(); dict_boot();
trx_sys_init_at_db_start();
srv_startup_is_before_trx_rollback_phase = FALSE;
recv_recovery_from_archive_finish(); recv_recovery_from_archive_finish();
} else { } else {
/* We always try to do a recovery, even if the database had /* We always try to do a recovery, even if the database had
...@@ -759,12 +771,15 @@ innobase_start_or_create_for_mysql(void) ...@@ -759,12 +771,15 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR); 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(); dict_boot();
trx_sys_init_at_db_start();
/* The following needs trx lists which are initialized in /* The following needs trx lists which are initialized in
trx_sys_init_at_db_start */ trx_sys_init_at_db_start */
srv_startup_is_before_trx_rollback_phase = FALSE;
recv_recovery_from_checkpoint_finish(); recv_recovery_from_checkpoint_finish();
} }
......
...@@ -166,6 +166,46 @@ struct sync_level_struct{ ...@@ -166,6 +166,46 @@ struct sync_level_struct{
ulint level; /* level of the latch in the latching order */ 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 Creates, or rather, initializes a mutex object in a specified memory
location (which must be appropriately aligned). The mutex is initialized location (which must be appropriately aligned). The mutex is initialized
......
...@@ -613,6 +613,10 @@ trx_undo_insert_header_reuse( ...@@ -613,6 +613,10 @@ trx_undo_insert_header_reuse(
/* Insert undo data is not needed after commit: we may free all /* Insert undo data is not needed after commit: we may free all
the space on the page */ 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_START, new_free);
mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free);
...@@ -800,7 +804,7 @@ trx_undo_free_page( ...@@ -800,7 +804,7 @@ trx_undo_free_page(
ulint hist_size; ulint hist_size;
UT_NOT_USED(hdr_offset); 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(&kernel_mutex));
ut_ad(mutex_own(&(rseg->mutex))); ut_ad(mutex_own(&(rseg->mutex)));
...@@ -1411,6 +1415,10 @@ trx_undo_reuse_cached( ...@@ -1411,6 +1415,10 @@ trx_undo_reuse_cached(
if (type == TRX_UNDO_INSERT) { if (type == TRX_UNDO_INSERT) {
offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr); offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr);
} else { } 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); offset = trx_undo_header_create(undo_page, trx_id, mtr);
} }
......
...@@ -206,7 +206,7 @@ static struct option long_options[] = ...@@ -206,7 +206,7 @@ static struct option long_options[] =
static void print_version(void) static void print_version(void)
{ {
printf("%s Ver 1.46 for %s at %s\n",my_progname,SYSTEM_TYPE, printf("%s Ver 1.47 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE); MACHINE_TYPE);
} }
...@@ -239,7 +239,8 @@ static void usage(void) ...@@ -239,7 +239,8 @@ static void usage(void)
-F, --fast Check only tables that hasn't been closed properly\n\ -F, --fast Check only tables that hasn't been closed properly\n\
-C, --check-only-changed\n\ -C, --check-only-changed\n\
Check only tables that has changed since last check\n\ Check only tables that has changed since last check\n\
-f, --force Restart with -r if there are any errors in the table\n\ -f, --force Restart with -r if there are any errors in the table.\n\
States will be updated as with --update-state\n\
-i, --information Print statistics information about table that is checked\n\ -i, --information Print statistics information about table that is checked\n\
-m, --medium-check Faster than extended-check, but only finds 99.99% of\n\ -m, --medium-check Faster than extended-check, but only finds 99.99% of\n\
all errors. Should be good enough for most cases\n\ all errors. Should be good enough for most cases\n\
...@@ -364,7 +365,7 @@ static void get_options(register int *argc,register char ***argv) ...@@ -364,7 +365,7 @@ static void get_options(register int *argc,register char ***argv)
break; break;
case 'f': case 'f':
check_param.tmpfile_createflag= O_RDWR | O_TRUNC; check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
check_param.testflag|=T_FORCE_CREATE; check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
break; break;
case 'F': case 'F':
check_param.testflag|=T_FAST; check_param.testflag|=T_FAST;
......
...@@ -39,3 +39,5 @@ drop database foo; ...@@ -39,3 +39,5 @@ drop database foo;
unlock tables; unlock tables;
drop database foo; drop database foo;
show databases; show databases;
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
# Numeric floating point. # Numeric floating point.
SELECT 10,10.0,10.,.1e+2,100.0e-1; SELECT 10,10.0,10.,.1e+2,100.0e-1;
select 6e-05, -6e-05, --6e-05, -6e-05+1.000000; SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
drop table if exists t1; drop table if exists t1;
create table t1 (f1 float(24),f2 float(52)); create table t1 (f1 float(24),f2 float(52));
......
...@@ -199,16 +199,16 @@ ...@@ -199,16 +199,16 @@
"La tabella '%-.64s' e` segnalata come corrotta e l'ultima ricostruzione (automatica?) e` fallita", "La tabella '%-.64s' e` segnalata come corrotta e l'ultima ricostruzione (automatica?) e` fallita",
"Attenzione: Alcune delle modifiche alle tabelle non transazionali non possono essere ripristinate (roll back impossibile)", "Attenzione: Alcune delle modifiche alle tabelle non transazionali non possono essere ripristinate (roll back impossibile)",
"La transazione a comandi multipli (multi-statement) ha richiesto piu` di 'max_binlog_cache_size' bytes di disco: aumentare questa variabile di mysqld e riprovare', "La transazione a comandi multipli (multi-statement) ha richiesto piu` di 'max_binlog_cache_size' bytes di disco: aumentare questa variabile di mysqld e riprovare',
"This operation cannot be performed with a running slave, run SLAVE STOP first", "Questa operazione non puo' essere eseguita con un database 'slave' che gira, lanciare prima SLAVE STOP",
"This operation requires a running slave, configure slave and do SLAVE START", "Questa operaione richiede un database 'slave', configurarlo ed eseguire SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO", "Il server non e' configurato come 'slave', correggere il file di configurazione cambiando CHANGE MASTER TO",
"Could not initialize master info structure, check permisions on master.info", "Impossibile inizializzare la struttura 'master info', controllare i permessi sul file master.info",
"Could not create slave thread, check system resources", "Impossibile creare il thread 'slave', controllare le risorse di sistema",
"User %-.64s has already more than 'max_user_connections' active connections", "L'utente %-.64s ha gia' piu' di 'max_user_connections' connessioni attive",
"You may only use constant expressions with SET", "Si possono usare solo espressioni costanti con SET",
"Lock wait timeout exceeded", "E' scaduto il timeout per l'attesa del lock",
"The total number of locks exceeds the lock table size", "Il numero totale di lock e' maggiore della grandezza della tabella di lock",
"Update locks cannot be acquired during a READ UNCOMMITTED transaction", "I lock di aggiornamento non possono essere acquisiti durante una transazione 'READ UNCOMMITTED'",
"DROP DATABASE not allowed while thread is holding global read lock", "DROP DATABASE not allowed while thread is holding global read lock",
"CREATE DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock",
"Error connecting to master: %-.128s", "Error connecting to master: %-.128s",
......
...@@ -656,12 +656,9 @@ int yylex(void *arg) ...@@ -656,12 +656,9 @@ int yylex(void *arg)
if (c == 'e' || c == 'E') if (c == 'e' || c == 'E')
{ {
c = yyGet(); c = yyGet();
if (c != '-' && c != '+' && !isdigit(c)) if (c == '-' || c == '+')
{ // No exp sig found c = yyGet(); // Skipp sign
state= STATE_CHAR; if (!isdigit(c))
break;
}
if (!isdigit(yyGet()))
{ // No digit after sign { // No digit after sign
state= STATE_CHAR; state= STATE_CHAR;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment