mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#13025132 - PARTITIONS USE TOO MUCH MEMORY
Additional patch to remove the part_id -> ref_buffer offset. The partitioning id and the associate record buffer can be found without having to calculate it. By initializing it for each used partition, and then reuse the key-buffer from the queue, it is not needed to have such map.
This commit is contained in:
@ -4055,13 +4055,9 @@ bool ha_partition::init_record_priority_queue()
|
|||||||
if (!m_ordered_rec_buffer)
|
if (!m_ordered_rec_buffer)
|
||||||
{
|
{
|
||||||
uint map_len, alloc_len;
|
uint map_len, alloc_len;
|
||||||
uint used_parts= 0;
|
uint used_parts= bitmap_bits_set(&m_part_info->used_partitions);
|
||||||
/* Allocate an array for mapping used partitions to their record buffer. */
|
|
||||||
map_len= m_tot_parts * PARTITION_BYTES_IN_POS;
|
|
||||||
alloc_len= map_len;
|
|
||||||
/* Allocate record buffer for each used partition. */
|
/* Allocate record buffer for each used partition. */
|
||||||
alloc_len+= bitmap_bits_set(&m_part_info->used_partitions) *
|
alloc_len= used_parts * (m_rec_length + PARTITION_BYTES_IN_POS);
|
||||||
(m_rec_length + PARTITION_BYTES_IN_POS);
|
|
||||||
/* Allocate a key for temporary use when setting up the scan. */
|
/* Allocate a key for temporary use when setting up the scan. */
|
||||||
alloc_len+= table_share->max_key_length;
|
alloc_len+= table_share->max_key_length;
|
||||||
|
|
||||||
@ -4074,18 +4070,13 @@ bool ha_partition::init_record_priority_queue()
|
|||||||
index_read.
|
index_read.
|
||||||
We also set-up a reference to the first record for temporary use in
|
We also set-up a reference to the first record for temporary use in
|
||||||
setting up the scan.
|
setting up the scan.
|
||||||
No need to initialize the full map, it should only be used partitions
|
|
||||||
that will be read, so it is better to not set them to find possible
|
|
||||||
bugs through valgrind.
|
|
||||||
*/
|
*/
|
||||||
uint16 *map= (uint16*) m_ordered_rec_buffer;
|
char *ptr= (char*) m_ordered_rec_buffer;
|
||||||
char *ptr= (char*) m_ordered_rec_buffer + map_len;
|
|
||||||
uint16 i= 0;
|
uint16 i= 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (bitmap_is_set(&m_part_info->used_partitions, i))
|
if (bitmap_is_set(&m_part_info->used_partitions, i))
|
||||||
{
|
{
|
||||||
map[i]= used_parts++;
|
|
||||||
int2store(ptr, i);
|
int2store(ptr, i);
|
||||||
ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
|
ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
|
||||||
}
|
}
|
||||||
@ -4984,6 +4975,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
|
|||||||
uint i;
|
uint i;
|
||||||
uint j= 0;
|
uint j= 0;
|
||||||
bool found= FALSE;
|
bool found= FALSE;
|
||||||
|
uchar *part_rec_buf_ptr= m_ordered_rec_buffer;
|
||||||
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
|
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
|
||||||
|
|
||||||
m_top_entry= NO_CURRENT_PART_ID;
|
m_top_entry= NO_CURRENT_PART_ID;
|
||||||
@ -4994,7 +4986,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
|
|||||||
{
|
{
|
||||||
if (!(bitmap_is_set(&(m_part_info->used_partitions), i)))
|
if (!(bitmap_is_set(&(m_part_info->used_partitions), i)))
|
||||||
continue;
|
continue;
|
||||||
uchar *rec_buf_ptr= rec_buf(i);
|
uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS;
|
||||||
int error;
|
int error;
|
||||||
handler *file= m_file[i];
|
handler *file= m_file[i];
|
||||||
|
|
||||||
@ -5041,12 +5033,13 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
|
|||||||
/*
|
/*
|
||||||
Initialize queue without order first, simply insert
|
Initialize queue without order first, simply insert
|
||||||
*/
|
*/
|
||||||
queue_element(&m_queue, j++)= (uchar*)queue_buf(i);
|
queue_element(&m_queue, j++)= part_rec_buf_ptr;
|
||||||
}
|
}
|
||||||
else if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
else if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
||||||
{
|
{
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
@ -5109,18 +5102,19 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint part_id= m_top_entry;
|
uint part_id= m_top_entry;
|
||||||
|
uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS;
|
||||||
handler *file= m_file[part_id];
|
handler *file= m_file[part_id];
|
||||||
DBUG_ENTER("ha_partition::handle_ordered_next");
|
DBUG_ENTER("ha_partition::handle_ordered_next");
|
||||||
|
|
||||||
if (m_index_scan_type == partition_read_range)
|
if (m_index_scan_type == partition_read_range)
|
||||||
{
|
{
|
||||||
error= file->read_range_next();
|
error= file->read_range_next();
|
||||||
memcpy(rec_buf(part_id), table->record[0], m_rec_length);
|
memcpy(rec_buf, table->record[0], m_rec_length);
|
||||||
}
|
}
|
||||||
else if (!is_next_same)
|
else if (!is_next_same)
|
||||||
error= file->index_next(rec_buf(part_id));
|
error= file->index_next(rec_buf);
|
||||||
else
|
else
|
||||||
error= file->index_next_same(rec_buf(part_id), m_start_key.key,
|
error= file->index_next_same(rec_buf, m_start_key.key,
|
||||||
m_start_key.length);
|
m_start_key.length);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@ -5163,10 +5157,11 @@ int ha_partition::handle_ordered_prev(uchar *buf)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint part_id= m_top_entry;
|
uint part_id= m_top_entry;
|
||||||
|
uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS;
|
||||||
handler *file= m_file[part_id];
|
handler *file= m_file[part_id];
|
||||||
DBUG_ENTER("ha_partition::handle_ordered_prev");
|
DBUG_ENTER("ha_partition::handle_ordered_prev");
|
||||||
|
|
||||||
if ((error= file->index_prev(rec_buf(part_id))))
|
if ((error= file->index_prev(rec_buf)))
|
||||||
{
|
{
|
||||||
if (error == HA_ERR_END_OF_FILE)
|
if (error == HA_ERR_END_OF_FILE)
|
||||||
{
|
{
|
||||||
|
@ -524,23 +524,6 @@ private:
|
|||||||
int partition_scan_set_up(uchar * buf, bool idx_read_flag);
|
int partition_scan_set_up(uchar * buf, bool idx_read_flag);
|
||||||
int handle_unordered_next(uchar * buf, bool next_same);
|
int handle_unordered_next(uchar * buf, bool next_same);
|
||||||
int handle_unordered_scan_next_partition(uchar * buf);
|
int handle_unordered_scan_next_partition(uchar * buf);
|
||||||
uchar *queue_buf(uint part_id)
|
|
||||||
{
|
|
||||||
uint16 *part_id_map= (uint16*) m_ordered_rec_buffer;
|
|
||||||
/* Offset to the partition's record buffer in number of partitions. */
|
|
||||||
uint offset= part_id_map[part_id];
|
|
||||||
/*
|
|
||||||
Return the pointer to the partition's record buffer.
|
|
||||||
First skip the partition id map, and then add the offset.
|
|
||||||
*/
|
|
||||||
return (m_ordered_rec_buffer + m_tot_parts * PARTITION_BYTES_IN_POS +
|
|
||||||
(offset * (m_rec_length + PARTITION_BYTES_IN_POS)));
|
|
||||||
}
|
|
||||||
uchar *rec_buf(uint part_id)
|
|
||||||
{
|
|
||||||
return (queue_buf(part_id) +
|
|
||||||
PARTITION_BYTES_IN_POS);
|
|
||||||
}
|
|
||||||
int handle_ordered_index_scan(uchar * buf, bool reverse_order);
|
int handle_ordered_index_scan(uchar * buf, bool reverse_order);
|
||||||
int handle_ordered_next(uchar * buf, bool next_same);
|
int handle_ordered_next(uchar * buf, bool next_same);
|
||||||
int handle_ordered_prev(uchar * buf);
|
int handle_ordered_prev(uchar * buf);
|
||||||
|
Reference in New Issue
Block a user