From: Anitha Gopi Date: May 24 2011 4:28pm Subject: bzr commit into mysql-trunk branch (anitha.gopi:3106) List-Archive: http://lists.mysql.com/commits/138009 Message-Id: <201105241629.p4OGTHSk011508@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0774479085==" --===============0774479085== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/anitha/mysql/repo/mysql-trunk-mod/ based on revid:anitha.gopi@stripped 3106 Anitha Gopi 2011-05-24 [merge] Autocommit : Updating local tree modified: storage/innobase/include/lock0priv.h storage/innobase/include/lock0priv.ic storage/innobase/include/row0row.h storage/innobase/include/row0row.ic storage/innobase/lock/lock0lock.c storage/innobase/row/row0row.c === modified file 'storage/innobase/include/lock0priv.h' --- a/storage/innobase/include/lock0priv.h 2011-01-18 21:14:22 +0000 +++ b/storage/innobase/include/lock0priv.h 2011-05-24 12:05:57 +0000 @@ -118,9 +118,10 @@ UNIV_INLINE trx_id_t lock_clust_rec_some_has_impl( /*=========================*/ - const rec_t* rec, /*!< in: user record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets); /*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: user record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "lock0priv.ic" === modified file 'storage/innobase/include/lock0priv.ic' --- a/storage/innobase/include/lock0priv.ic 2010-09-09 17:40:13 +0000 +++ b/storage/innobase/include/lock0priv.ic 2011-05-24 12:05:57 +0000 @@ -54,9 +54,9 @@ UNIV_INLINE trx_id_t lock_clust_rec_some_has_impl( /*=========================*/ - const rec_t* rec, /*!< in: user record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: user record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { ut_ad(dict_index_is_clust(index)); ut_ad(page_rec_is_user_rec(rec)); === modified file 'storage/innobase/include/row0row.h' --- a/storage/innobase/include/row0row.h 2010-10-21 03:54:20 +0000 +++ b/storage/innobase/include/row0row.h 2011-05-24 12:05:57 +0000 @@ -41,13 +41,24 @@ Created 4/20/1996 Heikki Tuuri Gets the offset of the trx id field, in bytes relative to the origin of a clustered index record. @return offset of DATA_TRX_ID */ -UNIV_INTERN +UNIV_INLINE ulint -row_get_trx_id_offset( -/*==================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ +row_get_trx_id_offset_func( +/*=======================*/ +#ifdef UNIV_DEBUG + const rec_t* rec, /*!< in: record */ +#endif /* UNIV_DEBUG */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __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 */ @@ -55,9 +66,10 @@ UNIV_INLINE trx_id_t row_get_rec_trx_id( /*===============*/ - 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)); /*********************************************************************//** Reads the roll pointer field from a clustered index record. @return value of the field */ === modified file 'storage/innobase/include/row0row.ic' --- a/storage/innobase/include/row0row.ic 2010-07-16 21:00:50 +0000 +++ b/storage/innobase/include/row0row.ic 2011-05-24 12:05:57 +0000 @@ -28,15 +28,45 @@ Created 4/20/1996 Heikki Tuuri #include "trx0undo.h" /*********************************************************************//** +Gets the offset of 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 */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ +{ + ulint pos; + ulint offset; + ulint len; + + ut_ad(dict_index_is_clust(index)); + ut_ad(rec_offs_validate(rec, index, offsets)); + + pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); + + offset = rec_get_nth_field_offs(offsets, pos, &len); + + ut_ad(len == DATA_TRX_ID_LEN); + + return(offset); +} + +/*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ UNIV_INLINE trx_id_t row_get_rec_trx_id( /*===============*/ - 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; === modified file 'storage/innobase/lock/lock0lock.c' --- a/storage/innobase/lock/lock0lock.c 2011-04-21 22:15:39 +0000 +++ b/storage/innobase/lock/lock0lock.c 2011-05-24 12:05:57 +0000 @@ -361,6 +361,7 @@ ibool lock_validate(void); /*===============*/ +# ifdef UNIV_DEBUG_LOCK_VALIDATE /*********************************************************************//** Validates the record lock queues on a page. @return TRUE if ok */ @@ -368,13 +369,9 @@ static ibool lock_rec_validate_page( /*===================*/ - ibool locked_lock_trx_sys, /*!< in: if the caller holds - both the lock mutex and - trx_sys_t->lock. */ - ulint space, /*!< in: space id */ - ulint zip_size, /*!< in: compressed page size - in bytes or 0 for uncompressed pages */ - ulint page_no); /*!< in: page number */ + const buf_block_t* block) /*!< in: buffer block */ + __attribute__((nonnull, warn_unused_result)); +# endif /* UNIV_DEBUG_LOCK_VALIDATE */ #endif /* UNIV_DEBUG */ /* The lock system */ @@ -1135,10 +1132,10 @@ lock_rec_reset_nth_bit( Gets the first or next record lock on a page. @return next lock, NULL if none exists */ UNIV_INLINE -lock_t* -lock_rec_get_next_on_page( -/*======================*/ - lock_t* lock) /*!< in: a record lock */ +const lock_t* +lock_rec_get_next_on_page_const( +/*============================*/ + const lock_t* lock) /*!< in: a record lock */ { ulint space; ulint page_no; @@ -1171,12 +1168,12 @@ lock_rec_get_next_on_page( Gets the first or next record lock on a page. @return next lock, NULL if none exists */ UNIV_INLINE -const lock_t* -lock_rec_get_next_on_page_const( -/*============================*/ - const lock_t* lock) /*!< in: a record lock */ +lock_t* +lock_rec_get_next_on_page( +/*======================*/ + lock_t* lock) /*!< in: a record lock */ { - return(lock_rec_get_next_on_page((lock_t*) lock)); + return((lock_t*) lock_rec_get_next_on_page_const(lock)); } /*********************************************************************//** @@ -2780,10 +2777,7 @@ lock_move_reorganize_page( mem_heap_free(heap); #ifdef UNIV_DEBUG_LOCK_VALIDATE - ut_ad(lock_rec_validate_page(FALSE, - buf_block_get_space(block), - buf_block_get_zip_size(block), - buf_block_get_page_no(block))); + ut_ad(lock_rec_validate_page(block)); #endif } @@ -2871,14 +2865,8 @@ lock_move_rec_list_end( lock_mutex_exit(); #ifdef UNIV_DEBUG_LOCK_VALIDATE - ut_ad(lock_rec_validate_page(FALSE, - buf_block_get_space(block), - buf_block_get_zip_size(block), - buf_block_get_page_no(block))); - ut_ad(lock_rec_validate_page(FALSE, - buf_block_get_space(new_block), - buf_block_get_zip_size(block), - buf_block_get_page_no(new_block))); + ut_ad(lock_rec_validate_page(block)); + ut_ad(lock_rec_validate_page(new_block)); #endif } @@ -2987,10 +2975,7 @@ lock_move_rec_list_start( lock_mutex_exit(); #ifdef UNIV_DEBUG_LOCK_VALIDATE - ut_ad(lock_rec_validate_page(FALSE, - buf_block_get_space(block), - buf_block_get_zip_size(block), - buf_block_get_page_no(block))); + ut_ad(lock_rec_validate_page(block)); #endif } @@ -4075,17 +4060,18 @@ Checks if other transactions have an inc the lock queue. @return lock or NULL */ UNIV_INLINE -lock_t* +const lock_t* lock_table_other_has_incompatible( /*==============================*/ - trx_t* trx, /*!< in: transaction, or NULL if all - transactions should be included */ - ulint wait, /*!< in: LOCK_WAIT if also waiting locks are - taken into account, or 0 if not */ - dict_table_t* table, /*!< in: table */ - enum lock_mode mode) /*!< in: lock mode */ + const trx_t* trx, /*!< in: transaction, or NULL if all + transactions should be included */ + ulint wait, /*!< in: LOCK_WAIT if also + waiting locks are taken into + account, or 0 if not */ + const dict_table_t* table, /*!< in: table */ + enum lock_mode mode) /*!< in: lock mode */ { - lock_t* lock; + const lock_t* lock; ut_ad(lock_mutex_own()); @@ -4121,7 +4107,7 @@ lock_table( { trx_t* trx; ulint err; - lock_t* lock; + const lock_t* lock; ut_ad(table && thr); @@ -5080,9 +5066,9 @@ static ibool lock_table_queue_validate( /*======================*/ - dict_table_t* table) /*!< in: table */ + const dict_table_t* table) /*!< in: table */ { - lock_t* lock; + const lock_t* lock; ut_ad(lock_mutex_own()); #ifdef UNIV_SYNC_DEBUG @@ -5128,7 +5114,7 @@ lock_rec_queue_validate( trx_sys_t->lock. */ const buf_block_t* block, /*!< in: buffer block containing rec */ const rec_t* rec, /*!< in: record to look at */ - dict_index_t* index, /*!< in: index, or NULL if not known */ + const dict_index_t* index, /*!< in: index, or NULL if not known */ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { const trx_t* impl_trx; @@ -5235,59 +5221,30 @@ func_exit: /*********************************************************************//** Validates the record lock queues on a page. @return TRUE if ok */ -static +static __attribute__((nonnull, warn_unused_result)) ibool -lock_rec_validate_page( -/*===================*/ - ibool locked_lock_trx_sys, /*!< in: if the caller holds - both the lock mutex and - trx_sys_t->lock. */ - ulint space, /*!< in: space id */ - ulint zip_size, /*!< in: compressed page size - in bytes or 0 for uncompressed pages */ - ulint page_no) /*!< in: page number */ +lock_rec_validate_page_low( +/*=======================*/ + const buf_block_t* block) /*!< in: buffer block */ { - dict_index_t* index; - buf_block_t* block; - const page_t* page; const lock_t* lock; const rec_t* rec; ulint nth_lock = 0; ulint nth_bit = 0; ulint i; - mtr_t mtr; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; rec_offs_init(offsets_); - /* This is to preserve latching order. */ - if (locked_lock_trx_sys) { - lock_mutex_exit(); - rw_lock_s_unlock(&trx_sys->lock); - } - - ut_ad(!lock_mutex_own()); + ut_ad(lock_mutex_own()); #ifdef UNIV_SYNC_DEBUG - ut_ad(!rw_lock_own(&trx_sys->lock, RW_LOCK_SHARED)); - ut_ad(!rw_lock_own(&trx_sys->lock, RW_LOCK_EX)); + ut_ad(rw_lock_own(&trx_sys->lock, RW_LOCK_SHARED)); #endif /* UNIV_SYNC_DEBUG */ - mtr_start(&mtr); - - ut_ad(zip_size != ULINT_UNDEFINED); - block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr); - buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); - - page = block->frame; - - /* Either way we need to (re)acquire the mutexes. */ - lock_mutex_enter(); - - rw_lock_s_lock(&trx_sys->lock); - loop: - lock = lock_rec_get_first_on_page_addr(space, page_no); + lock = lock_rec_get_first_on_page_addr(buf_block_get_space(block), + buf_block_get_page_no(block)); if (!lock) { goto function_exit; @@ -5315,15 +5272,14 @@ loop: if (i == 1 || lock_rec_get_nth_bit(lock, i)) { - index = lock->index; - rec = page_find_rec_with_heap_no(page, i); + rec = page_find_rec_with_heap_no(block->frame, i); ut_a(rec); - offsets = rec_get_offsets(rec, index, offsets, + offsets = rec_get_offsets(rec, lock->index, offsets, ULINT_UNDEFINED, &heap); #if 0 fprintf(stderr, - "Validating %lu %lu\n", - (ulong) space, (ulong) page_no); + "Validating %u %u\n", + block->page.space, block->page.offset); #endif /* If this thread is holding the file space latch (fil_space_t::latch), the following @@ -5331,7 +5287,7 @@ loop: cause a deadlock of threads. */ lock_rec_queue_validate( - TRUE, block, rec, index, offsets); + TRUE, block, rec, lock->index, offsets); nth_bit = i + 1; @@ -5345,20 +5301,34 @@ loop: goto loop; function_exit: - - mtr_commit(&mtr); - - if (!locked_lock_trx_sys) { - lock_mutex_exit(); - rw_lock_s_unlock(&trx_sys->lock); - } - if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(TRUE); } +#ifdef UNIV_DEBUG_LOCK_VALIDATE +/*********************************************************************//** +Validates the record lock queues on a page. +@return TRUE if ok */ +static +ibool +lock_rec_validate_page( +/*===================*/ + const buf_block_t* block) /*!< in: buffer block */ +{ + ibool valid; + + lock_mutex_enter(); + rw_lock_s_lock(&trx_sys->lock); + valid = lock_rec_validate_page_low(block); + lock_mutex_exit(); + rw_lock_s_unlock(&trx_sys->lock); + + return(valid); +} +#endif /* UNIV_DEBUG_LOCK_VALIDATE */ + /*********************************************************************//** Validates the lock system. @return TRUE if ok */ @@ -5369,8 +5339,6 @@ lock_validate(void) { const lock_t* lock; const trx_t* trx; - ulint space; - ulint page_no; ulint i; lock_mutex_enter(); @@ -5396,9 +5364,13 @@ lock_validate(void) } for (i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) { - ib_uint64_t limit = 0; + ulint space; + ulint page_no; + ib_uint64_t limit = 0; for (;;) { + mtr_t mtr; + buf_block_t* block; for (lock = HASH_GET_FIRST(lock_sys->rec_hash, i); lock != NULL; @@ -5419,11 +5391,16 @@ lock_validate(void) break; } - lock_rec_validate_page( - TRUE, space, - fil_space_get_zip_size(space), page_no); + mtr_start(&mtr); + block = buf_page_get( + space, fil_space_get_zip_size(space), + page_no, RW_X_LATCH, &mtr); + buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); + + ut_ad(lock_rec_validate_page_low(block)); + mtr_commit(&mtr); - limit = ut_ull_create(space, page_no + 1); + limit++; } } === modified file 'storage/innobase/row/row0row.c' --- a/storage/innobase/row/row0row.c 2011-04-27 21:49:19 +0000 +++ b/storage/innobase/row/row0row.c 2011-05-24 12:05:57 +0000 @@ -47,35 +47,6 @@ Created 4/20/1996 Heikki Tuuri #include "read0read.h" #include "ut0mem.h" -/*********************************************************************//** -Gets the offset of trx id field, in bytes relative to the origin of -a clustered index record. -@return offset of DATA_TRX_ID */ -UNIV_INTERN -ulint -row_get_trx_id_offset( -/*==================*/ - const rec_t* rec __attribute__((unused)), - /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ -{ - ulint pos; - ulint offset; - ulint len; - - ut_ad(dict_index_is_clust(index)); - ut_ad(rec_offs_validate(rec, index, offsets)); - - pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); - - offset = rec_get_nth_field_offs(offsets, pos, &len); - - ut_ad(len == DATA_TRX_ID_LEN); - - return(offset); -} - /*****************************************************************//** 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. --===============0774479085== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/anitha.gopi@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: anitha.gopi@stripped # target_branch: file:///home/anitha/mysql/repo/mysql-trunk-mod/ # testament_sha1: da74420c9cac2191b7a49e776e1967b8df9a3f19 # timestamp: 2011-05-24 21:58:58 +0530 # source_branch: file:///home/anitha/mysql/repo/mysql-5.5-mod/ # base_revision_id: anitha.gopi@stripped\ # yazabkeu8bzkdxe2 # # Begin bundle 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 --===============0774479085==--