Commit 75e7132f authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-21842 auto_increment does not increment with compound primary key on partitioned table.

The idea of this fix is that it's enough to prevent the
next_auto_inc_val from incrementing if an error, to fix this problem
and also the MDEV-17333.
So this patch basically reverts the existing fix to the MDEV-17333.
parent eae9311f
...@@ -289,3 +289,51 @@ pk f ...@@ -289,3 +289,51 @@ pk f
5 a 5 a
6 <=== 6 <===
drop table t1; drop table t1;
#
# MDEV-21842: auto_increment does not increment with compound primary
# key on partitioned table
#
create or replace table `t` (
`id` bigint(20) unsigned not null auto_increment,
`a` int(10) not null ,
`dt` date not null,
primary key (`id`, `dt`) ,
unique key (`a`, `dt`)
)
partition by range columns(`dt`)
(
partition `p202002` values less than ('2020-03-01'),
partition `P202003` values less than ('2020-04-01')
);
connect con1, localhost, root,,;
connect con2, localhost, root,,;
connection con1;
start transaction;
insert into t (a, dt) values (1, '2020-02-29');
connection con2;
start transaction;
insert into t (a, dt) values (1, '2020-02-29');
connection con1;
insert into t (a, dt) values (2, '2020-02-29');
select auto_increment from information_schema.tables where table_name='t';
auto_increment
4
commit;
connection con2;
ERROR 23000: Duplicate entry '1-2020-02-29' for key 'a'
connection con1;
select auto_increment from information_schema.tables where table_name='t';
auto_increment
4
insert into t (a, dt) values (3, '2020-02-29');
insert into t (a, dt) values (4, '2020-02-29');
disconnect con1;
disconnect con2;
connection default;
select * from t;
id a dt
1 1 2020-02-29
3 2 2020-02-29
4 3 2020-02-29
5 4 2020-02-29
drop table t;
...@@ -18,3 +18,62 @@ select * from t1; ...@@ -18,3 +18,62 @@ select * from t1;
drop table t1; drop table t1;
--let $datadir=`select @@datadir` --let $datadir=`select @@datadir`
--remove_file $datadir/test/load.data --remove_file $datadir/test/load.data
--echo #
--echo # MDEV-21842: auto_increment does not increment with compound primary
--echo # key on partitioned table
--echo #
create or replace table `t` (
`id` bigint(20) unsigned not null auto_increment,
`a` int(10) not null ,
`dt` date not null,
primary key (`id`, `dt`) ,
unique key (`a`, `dt`)
)
partition by range columns(`dt`)
(
partition `p202002` values less than ('2020-03-01'),
partition `P202003` values less than ('2020-04-01')
);
connect (con1, localhost, root,,);
connect (con2, localhost, root,,);
--connection con1
start transaction;
insert into t (a, dt) values (1, '2020-02-29');
--connection con2
start transaction;
let $conn2_id= `SELECT CONNECTION_ID()`;
send insert into t (a, dt) values (1, '2020-02-29');
--connection con1
# Ensure that the above insert via conn2 increments next_auto_inc_val
# before the following insert via conn1 starts.
let $wait_condition=select 1 from Information_schema.INNODB_TRX
where trx_mysql_thread_id = $conn2_id and trx_state = 'LOCK WAIT'
and trx_query = "insert into t (a, dt) values (1, '2020-02-29')";
--source include/wait_condition.inc
insert into t (a, dt) values (2, '2020-02-29');
select auto_increment from information_schema.tables where table_name='t';
commit;
--connection con2
--error ER_DUP_ENTRY
reap;
--connection con1
select auto_increment from information_schema.tables where table_name='t';
insert into t (a, dt) values (3, '2020-02-29');
insert into t (a, dt) values (4, '2020-02-29');
disconnect con1;
disconnect con2;
--connection default
select * from t;
drop table t;
...@@ -1046,10 +1046,10 @@ INSERT INTO t1 VALUES (); ...@@ -1046,10 +1046,10 @@ INSERT INTO t1 VALUES ();
SELECT * FROM t1; SELECT * FROM t1;
a a
-1 -1
1
3 3
4 4
6 6
7
DROP TABLE t1; DROP TABLE t1;
# #
# End of 10.3 tests # End of 10.3 tests
......
...@@ -4341,7 +4341,7 @@ int ha_partition::write_row(uchar * buf) ...@@ -4341,7 +4341,7 @@ int ha_partition::write_row(uchar * buf)
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[part_id]->ha_write_row(buf); error= m_file[part_id]->ha_write_row(buf);
if (have_auto_increment && !table->s->next_number_keypart) if (!error && have_auto_increment && !table->s->next_number_keypart)
set_auto_increment_if_higher(table->next_number_field); set_auto_increment_if_higher(table->next_number_field);
reenable_binlog(thd); reenable_binlog(thd);
......
...@@ -92,7 +92,6 @@ class Partition_share : public Handler_share ...@@ -92,7 +92,6 @@ class Partition_share : public Handler_share
bool auto_inc_initialized; bool auto_inc_initialized;
mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */ mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */
ulonglong next_auto_inc_val; /**< first non reserved value */ ulonglong next_auto_inc_val; /**< first non reserved value */
ulonglong prev_auto_inc_val; /**< stored next_auto_inc_val */
/** /**
Hash of partition names. Initialized in the first ha_partition::open() Hash of partition names. Initialized in the first ha_partition::open()
for the table_share. After that it is read-only, i.e. no locking required. for the table_share. After that it is read-only, i.e. no locking required.
...@@ -104,7 +103,6 @@ class Partition_share : public Handler_share ...@@ -104,7 +103,6 @@ class Partition_share : public Handler_share
Partition_share() Partition_share()
: auto_inc_initialized(false), : auto_inc_initialized(false),
next_auto_inc_val(0), next_auto_inc_val(0),
prev_auto_inc_val(0),
partition_name_hash_initialized(false), partition_name_hash_initialized(false),
partition_names(NULL) partition_names(NULL)
{ {
...@@ -430,24 +428,6 @@ class ha_partition :public handler ...@@ -430,24 +428,6 @@ class ha_partition :public handler
MY_BITMAP m_locked_partitions; MY_BITMAP m_locked_partitions;
/** Stores shared auto_increment etc. */ /** Stores shared auto_increment etc. */
Partition_share *part_share; Partition_share *part_share;
/** Fix spurious -Werror=overloaded-virtual in GCC 9 */
virtual void restore_auto_increment(ulonglong prev_insert_id)
{
handler::restore_auto_increment(prev_insert_id);
}
/** Store and restore next_auto_inc_val over duplicate key errors. */
virtual void store_auto_increment()
{
DBUG_ASSERT(part_share);
part_share->prev_auto_inc_val= part_share->next_auto_inc_val;
handler::store_auto_increment();
}
virtual void restore_auto_increment()
{
DBUG_ASSERT(part_share);
part_share->next_auto_inc_val= part_share->prev_auto_inc_val;
handler::restore_auto_increment();
}
/** Temporary storage for new partitions Handler_shares during ALTER */ /** Temporary storage for new partitions Handler_shares during ALTER */
List<Parts_share_refs> m_new_partitions_share_refs; List<Parts_share_refs> m_new_partitions_share_refs;
/** Sorted array of partition ids in descending order of number of rows. */ /** Sorted array of partition ids in descending order of number of rows. */
......
...@@ -3015,10 +3015,6 @@ class handler :public Sql_alloc ...@@ -3015,10 +3015,6 @@ class handler :public Sql_alloc
*/ */
Handler_share **ha_share; Handler_share **ha_share;
/** Stores next_insert_id for handling duplicate key errors. */
ulonglong m_prev_insert_id;
public: public:
handler(handlerton *ht_arg, TABLE_SHARE *share_arg) handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
:table_share(share_arg), table(0), :table_share(share_arg), table(0),
...@@ -3041,7 +3037,7 @@ class handler :public Sql_alloc ...@@ -3041,7 +3037,7 @@ class handler :public Sql_alloc
auto_inc_intervals_count(0), auto_inc_intervals_count(0),
m_psi(NULL), set_top_table_fields(FALSE), top_table(0), m_psi(NULL), set_top_table_fields(FALSE), top_table(0),
top_table_field(0), top_table_fields(0), top_table_field(0), top_table_fields(0),
m_lock_type(F_UNLCK), ha_share(NULL), m_prev_insert_id(0) m_lock_type(F_UNLCK), ha_share(NULL)
{ {
DBUG_PRINT("info", DBUG_PRINT("info",
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d", ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
...@@ -3705,16 +3701,6 @@ class handler :public Sql_alloc ...@@ -3705,16 +3701,6 @@ class handler :public Sql_alloc
insert_id_for_cur_row; insert_id_for_cur_row;
} }
/** Store and restore next_insert_id over duplicate key errors. */
virtual void store_auto_increment()
{
m_prev_insert_id= next_insert_id;
}
virtual void restore_auto_increment()
{
restore_auto_increment(m_prev_insert_id);
}
virtual void update_create_info(HA_CREATE_INFO *create_info) {} virtual void update_create_info(HA_CREATE_INFO *create_info) {}
int check_old_types(); int check_old_types();
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
......
...@@ -1697,7 +1697,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1697,7 +1697,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
int error, trg_error= 0; int error, trg_error= 0;
char *key=0; char *key=0;
MY_BITMAP *save_read_set, *save_write_set; MY_BITMAP *save_read_set, *save_write_set;
table->file->store_auto_increment(); ulonglong prev_insert_id= table->file->next_insert_id;
ulonglong insert_id_for_cur_row= 0; ulonglong insert_id_for_cur_row= 0;
ulonglong prev_insert_id_for_cur_row= 0; ulonglong prev_insert_id_for_cur_row= 0;
DBUG_ENTER("write_record"); DBUG_ENTER("write_record");
...@@ -1848,7 +1848,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1848,7 +1848,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (res == VIEW_CHECK_ERROR) if (res == VIEW_CHECK_ERROR)
goto before_trg_err; goto before_trg_err;
table->file->restore_auto_increment(); table->file->restore_auto_increment(prev_insert_id);
info->touched++; info->touched++;
if (different_records) if (different_records)
{ {
...@@ -2042,7 +2042,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -2042,7 +2042,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (!(thd->variables.old_behavior & if (!(thd->variables.old_behavior &
OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE))
table->file->print_error(error, MYF(ME_JUST_WARNING)); table->file->print_error(error, MYF(ME_JUST_WARNING));
table->file->restore_auto_increment(); table->file->restore_auto_increment(prev_insert_id);
goto ok_or_after_trg_err; goto ok_or_after_trg_err;
} }
...@@ -2065,7 +2065,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -2065,7 +2065,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
before_trg_err: before_trg_err:
table->file->restore_auto_increment(); table->file->restore_auto_increment(prev_insert_id);
if (key) if (key)
my_safe_afree(key, table->s->max_unique_length); my_safe_afree(key, table->s->max_unique_length);
table->column_bitmaps_set(save_read_set, save_write_set); table->column_bitmaps_set(save_read_set, save_write_set);
......
...@@ -571,11 +571,6 @@ public: ...@@ -571,11 +571,6 @@ public:
void set_next_insert_id(ulonglong id); void set_next_insert_id(ulonglong id);
void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values,
ulonglong *first_value, ulonglong *nb_reserved_values) mrn_override; ulonglong *first_value, ulonglong *nb_reserved_values) mrn_override;
/** Fix spurious -Werror=overloaded-virtual in GCC 9 */
void restore_auto_increment() mrn_override
{
handler::restore_auto_increment();
}
void restore_auto_increment(ulonglong prev_insert_id) mrn_override; void restore_auto_increment(ulonglong prev_insert_id) mrn_override;
void release_auto_increment() mrn_override; void release_auto_increment() mrn_override;
int check_for_upgrade(HA_CHECK_OPT *check_opt) mrn_override; int check_for_upgrade(HA_CHECK_OPT *check_opt) mrn_override;
......
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