Skip to content

Commit 0503c5d

Browse files
author
Mattias Jonsson
committed
WL#4443:
Replaced check for partitioned handler with HA_OPEN_NO_PSI_CALL, to avoid using psi for partitions. Changed using read_partitions to lock_partitions for pruning of start_stmt. Now sets m_partitions_to_reset also in ::extra() calls. Use is_query_tables_locked() in prune_partitions() instead of checking get_lock_type().
1 parent 9a306ec commit 0503c5d

4 files changed

Lines changed: 42 additions & 43 deletions

File tree

include/my_base.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
#define HA_OPEN_COPY 256 /* Open copy (for repair) */
4949
/* Internal temp table, used for temporary results */
5050
#define HA_OPEN_INTERNAL_TABLE 512
51+
/**
52+
Don't connect any share_psi to the handler, since it is a partition.
53+
It would not be used, since partitions don't call unbind_psi()/rebind_psi().
54+
*/
55+
#define HA_OPEN_NO_PSI_CALL 1024 /* Don't call/connect PSI */
5156

5257
/* The following is parameter to ha_rkey() how to use key */
5358

sql/ha_partition.cc

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,8 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
14641464
goto error_create;
14651465
}
14661466
DBUG_PRINT("info", ("partition %s created", part_name));
1467-
if ((error= file->ha_open(tbl, part_name, m_mode, m_open_test_lock)))
1467+
if ((error= file->ha_open(tbl, part_name, m_mode,
1468+
m_open_test_lock | HA_OPEN_NO_PSI_CALL)))
14681469
goto error_open;
14691470
DBUG_PRINT("info", ("partition %s opened", part_name));
14701471
/*
@@ -3115,7 +3116,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
31153116
{
31163117
create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
31173118
FALSE);
3118-
if ((error= (*file)->ha_open(table, name_buff, mode, test_if_locked)))
3119+
if ((error= (*file)->ha_open(table, name_buff, mode,
3120+
test_if_locked | HA_OPEN_NO_PSI_CALL)))
31193121
goto err_handler;
31203122
if (m_file == file)
31213123
m_num_locks= (*file)->lock_count();
@@ -3274,7 +3276,8 @@ handler *ha_partition::clone(const char *name, MEM_ROOT *mem_root)
32743276
goto err;
32753277

32763278
if (new_handler->ha_open(table, name,
3277-
table->db_stat, HA_OPEN_IGNORE_IF_LOCKED))
3279+
table->db_stat,
3280+
HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_NO_PSI_CALL))
32783281
goto err;
32793282

32803283
DBUG_RETURN((handler*) new_handler);
@@ -3384,14 +3387,8 @@ int ha_partition::external_lock(THD *thd, int lock_type)
33843387
if (lock_type == F_UNLCK)
33853388
used_partitions= &m_locked_partitions;
33863389
else
3387-
{
3388-
/*
3389-
Only clear this when a new lock is taken or start_stmt is called,
3390-
leave it as is after unlocking to be able to prune ::reset() calls.
3391-
*/
3392-
DBUG_ASSERT(bitmap_is_clear_all(&m_partitions_to_reset));
33933390
used_partitions= &(m_part_info->lock_partitions);
3394-
}
3391+
33953392
first_used_partition= bitmap_get_first_set(used_partitions);
33963393

33973394
for (i= first_used_partition;
@@ -3414,7 +3411,8 @@ int ha_partition::external_lock(THD *thd, int lock_type)
34143411
}
34153412
else
34163413
{
3417-
bitmap_copy(&m_partitions_to_reset, used_partitions);
3414+
/* Add touched partitions to be included in reset(). */
3415+
bitmap_union(&m_partitions_to_reset, used_partitions);
34183416
}
34193417

34203418
if (m_added_file && m_added_file[0])
@@ -3437,7 +3435,6 @@ int ha_partition::external_lock(THD *thd, int lock_type)
34373435
(void) m_file[j]->ha_external_lock(thd, F_UNLCK);
34383436
}
34393437
bitmap_clear_all(&m_locked_partitions);
3440-
bitmap_clear_all(&m_partitions_to_reset);
34413438
DBUG_RETURN(error);
34423439
}
34433440

@@ -3538,14 +3535,13 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
35383535
&m_locked_partitions));
35393536
DBUG_ENTER("ha_partition::start_stmt");
35403537

3541-
/* Needed to clear all bits from the LOCK TABLES statement. */
3542-
bitmap_clear_all(&m_partitions_to_reset);
3543-
for (i= bitmap_get_first_set(&(m_part_info->read_partitions));
3538+
for (i= bitmap_get_first_set(&(m_part_info->lock_partitions));
35443539
i < m_tot_parts;
3545-
i= bitmap_get_next_set(&m_part_info->read_partitions, i))
3540+
i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
35463541
{
35473542
if ((error= m_file[i]->start_stmt(thd, lock_type)))
35483543
break;
3544+
/* Add partition to be called in reset(). */
35493545
bitmap_set_bit(&m_partitions_to_reset, i);
35503546
}
35513547
DBUG_RETURN(error);
@@ -6523,40 +6519,34 @@ int ha_partition::extra(enum ha_extra_function operation)
65236519
}
65246520

65256521

6526-
/*
6522+
/**
65276523
Special extra call to reset extra parameters
65286524
6529-
SYNOPSIS
6530-
reset()
6531-
6532-
RETURN VALUE
6533-
>0 Error code
6534-
0 Success
6525+
@return Operation status.
6526+
@retval >0 Error code
6527+
@retval 0 Success
65356528
6536-
DESCRIPTION
6537-
Called at end of each statement to reset buffers
6529+
@note Called at end of each statement to reset buffers.
6530+
To avoid excessive calls, the m_partitions_to_reset bitmap keep records
6531+
of which partitions that have been used in external_lock() or start_stmt()
6532+
and is needed to be called.
65386533
*/
65396534

65406535
int ha_partition::reset(void)
65416536
{
65426537
int result= 0;
6538+
int tmp;
6539+
uint i;
65436540
DBUG_ENTER("ha_partition::reset");
65446541

6545-
/* May not have m_part_info set (in case of failed open or prune). */
6546-
if (m_part_info && m_part_info->bitmaps_are_initialized)
6542+
for (i= bitmap_get_first_set(&m_partitions_to_reset);
6543+
i < m_tot_parts;
6544+
i= bitmap_get_next_set(&m_partitions_to_reset, i))
65476545
{
6548-
int tmp;
6549-
uint i;
6550-
6551-
for (i= bitmap_get_first_set(&m_partitions_to_reset);
6552-
i < m_tot_parts;
6553-
i= bitmap_get_next_set(&m_partitions_to_reset, i))
6554-
{
6555-
if ((tmp= m_file[i]->ha_reset()))
6556-
result= tmp;
6557-
}
6558-
bitmap_clear_all(&m_partitions_to_reset);
6546+
if ((tmp= m_file[i]->ha_reset()))
6547+
result= tmp;
65596548
}
6549+
bitmap_clear_all(&m_partitions_to_reset);
65606550
DBUG_RETURN(result);
65616551
}
65626552

@@ -6603,6 +6593,9 @@ void ha_partition::prepare_extra_cache(uint cachesize)
66036593
m_extra_cache_size= cachesize;
66046594
if (m_part_spec.start_part != NO_CURRENT_PART_ID)
66056595
{
6596+
DBUG_ASSERT(bitmap_is_set(&m_partitions_to_reset,
6597+
m_part_spec.start_part));
6598+
bitmap_set_bit(&m_partitions_to_reset, m_part_spec.start_part);
66066599
late_extra_cache(m_part_spec.start_part);
66076600
}
66086601
DBUG_VOID_RETURN;
@@ -6669,6 +6662,8 @@ int ha_partition::loop_extra(enum ha_extra_function operation)
66696662
if ((tmp= m_file[i]->extra(operation)))
66706663
result= tmp;
66716664
}
6665+
/* Add all used partitions to be called in reset(). */
6666+
bitmap_union(&m_partitions_to_reset, &m_part_info->lock_partitions);
66726667
DBUG_RETURN(result);
66736668
}
66746669

sql/handler.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,11 +2359,9 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
23592359
/*
23602360
Do not call this for partitions handlers, since it may take too much
23612361
resources.
2362-
If a table is partitioned it's main handler will be ha_partition and
2363-
its partitions handlers will be the normal handlers, like ha_innobase.
23642362
So only use the m_psi on table level, not for individual partitions.
23652363
*/
2366-
if (ht == table->file->ht)
2364+
if (test_if_locked & HA_OPEN_NO_PSI_CALL)
23672365
{
23682366
PSI_table_share *share_psi= ha_table_share_psi(table_share);
23692367
m_psi= PSI_TABLE_CALL(open_table)(share_psi, this);

sql/opt_range.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,12 +3237,13 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
32373237
&prune_param.part_info->lock_partitions);
32383238
/*
32393239
If not yet locked, also prune partitions to lock if not UPDATEing
3240-
partition key fields.
3240+
partition key fields. This will also prune lock_partitions if we are under
3241+
LOCK TABLES, so prune away calls to start_stmt().
32413242
TODO: enhance this prune locking to also allow pruning of
32423243
'UPDATE t SET part_key = const WHERE cond_is_prunable' so it adds
32433244
a lock for part_key partition.
32443245
*/
3245-
if (table->file->get_lock_type() == F_UNLCK &&
3246+
if (!thd->lex->is_query_tables_locked() &&
32463247
!partition_key_modified(table, table->write_set))
32473248
{
32483249
bitmap_copy(&prune_param.part_info->lock_partitions,

0 commit comments

Comments
 (0)