diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-04-10 08:28:13 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-04-10 08:28:13 +0200 |
commit | 16c5c53fc21b162844c38a87ac48205448ca1d2f (patch) | |
tree | 7a50437d5f9da772ec8aaacab322e5f6c13e7305 /storage/xtradb | |
parent | f860b2aad41cd1b5ed0438ea211dcd78eec82b94 (diff) | |
parent | ed418461614d912fbb114053508b3fb09b1fc2f0 (diff) | |
download | mariadb-git-16c5c53fc21b162844c38a87ac48205448ca1d2f.tar.gz |
mysql 5.5.23 merge
Diffstat (limited to 'storage/xtradb')
-rw-r--r-- | storage/xtradb/fsp/fsp0fsp.c | 40 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 104 |
2 files changed, 89 insertions, 55 deletions
diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c index 6102c5decd8..0c96aab0356 100644 --- a/storage/xtradb/fsp/fsp0fsp.c +++ b/storage/xtradb/fsp/fsp0fsp.c @@ -211,15 +211,13 @@ fseg_n_reserved_pages_low( /********************************************************************//** Marks a page used. The page must reside within the extents of the given segment. */ -static +static __attribute__((nonnull)) void fseg_mark_page_used( /*================*/ fseg_inode_t* seg_inode,/*!< in: segment inode */ - ulint space, /*!< in: space id */ - ulint zip_size,/*!< in: compressed page size in bytes - or 0 for uncompressed pages */ ulint page, /*!< in: page offset */ + xdes_t* descr, /* extent descriptor */ mtr_t* mtr); /*!< in: mtr */ /**********************************************************************//** Returns the first extent descriptor for a segment. We think of the extent @@ -677,19 +675,10 @@ xdes_get_descriptor_with_space_hdr( zip_size = dict_table_flags_to_zip_size( mach_read_from_4(sp_header + FSP_SPACE_FLAGS)); - /* If offset is >= size or > limit, return NULL */ - - if ((offset >= size) || (offset > limit)) { - + if ((offset >= size) || (offset >= limit)) { return(NULL); } - /* If offset is == limit, fill free list of the space. */ - - if (offset == limit) { - fsp_fill_free_list(FALSE, space, sp_header, mtr); - } - descr_page_no = xdes_calc_descriptor_page(zip_size, offset); if (descr_page_no == 0) { @@ -711,14 +700,11 @@ xdes_get_descriptor_with_space_hdr( } /********************************************************************//** -Gets pointer to a the extent descriptor of a page. The page where the -extent descriptor resides is x-locked. If the page offset is equal to -the free limit of the space, adds new extents from above the free limit -to the space free list, if not free limit == space size. This adding -is necessary to make the descriptor defined, as they are uninitialized -above the free limit. +Gets pointer to a the extent descriptor of a page. The page where the extent +descriptor resides is x-locked. This function no longer extends the data +file. @return pointer to the extent descriptor, NULL if the page does not -exist in the space or if the offset exceeds the free limit */ +exist in the space or if the offset is >= the free limit */ static xdes_t* xdes_get_descriptor( @@ -2763,7 +2749,7 @@ fseg_alloc_free_page_low( ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT, ret_page % FSP_EXTENT_SIZE, mtr) == TRUE); - fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr); + fseg_mark_page_used(seg_inode, ret_page, ret_descr, mtr); } buf_reset_check_index_page_at_flush(space, ret_page); @@ -3183,27 +3169,21 @@ fsp_get_available_space_in_free_extents( /********************************************************************//** Marks a page used. The page must reside within the extents of the given segment. */ -static +static __attribute__((nonnull)) void fseg_mark_page_used( /*================*/ fseg_inode_t* seg_inode,/*!< in: segment inode */ - ulint space, /*!< in: space id */ - ulint zip_size,/*!< in: compressed page size in bytes - or 0 for uncompressed pages */ ulint page, /*!< in: page offset */ + xdes_t* descr, /* extent descriptor */ mtr_t* mtr) /*!< in: mtr */ { - xdes_t* descr; ulint not_full_n_used; - ut_ad(seg_inode && mtr); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); - descr = xdes_get_descriptor(space, zip_size, page, mtr); - ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr) == mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr)); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 5c6c361962a..4cb21d46804 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1618,37 +1618,88 @@ values we want to reserve for multi-value inserts e.g., INSERT INTO T VALUES(), (), (); -innobase_next_autoinc() will be called with increment set to -n * 3 where autoinc_lock_mode != TRADITIONAL because we want -to reserve 3 values for the multi-value INSERT above. +innobase_next_autoinc() will be called with increment set to 3 where +autoinc_lock_mode != TRADITIONAL because we want to reserve 3 values for +the multi-value INSERT above. @return the next value */ static ulonglong innobase_next_autoinc( /*==================*/ ulonglong current, /*!< in: Current value */ - ulonglong increment, /*!< in: increment current by */ + ulonglong need, /*!< in: count of values needed */ + ulonglong step, /*!< in: AUTOINC increment step */ ulonglong offset, /*!< in: AUTOINC offset */ - ulonglong max_value, /*!< in: max value for type */ - ulonglong reserve) /*!< in: how many values to reserve */ + ulonglong max_value) /*!< in: max value for type */ { ulonglong next_value; + ulonglong block = need * step; /* Should never be 0. */ - ut_a(increment > 0); + ut_a(need > 0); + ut_a(block > 0); + ut_a(max_value > 0); + + /* Current value should never be greater than the maximum. */ + ut_a(current <= max_value); /* According to MySQL documentation, if the offset is greater than - the increment then the offset is ignored. */ - if (offset >= increment) + the step then the offset is ignored. */ + if (offset > block) { offset = 0; + } + + /* Check for overflow. */ + if (block >= max_value + || offset > max_value + || current == max_value + || max_value - offset <= offset) { + + next_value = max_value; + } else { + ut_a(max_value > current); + + ulonglong free = max_value - current; + + if (free < offset || free - offset <= block) { + next_value = max_value; + } else { + next_value = 0; + } + } + + if (next_value == 0) { + ulonglong next; + + if (current > offset) { + next = (current - offset) / step; + } else { + next = (offset - current) / step; + } + + ut_a(max_value > next); + next_value = next * step; + /* Check for multiplication overflow. */ + ut_a(next_value >= next); + ut_a(max_value > next_value); - if (max_value <= current) - return max_value; - next_value = (current / increment) + reserve; - next_value = next_value * increment + offset; - /* Check for overflow. */ - if (next_value < current || next_value > max_value) - next_value = max_value; + /* Check for overflow */ + if (max_value - next_value >= block) { + + next_value += block; + + if (max_value - next_value >= offset) { + next_value += offset; + } else { + next_value = max_value; + } + } else { + next_value = max_value; + } + } + + ut_a(next_value != 0); + ut_a(next_value <= max_value); return(next_value); } @@ -4156,7 +4207,8 @@ ha_innobase::innobase_initialize_autoinc() nor the offset, so use a default increment of 1. */ auto_inc = innobase_next_autoinc( - read_auto_inc, 1, 1, col_max_value, 1); + read_auto_inc, 1, 1, 0, col_max_value); + break; } case DB_RECORD_NOT_FOUND: @@ -5833,15 +5885,16 @@ set_max_autoinc: if (auto_inc <= col_max_value) { ut_a(prebuilt->autoinc_increment > 0); - ulonglong need; ulonglong offset; + ulonglong increment; offset = prebuilt->autoinc_offset; - need = prebuilt->autoinc_increment; + increment = prebuilt->autoinc_increment; auto_inc = innobase_next_autoinc( auto_inc, - need, offset, col_max_value, 1); + 1, increment, offset, + col_max_value); err = innobase_set_max_autoinc( auto_inc); @@ -6105,14 +6158,14 @@ ha_innobase::update_row( if (auto_inc <= col_max_value && auto_inc != 0) { - ulonglong need; ulonglong offset; + ulonglong increment; offset = prebuilt->autoinc_offset; - need = prebuilt->autoinc_increment; + increment = prebuilt->autoinc_increment; auto_inc = innobase_next_autoinc( - auto_inc, need, offset, col_max_value, 1); + auto_inc, 1, increment, offset, col_max_value); error = innobase_set_max_autoinc(auto_inc); } @@ -10937,10 +10990,11 @@ ha_innobase::get_auto_increment( ulonglong next_value; current = *first_value > col_max_value ? autoinc : *first_value; - + /* Compute the last value in the interval */ next_value = innobase_next_autoinc( - current, increment, offset, col_max_value, *nb_reserved_values); + current, *nb_reserved_values, increment, offset, + col_max_value); prebuilt->autoinc_last_value = next_value; |