summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@oracle.com>2010-10-01 13:39:49 +0200
committerMattias Jonsson <mattias.jonsson@oracle.com>2010-10-01 13:39:49 +0200
commitcfcf51b719b73c3dd5b854b14dc4829f3a5b7650 (patch)
tree091a2e59c87cb003723f6af8740cfa8647842ef4
parent0b7c5f4dcc496a9bbae17e386552d2d36700c3e9 (diff)
parent814fbc5b6f2bf40c91bfb01dfa1bcf711af01d76 (diff)
downloadmariadb-git-cfcf51b719b73c3dd5b854b14dc4829f3a5b7650.tar.gz
merge
-rw-r--r--mysql-test/r/partition_binlog_stmt.result13
-rw-r--r--mysql-test/t/partition_binlog_stmt.test26
-rw-r--r--sql/ha_partition.cc17
-rw-r--r--sql/ha_partition.h7
-rw-r--r--sql/table.cc10
-rw-r--r--sql/table.h1
6 files changed, 72 insertions, 2 deletions
diff --git a/mysql-test/r/partition_binlog_stmt.result b/mysql-test/r/partition_binlog_stmt.result
new file mode 100644
index 00000000000..9be23636ca6
--- /dev/null
+++ b/mysql-test/r/partition_binlog_stmt.result
@@ -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;
diff --git a/mysql-test/t/partition_binlog_stmt.test b/mysql-test/t/partition_binlog_stmt.test
new file mode 100644
index 00000000000..c426de9f303
--- /dev/null
+++ b/mysql-test/t/partition_binlog_stmt.test
@@ -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;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index ee24a36985e..52e39f397a6 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2451,6 +2451,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
@@ -2607,6 +2622,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);
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index feb2ddb9cfc..76b91e160ca 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -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;
@@ -948,8 +949,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()
@@ -962,7 +964,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;
}
}
diff --git a/sql/table.cc b/sql/table.cc
index e989ab039a0..18523f08551 100644
--- a/sql/table.cc
+++ b/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);
diff --git a/sql/table.h b/sql/table.h
index bbb39aae6f7..132279169cb 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -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. */
/*