diff options
author | unknown <antony@pcg5ppc.xiphis.org> | 2007-09-08 20:26:12 -0700 |
---|---|---|
committer | unknown <antony@pcg5ppc.xiphis.org> | 2007-09-08 20:26:12 -0700 |
commit | db1f9468d4c4e4981fb4bc6e96de19766d0ca377 (patch) | |
tree | 5fe93bb7fb897e508920154ea011da88aa495e84 /sql/ha_partition.cc | |
parent | 67a8e6a0c1a9d2b987db3b3e12eaf383e834ef0a (diff) | |
download | mariadb-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.cc | 36 |
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 |