diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-11-03 19:17:05 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-11-03 19:17:05 +0100 |
commit | 0e007344eae972b9be7d88ca43373cb33662ac1c (patch) | |
tree | 7b3561cb3ea2ad24d013e847680ec165f406387e /storage/innobase/include | |
parent | 3794110f0215f0631107c2694dc0f1675a4bb520 (diff) | |
parent | 681476255147dacac7e3674b6cd2ae770fee2208 (diff) | |
download | mariadb-git-0e007344eae972b9be7d88ca43373cb33662ac1c.tar.gz |
mysql-5.5.18 merge
Diffstat (limited to 'storage/innobase/include')
32 files changed, 502 insertions, 289 deletions
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 5b3e166371d..71e772388a0 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -199,26 +199,45 @@ btr_block_get_func( ulint mode, /*!< in: latch mode */ const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ - mtr_t* mtr) /*!< in/out: mtr */ - __attribute__((nonnull)); +# ifdef UNIV_SYNC_DEBUG + const dict_index_t* index, /*!< in: index tree, may be NULL + if it is not an insert buffer tree */ +# endif /* UNIV_SYNC_DEBUG */ + mtr_t* mtr); /*!< in/out: mini-transaction */ +# ifdef UNIV_SYNC_DEBUG +/** Gets a buffer page and declares its latching order level. +@param space tablespace identifier +@param zip_size compressed page size in bytes or 0 for uncompressed pages +@param page_no page number +@param mode latch mode +@param index index tree, may be NULL if not the insert buffer tree +@param mtr mini-transaction handle +@return the block descriptor */ +# define btr_block_get(space,zip_size,page_no,mode,index,mtr) \ + btr_block_get_func(space,zip_size,page_no,mode, \ + __FILE__,__LINE__,index,mtr) +# else /* UNIV_SYNC_DEBUG */ /** Gets a buffer page and declares its latching order level. @param space tablespace identifier @param zip_size compressed page size in bytes or 0 for uncompressed pages @param page_no page number @param mode latch mode +@param idx index tree, may be NULL if not the insert buffer tree @param mtr mini-transaction handle @return the block descriptor */ -# define btr_block_get(space,zip_size,page_no,mode,mtr) \ +# define btr_block_get(space,zip_size,page_no,mode,idx,mtr) \ btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,mtr) +# endif /* UNIV_SYNC_DEBUG */ /** Gets a buffer page and declares its latching order level. @param space tablespace identifier @param zip_size compressed page size in bytes or 0 for uncompressed pages @param page_no page number @param mode latch mode +@param idx index tree, may be NULL if not the insert buffer tree @param mtr mini-transaction handle @return the uncompressed page frame */ -# define btr_page_get(space,zip_size,page_no,mode,mtr) \ - buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr)) +# define btr_page_get(space,zip_size,page_no,mode,idx,mtr) \ + buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,idx,mtr)) #endif /* !UNIV_HOTBACKUP */ /**************************************************************//** Gets the index id field of a page. @@ -344,8 +363,7 @@ btr_free_root( ulint zip_size, /*!< in: compressed page size in bytes or 0 for uncompressed pages */ ulint root_page_no, /*!< in: root page number */ - mtr_t* mtr); /*!< in: a mini-transaction which has already - been started */ + mtr_t* mtr); /*!< in/out: mini-transaction */ /*************************************************************//** Makes tree one level higher by splitting the root, and inserts the tuple. It is assumed that mtr contains an x-latch on the tree. diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic index ccf41904fd0..1bd22a0ebc6 100644 --- a/storage/innobase/include/btr0btr.ic +++ b/storage/innobase/include/btr0btr.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -48,6 +48,10 @@ btr_block_get_func( ulint mode, /*!< in: latch mode */ const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ +#ifdef UNIV_SYNC_DEBUG + const dict_index_t* index, /*!< in: index tree, may be NULL + if it is not an insert buffer tree */ +#endif /* UNIV_SYNC_DEBUG */ mtr_t* mtr) /*!< in/out: mtr */ { buf_block_t* block; @@ -57,7 +61,9 @@ btr_block_get_func( if (mode != RW_NO_LATCH) { - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level( + block, index != NULL && dict_index_is_ibuf(index) + ? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE); } return(block); diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index 6c11c973fc9..f605c476844 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -244,18 +244,6 @@ btr_pcur_restore_position_func( mtr_t* mtr); /*!< in: mtr */ #define btr_pcur_restore_position(l,cur,mtr) \ btr_pcur_restore_position_func(l,cur,__FILE__,__LINE__,mtr) -/**************************************************************//** -If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY, -releases the page latch and bufferfix reserved by the cursor. -NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes -made by the current mini-transaction to the data protected by the -cursor latch, as then the latch must not be released until mtr_commit. */ -UNIV_INTERN -void -btr_pcur_release_leaf( -/*==================*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr); /*!< in: mtr */ /*********************************************************//** Gets the rel_pos field for a cursor whose position has been stored. @return BTR_PCUR_ON, ... */ @@ -266,10 +254,9 @@ btr_pcur_get_rel_pos( const btr_pcur_t* cursor);/*!< in: persistent cursor */ /**************************************************************//** Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES, -that is, the cursor becomes detached. If there have been modifications -to the page where pcur is positioned, this can be used instead of -btr_pcur_release_leaf. Function btr_pcur_store_position should be used -before calling this, if restoration of cursor is wanted later. */ +that is, the cursor becomes detached. +Function btr_pcur_store_position should be used before calling this, +if restoration of cursor is wanted later. */ UNIV_INLINE void btr_pcur_commit_specify_mtr( diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 59fdb21824b..d86601e5a32 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -369,10 +369,9 @@ btr_pcur_move_to_next( /**************************************************************//** Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES, -that is, the cursor becomes detached. If there have been modifications -to the page where pcur is positioned, this can be used instead of -btr_pcur_release_leaf. Function btr_pcur_store_position should be used -before calling this, if restoration of cursor is wanted later. */ +that is, the cursor becomes detached. +Function btr_pcur_store_position should be used before calling this, +if restoration of cursor is wanted later. */ UNIV_INLINE void btr_pcur_commit_specify_mtr( diff --git a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h index b255d8c9351..2d7d6146092 100644 --- a/storage/innobase/include/buf0buddy.h +++ b/storage/innobase/include/buf0buddy.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -37,37 +37,37 @@ Created December 2006 by Marko Makela /**********************************************************************//** Allocate a block. The thread calling this function must hold buf_pool->mutex and must not hold buf_pool->zip_mutex or any -block->mutex. The buf_pool->mutex may only be released and reacquired -if lru != NULL. This function should only be used for allocating -compressed page frames or control blocks (buf_page_t). Allocated -control blocks must be properly initialized immediately after -buf_buddy_alloc() has returned the memory, before releasing -buf_pool->mutex. -@return allocated block, possibly NULL if lru == NULL */ +block->mutex. The buf_pool->mutex may be released and reacquired. +This function should only be used for allocating compressed page frames. +@return allocated block, never NULL */ UNIV_INLINE -void* +byte* buf_buddy_alloc( /*============*/ - buf_pool_t* buf_pool, - /*!< buffer pool in which the block resides */ - ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */ - ibool* lru) /*!< in: pointer to a variable that will be assigned - TRUE if storage was allocated from the LRU list - and buf_pool->mutex was temporarily released, - or NULL if the LRU list should not be used */ - __attribute__((malloc)); + buf_pool_t* buf_pool, /*!< in/out: buffer pool in which + the page resides */ + ulint size, /*!< in: compressed page size + (between PAGE_ZIP_MIN_SIZE and + UNIV_PAGE_SIZE) */ + ibool* lru) /*!< in: pointer to a variable + that will be assigned TRUE if + storage was allocated from the + LRU list and buf_pool->mutex was + temporarily released */ + __attribute__((malloc, nonnull)); /**********************************************************************//** -Release a block. */ +Deallocate a block. */ UNIV_INLINE void buf_buddy_free( /*===========*/ - buf_pool_t* buf_pool, - /*!< buffer pool in which the block resides */ - void* buf, /*!< in: block to be freed, must not be - pointed to by the buffer pool */ - ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */ + buf_pool_t* buf_pool, /*!< in/out: buffer pool in which + the block resides */ + void* buf, /*!< in: block to be freed, must not + be pointed to by the buffer pool */ + ulint size) /*!< in: block size, + up to UNIV_PAGE_SIZE */ __attribute__((nonnull)); #ifndef UNIV_NONINL diff --git a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic index e50c33ea15a..b8281f7341a 100644 --- a/storage/innobase/include/buf0buddy.ic +++ b/storage/innobase/include/buf0buddy.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -36,21 +36,21 @@ Created December 2006 by Marko Makela /**********************************************************************//** Allocate a block. The thread calling this function must hold buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. -The buf_pool->mutex may only be released and reacquired if lru != NULL. -@return allocated block, possibly NULL if lru==NULL */ +The buf_pool_mutex may be released and reacquired. +@return allocated block, never NULL */ UNIV_INTERN void* buf_buddy_alloc_low( /*================*/ - buf_pool_t* buf_pool, - /*!< in: buffer pool in which the page resides */ - ulint i, /*!< in: index of buf_pool->zip_free[], - or BUF_BUDDY_SIZES */ - ibool* lru) /*!< in: pointer to a variable that will be assigned - TRUE if storage was allocated from the LRU list - and buf_pool->mutex was temporarily released, - or NULL if the LRU list should not be used */ - __attribute__((malloc)); + buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */ + ulint i, /*!< in: index of buf_pool->zip_free[], + or BUF_BUDDY_SIZES */ + ibool* lru) /*!< in: pointer to a variable that + will be assigned TRUE if storage was + allocated from the LRU list and + buf_pool->mutex was temporarily + released */ + __attribute__((malloc, nonnull)); /**********************************************************************//** Deallocate a block. */ @@ -77,6 +77,8 @@ buf_buddy_get_slot( ulint i; ulint s; + ut_ad(size >= PAGE_ZIP_MIN_SIZE); + for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1) { } @@ -87,31 +89,31 @@ buf_buddy_get_slot( /**********************************************************************//** Allocate a block. The thread calling this function must hold buf_pool->mutex and must not hold buf_pool->zip_mutex or any -block->mutex. The buf_pool->mutex may only be released and reacquired -if lru != NULL. This function should only be used for allocating -compressed page frames or control blocks (buf_page_t). Allocated -control blocks must be properly initialized immediately after -buf_buddy_alloc() has returned the memory, before releasing -buf_pool->mutex. -@return allocated block, possibly NULL if lru == NULL */ +block->mutex. The buf_pool->mutex may be released and reacquired. +This function should only be used for allocating compressed page frames. +@return allocated block, never NULL */ UNIV_INLINE -void* +byte* buf_buddy_alloc( /*============*/ - buf_pool_t* buf_pool, /*!< in: buffer pool in which + buf_pool_t* buf_pool, /*!< in/out: buffer pool in which the page resides */ - ulint size, /*!< in: block size, up to - UNIV_PAGE_SIZE */ + ulint size, /*!< in: compressed page size + (between PAGE_ZIP_MIN_SIZE and + UNIV_PAGE_SIZE) */ ibool* lru) /*!< in: pointer to a variable that will be assigned TRUE if storage was allocated from the LRU list and buf_pool->mutex was - temporarily released, or NULL if - the LRU list should not be used */ + temporarily released */ { ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(ut_is_2pow(size)); + ut_ad(size >= PAGE_ZIP_MIN_SIZE); + ut_ad(size <= UNIV_PAGE_SIZE); - return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru)); + return((byte*) buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), + lru)); } /**********************************************************************//** @@ -120,13 +122,17 @@ UNIV_INLINE void buf_buddy_free( /*===========*/ - buf_pool_t* buf_pool, /*!< in: buffer pool instance */ - void* buf, /*!< in: block to be freed, must not be - pointed to by the buffer pool */ - ulint size) /*!< in: block size, up to - UNIV_PAGE_SIZE */ + buf_pool_t* buf_pool, /*!< in/out: buffer pool in which + the block resides */ + void* buf, /*!< in: block to be freed, must not + be pointed to by the buffer pool */ + ulint size) /*!< in: block size, + up to UNIV_PAGE_SIZE */ { ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(ut_is_2pow(size)); + ut_ad(size >= PAGE_ZIP_MIN_SIZE); + ut_ad(size <= UNIV_PAGE_SIZE); buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size)); } diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index d83d484bace..ccebb69a4fe 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -147,6 +147,8 @@ struct buf_pool_info_struct{ ulint n_pages_created; /*!< buf_pool->n_pages_created */ ulint n_pages_written; /*!< buf_pool->n_pages_written */ ulint n_page_gets; /*!< buf_pool->n_page_gets */ + ulint n_ra_pages_read_rnd; /*!< buf_pool->n_ra_pages_read_rnd, + number of pages readahead */ ulint n_ra_pages_read; /*!< buf_pool->n_ra_pages_read, number of pages readahead */ ulint n_ra_pages_evicted; /*!< buf_pool->n_ra_pages_evicted, @@ -171,6 +173,8 @@ struct buf_pool_info_struct{ last printout */ /* Statistics about read ahead algorithm. */ + double pages_readahead_rnd_rate;/*!< random readahead rate in pages per + second */ double pages_readahead_rate; /*!< readahead rate in pages per second */ double pages_evicted_rate; /*!< rate of readahead page evicted @@ -246,12 +250,6 @@ buf_relocate( BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */ buf_page_t* dpage) /*!< in/out: destination control block */ __attribute__((nonnull)); -/********************************************************************//** -Resizes the buffer pool. */ -UNIV_INTERN -void -buf_pool_resize(void); -/*=================*/ /*********************************************************************//** Gets the current size of buffer buf_pool in bytes. @return size in bytes */ @@ -275,6 +273,23 @@ ib_uint64_t buf_pool_get_oldest_modification(void); /*==================================*/ /********************************************************************//** +Allocates a buf_page_t descriptor. This function must succeed. In case +of failure we assert in this function. */ +UNIV_INLINE +buf_page_t* +buf_page_alloc_descriptor(void) +/*===========================*/ + __attribute__((malloc)); +/********************************************************************//** +Free a buf_page_t descriptor. */ +UNIV_INLINE +void +buf_page_free_descriptor( +/*=====================*/ + buf_page_t* bpage) /*!< in: bpage descriptor to free. */ + __attribute__((nonnull)); + +/********************************************************************//** Allocates a buffer block. @return own: the allocated block, in state BUF_BLOCK_MEMORY */ UNIV_INTERN @@ -531,6 +546,18 @@ buf_block_get_freed_page_clock( __attribute__((pure)); /********************************************************************//** +Tells if a block is still close enough to the MRU end of the LRU list +meaning that it is not in danger of getting evicted and also implying +that it has been accessed recently. +Note that this is for heuristics only and does not reserve buffer pool +mutex. +@return TRUE if block is close to MRU end of LRU */ +UNIV_INLINE +ibool +buf_page_peek_if_young( +/*===================*/ + const buf_page_t* bpage); /*!< in: block */ +/********************************************************************//** 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 mutex. @@ -1196,7 +1223,7 @@ ulint buf_get_free_list_len(void); /*=======================*/ -/******************************************************************** +/********************************************************************//** Determine if a block is a sentinel for a buffer pool watch. @return TRUE if a sentinel for a buffer pool watch, FALSE if not */ UNIV_INTERN @@ -1569,6 +1596,8 @@ struct buf_pool_stat_struct{ ulint n_pages_written;/*!< number write operations */ ulint n_pages_created;/*!< number of pages created in the pool with no read */ + ulint n_ra_pages_read_rnd;/*!< number of pages read in + as part of random read ahead */ ulint n_ra_pages_read;/*!< number of pages read in as part of read ahead */ ulint n_ra_pages_evicted;/*!< number of read ahead @@ -1708,7 +1737,7 @@ struct buf_pool_struct{ UT_LIST_BASE_NODE_T(buf_page_t) LRU; /*!< base node of the LRU list */ buf_page_t* LRU_old; /*!< pointer to the about - buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV + LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV oldest blocks in the LRU list; NULL if LRU length less than BUF_LRU_OLD_MIN_LEN; @@ -1732,8 +1761,10 @@ struct buf_pool_struct{ frames and buf_page_t descriptors of blocks that exist in the buffer pool only in compressed form. */ /* @{ */ +#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG UT_LIST_BASE_NODE_T(buf_page_t) zip_clean; /*!< unmodified compressed pages */ +#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES]; /*!< buddy free lists */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index e2e83de0a78..b65b5133c15 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -125,6 +125,29 @@ buf_block_get_freed_page_clock( } /********************************************************************//** +Tells if a block is still close enough to the MRU end of the LRU list +meaning that it is not in danger of getting evicted and also implying +that it has been accessed recently. +Note that this is for heuristics only and does not reserve buffer pool +mutex. +@return TRUE if block is close to MRU end of LRU */ +UNIV_INLINE +ibool +buf_page_peek_if_young( +/*===================*/ + const buf_page_t* bpage) /*!< in: block */ +{ + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + + /* FIXME: bpage->freed_page_clock is 31 bits */ + return((buf_pool->freed_page_clock & ((1UL << 31) - 1)) + < ((ulint) bpage->freed_page_clock + + (buf_pool->curr_size + * (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio) + / (BUF_LRU_OLD_RATIO_DIV * 4)))); +} + +/********************************************************************//** 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 mutex. @@ -154,12 +177,7 @@ buf_page_peek_if_too_old( buf_pool->stat.n_pages_not_made_young++; return(FALSE); } else { - /* FIXME: bpage->freed_page_clock is 31 bits */ - return((buf_pool->freed_page_clock & ((1UL << 31) - 1)) - > ((ulint) bpage->freed_page_clock - + (buf_pool->curr_size - * (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio) - / (BUF_LRU_OLD_RATIO_DIV * 4)))); + return(!buf_page_peek_if_young(bpage)); } } @@ -754,6 +772,35 @@ buf_block_get_lock_hash_val( } /********************************************************************//** +Allocates a buf_page_t descriptor. This function must succeed. In case +of failure we assert in this function. +@return: the allocated descriptor. */ +UNIV_INLINE +buf_page_t* +buf_page_alloc_descriptor(void) +/*===========================*/ +{ + buf_page_t* bpage; + + bpage = (buf_page_t*) ut_malloc(sizeof *bpage); + ut_d(memset(bpage, 0, sizeof *bpage)); + UNIV_MEM_ALLOC(bpage, sizeof *bpage); + + return(bpage); +} + +/********************************************************************//** +Free a buf_page_t descriptor. */ +UNIV_INLINE +void +buf_page_free_descriptor( +/*=====================*/ + buf_page_t* bpage) /*!< in: bpage descriptor to free. */ +{ + ut_free(bpage); +} + +/********************************************************************//** Frees a buffer block which does not contain a file page. */ UNIV_INLINE void diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 9b150188b03..eb40621abbe 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -30,18 +30,6 @@ Created 11/5/1995 Heikki Tuuri #include "ut0byte.h" #include "buf0types.h" -/** The return type of buf_LRU_free_block() */ -enum buf_lru_free_block_status { - /** freed */ - BUF_LRU_FREED = 0, - /** not freed because the caller asked to remove the - uncompressed frame but the control block cannot be - relocated */ - BUF_LRU_CANNOT_RELOCATE, - /** not freed because of some other reason */ - BUF_LRU_NOT_FREED -}; - /******************************************************************//** Tries to remove LRU flushed blocks from the end of the LRU list and put them to the free list. This is beneficial for the efficiency of the insert buffer @@ -85,6 +73,7 @@ void buf_LRU_invalidate_tablespace( /*==========================*/ ulint id); /*!< in: space id */ +#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /********************************************************************//** Insert a compressed block into buf_pool->zip_clean in the LRU order. */ UNIV_INTERN @@ -92,22 +81,22 @@ void buf_LRU_insert_zip_clean( /*=====================*/ buf_page_t* bpage); /*!< in: pointer to the block in question */ +#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ /******************************************************************//** Try to free a block. If bpage is a descriptor of a compressed-only page, the descriptor object will be freed as well. -NOTE: If this function returns BUF_LRU_FREED, it will temporarily +NOTE: If this function returns TRUE, it will temporarily release buf_pool->mutex. Furthermore, the page frame will no longer be accessible via bpage. The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and release these two mutexes after the call. No other buf_page_get_mutex() may be held when calling this function. -@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or -BUF_LRU_NOT_FREED otherwise. */ +@return TRUE if freed, FALSE otherwise. */ UNIV_INTERN -enum buf_lru_free_block_status +ibool buf_LRU_free_block( /*===============*/ buf_page_t* bpage, /*!< in: block to be freed */ @@ -195,7 +184,7 @@ buf_LRU_make_block_old( /*===================*/ buf_page_t* bpage); /*!< in: control block */ /**********************************************************************//** -Updates buf_LRU_old_ratio. +Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN ulint @@ -204,7 +193,7 @@ buf_LRU_old_ratio_update( uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ ibool adjust);/*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_LRU_old_ratio + FALSE=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ /********************************************************************//** Update the historical stats that we are collecting for LRU eviction @@ -214,6 +203,17 @@ void buf_LRU_stat_update(void); /*=====================*/ +/******************************************************************//** +Remove one page from LRU list and put it to free list */ +UNIV_INTERN +void +buf_LRU_free_one_page( +/*==================*/ + buf_page_t* bpage) /*!< in/out: block, must contain a file page and + be in a state where it can be freed; there + may or may not be a hash index to the page */ + __attribute__((nonnull)); + #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /**********************************************************************//** Validates the LRU list. @@ -233,18 +233,15 @@ buf_LRU_print(void); #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */ /** @name Heuristics for detecting index scan @{ */ -/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for -"old" blocks. Protected by buf_pool->mutex. */ -extern uint buf_LRU_old_ratio; -/** The denominator of buf_LRU_old_ratio. */ +/** The denominator of buf_pool->LRU_old_ratio. */ #define BUF_LRU_OLD_RATIO_DIV 1024 -/** Maximum value of buf_LRU_old_ratio. +/** Maximum value of buf_pool->LRU_old_ratio. @see buf_LRU_old_adjust_len -@see buf_LRU_old_ratio_update */ +@see buf_pool->LRU_old_ratio_update */ #define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV -/** Minimum value of buf_LRU_old_ratio. +/** Minimum value of buf_pool->LRU_old_ratio. @see buf_LRU_old_adjust_len -@see buf_LRU_old_ratio_update +@see buf_pool->LRU_old_ratio_update The minimum must exceed (BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */ #define BUF_LRU_OLD_RATIO_MIN 51 diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index cdf6cdba3d1..cd5eff66ee8 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -43,6 +43,31 @@ buf_read_page( ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ ulint offset);/*!< in: page number */ /********************************************************************//** +Applies a random read-ahead in buf_pool if there are at least a threshold +value of accessed pages from the random read-ahead area. Does not read any +page, not even the one at the position (space, offset), if the read-ahead +mechanism is not activated. NOTE 1: the calling thread may own latches on +pages: to avoid deadlocks this function must be written such that it cannot +end up waiting for these latches! NOTE 2: the calling thread must want +access to the page given: this rule is set to prevent unintended read-aheads +performed by ibuf routines, a situation which could result in a deadlock if +the OS does not support asynchronous i/o. +@return number of page read requests issued; NOTE that if we read ibuf +pages, it may happen that the page at the given page number does not +get read even if we return a positive value! +@return number of page read requests issued */ +UNIV_INTERN +ulint +buf_read_ahead_random( +/*==================*/ + ulint space, /*!< in: space id */ + ulint zip_size, /*!< in: compressed page size in bytes, + or 0 */ + ulint offset, /*!< in: page number of a page which + the current thread wants to access */ + ibool inside_ibuf); /*!< in: TRUE if we are inside ibuf + routine */ +/********************************************************************//** Applies linear read-ahead if in the buf_pool the page is a border page of a linear read-ahead area and all the pages in the area have been accessed. Does not read any page if the read-ahead mechanism is not activated. Note diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h index a2175098704..0cc2defb3ff 100644 --- a/storage/innobase/include/buf0types.h +++ b/storage/innobase/include/buf0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,6 +26,8 @@ Created 11/17/1995 Heikki Tuuri #ifndef buf0types_h #define buf0types_h +#include "page0types.h" + /** Buffer page (uncompressed or compressed) */ typedef struct buf_page_struct buf_page_t; /** Buffer block for which an uncompressed page exists */ @@ -60,17 +62,10 @@ enum buf_io_fix { /** Parameters of binary buddy system for compressed pages (buf0buddy.h) */ /* @{ */ -#if UNIV_WORD_SIZE <= 4 /* 32-bit system */ -/** Base-2 logarithm of the smallest buddy block size */ -# define BUF_BUDDY_LOW_SHIFT 6 -#else /* 64-bit system */ -/** Base-2 logarithm of the smallest buddy block size */ -# define BUF_BUDDY_LOW_SHIFT 7 -#endif +#define BUF_BUDDY_LOW_SHIFT PAGE_ZIP_MIN_SIZE_SHIFT + #define BUF_BUDDY_LOW (1 << BUF_BUDDY_LOW_SHIFT) - /*!< minimum block size in the binary - buddy system; must be at least - sizeof(buf_page_t) */ + #define BUF_BUDDY_SIZES (UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT) /*!< number of buddy sizes */ diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 74a2354bce3..e0952f0709d 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -64,8 +64,6 @@ enum db_err { DB_CANNOT_ADD_CONSTRAINT, /* adding a foreign key constraint to a table failed */ DB_CORRUPTION, /* data structure corruption noticed */ - DB_COL_APPEARS_TWICE_IN_INDEX, /* InnoDB cannot handle an index - where same column appears twice */ DB_CANNOT_DROP_CONSTRAINT, /* dropping a foreign key constraint from a table failed */ DB_NO_SAVEPOINT, /* no savepoint exists with the given @@ -112,6 +110,8 @@ enum db_err { foreign keys as its prefix columns */ DB_TOO_BIG_INDEX_COL, /* index column size exceeds maximum limit */ + DB_INDEX_CORRUPT, /* we have corrupted index */ + DB_UNDO_RECORD_TOO_BIG, /* the undo log record is too big */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h index 22df826da65..5d136862bc6 100644 --- a/storage/innobase/include/dict0boot.h +++ b/storage/innobase/include/dict0boot.h @@ -137,8 +137,10 @@ dict_create(void); header is created */ /*-------------------------------------------------------------*/ -/* The field number of the page number field in the sys_indexes table -clustered index */ +/* The field numbers in the SYS_TABLES clustered index */ +#define DICT_SYS_TABLES_TYPE_FIELD 5 + +/* The field numbers in the SYS_INDEXES clustered index */ #define DICT_SYS_INDEXES_PAGE_NO_FIELD 8 #define DICT_SYS_INDEXES_SPACE_NO_FIELD 7 #define DICT_SYS_INDEXES_TYPE_FIELD 6 diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index f979d0fcc96..57e51cbb6ba 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -585,6 +585,20 @@ dict_table_get_next_index( # define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index) #endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ + +/* Skip corrupted index */ +#define dict_table_skip_corrupt_index(index) \ + while (index && dict_index_is_corrupted(index)) { \ + index = dict_table_get_next_index(index); \ + } + +/* Get the next non-corrupt index */ +#define dict_table_next_uncorrupted_index(index) \ +do { \ + index = dict_table_get_next_index(index); \ + dict_table_skip_corrupt_index(index); \ +} while (0) + /********************************************************************//** Check whether the index is the clustered index. @return nonzero for clustered index, zero for other indexes */ @@ -593,7 +607,7 @@ ulint dict_index_is_clust( /*================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((pure)); + __attribute__((nonnull, pure, warn_unused_result)); /********************************************************************//** Check whether the index is unique. @return nonzero for unique index, zero for other indexes */ @@ -602,7 +616,7 @@ ulint dict_index_is_unique( /*=================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((pure)); + __attribute__((nonnull, pure, warn_unused_result)); /********************************************************************//** Check whether the index is the insert buffer tree. @return nonzero for insert buffer, zero for other indexes */ @@ -611,7 +625,7 @@ ulint dict_index_is_ibuf( /*===============*/ const dict_index_t* index) /*!< in: index */ - __attribute__((pure)); + __attribute__((nonnull, pure, warn_unused_result)); /********************************************************************//** Check whether the index is a secondary index or the insert buffer tree. @return nonzero for insert buffer, zero for other indexes */ @@ -620,7 +634,7 @@ ulint dict_index_is_sec_or_ibuf( /*======================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((pure)); + __attribute__((nonnull, pure, warn_unused_result)); /********************************************************************//** Gets the number of user-defined columns in a table in the dictionary @@ -630,7 +644,8 @@ UNIV_INLINE ulint dict_table_get_n_user_cols( /*=======================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, pure, warn_unused_result)); /********************************************************************//** Gets the number of system columns in a table in the dictionary cache. @return number of system (e.g., ROW_ID) columns of a table */ @@ -638,7 +653,8 @@ UNIV_INLINE ulint dict_table_get_n_sys_cols( /*======================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, pure, warn_unused_result)); /********************************************************************//** Gets the number of all columns (also system) in a table in the dictionary cache. @@ -647,7 +663,8 @@ UNIV_INLINE ulint dict_table_get_n_cols( /*==================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, pure, warn_unused_result)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the nth column of a table. @@ -1243,6 +1260,57 @@ void dict_close(void); /*============*/ +/**********************************************************************//** +Check whether the table is corrupted. +@return nonzero for corrupted table, zero for valid tables */ +UNIV_INLINE +ulint +dict_table_is_corrupted( +/*====================*/ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, pure, warn_unused_result)); + +/**********************************************************************//** +Check whether the index is corrupted. +@return nonzero for corrupted index, zero for valid indexes */ +UNIV_INLINE +ulint +dict_index_is_corrupted( +/*====================*/ + const dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, pure, warn_unused_result)); + +/**********************************************************************//** +Flags an index and table corrupted both in the data dictionary cache +and in the system table SYS_INDEXES. */ +UNIV_INTERN +void +dict_set_corrupted( +/*===============*/ + dict_index_t* index) /*!< in/out: index */ + UNIV_COLD __attribute__((nonnull)); + +/**********************************************************************//** +Flags an index corrupted in the data dictionary cache only. This +is used mostly to mark a corrupted index when index's own dictionary +is corrupted, and we force to load such index for repair purpose */ +UNIV_INTERN +void +dict_set_corrupted_index_cache_only( +/*================================*/ + dict_index_t* index, /*!< in/out: index */ + dict_table_t* table); /*!< in/out: table */ + +/**********************************************************************//** +Flags a table with specified space_id corrupted in the table dictionary +cache. +@return TRUE if successful */ +UNIV_INTERN +ibool +dict_set_corrupted_by_space( +/*========================*/ + ulint space_id); /*!< in: space ID */ + #ifndef UNIV_NONINL #include "dict0dict.ic" #endif diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 59811568556..ade9e627e29 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -27,6 +27,7 @@ Created 1/8/1996 Heikki Tuuri #ifndef UNIV_HOTBACKUP #include "dict0load.h" #include "rem0types.h" +#include "srv0srv.h" /*********************************************************************//** Gets the minimum number of bytes per character. @@ -828,7 +829,7 @@ dict_table_check_if_in_cache_low( } /**********************************************************************//** -load a table into dictionary cache, ignore any error specified during load; +load a table into dictionary cache, ignore any error specified during load; @return table, NULL if not found */ UNIV_INLINE dict_table_t* @@ -872,6 +873,18 @@ dict_table_get_low( table = dict_table_check_if_in_cache_low(table_name); + if (table && table->corrupted) { + fprintf(stderr, "InnoDB: table"); + ut_print_name(stderr, NULL, TRUE, table->name); + if (srv_load_corrupted) { + fputs(" is corrupted, but" + " innodb_force_load_corrupted is set\n", stderr); + } else { + fputs(" is corrupted\n", stderr); + return(NULL); + } + } + if (table == NULL) { table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE); } @@ -937,4 +950,35 @@ dict_max_field_len_store_undo( return(prefix_len); } +/********************************************************************//** +Check whether the table is corrupted. +@return nonzero for corrupted table, zero for valid tables */ +UNIV_INLINE +ulint +dict_table_is_corrupted( +/*====================*/ + const dict_table_t* table) /*!< in: table */ +{ + ut_ad(table); + ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); + + return(UNIV_UNLIKELY(table->corrupted)); +} + +/********************************************************************//** +Check whether the index is corrupted. +@return nonzero for corrupted index, zero for valid indexes */ +UNIV_INLINE +ulint +dict_index_is_corrupted( +/*====================*/ + const dict_index_t* index) /*!< in: index */ +{ + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + + return(UNIV_UNLIKELY((index->type & DICT_CORRUPT) + || (index->table && index->table->corrupted))); +} + #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 3a475fa85fc..9ded0dba39b 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -51,7 +51,12 @@ combination of types */ #define DICT_UNIQUE 2 /*!< unique index */ #define DICT_UNIVERSAL 4 /*!< index which can contain records from any other index */ -#define DICT_IBUF 8 /*!< insert buffer tree */ +#define DICT_IBUF 8 /*!< insert buffer tree */ +#define DICT_CORRUPT 16 /*!< bit to store the corrupted flag + in SYS_INDEXES.TYPE */ + +#define DICT_IT_BITS 5 /*!< number of bits used for + SYS_INDEXES.TYPE */ /* @} */ /** Types for a table object */ @@ -369,8 +374,9 @@ struct dict_index_struct{ /*!< space where the index tree is placed */ unsigned page:32;/*!< index tree root page number */ #endif /* !UNIV_HOTBACKUP */ - unsigned type:4; /*!< index type (DICT_CLUSTERED, DICT_UNIQUE, - DICT_UNIVERSAL, DICT_IBUF) */ + unsigned type:DICT_IT_BITS; + /*!< index type (DICT_CLUSTERED, DICT_UNIQUE, + DICT_UNIVERSAL, DICT_IBUF, DICT_CORRUPT) */ unsigned trx_id_offset:10;/*!< position of the trx id column in a clustered index record, if the fields before it are known to be of a fixed size, @@ -391,8 +397,6 @@ struct dict_index_struct{ /*!< TRUE if this index is marked to be dropped in ha_innobase::prepare_drop_index(), otherwise FALSE */ - unsigned corrupted:1; - /*!< TRUE if the index object is corrupted */ dict_field_t* fields; /*!< array of field descriptions */ #ifndef UNIV_HOTBACKUP UT_LIST_NODE_T(dict_index_t) diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index 8cbd7cd5783..f0a05a38070 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -51,7 +51,8 @@ be or-ed together */ enum dict_err_ignore { DICT_ERR_IGNORE_NONE = 0, /*!< no error to ignore */ DICT_ERR_IGNORE_INDEX_ROOT = 1, /*!< ignore error if index root - page is FIL_NUL or incorrect value */ + page is FIL_NULL or incorrect value */ + DICT_ERR_IGNORE_CORRUPT = 2, /*!< skip corrupted indexes */ DICT_ERR_IGNORE_ALL = 0xFFFF /*!< ignore all errors */ }; diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 5582ad63039..7f608546cc2 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -213,16 +213,6 @@ ulint mtr_set_savepoint( /*==============*/ mtr_t* mtr); /*!< in: mtr */ -/**********************************************************//** -Releases the latches stored in an mtr memo down to a savepoint. -NOTE! The mtr must not have made changes to buffer pages after the -savepoint, as these can be handled only by mtr_commit. */ -UNIV_INTERN -void -mtr_rollback_to_savepoint( -/*======================*/ - mtr_t* mtr, /*!< in: mtr */ - ulint savepoint); /*!< in: savepoint */ #ifndef UNIV_HOTBACKUP /**********************************************************//** Releases the (index tree) s-latch stored in an mtr memo after a diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 7091d8c2707..6a82e820312 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -68,10 +68,7 @@ typedef byte page_header_t; #define PAGE_MAX_TRX_ID 18 /* highest id of a trx which may have modified a record on the page; trx_id_t; defined only in secondary indexes and in the insert buffer - tree; NOTE: this may be modified only - when the thread has an x-latch to the page, - and ALSO an x-latch to btr_search_latch - if there is a hash index to the page! */ + tree */ #define PAGE_HEADER_PRIV_END 26 /* end of private data structure of the page header which are set in a page create */ /*----*/ diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h index 75e15d67246..c2849be7c3e 100644 --- a/storage/innobase/include/row0row.h +++ b/storage/innobase/include/row0row.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -38,27 +38,16 @@ Created 4/20/1996 Heikki Tuuri #include "btr0types.h" /*********************************************************************//** -Gets the offset of the trx id field, in bytes relative to the origin of +Gets the offset of the DB_TRX_ID field, in bytes relative to the origin of a clustered index record. @return offset of DATA_TRX_ID */ UNIV_INLINE ulint -row_get_trx_id_offset_func( -/*=======================*/ -#ifdef UNIV_DEBUG - const rec_t* rec, /*!< in: record */ -#endif /* UNIV_DEBUG */ +row_get_trx_id_offset( +/*==================*/ const dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const ulint* offsets)/*!< in: record offsets */ __attribute__((nonnull, warn_unused_result)); -#ifdef UNIV_DEBUG -# define row_get_trx_id_offset(rec, index, offsets) \ - row_get_trx_id_offset_func(rec, index, offsets) -#else /* UNIV_DEBUG */ -# define row_get_trx_id_offset(rec, index, offsets) \ - row_get_trx_id_offset_func(index, offsets) -#endif /* UNIV_DEBUG */ - /*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ @@ -77,9 +66,10 @@ UNIV_INLINE roll_ptr_t row_get_rec_roll_ptr( /*=================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); /*****************************************************************//** When an insert or purge to a table is performed, this function builds the entry to be inserted into or purged from an index on the table. diff --git a/storage/innobase/include/row0row.ic b/storage/innobase/include/row0row.ic index 9d19e430e16..0b9ca982af8 100644 --- a/storage/innobase/include/row0row.ic +++ b/storage/innobase/include/row0row.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -28,25 +28,22 @@ Created 4/20/1996 Heikki Tuuri #include "trx0undo.h" /*********************************************************************//** -Gets the offset of trx id field, in bytes relative to the origin of +Gets the offset of the DB_TRX_ID field, in bytes relative to the origin of a clustered index record. @return offset of DATA_TRX_ID */ UNIV_INLINE ulint -row_get_trx_id_offset_func( -/*=======================*/ -#ifdef UNIV_DEBUG - const rec_t* rec, /*!< in: record */ -#endif /* UNIV_DEBUG */ +row_get_trx_id_offset( +/*==================*/ const dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const ulint* offsets)/*!< in: record offsets */ { ulint pos; ulint offset; ulint len; ut_ad(dict_index_is_clust(index)); - ut_ad(rec_offs_validate(rec, index, offsets)); + ut_ad(rec_offs_validate(NULL, index, offsets)); pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); @@ -76,7 +73,7 @@ row_get_rec_trx_id( offset = index->trx_id_offset; if (!offset) { - offset = row_get_trx_id_offset(rec, index, offsets); + offset = row_get_trx_id_offset(index, offsets); } return(trx_read_trx_id(rec + offset)); @@ -89,9 +86,9 @@ UNIV_INLINE roll_ptr_t row_get_rec_roll_ptr( /*=================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { ulint offset; @@ -101,7 +98,7 @@ row_get_rec_roll_ptr( offset = index->trx_id_offset; if (!offset) { - offset = row_get_trx_id_offset(rec, index, offsets); + offset = row_get_trx_id_offset(index, offsets); } return(trx_read_roll_ptr(rec + offset + DATA_TRX_ID_LEN)); diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic index 18e22f1eca9..11db82f64da 100644 --- a/storage/innobase/include/row0upd.ic +++ b/storage/innobase/include/row0upd.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -157,11 +157,6 @@ row_upd_rec_sys_fields( { ut_ad(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); -#ifdef UNIV_SYNC_DEBUG - if (!rw_lock_own(&btr_search_latch, RW_LOCK_EX)) { - ut_ad(!buf_block_align(rec)->is_hashed); - } -#endif /* UNIV_SYNC_DEBUG */ if (UNIV_LIKELY_NULL(page_zip)) { ulint pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); @@ -171,7 +166,7 @@ row_upd_rec_sys_fields( ulint offset = index->trx_id_offset; if (!offset) { - offset = row_get_trx_id_offset(rec, index, offsets); + offset = row_get_trx_id_offset(index, offsets); } #if DATA_TRX_ID + 1 != DATA_ROLL_PTR diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index fc9401a12f5..dfe7397d189 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -141,6 +141,10 @@ extern ulint srv_log_buffer_size; extern ulong srv_flush_log_at_trx_commit; extern char srv_adaptive_flushing; +/* If this flag is TRUE, then we will load the indexes' (and tables') metadata +even if they are marked as "corrupted". Mostly it is for DBA to process +corrupted index and table */ +extern my_bool srv_load_corrupted; /* The sort order table of the MySQL latin1_swedish_ci character set collation */ @@ -158,6 +162,7 @@ extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; extern ulint srv_n_file_io_threads; +extern my_bool srv_random_read_ahead; extern ulong srv_read_ahead_threshold; extern ulint srv_n_read_io_threads; extern ulint srv_n_write_io_threads; @@ -703,6 +708,7 @@ struct export_var_struct{ ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */ ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */ ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */ + ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */ diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index 9e5c96fa323..dedf080d00a 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -542,7 +542,7 @@ mutex. */ UNIV_INTERN void rw_lock_debug_mutex_enter(void); -/*==========================*/ +/*===========================*/ /******************************************************************//** Releases the debug mutex. */ UNIV_INTERN @@ -632,7 +632,8 @@ struct rw_lock_struct { }; #ifdef UNIV_SYNC_DEBUG -/** The structure for storing debug info of an rw-lock */ +/** The structure for storing debug info of an rw-lock. All access to this +structure must be protected by rw_lock_debug_mutex_enter(). */ struct rw_lock_debug_struct { os_thread_id_t thread_id; /*!< The thread id of the thread which diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic index 2ffd9fdafb5..51cf7121b4c 100644 --- a/storage/innobase/include/sync0rw.ic +++ b/storage/innobase/include/sync0rw.ic @@ -406,6 +406,7 @@ rw_lock_s_lock_func( #ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */ + ut_ad(!rw_lock_own(lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ /* TODO: study performance of UNIV_LIKELY branch prediction hints. */ diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index b823c9d5259..d9dea0aa63d 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -636,10 +636,6 @@ or row lock! */ #define SYNC_DICT_HEADER 995 #define SYNC_IBUF_HEADER 914 #define SYNC_IBUF_PESS_INSERT_MUTEX 912 -#define SYNC_IBUF_MUTEX 910 /* ibuf mutex is really below - SYNC_FSP_PAGE: we assign a value this - high only to make the program to pass - the debug checks */ /*-------------------------------*/ #define SYNC_INDEX_TREE 900 #define SYNC_TREE_NODE_NEW 892 @@ -655,8 +651,11 @@ or row lock! */ #define SYNC_FSP 400 #define SYNC_FSP_PAGE 395 /*------------------------------------- Insert buffer headers */ -/*------------------------------------- ibuf_mutex */ +#define SYNC_IBUF_MUTEX 370 /* ibuf_mutex */ /*------------------------------------- Insert buffer tree */ +#define SYNC_IBUF_INDEX_TREE 360 +#define SYNC_IBUF_TREE_NODE_NEW 359 +#define SYNC_IBUF_TREE_NODE 358 #define SYNC_IBUF_BITMAP_MUTEX 351 #define SYNC_IBUF_BITMAP 350 /*------------------------------------- MySQL query cache mutex */ @@ -683,7 +682,6 @@ or row lock! */ #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */ #define SYNC_DOUBLEWRITE 140 #define SYNC_ANY_LATCH 135 -#define SYNC_THR_LOCAL 133 #define SYNC_MEM_HASH 131 #define SYNC_MEM_POOL 130 diff --git a/storage/innobase/include/sync0sync.ic b/storage/innobase/include/sync0sync.ic index 2977f71154a..eb21f44c65e 100644 --- a/storage/innobase/include/sync0sync.ic +++ b/storage/innobase/include/sync0sync.ic @@ -272,11 +272,10 @@ pfs_mutex_enter_nowait_func( ulint ret; struct PSI_mutex_locker* locker = NULL; PSI_mutex_locker_state state; - int result = 0; if (UNIV_LIKELY(PSI_server && mutex->pfs_psi)) { locker = PSI_server->get_thread_mutex_locker( - &state, mutex->pfs_psi, PSI_MUTEX_LOCK); + &state, mutex->pfs_psi, PSI_MUTEX_TRYLOCK); if (locker) { PSI_server->start_mutex_wait(locker, file_name, line); } @@ -285,7 +284,7 @@ pfs_mutex_enter_nowait_func( ret = mutex_enter_nowait_func(mutex, file_name, line); if (locker) { - PSI_server->end_mutex_wait(locker, result); + PSI_server->end_mutex_wait(locker, ret); } return(ret); diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index dc0ca2285b9..9cec1933e9d 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -278,6 +278,17 @@ ibool trx_in_trx_list( /*============*/ trx_t* in_trx);/*!< in: trx */ +#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG +/***********************************************************//** +Assert that a transaction has been recovered. +@return TRUE */ +UNIV_INLINE +ibool +trx_assert_recovered( +/*=================*/ + trx_id_t trx_id) /*!< in: transaction identifier */ + __attribute__((warn_unused_result)); +#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ /*****************************************************************//** Updates the offset information about the end of the MySQL binlog entry which corresponds to the transaction just being committed. In a MySQL diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index 355f118a1ec..5e702b25325 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -277,6 +277,28 @@ trx_get_on_id( return(NULL); } +#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG +/***********************************************************//** +Assert that a transaction has been recovered. +@return TRUE */ +UNIV_INLINE +ibool +trx_assert_recovered( +/*=================*/ + trx_id_t trx_id) /*!< in: transaction identifier */ +{ + trx_t* trx; + + mutex_enter(&kernel_mutex); + trx = trx_get_on_id(trx_id); + ut_a(trx); + ut_a(trx->is_recovered); + mutex_exit(&kernel_mutex); + + return(TRUE); +} +#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ + /****************************************************************//** Returns the minumum trx id in trx list. This is the smallest id for which the trx can possibly be active. (But, you must look at the trx->conc_state to diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index df16c939070..50aa6d0ac09 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -204,17 +204,51 @@ trx_undo_add_page( mtr_t* mtr); /*!< in: mtr which does not have a latch to any undo log page; the caller must have reserved the rollback segment mutex */ +/********************************************************************//** +Frees the last undo log page. +The caller must hold the rollback segment mutex. */ +UNIV_INTERN +void +trx_undo_free_last_page_func( +/*==========================*/ +#ifdef UNIV_DEBUG + const trx_t* trx, /*!< in: transaction */ +#endif /* UNIV_DEBUG */ + trx_undo_t* undo, /*!< in/out: undo log memory copy */ + mtr_t* mtr) /*!< in/out: mini-transaction which does not + have a latch to any undo log page or which + has allocated the undo log page */ + __attribute__((nonnull)); +#ifdef UNIV_DEBUG +# define trx_undo_free_last_page(trx,undo,mtr) \ + trx_undo_free_last_page_func(trx,undo,mtr) +#else /* UNIV_DEBUG */ +# define trx_undo_free_last_page(trx,undo,mtr) \ + trx_undo_free_last_page_func(undo,mtr) +#endif /* UNIV_DEBUG */ + /***********************************************************************//** Truncates an undo log from the end. This function is used during a rollback to free space from an undo log. */ UNIV_INTERN void -trx_undo_truncate_end( -/*==================*/ - trx_t* trx, /*!< in: transaction whose undo log it is */ - trx_undo_t* undo, /*!< in: undo log */ - undo_no_t limit); /*!< in: all undo records with undo number +trx_undo_truncate_end_func( +/*=======================*/ +#ifdef UNIV_DEBUG + const trx_t* trx, /*!< in: transaction whose undo log it is */ +#endif /* UNIV_DEBUG */ + trx_undo_t* undo, /*!< in/out: undo log */ + undo_no_t limit) /*!< in: all undo records with undo number >= this value should be truncated */ + __attribute__((nonnull)); +#ifdef UNIV_DEBUG +# define trx_undo_truncate_end(trx,undo,limit) \ + trx_undo_truncate_end_func(trx,undo,limit) +#else /* UNIV_DEBUG */ +# define trx_undo_truncate_end(trx,undo,limit) \ + trx_undo_truncate_end_func(undo,limit) +#endif /* UNIV_DEBUG */ + /***********************************************************************//** Truncates an undo log from the start. This function is used during a purge operation. */ diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h index 57dfb08f41c..faf6f242883 100644 --- a/storage/innobase/include/ut0mem.h +++ b/storage/innobase/include/ut0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -210,43 +210,6 @@ ut_strlcpy_rev( ulint size); /*!< in: size of destination buffer */ /**********************************************************************//** -Compute strlen(ut_strcpyq(str, q)). -@return length of the string when quoted */ -UNIV_INLINE -ulint -ut_strlenq( -/*=======*/ - const char* str, /*!< in: null-terminated string */ - char q); /*!< in: the quote character */ - -/**********************************************************************//** -Make a quoted copy of a NUL-terminated string. Leading and trailing -quotes will not be included; only embedded quotes will be escaped. -See also ut_strlenq() and ut_memcpyq(). -@return pointer to end of dest */ -UNIV_INTERN -char* -ut_strcpyq( -/*=======*/ - char* dest, /*!< in: output buffer */ - char q, /*!< in: the quote character */ - const char* src); /*!< in: null-terminated string */ - -/**********************************************************************//** -Make a quoted copy of a fixed-length string. Leading and trailing -quotes will not be included; only embedded quotes will be escaped. -See also ut_strlenq() and ut_strcpyq(). -@return pointer to end of dest */ -UNIV_INTERN -char* -ut_memcpyq( -/*=======*/ - char* dest, /*!< in: output buffer */ - char q, /*!< in: the quote character */ - const char* src, /*!< in: string to be quoted */ - ulint len); /*!< in: length of src */ - -/**********************************************************************//** Return the number of times s2 occurs in s1. Overlapping instances of s2 are only counted once. @return the number of times s2 occurs in s1 */ diff --git a/storage/innobase/include/ut0mem.ic b/storage/innobase/include/ut0mem.ic index f36c28f1989..c06e2b3ae81 100644 --- a/storage/innobase/include/ut0mem.ic +++ b/storage/innobase/include/ut0mem.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -99,27 +99,6 @@ ut_strcmp(const char* str1, const char* str2) } /**********************************************************************//** -Compute strlen(ut_strcpyq(str, q)). -@return length of the string when quoted */ -UNIV_INLINE -ulint -ut_strlenq( -/*=======*/ - const char* str, /*!< in: null-terminated string */ - char q) /*!< in: the quote character */ -{ - ulint len; - - for (len = 0; *str; len++, str++) { - if (*str == q) { - len++; - } - } - - return(len); -} - -/**********************************************************************//** Converts a raw binary data to a NUL-terminated hex string. The output is truncated if there is not enough space in "hex", make sure "hex_size" is at least (2 * raw_size + 1) if you do not want this to happen. Returns the |