Commit 6b720ae4 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-6605 Multiple Clients Inserting Causing Error: Failed to read...

MDEV-6605 Multiple Clients Inserting Causing Error: Failed to read auto-increment value from storage engine

* handler::get_auto_increment() was not expecting any errors from the storage engine.
  That was wrong, errors could happen.
* ha_partition::get_auto_increment() was doing index lookups in partition under a mutex.
  This was redundant (engine transaction isolation was covering that anyway)
  and harmful (causing deadlocks).
parent 8deb9066
...@@ -7854,8 +7854,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment, ...@@ -7854,8 +7854,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong first_value_part, max_first_value; ulonglong first_value_part, max_first_value;
handler **file= m_file; handler **file= m_file;
first_value_part= max_first_value= *first_value; first_value_part= max_first_value= *first_value;
/* Must lock and find highest value among all partitions. */ /* Must find highest value among all partitions. */
lock_auto_increment();
do do
{ {
/* Only nb_desired_values = 1 makes sense */ /* Only nb_desired_values = 1 makes sense */
...@@ -7866,7 +7865,6 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment, ...@@ -7866,7 +7865,6 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
*first_value= first_value_part; *first_value= first_value_part;
/* log that the error was between table/partition handler */ /* log that the error was between table/partition handler */
sql_print_error("Partition failed to reserve auto_increment value"); sql_print_error("Partition failed to reserve auto_increment value");
unlock_auto_increment();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
DBUG_PRINT("info", ("first_value_part: %lu", (ulong) first_value_part)); DBUG_PRINT("info", ("first_value_part: %lu", (ulong) first_value_part));
...@@ -7874,7 +7872,6 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment, ...@@ -7874,7 +7872,6 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
} while (*(++file)); } while (*(++file));
*first_value= max_first_value; *first_value= max_first_value;
*nb_reserved_values= 1; *nb_reserved_values= 1;
unlock_auto_increment();
} }
else else
{ {
......
...@@ -2819,15 +2819,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, ...@@ -2819,15 +2819,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
if (error) if (error)
{ {
if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND) if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
{ /* No entry found, that's fine */;
/* No entry found, start with 1. */
nr= 1;
}
else else
{ print_error(error, MYF(0));
DBUG_ASSERT(0); nr= 1;
nr= ULONGLONG_MAX;
}
} }
else else
nr= ((ulonglong) table->next_number_field-> nr= ((ulonglong) table->next_number_field->
......
create table t1 (a int auto_increment, b bigint(20), primary key (b,a)) engine=tokudb;
start transaction;
insert t1 (b) values (1);
set tokudb_lock_timeout=1;
insert t1 (b) values (1);
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
set tokudb_lock_timeout=default;
insert t1 (b) values (1);
insert t1 (b) values (1);
commit;
commit;
select * from t1;
a b
1 1
2 1
3 1
alter table t1 partition by range (b) (partition p0 values less than (9));
start transaction;
insert t1 (b) values (2);
set tokudb_lock_timeout=1;
insert t1 (b) values (2);
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
set tokudb_lock_timeout=default;
insert t1 (b) values (2);
insert t1 (b) values (2);
commit;
commit;
select * from t1;
a b
1 1
2 1
3 1
1 2
2 2
3 2
drop table t1;
#
# MDEV-6605 Multiple Clients Inserting Causing Error: Failed to read auto-increment value from storage engine
#
--source include/have_partition.inc
create table t1 (a int auto_increment, b bigint(20), primary key (b,a)) engine=tokudb;
# first, without partitions
start transaction;
insert t1 (b) values (1);
--connect(con2,localhost,root)
set tokudb_lock_timeout=1;
# auto-inc value is locked
--error ER_LOCK_WAIT_TIMEOUT
insert t1 (b) values (1);
# but no deadlock
set tokudb_lock_timeout=default;
--send insert t1 (b) values (1)
--connection default
insert t1 (b) values (1);
commit;
--connection con2
--reap
commit;
select * from t1;
# now with partitions
--connection default
alter table t1 partition by range (b) (partition p0 values less than (9));
start transaction;
insert t1 (b) values (2);
--connection con2
set tokudb_lock_timeout=1;
# auto-inc value is locked
--error ER_LOCK_WAIT_TIMEOUT
insert t1 (b) values (2);
# but no deadlock
set tokudb_lock_timeout=default;
--send insert t1 (b) values (2)
--connection default
insert t1 (b) values (2);
commit;
--connection con2
--reap
commit;
select * from t1;
drop table t1;
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