summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
authorunknown <antony@pcg5ppc.xiphis.org>2007-09-08 20:26:12 -0700
committerunknown <antony@pcg5ppc.xiphis.org>2007-09-08 20:26:12 -0700
commitdb1f9468d4c4e4981fb4bc6e96de19766d0ca377 (patch)
tree5fe93bb7fb897e508920154ea011da88aa495e84 /sql/ha_partition.cc
parent67a8e6a0c1a9d2b987db3b3e12eaf383e834ef0a (diff)
downloadmariadb-git-db1f9468d4c4e4981fb4bc6e96de19766d0ca377.tar.gz
Bug#30919
"Rows not deleted from innodb partitioned tables if --innodb_autoinc_lock_mode=0" Due to a previous bugfix which initializes a previously uninitialized variable, ha_partition::get_auto_increment() may fail to operate correctly when the storage engine reports that it is only reserving one value and one or more partitions have a different 'next-value'. Currently, only affects Innodb's new-style auto-increment code which reserves larger blocks of values and has less inter-thread contention. mysql-test/suite/rpl/r/rpl_innodb_bug28430.result: Fix results - previous results shows symptoms of Bug30919 sql/ha_partition.cc: Bug30919 ha_partition::write_row() Do not insert a row if a failure occurred while generating auto-increment value. ha_partition::get_auto_increment() If there is an empty 'intersection' of auto-increment values, perform a second pass before failing because partitions may have different auto-increment 'next-value' attributes. storage/innobase/handler/ha_innodb.cc: Bug30919 Only set *first_value if it is less than autoinc value. This allows a higher value to be hinted when operating as a partitioned table. mysql-test/suite/rpl/r/rpl_innodb_bug30919.result: New BitKeeper file ``mysql-test/suite/rpl/r/rpl_innodb_bug30919.result'' mysql-test/suite/rpl/t/rpl_innodb_bug30919-master.opt: New BitKeeper file ``mysql-test/suite/rpl/t/rpl_innodb_bug30919-master.opt'' mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: New BitKeeper file ``mysql-test/suite/rpl/t/rpl_innodb_bug30919.test''
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc36
1 files changed, 34 insertions, 2 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 580e28e3ee2..e2c054e9a13 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2693,7 +2693,17 @@ int ha_partition::write_row(uchar * buf)
or a new row, then update the auto_increment value in the record.
*/
if (table->next_number_field && buf == table->record[0])
- update_auto_increment();
+ {
+ error= update_auto_increment();
+
+ /*
+ If we have failed to set the auto-increment value for this row,
+ it is highly likely that we will not be able to insert it into
+ the correct partition. We must check and fail if neccessary.
+ */
+ if (error)
+ DBUG_RETURN(error);
+ }
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
#ifdef NOT_NEEDED
@@ -5456,8 +5466,10 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong first_value_part, last_value_part, nb_reserved_values_part,
last_value= ~ (ulonglong) 0;
handler **pos, **end;
+ bool retry= TRUE;
DBUG_ENTER("ha_partition::get_auto_increment");
+again:
for (pos=m_file, end= m_file+ m_tot_parts; pos != end ; pos++)
{
first_value_part= *first_value;
@@ -5466,7 +5478,8 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
if (first_value_part == ~(ulonglong)(0)) // error in one partition
{
*first_value= first_value_part;
- break;
+ sql_print_error("Partition failed to reserve auto_increment value");
+ DBUG_VOID_RETURN;
}
/*
Partition has reserved an interval. Intersect it with the intervals
@@ -5479,6 +5492,25 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
}
if (last_value < *first_value) /* empty intersection, error */
{
+ /*
+ When we have an empty intersection, it means that one or more
+ partitions may have a significantly different autoinc next value.
+ We should not fail here - it just means that we should try to
+ find a new reservation making use of the current *first_value
+ wbich should now be compatible with all partitions.
+ */
+ if (retry)
+ {
+ retry= FALSE;
+ last_value= ~ (ulonglong) 0;
+ release_auto_increment();
+ goto again;
+ }
+ /*
+ We should not get here.
+ */
+ sql_print_error("Failed to calculate auto_increment value for partition");
+
*first_value= ~(ulonglong)(0);
}
if (increment) // If not check for values