mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
@ -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;
|
|||||||
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 ();
|
|||||||
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)
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ private:
|
|||||||
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 @@ private:
|
|||||||
*/
|
*/
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ err:
|
|||||||
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:
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user