summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-04-10 08:28:13 +0200
committerSergei Golubchik <sergii@pisem.net>2012-04-10 08:28:13 +0200
commit16c5c53fc21b162844c38a87ac48205448ca1d2f (patch)
tree7a50437d5f9da772ec8aaacab322e5f6c13e7305 /storage/xtradb
parentf860b2aad41cd1b5ed0438ea211dcd78eec82b94 (diff)
parented418461614d912fbb114053508b3fb09b1fc2f0 (diff)
downloadmariadb-git-16c5c53fc21b162844c38a87ac48205448ca1d2f.tar.gz
mysql 5.5.23 merge
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/fsp/fsp0fsp.c40
-rw-r--r--storage/xtradb/handler/ha_innodb.cc104
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;