Commit 29aaa658 authored by Annamalai Gurusami's avatar Annamalai Gurusami

Bug #11766634 59783: InnoDB data grows unexpectedly when inserting,

truncating, inserting the same set of rows. When a table is 
re-created with the same set of rows, the data file size must
not grow.  

rb:968
Approved by Marko. 
parent 6e6ba865
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
# Bug 11766634 59783: InnoDB data grows unexpectedly when inserting,
# truncating, inserting the same set of rows.
#
# Scenario:
# create table t1. Insert $recs records. check size of ibdata1.
# drop table t1. create table t1. Insert the same set of $recs
# records. The size of ibdata1 must not increase.
#
-- source include/not_embedded.inc
-- source include/have_innodb.inc
create table t1 (f1 char(255)) engine innodb;
let $MYSQLD_DATADIR=`select @@datadir`;
let IBDATA1=$MYSQLD_DATADIR/ibdata1;
let $recs = 36262;
--disable_query_log
let $c = $recs;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
create table t1 (f1 char(255)) engine innodb;
--disable_query_log
let $c = $recs;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
# Bug 11766634 59783: InnoDB data grows unexpectedly when inserting,
# truncating, inserting the same set of rows.
#
# Scenario:
# create table t1. Insert $recs records. check size of ibdata1.
# drop table t1. create table t1. Insert the same set of $recs
# records. The size of ibdata1 must not increase.
#
-- source include/not_embedded.inc
-- source include/have_innodb_plugin.inc
create table t1 (f1 char(255)) engine innodb;
let $MYSQLD_DATADIR=`select @@datadir`;
let IBDATA1=$MYSQLD_DATADIR/ibdata1;
let $recs = 36262;
--disable_query_log
let $c = $recs;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
create table t1 (f1 char(255)) engine innodb;
--disable_query_log
let $c = $recs;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
...@@ -245,13 +245,13 @@ fseg_n_reserved_pages_low( ...@@ -245,13 +245,13 @@ fseg_n_reserved_pages_low(
/************************************************************************ /************************************************************************
Marks a page used. The page must reside within the extents of the given Marks a page used. The page must reside within the extents of the given
segment. */ segment. */
static static __attribute__((nonnull))
void void
fseg_mark_page_used( fseg_mark_page_used(
/*================*/ /*================*/
fseg_inode_t* seg_inode,/* in: segment inode */ fseg_inode_t* seg_inode,/* in: segment inode */
ulint space, /* in: space id */
ulint page, /* in: page offset */ ulint page, /* in: page offset */
xdes_t* descr, /* in: extent descriptor */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/************************************************************************** /**************************************************************************
Returns the first extent descriptor for a segment. We think of the extent Returns the first extent descriptor for a segment. We think of the extent
...@@ -635,10 +635,8 @@ xdes_calc_descriptor_index( ...@@ -635,10 +635,8 @@ xdes_calc_descriptor_index(
/************************************************************************ /************************************************************************
Gets pointer to a the extent descriptor of a page. The page where the extent 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 descriptor resides is x-locked. This function no longer extends the data
of the space, adds new extents from above the free limit to the space free file. */
list, if not free limit == space size. This adding is necessary to make the
descriptor defined, as they are uninitialized above the free limit. */
UNIV_INLINE UNIV_INLINE
xdes_t* xdes_t*
xdes_get_descriptor_with_space_hdr( xdes_get_descriptor_with_space_hdr(
...@@ -666,19 +664,10 @@ xdes_get_descriptor_with_space_hdr( ...@@ -666,19 +664,10 @@ xdes_get_descriptor_with_space_hdr(
limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr); limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);
size = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr); size = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr);
/* If offset is >= size or > limit, return NULL */ if ((offset >= size) || (offset >= limit)) {
if ((offset >= size) || (offset > limit)) {
return(NULL); 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(offset); descr_page_no = xdes_calc_descriptor_page(offset);
if (descr_page_no == 0) { if (descr_page_no == 0) {
...@@ -2552,7 +2541,7 @@ fseg_alloc_free_page_low( ...@@ -2552,7 +2541,7 @@ fseg_alloc_free_page_low(
ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT, ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
ret_page % FSP_EXTENT_SIZE, mtr) == TRUE); ret_page % FSP_EXTENT_SIZE, mtr) == TRUE);
fseg_mark_page_used(seg_inode, space, ret_page, mtr); fseg_mark_page_used(seg_inode, ret_page, ret_descr, mtr);
} }
return(ret_page); return(ret_page);
...@@ -2946,22 +2935,17 @@ fsp_get_available_space_in_free_extents( ...@@ -2946,22 +2935,17 @@ fsp_get_available_space_in_free_extents(
/************************************************************************ /************************************************************************
Marks a page used. The page must reside within the extents of the given Marks a page used. The page must reside within the extents of the given
segment. */ segment. */
static static __attribute__((nonnull))
void void
fseg_mark_page_used( fseg_mark_page_used(
/*================*/ /*================*/
fseg_inode_t* seg_inode,/* in: segment inode */ fseg_inode_t* seg_inode,/* in: segment inode */
ulint space, /* in: space id */
ulint page, /* in: page offset */ ulint page, /* in: page offset */
xdes_t* descr, /* in: extent descriptor */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
xdes_t* descr;
ulint not_full_n_used; ulint not_full_n_used;
ut_ad(seg_inode && mtr);
descr = xdes_get_descriptor(space, page, mtr);
ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr) ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr)
== mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr)); == mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr));
......
...@@ -273,15 +273,13 @@ fseg_n_reserved_pages_low( ...@@ -273,15 +273,13 @@ fseg_n_reserved_pages_low(
/********************************************************************//** /********************************************************************//**
Marks a page used. The page must reside within the extents of the given Marks a page used. The page must reside within the extents of the given
segment. */ segment. */
static static __attribute__((nonnull))
void void
fseg_mark_page_used( fseg_mark_page_used(
/*================*/ /*================*/
fseg_inode_t* seg_inode,/*!< in: segment inode */ 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 */ ulint page, /*!< in: page offset */
xdes_t* descr, /* extent descriptor */
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr); /*!< in: mtr */
/**********************************************************************//** /**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent Returns the first extent descriptor for a segment. We think of the extent
...@@ -705,12 +703,10 @@ xdes_calc_descriptor_index( ...@@ -705,12 +703,10 @@ xdes_calc_descriptor_index(
/********************************************************************//** /********************************************************************//**
Gets pointer to a the extent descriptor of a page. The page where the extent 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 descriptor resides is x-locked. This function no longer extends the data
of the space, adds new extents from above the free limit to the space free file.
list, if not free limit == space size. This adding is necessary to make the
descriptor defined, as they are uninitialized above the free limit.
@return pointer to the extent descriptor, NULL if the page does not @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 */
UNIV_INLINE __attribute__((nonnull, warn_unused_result)) UNIV_INLINE __attribute__((nonnull, warn_unused_result))
xdes_t* xdes_t*
xdes_get_descriptor_with_space_hdr( xdes_get_descriptor_with_space_hdr(
...@@ -740,19 +736,10 @@ xdes_get_descriptor_with_space_hdr( ...@@ -740,19 +736,10 @@ xdes_get_descriptor_with_space_hdr(
zip_size = dict_table_flags_to_zip_size( zip_size = dict_table_flags_to_zip_size(
mach_read_from_4(sp_header + FSP_SPACE_FLAGS)); 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); 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); descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
if (descr_page_no == 0) { if (descr_page_no == 0) {
...@@ -2877,7 +2864,7 @@ fseg_alloc_free_page_low( ...@@ -2877,7 +2864,7 @@ fseg_alloc_free_page_low(
ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT, ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
ret_page % FSP_EXTENT_SIZE, mtr) == TRUE); 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);
} }
return(fsp_page_create( return(fsp_page_create(
...@@ -3283,27 +3270,21 @@ fsp_get_available_space_in_free_extents( ...@@ -3283,27 +3270,21 @@ fsp_get_available_space_in_free_extents(
/********************************************************************//** /********************************************************************//**
Marks a page used. The page must reside within the extents of the given Marks a page used. The page must reside within the extents of the given
segment. */ segment. */
static static __attribute__((nonnull))
void void
fseg_mark_page_used( fseg_mark_page_used(
/*================*/ /*================*/
fseg_inode_t* seg_inode,/*!< in: segment inode */ 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 */ ulint page, /*!< in: page offset */
xdes_t* descr, /* extent descriptor */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
xdes_t* descr;
ulint not_full_n_used; ulint not_full_n_used;
ut_ad(seg_inode && mtr);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE); == 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) ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr)
== mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr)); == mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment