mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge of bug#51851.
Also moved HA_DATA_PARTITION from ha_partition.cc to table.h.
This commit is contained in:
commit
7af0bbc3bc
18 changed files with 151 additions and 257 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;
|
28
mysql-test/t/partition_binlog_stmt.test
Normal file
28
mysql-test/t/partition_binlog_stmt.test
Normal file
|
@ -0,0 +1,28 @@
|
|||
--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
|
||||
perl;
|
||||
open( INIT, ">init_file.txt");
|
||||
print INIT "abcd\n";
|
||||
close( INIT );
|
||||
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;
|
|
@ -4249,7 +4249,7 @@ int ha_ndbcluster::info(uint flag)
|
|||
}
|
||||
|
||||
|
||||
void ha_ndbcluster::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
void ha_ndbcluster::get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||
uint part_id)
|
||||
{
|
||||
/*
|
||||
|
@ -4257,7 +4257,7 @@ void ha_ndbcluster::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
|||
implement ndb function which retrives the statistics
|
||||
about ndb partitions.
|
||||
*/
|
||||
bzero((char*) stat_info, sizeof(PARTITION_INFO));
|
||||
bzero((char*) stat_info, sizeof(PARTITION_STATS));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ class ha_ndbcluster: public handler
|
|||
ha_rows estimate_rows_upper_bound()
|
||||
{ return HA_POS_ERROR; }
|
||||
int info(uint);
|
||||
void get_dynamic_partition_info(PARTITION_INFO *stat_info, uint part_id);
|
||||
void get_dynamic_partition_info(PARTITION_STATS *stat_info, uint part_id);
|
||||
int extra(enum ha_extra_function operation);
|
||||
int extra_opt(enum ha_extra_function operation, ulong cache_size);
|
||||
int reset();
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "sql_table.h" // tablename_to_filename
|
||||
#include "key.h"
|
||||
#include "sql_plugin.h"
|
||||
#include "table.h" /* HA_DATA_PARTITION */
|
||||
|
||||
static const char *ha_par_ext= ".par";
|
||||
#ifdef NOT_USED
|
||||
|
@ -2498,12 +2499,11 @@ err1:
|
|||
A destructor for partition-specific TABLE_SHARE data.
|
||||
*/
|
||||
|
||||
void ha_data_partition_destroy(void *ha_data)
|
||||
void ha_data_partition_destroy(HA_DATA_PARTITION* ha_part_data)
|
||||
{
|
||||
if (ha_data)
|
||||
if (ha_part_data)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_data_partition= (HA_DATA_PARTITION*) ha_data;
|
||||
pthread_mutex_destroy(&ha_data_partition->mutex);
|
||||
mysql_mutex_destroy(&ha_part_data->LOCK_auto_inc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2643,28 +2643,30 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
|||
goto err_handler;
|
||||
|
||||
/*
|
||||
Use table_share->ha_data to share auto_increment_value among all handlers
|
||||
for the same table.
|
||||
Use table_share->ha_part_data to share auto_increment_value among
|
||||
all handlers for the same table.
|
||||
*/
|
||||
if (is_not_tmp_table)
|
||||
mysql_mutex_lock(&table_share->LOCK_ha_data);
|
||||
if (!table_share->ha_data)
|
||||
if (!table_share->ha_part_data)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_data;
|
||||
/* currently only needed for auto_increment */
|
||||
table_share->ha_data= ha_data= (HA_DATA_PARTITION*)
|
||||
table_share->ha_part_data= (HA_DATA_PARTITION*)
|
||||
alloc_root(&table_share->mem_root,
|
||||
sizeof(HA_DATA_PARTITION));
|
||||
if (!ha_data)
|
||||
if (!table_share->ha_part_data)
|
||||
{
|
||||
if (is_not_tmp_table)
|
||||
mysql_mutex_unlock(&table_share->LOCK_ha_data);
|
||||
goto err_handler;
|
||||
}
|
||||
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;
|
||||
pthread_mutex_init(&ha_data->mutex, MY_MUTEX_INIT_FAST);
|
||||
DBUG_PRINT("info", ("table_share->ha_part_data 0x%p",
|
||||
table_share->ha_part_data));
|
||||
bzero(table_share->ha_part_data, sizeof(HA_DATA_PARTITION));
|
||||
table_share->ha_part_data_destroy= ha_data_partition_destroy;
|
||||
mysql_mutex_init(key_PARTITION_LOCK_auto_inc,
|
||||
&table_share->ha_part_data->LOCK_auto_inc,
|
||||
MY_MUTEX_INIT_FAST);
|
||||
}
|
||||
if (is_not_tmp_table)
|
||||
mysql_mutex_unlock(&table_share->LOCK_ha_data);
|
||||
|
@ -3088,7 +3090,6 @@ int ha_partition::write_row(uchar * buf)
|
|||
longlong func_value;
|
||||
bool have_auto_increment= table->next_number_field && buf == table->record[0];
|
||||
my_bitmap_map *old_map;
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
THD *thd= ha_thd();
|
||||
timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
|
||||
#ifdef NOT_NEEDED
|
||||
|
@ -3108,8 +3109,8 @@ int ha_partition::write_row(uchar * buf)
|
|||
*/
|
||||
if (have_auto_increment)
|
||||
{
|
||||
if (!ha_data->auto_inc_initialized &&
|
||||
!table->s->next_number_keypart)
|
||||
if (!table_share->ha_part_data->auto_inc_initialized &&
|
||||
!table_share->next_number_keypart)
|
||||
{
|
||||
/*
|
||||
If auto_increment in table_share is not initialized, start by
|
||||
|
@ -3249,7 +3250,7 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
|
|||
exit:
|
||||
/*
|
||||
if updating an auto_increment column, update
|
||||
table_share->ha_data->next_auto_inc_val if needed.
|
||||
table_share->ha_part_data->next_auto_inc_val if needed.
|
||||
(not to be used if auto_increment on secondary field in a multi-column
|
||||
index)
|
||||
mysql_update does not set table->next_number_field, so we use
|
||||
|
@ -3258,8 +3259,7 @@ exit:
|
|||
if (table->found_next_number_field && new_data == table->record[0] &&
|
||||
!table->s->next_number_keypart)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
if (!ha_data->auto_inc_initialized)
|
||||
if (!table_share->ha_part_data->auto_inc_initialized)
|
||||
info(HA_STATUS_AUTO);
|
||||
set_auto_increment_if_higher(table->found_next_number_field);
|
||||
}
|
||||
|
@ -3351,11 +3351,10 @@ int ha_partition::delete_all_rows()
|
|||
if (thd->lex->sql_command == SQLCOM_TRUNCATE)
|
||||
{
|
||||
Alter_info *alter_info= &thd->lex->alter_info;
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
/* TRUNCATE also means resetting auto_increment */
|
||||
lock_auto_increment();
|
||||
ha_data->next_auto_inc_val= 0;
|
||||
ha_data->auto_inc_initialized= FALSE;
|
||||
table_share->ha_part_data->next_auto_inc_val= 0;
|
||||
table_share->ha_part_data->auto_inc_initialized= FALSE;
|
||||
unlock_auto_increment();
|
||||
if (alter_info->flags & ALTER_ADMIN_PARTITION)
|
||||
{
|
||||
|
@ -5071,22 +5070,22 @@ int ha_partition::info(uint flag)
|
|||
if (flag & HA_STATUS_AUTO)
|
||||
{
|
||||
bool auto_inc_is_first_in_idx= (table_share->next_number_keypart == 0);
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
DBUG_PRINT("info", ("HA_STATUS_AUTO"));
|
||||
if (!table->found_next_number_field)
|
||||
stats.auto_increment_value= 0;
|
||||
else if (ha_data->auto_inc_initialized)
|
||||
else if (table_share->ha_part_data->auto_inc_initialized)
|
||||
{
|
||||
lock_auto_increment();
|
||||
stats.auto_increment_value= ha_data->next_auto_inc_val;
|
||||
stats.auto_increment_value= table_share->ha_part_data->next_auto_inc_val;
|
||||
unlock_auto_increment();
|
||||
}
|
||||
else
|
||||
{
|
||||
lock_auto_increment();
|
||||
/* to avoid two concurrent initializations, check again when locked */
|
||||
if (ha_data->auto_inc_initialized)
|
||||
stats.auto_increment_value= ha_data->next_auto_inc_val;
|
||||
if (table_share->ha_part_data->auto_inc_initialized)
|
||||
stats.auto_increment_value=
|
||||
table_share->ha_part_data->next_auto_inc_val;
|
||||
else
|
||||
{
|
||||
handler *file, **file_array;
|
||||
|
@ -5106,10 +5105,11 @@ int ha_partition::info(uint flag)
|
|||
stats.auto_increment_value= auto_increment_value;
|
||||
if (auto_inc_is_first_in_idx)
|
||||
{
|
||||
set_if_bigger(ha_data->next_auto_inc_val, auto_increment_value);
|
||||
ha_data->auto_inc_initialized= TRUE;
|
||||
set_if_bigger(table_share->ha_part_data->next_auto_inc_val,
|
||||
auto_increment_value);
|
||||
table_share->ha_part_data->auto_inc_initialized= TRUE;
|
||||
DBUG_PRINT("info", ("initializing next_auto_inc_val to %lu",
|
||||
(ulong) ha_data->next_auto_inc_val));
|
||||
(ulong) table_share->ha_part_data->next_auto_inc_val));
|
||||
}
|
||||
}
|
||||
unlock_auto_increment();
|
||||
|
@ -5284,7 +5284,7 @@ int ha_partition::info(uint flag)
|
|||
}
|
||||
|
||||
|
||||
void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||
uint part_id)
|
||||
{
|
||||
handler *file= m_file[part_id];
|
||||
|
@ -6499,11 +6499,10 @@ int ha_partition::reset_auto_increment(ulonglong value)
|
|||
{
|
||||
handler **file= m_file;
|
||||
int res;
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
DBUG_ENTER("ha_partition::reset_auto_increment");
|
||||
lock_auto_increment();
|
||||
ha_data->auto_inc_initialized= FALSE;
|
||||
ha_data->next_auto_inc_val= 0;
|
||||
table_share->ha_part_data->auto_inc_initialized= FALSE;
|
||||
table_share->ha_part_data->next_auto_inc_val= 0;
|
||||
do
|
||||
{
|
||||
if ((res= (*file)->ha_reset_auto_increment(value)) != 0)
|
||||
|
@ -6517,7 +6516,7 @@ int ha_partition::reset_auto_increment(ulonglong value)
|
|||
/**
|
||||
This method is called by update_auto_increment which in turn is called
|
||||
by the individual handlers as part of write_row. We use the
|
||||
table_share->ha_data->next_auto_inc_val, or search all
|
||||
table_share->ha_part_data->next_auto_inc_val, or search all
|
||||
partitions for the highest auto_increment_value if not initialized or
|
||||
if auto_increment field is a secondary part of a key, we must search
|
||||
every partition when holding a mutex to be sure of correctness.
|
||||
|
@ -6570,13 +6569,12 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
|
|||
else
|
||||
{
|
||||
THD *thd= ha_thd();
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
/*
|
||||
This is initialized in the beginning of the first write_row call.
|
||||
*/
|
||||
DBUG_ASSERT(ha_data->auto_inc_initialized);
|
||||
DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized);
|
||||
/*
|
||||
Get a lock for handling the auto_increment in table_share->ha_data
|
||||
Get a lock for handling the auto_increment in table_share->ha_part_data
|
||||
for avoiding two concurrent statements getting the same number.
|
||||
*/
|
||||
|
||||
|
@ -6603,8 +6601,9 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
|
|||
}
|
||||
|
||||
/* this gets corrected (for offset/increment) in update_auto_increment */
|
||||
*first_value= ha_data->next_auto_inc_val;
|
||||
ha_data->next_auto_inc_val+= nb_desired_values * increment;
|
||||
*first_value= table_share->ha_part_data->next_auto_inc_val;
|
||||
table_share->ha_part_data->next_auto_inc_val+=
|
||||
nb_desired_values * increment;
|
||||
|
||||
unlock_auto_increment();
|
||||
DBUG_PRINT("info", ("*first_value: %lu", (ulong) *first_value));
|
||||
|
@ -6624,10 +6623,9 @@ void ha_partition::release_auto_increment()
|
|||
}
|
||||
else if (next_insert_id)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
ulonglong next_auto_inc_val;
|
||||
lock_auto_increment();
|
||||
next_auto_inc_val= ha_data->next_auto_inc_val;
|
||||
next_auto_inc_val= table_share->ha_part_data->next_auto_inc_val;
|
||||
/*
|
||||
If the current auto_increment values is lower than the reserved
|
||||
value, and the reserved value was reserved by this thread,
|
||||
|
@ -6642,10 +6640,10 @@ void ha_partition::release_auto_increment()
|
|||
with SET INSERT_ID, i.e. forced/non generated values.
|
||||
*/
|
||||
if (thd->auto_inc_intervals_forced.maximum() < next_insert_id)
|
||||
ha_data->next_auto_inc_val= next_insert_id;
|
||||
table_share->ha_part_data->next_auto_inc_val= next_insert_id;
|
||||
}
|
||||
DBUG_PRINT("info", ("ha_data->next_auto_inc_val: %lu",
|
||||
(ulong) ha_data->next_auto_inc_val));
|
||||
DBUG_PRINT("info", ("table_share->ha_part_data->next_auto_inc_val: %lu",
|
||||
(ulong) table_share->ha_part_data->next_auto_inc_val));
|
||||
|
||||
/* Unlock the multi row statement lock taken in get_auto_increment */
|
||||
if (auto_increment_safe_stmt_log_lock)
|
||||
|
@ -6745,127 +6743,6 @@ int ha_partition::indexes_are_disabled(void)
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
MODULE Partition Share
|
||||
****************************************************************************/
|
||||
/*
|
||||
Service routines for ... methods.
|
||||
-------------------------------------------------------------------------
|
||||
Variables for partition share methods. A hash used to track open tables.
|
||||
A mutex for the hash table and an init variable to check if hash table
|
||||
is initialized.
|
||||
There is also a constant ending of the partition handler file name.
|
||||
*/
|
||||
|
||||
#ifdef NOT_USED
|
||||
static HASH partition_open_tables;
|
||||
static mysql_mutex_t partition_mutex;
|
||||
static int partition_init= 0;
|
||||
|
||||
|
||||
/*
|
||||
Function we use in the creation of our hash to get key.
|
||||
*/
|
||||
|
||||
static uchar *partition_get_key(PARTITION_SHARE *share, size_t *length,
|
||||
my_bool not_used __attribute__ ((unused)))
|
||||
{
|
||||
*length= share->table_name_length;
|
||||
return (uchar *) share->table_name;
|
||||
}
|
||||
|
||||
/*
|
||||
Example of simple lock controls. The "share" it creates is structure we
|
||||
will pass to each partition handler. Do you have to have one of these?
|
||||
Well, you have pieces that are used for locking, and they are needed to
|
||||
function.
|
||||
*/
|
||||
|
||||
static PARTITION_SHARE *get_share(const char *table_name, TABLE *table)
|
||||
{
|
||||
PARTITION_SHARE *share;
|
||||
uint length;
|
||||
char *tmp_name;
|
||||
|
||||
/*
|
||||
So why does this exist? There is no way currently to init a storage
|
||||
engine.
|
||||
Innodb and BDB both have modifications to the server to allow them to
|
||||
do this. Since you will not want to do this, this is probably the next
|
||||
best method.
|
||||
*/
|
||||
if (!partition_init)
|
||||
{
|
||||
/* Hijack a mutex for init'ing the storage engine */
|
||||
mysql_mutex_lock(&LOCK_mysql_create_db);
|
||||
if (!partition_init)
|
||||
{
|
||||
partition_init++;
|
||||
mysql_mutex_init(INSTRUMENT_ME, &partition_mutex, MY_MUTEX_INIT_FAST);
|
||||
(void) hash_init(&partition_open_tables, system_charset_info, 32, 0, 0,
|
||||
(hash_get_key) partition_get_key, 0, 0);
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_mysql_create_db);
|
||||
}
|
||||
mysql_mutex_lock(&partition_mutex);
|
||||
length= (uint) strlen(table_name);
|
||||
|
||||
if (!(share= (PARTITION_SHARE *) hash_search(&partition_open_tables,
|
||||
(uchar *) table_name, length)))
|
||||
{
|
||||
if (!(share= (PARTITION_SHARE *)
|
||||
my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
|
||||
&share, (uint) sizeof(*share),
|
||||
&tmp_name, (uint) length + 1, NullS)))
|
||||
{
|
||||
mysql_mutex_unlock(&partition_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
share->use_count= 0;
|
||||
share->table_name_length= length;
|
||||
share->table_name= tmp_name;
|
||||
strmov(share->table_name, table_name);
|
||||
if (my_hash_insert(&partition_open_tables, (uchar *) share))
|
||||
goto error;
|
||||
thr_lock_init(&share->lock);
|
||||
mysql_mutex_init(INSTRUMENT_ME, &share->mutex, MY_MUTEX_INIT_FAST);
|
||||
}
|
||||
share->use_count++;
|
||||
mysql_mutex_unlock(&partition_mutex);
|
||||
|
||||
return share;
|
||||
|
||||
error:
|
||||
mysql_mutex_unlock(&partition_mutex);
|
||||
my_free((uchar*) share, MYF(0));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Free lock controls. We call this whenever we close a table. If the table
|
||||
had the last reference to the share then we free memory associated with
|
||||
it.
|
||||
*/
|
||||
|
||||
static int free_share(PARTITION_SHARE *share)
|
||||
{
|
||||
mysql_mutex_lock(&partition_mutex);
|
||||
if (!--share->use_count)
|
||||
{
|
||||
hash_delete(&partition_open_tables, (uchar *) share);
|
||||
thr_lock_delete(&share->lock);
|
||||
mysql_mutex_destroy(&share->mutex);
|
||||
my_free((uchar*) share, MYF(0));
|
||||
}
|
||||
mysql_mutex_unlock(&partition_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NOT_USED */
|
||||
|
||||
struct st_mysql_storage_engine partition_storage_engine=
|
||||
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
|
||||
|
||||
|
|
|
@ -29,31 +29,6 @@ enum partition_keywords
|
|||
PKW_COLUMNS
|
||||
};
|
||||
|
||||
/*
|
||||
PARTITION_SHARE is a structure that will be shared amoung all open handlers
|
||||
The partition implements the minimum of what you will probably need.
|
||||
*/
|
||||
|
||||
#ifdef NOT_USED
|
||||
typedef struct st_partition_share
|
||||
{
|
||||
char *table_name;
|
||||
uint table_name_length, use_count;
|
||||
mysql_mutex_t mutex;
|
||||
THR_LOCK lock;
|
||||
} PARTITION_SHARE;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Partition specific ha_data struct.
|
||||
@todo: move all partition specific data from TABLE_SHARE here.
|
||||
*/
|
||||
typedef struct st_ha_data_partition
|
||||
{
|
||||
ulonglong next_auto_inc_val; /**< first non reserved value */
|
||||
bool auto_inc_initialized;
|
||||
pthread_mutex_t mutex;
|
||||
} HA_DATA_PARTITION;
|
||||
|
||||
#define PARTITION_BYTES_IN_POS 2
|
||||
#define PARTITION_ENABLED_TABLE_FLAGS (HA_FILE_BASED | HA_REC_NOT_IN_SEQ)
|
||||
|
@ -522,7 +497,7 @@ public:
|
|||
-------------------------------------------------------------------------
|
||||
*/
|
||||
virtual int info(uint);
|
||||
void get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
void get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||
uint part_id);
|
||||
virtual int extra(enum ha_extra_function operation);
|
||||
virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
|
||||
|
@ -944,16 +919,16 @@ private:
|
|||
/* lock already taken */
|
||||
if (auto_increment_safe_stmt_log_lock)
|
||||
return;
|
||||
DBUG_ASSERT(table_share->ha_data && !auto_increment_lock);
|
||||
DBUG_ASSERT(table_share->ha_part_data && !auto_increment_lock);
|
||||
if(table_share->tmp_table == NO_TMP_TABLE)
|
||||
{
|
||||
auto_increment_lock= TRUE;
|
||||
mysql_mutex_lock(&table_share->LOCK_ha_data);
|
||||
mysql_mutex_lock(&table_share->ha_part_data->LOCK_auto_inc);
|
||||
}
|
||||
}
|
||||
virtual void unlock_auto_increment()
|
||||
{
|
||||
DBUG_ASSERT(table_share->ha_data);
|
||||
DBUG_ASSERT(table_share->ha_part_data);
|
||||
/*
|
||||
If auto_increment_safe_stmt_log_lock is true, we have to keep the lock.
|
||||
It will be set to false and thus unlocked at the end of the statement by
|
||||
|
@ -961,20 +936,19 @@ private:
|
|||
*/
|
||||
if(auto_increment_lock && !auto_increment_safe_stmt_log_lock)
|
||||
{
|
||||
mysql_mutex_unlock(&table_share->LOCK_ha_data);
|
||||
mysql_mutex_unlock(&table_share->ha_part_data->LOCK_auto_inc);
|
||||
auto_increment_lock= FALSE;
|
||||
}
|
||||
}
|
||||
virtual void set_auto_increment_if_higher(Field *field)
|
||||
{
|
||||
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
|
||||
ulonglong nr= (((Field_num*) field)->unsigned_flag ||
|
||||
field->val_int() > 0) ? field->val_int() : 0;
|
||||
lock_auto_increment();
|
||||
DBUG_ASSERT(ha_data->auto_inc_initialized == TRUE);
|
||||
DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized == TRUE);
|
||||
/* must check when the mutex is taken */
|
||||
if (nr >= ha_data->next_auto_inc_val)
|
||||
ha_data->next_auto_inc_val= nr + 1;
|
||||
if (nr >= table_share->ha_part_data->next_auto_inc_val)
|
||||
table_share->ha_part_data->next_auto_inc_val= nr + 1;
|
||||
unlock_auto_increment();
|
||||
}
|
||||
|
||||
|
|
|
@ -3548,7 +3548,7 @@ int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
|
|||
}
|
||||
|
||||
|
||||
void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||
uint part_id)
|
||||
{
|
||||
info(HA_STATUS_CONST | HA_STATUS_TIME | HA_STATUS_VARIABLE |
|
||||
|
|
|
@ -961,7 +961,7 @@ typedef struct {
|
|||
ulong check_time;
|
||||
ulong update_time;
|
||||
ulonglong check_sum;
|
||||
} PARTITION_INFO;
|
||||
} PARTITION_STATS;
|
||||
|
||||
#define UNDEF_NODEGROUP 65535
|
||||
class Item;
|
||||
|
@ -1560,7 +1560,7 @@ public:
|
|||
{ return (ha_rows) 10; }
|
||||
virtual void position(const uchar *record)=0;
|
||||
virtual int info(uint)=0; // see my_base.h for full description
|
||||
virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
||||
uint part_id);
|
||||
virtual int extra(enum ha_extra_function operation)
|
||||
{ return 0; }
|
||||
|
|
|
@ -7918,8 +7918,9 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
|
|||
key_master_info_data_lock, key_master_info_run_lock,
|
||||
key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
|
||||
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
|
||||
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages,
|
||||
key_LOG_INFO_lock, key_LOCK_thread_count;
|
||||
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
|
||||
key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count,
|
||||
key_PARTITION_LOCK_auto_inc;
|
||||
|
||||
static PSI_mutex_info all_server_mutexes[]=
|
||||
{
|
||||
|
@ -7973,7 +7974,8 @@ static PSI_mutex_info all_server_mutexes[]=
|
|||
{ &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0},
|
||||
{ &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
|
||||
{ &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL}
|
||||
{ &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
|
||||
{ &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0}
|
||||
};
|
||||
|
||||
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
|
||||
|
|
|
@ -240,8 +240,8 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
|
|||
key_master_info_data_lock, key_master_info_run_lock,
|
||||
key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
|
||||
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
|
||||
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages,
|
||||
key_LOCK_thread_count;
|
||||
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
|
||||
key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc;
|
||||
|
||||
extern PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
|
||||
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
|
||||
|
|
|
@ -151,8 +151,6 @@ public:
|
|||
char *part_func_string;
|
||||
char *subpart_func_string;
|
||||
|
||||
const char *part_state;
|
||||
|
||||
partition_element *curr_part_elem;
|
||||
partition_element *current_partition;
|
||||
part_elem_value *curr_list_val;
|
||||
|
@ -173,7 +171,6 @@ public:
|
|||
partition_type subpart_type;
|
||||
|
||||
uint part_info_len;
|
||||
uint part_state_len;
|
||||
uint part_func_len;
|
||||
uint subpart_func_len;
|
||||
|
||||
|
@ -226,13 +223,12 @@ public:
|
|||
list_array(NULL), err_value(0),
|
||||
part_info_string(NULL),
|
||||
part_func_string(NULL), subpart_func_string(NULL),
|
||||
part_state(NULL),
|
||||
curr_part_elem(NULL), current_partition(NULL),
|
||||
curr_list_object(0), num_columns(0),
|
||||
default_engine_type(NULL),
|
||||
part_result_type(INT_RESULT),
|
||||
part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
|
||||
part_info_len(0), part_state_len(0),
|
||||
part_info_len(0),
|
||||
part_func_len(0), subpart_func_len(0),
|
||||
num_parts(0), num_subparts(0),
|
||||
count_curr_subparts(0), part_error_code(0),
|
||||
|
|
|
@ -2943,7 +2943,7 @@ end_with_restore_list:
|
|||
access is granted. We need to check if first_table->grant.privilege
|
||||
contains any table-specific privilege.
|
||||
*/
|
||||
DBUG_PRINT("debug", ("first_table->grant.privilege: %x",
|
||||
DBUG_PRINT("debug", ("first_table->grant.privilege: %lx",
|
||||
first_table->grant.privilege));
|
||||
if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) ||
|
||||
(first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0)
|
||||
|
|
|
@ -4186,7 +4186,6 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index,
|
|||
|
||||
bool mysql_unpack_partition(THD *thd,
|
||||
const char *part_buf, uint part_info_len,
|
||||
const char *part_state, uint part_state_len,
|
||||
TABLE* table, bool is_create_table_ind,
|
||||
handlerton *default_db_type,
|
||||
bool *work_part_info_used)
|
||||
|
@ -4222,8 +4221,6 @@ bool mysql_unpack_partition(THD *thd,
|
|||
goto end;
|
||||
}
|
||||
part_info= lex.part_info;
|
||||
part_info->part_state= part_state;
|
||||
part_info->part_state_len= part_state_len;
|
||||
DBUG_PRINT("info", ("Parse: %s", part_buf));
|
||||
if (parse_sql(thd, & parser_state, NULL) ||
|
||||
part_info->fix_parser_data(thd))
|
||||
|
|
|
@ -64,20 +64,6 @@ typedef struct st_lock_param_type
|
|||
partition_info *part_info;
|
||||
} ALTER_PARTITION_PARAM_TYPE;
|
||||
|
||||
|
||||
/*typedef struct {
|
||||
ulonglong data_file_length;
|
||||
ulonglong max_data_file_length;
|
||||
ulonglong index_file_length;
|
||||
ulonglong delete_length;
|
||||
ha_rows records;
|
||||
ulong mean_rec_length;
|
||||
time_t create_time;
|
||||
time_t check_time;
|
||||
time_t update_time;
|
||||
ulonglong check_sum;
|
||||
} PARTITION_INFO;
|
||||
*/
|
||||
typedef struct {
|
||||
longlong list_value;
|
||||
uint32 partition_id;
|
||||
|
@ -126,7 +112,6 @@ void get_full_part_id_from_key(const TABLE *table, uchar *buf,
|
|||
part_id_range *part_spec);
|
||||
bool mysql_unpack_partition(THD *thd, const char *part_buf,
|
||||
uint part_info_len,
|
||||
const char *part_state, uint part_state_len,
|
||||
TABLE *table, bool is_create_table_ind,
|
||||
handlerton *default_db_type,
|
||||
bool *work_part_info_used);
|
||||
|
|
|
@ -3750,7 +3750,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
|
|||
}
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (share->db_type() == partition_hton &&
|
||||
share->partition_info_len)
|
||||
share->partition_info_str_len)
|
||||
{
|
||||
tmp_db_type= share->default_part_db_type;
|
||||
is_partitioned= TRUE;
|
||||
|
@ -5313,7 +5313,7 @@ static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
|
|||
{
|
||||
TABLE* table= schema_table;
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
PARTITION_INFO stat_info;
|
||||
PARTITION_STATS stat_info;
|
||||
MYSQL_TIME time;
|
||||
file->get_dynamic_partition_info(&stat_info, part_id);
|
||||
table->field[0]->store(STRING_WITH_LEN("def"), cs);
|
||||
|
|
|
@ -1751,11 +1751,12 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
|||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
share->partition_info= tmp_part_syntax_str;
|
||||
share->partition_info_str= tmp_part_syntax_str;
|
||||
}
|
||||
else
|
||||
memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
|
||||
share->partition_info_len= part_info->part_info_len= syntax_len;
|
||||
memcpy((char*) share->partition_info_str, part_syntax_buf,
|
||||
syntax_len + 1);
|
||||
share->partition_info_str_len= part_info->part_info_len= syntax_len;
|
||||
part_info->part_info_string= part_syntax_buf;
|
||||
}
|
||||
#endif
|
||||
|
|
24
sql/table.cc
24
sql/table.cc
|
@ -967,28 +967,28 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
}
|
||||
if (next_chunk + 5 < buff_end)
|
||||
{
|
||||
uint32 partition_info_len = uint4korr(next_chunk);
|
||||
uint32 partition_info_str_len = uint4korr(next_chunk);
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if ((share->partition_info_buffer_size=
|
||||
share->partition_info_len= partition_info_len))
|
||||
share->partition_info_str_len= partition_info_str_len))
|
||||
{
|
||||
if (!(share->partition_info= (char*)
|
||||
if (!(share->partition_info_str= (char*)
|
||||
memdup_root(&share->mem_root, next_chunk + 4,
|
||||
partition_info_len + 1)))
|
||||
partition_info_str_len + 1)))
|
||||
{
|
||||
my_free(buff, MYF(0));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (partition_info_len)
|
||||
if (partition_info_str_len)
|
||||
{
|
||||
DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
|
||||
my_free(buff, MYF(0));
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
next_chunk+= 5 + partition_info_len;
|
||||
next_chunk+= 5 + partition_info_str_len;
|
||||
}
|
||||
#if MYSQL_VERSION_ID < 50200
|
||||
if (share->mysql_version >= 50106 && share->mysql_version <= 50109)
|
||||
|
@ -1651,6 +1651,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
my_hash_free(&share->name_hash);
|
||||
if (share->ha_data_destroy)
|
||||
share->ha_data_destroy(share->ha_data);
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (share->ha_part_data_destroy)
|
||||
share->ha_part_data_destroy(share->ha_part_data);
|
||||
#endif
|
||||
|
||||
open_table_error(share, error, share->open_errno, errarg);
|
||||
DBUG_RETURN(error);
|
||||
|
@ -1842,7 +1846,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (share->partition_info_len && outparam->file)
|
||||
if (share->partition_info_str_len && outparam->file)
|
||||
{
|
||||
/*
|
||||
In this execution we must avoid calling thd->change_item_tree since
|
||||
|
@ -1863,10 +1867,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||
bool tmp;
|
||||
bool work_part_info_used;
|
||||
|
||||
tmp= mysql_unpack_partition(thd, share->partition_info,
|
||||
share->partition_info_len,
|
||||
share->part_state,
|
||||
share->part_state_len,
|
||||
tmp= mysql_unpack_partition(thd, share->partition_info_str,
|
||||
share->partition_info_str_len,
|
||||
outparam, is_create_table,
|
||||
share->default_part_db_type,
|
||||
&work_part_info_used);
|
||||
|
|
29
sql/table.h
29
sql/table.h
|
@ -488,6 +488,19 @@ typedef struct st_table_field_def
|
|||
} TABLE_FIELD_DEF;
|
||||
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/**
|
||||
Partition specific ha_data struct.
|
||||
*/
|
||||
typedef struct st_ha_data_partition
|
||||
{
|
||||
bool auto_inc_initialized;
|
||||
mysql_mutex_t LOCK_auto_inc; /**< protecting auto_inc val */
|
||||
ulonglong next_auto_inc_val; /**< first non reserved value */
|
||||
} HA_DATA_PARTITION;
|
||||
#endif
|
||||
|
||||
|
||||
class Table_check_intact
|
||||
{
|
||||
protected:
|
||||
|
@ -628,13 +641,11 @@ struct TABLE_SHARE
|
|||
int cached_row_logging_check;
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/** @todo: Move into *ha_data for partitioning */
|
||||
/* filled in when reading from frm */
|
||||
bool auto_partitioned;
|
||||
const char *partition_info;
|
||||
uint partition_info_len;
|
||||
const char *partition_info_str;
|
||||
uint partition_info_str_len;
|
||||
uint partition_info_buffer_size;
|
||||
const char *part_state;
|
||||
uint part_state_len;
|
||||
handlerton *default_part_db_type;
|
||||
#endif
|
||||
|
||||
|
@ -654,6 +665,14 @@ struct TABLE_SHARE
|
|||
void *ha_data;
|
||||
void (*ha_data_destroy)(void *); /* An optional destructor for ha_data */
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/** place to store partition specific data, LOCK_ha_data hold while init. */
|
||||
HA_DATA_PARTITION *ha_part_data;
|
||||
/* Destructor for ha_part_data */
|
||||
void (*ha_part_data_destroy)(HA_DATA_PARTITION *);
|
||||
#endif
|
||||
|
||||
|
||||
/** Instrumentation for this table share. */
|
||||
PSI_table_share *m_psi;
|
||||
|
||||
|
|
Loading…
Reference in a new issue