summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc97
1 files changed, 78 insertions, 19 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 305f83a25e5..b28e270a61c 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -232,6 +232,8 @@ void ha_partition::init_handler_variables()
m_innodb= FALSE;
m_extra_cache= FALSE;
m_extra_cache_size= 0;
+ m_extra_prepare_for_update= FALSE;
+ m_extra_cache_part_id= NO_CURRENT_PART_ID;
m_handler_status= handler_not_initialized;
m_low_byte_first= 1;
m_part_field_array= NULL;
@@ -2449,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
@@ -2605,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);
@@ -5380,9 +5399,6 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
when performing the sequential scan we will check this recorded value
and call extra_opt whenever we start scanning a new partition.
- monty: Neads to be fixed so that it's passed to all handlers when we
- move to another partition during table scan.
-
HA_EXTRA_NO_CACHE:
When performing a UNION SELECT HA_EXTRA_NO_CACHE is called from the
flush method in the select_union class.
@@ -5394,7 +5410,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
for. If no cache is in use they will quickly return after finding
this out. And we also ensure that all caches are disabled and no one
is left by mistake.
- In the future this call will probably be deleted an we will instead call
+ In the future this call will probably be deleted and we will instead call
::reset();
HA_EXTRA_WRITE_CACHE:
@@ -5406,8 +5422,9 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
This is called as part of a multi-table update. When the table to be
updated is also scanned then this informs MyISAM handler to drop any
caches if dynamic records are used (fixed size records do not care
- about this call). We pass this along to all underlying MyISAM handlers
- and ignore it for the rest.
+ about this call). We pass this along to the first partition to scan, and
+ flag that it is to be called after HA_EXTRA_CACHE when moving to the next
+ partition to scan.
HA_EXTRA_PREPARE_FOR_DROP:
Only used by MyISAM, called in preparation for a DROP TABLE.
@@ -5554,9 +5571,23 @@ int ha_partition::extra(enum ha_extra_function operation)
/* Category 3), used by MyISAM handlers */
case HA_EXTRA_PREPARE_FOR_RENAME:
DBUG_RETURN(prepare_for_rename());
+ break;
+ case HA_EXTRA_PREPARE_FOR_UPDATE:
+ /*
+ Needs to be run on the first partition in the range now, and
+ later in late_extra_cache, when switching to a new partition to scan.
+ */
+ m_extra_prepare_for_update= TRUE;
+ if (m_part_spec.start_part != NO_CURRENT_PART_ID)
+ {
+ if (!m_extra_cache)
+ m_extra_cache_part_id= m_part_spec.start_part;
+ DBUG_ASSERT(m_extra_cache_part_id == m_part_spec.start_part);
+ VOID(m_file[m_part_spec.start_part]->extra(HA_EXTRA_PREPARE_FOR_UPDATE));
+ }
+ break;
case HA_EXTRA_NORMAL:
case HA_EXTRA_QUICK:
- case HA_EXTRA_PREPARE_FOR_UPDATE:
case HA_EXTRA_FORCE_REOPEN:
case HA_EXTRA_PREPARE_FOR_DROP:
case HA_EXTRA_FLUSH_CACHE:
@@ -5577,10 +5608,22 @@ int ha_partition::extra(enum ha_extra_function operation)
break;
}
case HA_EXTRA_NO_CACHE:
+ {
+ int ret= 0;
+ if (m_extra_cache_part_id != NO_CURRENT_PART_ID)
+ ret= m_file[m_extra_cache_part_id]->extra(HA_EXTRA_NO_CACHE);
+ m_extra_cache= FALSE;
+ m_extra_cache_size= 0;
+ m_extra_prepare_for_update= FALSE;
+ m_extra_cache_part_id= NO_CURRENT_PART_ID;
+ DBUG_RETURN(ret);
+ }
case HA_EXTRA_WRITE_CACHE:
{
m_extra_cache= FALSE;
m_extra_cache_size= 0;
+ m_extra_prepare_for_update= FALSE;
+ m_extra_cache_part_id= NO_CURRENT_PART_ID;
DBUG_RETURN(loop_extra(operation));
}
case HA_EXTRA_IGNORE_NO_KEY:
@@ -5708,6 +5751,7 @@ int ha_partition::extra_opt(enum ha_extra_function operation, ulong cachesize)
void ha_partition::prepare_extra_cache(uint cachesize)
{
DBUG_ENTER("ha_partition::prepare_extra_cache()");
+ DBUG_PRINT("info", ("cachesize %u", cachesize));
m_extra_cache= TRUE;
m_extra_cache_size= cachesize;
@@ -5766,16 +5810,18 @@ int ha_partition::loop_extra(enum ha_extra_function operation)
{
int result= 0, tmp;
handler **file;
+ bool is_select;
DBUG_ENTER("ha_partition::loop_extra()");
- /*
- TODO, 5.2: this is where you could possibly add optimisations to add the
- bitmap _if_ a SELECT.
- */
+ is_select= (thd_sql_command(ha_thd()) == SQLCOM_SELECT);
for (file= m_file; *file; file++)
{
- if ((tmp= (*file)->extra(operation)))
- result= tmp;
+ if (!is_select ||
+ bitmap_is_set(&(m_part_info->used_partitions), file - m_file))
+ {
+ if ((tmp= (*file)->extra(operation)))
+ result= tmp;
+ }
}
DBUG_RETURN(result);
}
@@ -5796,14 +5842,25 @@ void ha_partition::late_extra_cache(uint partition_id)
{
handler *file;
DBUG_ENTER("ha_partition::late_extra_cache");
+ DBUG_PRINT("info", ("extra_cache %u prepare %u partid %u size %u",
+ m_extra_cache, m_extra_prepare_for_update,
+ partition_id, m_extra_cache_size));
- if (!m_extra_cache)
+ if (!m_extra_cache && !m_extra_prepare_for_update)
DBUG_VOID_RETURN;
file= m_file[partition_id];
- if (m_extra_cache_size == 0)
- VOID(file->extra(HA_EXTRA_CACHE));
- else
- VOID(file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size));
+ if (m_extra_cache)
+ {
+ if (m_extra_cache_size == 0)
+ VOID(file->extra(HA_EXTRA_CACHE));
+ else
+ VOID(file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size));
+ }
+ if (m_extra_prepare_for_update)
+ {
+ VOID(file->extra(HA_EXTRA_PREPARE_FOR_UPDATE));
+ }
+ m_extra_cache_part_id= partition_id;
DBUG_VOID_RETURN;
}
@@ -5824,10 +5881,12 @@ void ha_partition::late_extra_no_cache(uint partition_id)
handler *file;
DBUG_ENTER("ha_partition::late_extra_no_cache");
- if (!m_extra_cache)
+ if (!m_extra_cache && !m_extra_prepare_for_update)
DBUG_VOID_RETURN;
file= m_file[partition_id];
VOID(file->extra(HA_EXTRA_NO_CACHE));
+ DBUG_ASSERT(partition_id == m_extra_cache_part_id);
+ m_extra_cache_part_id= NO_CURRENT_PART_ID;
DBUG_VOID_RETURN;
}