mirror of
https://github.com/MariaDB/server.git
synced 2025-04-08 00:05:34 +02:00
Bug#51851: Server with SBR locks mutex twice on
LOAD DATA into partitioned MyISAM table Problem was that both partitioning and myisam used the same table_share->mutex for different protections (auto inc and repair). Solved by adding a specific mutex for the partitioning auto_increment. Also adding destroying the ha_data structure in free_table_share (which is to be propagated into 5.5). This is a 5.1 ONLY patch, already fixed in 5.5+.
This commit is contained in:
parent
a73b734949
commit
a01773dbee
6 changed files with 72 additions and 2 deletions
13
mysql-test/r/partition_binlog_stmt.result
Normal file
13
mysql-test/r/partition_binlog_stmt.result
Normal file
|
@ -0,0 +1,13 @@
|
|||
DROP TABLE IF EXISTS t1;
|
||||
#
|
||||
# Bug#51851: Server with SBR locks mutex twice on LOAD DATA into
|
||||
# partitioned MyISAM table
|
||||
CREATE TABLE t1
|
||||
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
name TINYBLOB NOT NULL,
|
||||
modified TIMESTAMP DEFAULT '0000-00-00 00:00:00',
|
||||
INDEX namelocs (name(255))) ENGINE = MyISAM
|
||||
PARTITION BY HASH(id) PARTITIONS 2;
|
||||
LOAD DATA LOCAL INFILE 'init_file.txt'
|
||||
INTO TABLE t1 (name);
|
||||
DROP TABLE t1;
|
26
mysql-test/t/partition_binlog_stmt.test
Normal file
26
mysql-test/t/partition_binlog_stmt.test
Normal file
|
@ -0,0 +1,26 @@
|
|||
--source include/have_partition.inc
|
||||
--source include/have_binlog_format_statement.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
--echo #
|
||||
--echo # Bug#51851: Server with SBR locks mutex twice on LOAD DATA into
|
||||
--echo # partitioned MyISAM table
|
||||
--write_file init_file.txt
|
||||
abcd
|
||||
EOF
|
||||
|
||||
CREATE TABLE t1
|
||||
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
name TINYBLOB NOT NULL,
|
||||
modified TIMESTAMP DEFAULT '0000-00-00 00:00:00',
|
||||
INDEX namelocs (name(255))) ENGINE = MyISAM
|
||||
PARTITION BY HASH(id) PARTITIONS 2;
|
||||
|
||||
LOAD DATA LOCAL INFILE 'init_file.txt'
|
||||
INTO TABLE t1 (name);
|
||||
|
||||
--remove_file init_file.txt
|
||||
DROP TABLE t1;
|
|
@ -2449,6 +2449,21 @@ err1:
|
|||
/****************************************************************************
|
||||
MODULE open/close object
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
A destructor for partition-specific TABLE_SHARE data.
|
||||
*/
|
||||
|
||||
void ha_data_partition_destroy(void *ha_data)
|
||||
{
|
||||
if (ha_data)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_part_data= (HA_DATA_PARTITION*) ha_data;
|
||||
pthread_mutex_destroy(&ha_part_data->LOCK_auto_inc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Open handler object
|
||||
|
||||
|
@ -2605,6 +2620,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
|||
}
|
||||
DBUG_PRINT("info", ("table_share->ha_data 0x%p", ha_data));
|
||||
bzero(ha_data, sizeof(HA_DATA_PARTITION));
|
||||
table_share->ha_data_destroy= ha_data_partition_destroy;
|
||||
VOID(pthread_mutex_init(&ha_data->LOCK_auto_inc, MY_MUTEX_INIT_FAST));
|
||||
}
|
||||
if (is_not_tmp_table)
|
||||
pthread_mutex_unlock(&table_share->mutex);
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef struct st_partition_share
|
|||
typedef struct st_ha_data_partition
|
||||
{
|
||||
ulonglong next_auto_inc_val; /**< first non reserved value */
|
||||
pthread_mutex_t LOCK_auto_inc;
|
||||
bool auto_inc_initialized;
|
||||
} HA_DATA_PARTITION;
|
||||
|
||||
|
@ -944,8 +945,9 @@ private:
|
|||
DBUG_ASSERT(table_share->ha_data && !auto_increment_lock);
|
||||
if(table_share->tmp_table == NO_TMP_TABLE)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
auto_increment_lock= TRUE;
|
||||
pthread_mutex_lock(&table_share->mutex);
|
||||
pthread_mutex_lock(&ha_data->LOCK_auto_inc);
|
||||
}
|
||||
}
|
||||
virtual void unlock_auto_increment()
|
||||
|
@ -958,7 +960,8 @@ private:
|
|||
*/
|
||||
if(auto_increment_lock && !auto_increment_safe_stmt_log_lock)
|
||||
{
|
||||
pthread_mutex_unlock(&table_share->mutex);
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
pthread_mutex_unlock(&ha_data->LOCK_auto_inc);
|
||||
auto_increment_lock= FALSE;
|
||||
}
|
||||
}
|
||||
|
|
10
sql/table.cc
10
sql/table.cc
|
@ -425,6 +425,11 @@ void free_table_share(TABLE_SHARE *share)
|
|||
key_info->flags= 0;
|
||||
}
|
||||
}
|
||||
if (share->ha_data_destroy)
|
||||
{
|
||||
share->ha_data_destroy(share->ha_data);
|
||||
share->ha_data_destroy= NULL;
|
||||
}
|
||||
/* We must copy mem_root from share because share is allocated through it */
|
||||
memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root));
|
||||
free_root(&mem_root, MYF(0)); // Free's share
|
||||
|
@ -1616,6 +1621,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
delete crypted;
|
||||
delete handler_file;
|
||||
hash_free(&share->name_hash);
|
||||
if (share->ha_data_destroy)
|
||||
{
|
||||
share->ha_data_destroy(share->ha_data);
|
||||
share->ha_data_destroy= NULL;
|
||||
}
|
||||
|
||||
open_table_error(share, error, share->open_errno, errarg);
|
||||
DBUG_RETURN(error);
|
||||
|
|
|
@ -463,6 +463,7 @@ typedef struct st_table_share
|
|||
|
||||
/** place to store storage engine specific data */
|
||||
void *ha_data;
|
||||
void (*ha_data_destroy)(void *); /* An optional destructor for ha_data. */
|
||||
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue