Skip to content

Commit 3ea6ece

Browse files
Thirunarayanandahlerlend
authored andcommitted
Bug#26197113 SLOW DYNAMIC TABLE STATISTICS RETRIVAL FROM I_S AFTER MYSQL-TRUNK-META-SYNC PUSH
Analysis: If the table is not present in the cache then opening the table takes lot of time and it leads to slow performance in information schema queries. Following changes are done to fix the issue, InnoDB changes: - Instead of opening the table, InnoDB can fetch the stats information from innodb_table_stats and innodb_index_stats. - Fetch the record from innodb_table_stats using db_name, table name and it will give information about n_rows, clustered index_size and sum of other index size. - Fetch the space id from Tablespace SE private data for general/system tablespace (or) Fetch the space id using db_name, table_name from fil_space_t hash. - Use the space_id to calculate the available length in the tablespace. - Maximum value of autoincremnt fetched from innodb_dynamic_metadata using table id and autoincrement fetched from table_se_private data. - Cardinality can be fetched from innodb_index_stats table using db_name, table name, index name and column offset. - If the table doesn't have persistent stats then InnoDB loads the table from the disk. Server changes: - Supply mysql.tablespaces.se_private_data to internal functions INTERNAL_*(), which is used by SE to read the SE specific tablespace metadata when fetching table dynamic statistics. E.g., InnoDB would read the SE specific space_id from se_private_data column. - INFORMATION_SCHEMA.TABLES system view is now joined with mysql.tablespaces, to get the mysql.tablespaces.se_private_data for a table. Reviewed-by: Jimmy Yang <[email protected]> Reviewed-by: Bin Su <[email protected]> Reviewed-by: Praveenkumar Hulakund <[email protected]> RB: 16467
1 parent 52bb1fb commit 3ea6ece

File tree

17 files changed

+833
-110
lines changed

17 files changed

+833
-110
lines changed

sql/dd/impl/system_views/tables.cc

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,43 +107,53 @@ Tables_dynamic::Tables_dynamic()
107107
m_target_def.add_field(FIELD_TABLE_ROWS, "TABLE_ROWS",
108108
"INTERNAL_TABLE_ROWS(sch.name, tbl.name,"
109109
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
110-
" tbl.se_private_id)");
110+
" tbl.se_private_id, ts.se_private_data)");
111111
m_target_def.add_field(FIELD_AVG_ROW_LENGTH, "AVG_ROW_LENGTH",
112112
"INTERNAL_AVG_ROW_LENGTH(sch.name, tbl.name,"
113113
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
114-
" tbl.se_private_id)");
114+
" tbl.se_private_id, ts.se_private_data)");
115115
m_target_def.add_field(FIELD_DATA_LENGTH, "DATA_LENGTH",
116116
"INTERNAL_DATA_LENGTH(sch.name, tbl.name,"
117117
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
118-
" tbl.se_private_id)");
118+
" tbl.se_private_id, ts.se_private_data)");
119119
m_target_def.add_field(FIELD_MAX_DATA_LENGTH, "MAX_DATA_LENGTH",
120120
"INTERNAL_MAX_DATA_LENGTH(sch.name, tbl.name,"
121121
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
122-
" tbl.se_private_id)");
122+
" tbl.se_private_id, ts.se_private_data)");
123123
m_target_def.add_field(FIELD_INDEX_LENGTH, "INDEX_LENGTH",
124124
"INTERNAL_INDEX_LENGTH(sch.name, tbl.name,"
125125
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
126-
" tbl.se_private_id)");
126+
" tbl.se_private_id, ts.se_private_data)");
127127
m_target_def.add_field(FIELD_DATA_FREE, "DATA_FREE",
128128
"INTERNAL_DATA_FREE(sch.name, tbl.name,"
129129
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
130-
" tbl.se_private_id)");
130+
" tbl.se_private_id, ts.se_private_data)");
131131
m_target_def.add_field(FIELD_AUTO_INCREMENT, "AUTO_INCREMENT",
132132
"INTERNAL_AUTO_INCREMENT(sch.name, tbl.name,"
133133
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
134-
" tbl.se_private_id)");
134+
" tbl.se_private_id, "
135+
"ts.se_private_data, tbl.se_private_data)");
135136
m_target_def.add_field(FIELD_UPDATE_TIME, "UPDATE_TIME",
136137
"INTERNAL_UPDATE_TIME(sch.name, tbl.name,"
137138
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
138-
" tbl.se_private_id)");
139+
" tbl.se_private_id, ts.se_private_data)");
139140
m_target_def.add_field(FIELD_CHECK_TIME, "CHECK_TIME",
140141
"INTERNAL_CHECK_TIME(sch.name, tbl.name,"
141142
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
142-
" tbl.se_private_id)");
143+
" tbl.se_private_id, ts.se_private_data)");
143144
m_target_def.add_field(FIELD_CHECKSUM, "CHECKSUM",
144145
"INTERNAL_CHECKSUM(sch.name, tbl.name,"
145146
" IF(IFNULL(tbl.partition_type,'')='',tbl.engine,''),"
146-
" tbl.se_private_id)");
147+
" tbl.se_private_id, ts.se_private_data)");
148+
149+
/*
150+
Supply mysql.tablespaces.se_private_data to internal functions
151+
INTERNAL_*(), which is used by SE to read the SE specific tablespace
152+
metadata when fetching table dynamic statistics. E.g., InnoDB would
153+
read the SE specific space_id from se_private_data column.
154+
*/
155+
m_target_def.add_from("LEFT JOIN mysql.tablespaces ts ON "
156+
"tbl.tablespace_id=ts.id");
147157
}
148158

149159
}

sql/dd/info_schema/stats.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ ulonglong Statistics_cache::read_stat(
296296
uint column_ordinal_position,
297297
const String &engine_name_ptr,
298298
Object_id se_private_id,
299+
const char* ts_se_private_data,
300+
const char* tbl_se_private_data,
299301
enum_statistics_type stype)
300302
{
301303
DBUG_ENTER("Statistics_cache::read_stat");
@@ -331,6 +333,8 @@ ulonglong Statistics_cache::read_stat(
331333
index_ordinal_position,
332334
column_ordinal_position,
333335
se_private_id,
336+
ts_se_private_data,
337+
tbl_se_private_data,
334338
stype);
335339
else
336340
result= read_stat_by_open_table(thd,
@@ -375,6 +379,8 @@ ulonglong Statistics_cache::read_stat_from_SE(
375379
uint index_ordinal_position,
376380
uint column_ordinal_position,
377381
Object_id se_private_id,
382+
const char* ts_se_private_data,
383+
const char* tbl_se_private_data,
378384
enum_statistics_type stype)
379385
{
380386
DBUG_ENTER("Statistics_cache::read_stat_from_SE");
@@ -481,6 +487,20 @@ ulonglong Statistics_cache::read_stat_from_SE(
481487
{
482488
error= -1;
483489

490+
/*
491+
It is possible that 'se_private_data' is not supplied to this
492+
function. The function dd::Properties::parse_properties() would
493+
at-least needs a single key-value pair to return a dd::Properties
494+
object. So, when se_private_data is not supplied, we force creation
495+
of dd::Properties object by passing a dummy=0 key-value pair.
496+
*/
497+
std::unique_ptr<dd::Properties> ts_se_private_data_obj(
498+
dd::Properties::parse_properties(
499+
ts_se_private_data?ts_se_private_data:"dummy=0;"));
500+
std::unique_ptr<dd::Properties> tbl_se_private_data_obj(
501+
dd::Properties::parse_properties(
502+
tbl_se_private_data?tbl_se_private_data:"dummy=0;"));
503+
484504
//
485505
// Read statistics from SE
486506
//
@@ -503,6 +523,8 @@ ulonglong Statistics_cache::read_stat_from_SE(
503523
!hton->get_table_statistics(schema_name_ptr.ptr(),
504524
table_name_ptr.ptr(),
505525
se_private_id,
526+
*ts_se_private_data_obj.get(),
527+
*tbl_se_private_data_obj.get(),
506528
se_flags,
507529
&ha_stat))
508530
{

sql/dd/info_schema/stats.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ class Statistics_cache
182182
@param column_ordinal_position - Ordinal position of column in table.
183183
@param engine_name_ptr - Engine of the table.
184184
@param se_private_id - se_private_id of the table.
185+
@param ts_se_private_data - Tablespace SE private data.
186+
@param tbl_se_private_data - Table SE private data.
185187
@param stype - Enum specifying the stat we are
186188
interested to read.
187189
@@ -195,6 +197,8 @@ class Statistics_cache
195197
uint column_ordinal_position,
196198
const String &engine_name_ptr,
197199
dd::Object_id se_private_id,
200+
const char* ts_se_private_data,
201+
const char* tbl_se_private_data,
198202
enum_statistics_type stype);
199203

200204

@@ -204,6 +208,8 @@ class Statistics_cache
204208
const String &table_name_ptr,
205209
const String &engine_name_ptr,
206210
dd::Object_id se_private_id,
211+
const char* ts_se_private_data,
212+
const char* tbl_se_private_data,
207213
enum_statistics_type stype)
208214
{
209215
const String tmp;
@@ -213,6 +219,8 @@ class Statistics_cache
213219
tmp, 0, 0,
214220
engine_name_ptr,
215221
se_private_id,
222+
ts_se_private_data,
223+
tbl_se_private_data,
216224
stype);
217225
}
218226

@@ -243,6 +251,8 @@ class Statistics_cache
243251
@param index_ordinal_position - Ordinal position of index in table.
244252
@param column_ordinal_position - Ordinal position of column in table.
245253
@param se_private_id - se_private_id of the table.
254+
@param ts_se_private_data - Tablespace SE private data.
255+
@param tbl_se_private_data - Table SE private data.
246256
@param stype - Enum specifying the stat we are
247257
interested to read.
248258
@@ -255,6 +265,8 @@ class Statistics_cache
255265
uint index_ordinal_position,
256266
uint column_ordinal_position,
257267
dd::Object_id se_private_id,
268+
const char* ts_se_private_data,
269+
const char* tbl_se_private_data,
258270
enum_statistics_type stype);
259271

260272

sql/handler.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <string>
3232

3333
#include "dd/object_id.h" // dd::Object_id
34+
#include "dd/properties.h" // dd::Properties
3435
#include "discrete_interval.h" // Discrete_interval
3536
#include "ft_global.h" // ft_hints
3637
#include "hash.h"
@@ -1565,17 +1566,22 @@ typedef bool (*rotate_encryption_master_key_t)(void);
15651566
@param db_name Name of schema
15661567
@param table_name Name of table
15671568
@param se_private_id SE private id of the table.
1569+
@param ts_se_private_data Tablespace SE private data.
1570+
@param tbl_se_private_data Table SE private data.
15681571
@param flags Type of statistics to retrieve.
15691572
@param stats (OUT) Contains statistics read from SE.
15701573
15711574
@returns false on success,
15721575
true on failure
15731576
*/
1574-
typedef bool (*get_table_statistics_t)(const char *db_name,
1575-
const char *table_name,
1576-
dd::Object_id se_private_id,
1577-
uint flags,
1578-
ha_statistics *stats);
1577+
typedef bool (*get_table_statistics_t)(
1578+
const char *db_name,
1579+
const char *table_name,
1580+
dd::Object_id se_private_id,
1581+
const dd::Properties &ts_se_private_data,
1582+
const dd::Properties &tbl_se_private_data,
1583+
uint flags,
1584+
ha_statistics *stats);
15791585

15801586
/**
15811587
@brief

sql/item_create.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,16 +1799,16 @@ static const std::pair<const char *, Create_func *> func_array[]=
17991799
{ "CAN_ACCESS_ROUTINE", SQL_FN_LIST_INTERNAL(Item_func_can_access_routine, 5) },
18001800
{ "CAN_ACCESS_EVENT", SQL_FN_INTERNAL(Item_func_can_access_event, 1) },
18011801
{ "IS_VISIBLE_DD_OBJECT", SQL_FN_INTERNAL_V(Item_func_is_visible_dd_object, 1, 2) },
1802-
{ "INTERNAL_TABLE_ROWS", SQL_FN_INTERNAL(Item_func_internal_table_rows, 4) },
1803-
{ "INTERNAL_AVG_ROW_LENGTH", SQL_FN_INTERNAL(Item_func_internal_avg_row_length, 4) },
1804-
{ "INTERNAL_DATA_LENGTH", SQL_FN_INTERNAL(Item_func_internal_data_length, 4) },
1805-
{ "INTERNAL_MAX_DATA_LENGTH", SQL_FN_INTERNAL(Item_func_internal_max_data_length, 4) },
1806-
{ "INTERNAL_INDEX_LENGTH", SQL_FN_INTERNAL(Item_func_internal_index_length, 4) },
1807-
{ "INTERNAL_DATA_FREE", SQL_FN_INTERNAL(Item_func_internal_data_free, 4) },
1808-
{ "INTERNAL_AUTO_INCREMENT", SQL_FN_INTERNAL(Item_func_internal_auto_increment, 4) },
1809-
{ "INTERNAL_CHECKSUM", SQL_FN_INTERNAL(Item_func_internal_checksum, 4) },
1810-
{ "INTERNAL_UPDATE_TIME", SQL_FN_INTERNAL(Item_func_internal_update_time, 4) },
1811-
{ "INTERNAL_CHECK_TIME", SQL_FN_INTERNAL(Item_func_internal_check_time, 4) },
1802+
{ "INTERNAL_TABLE_ROWS", SQL_FN_LIST_INTERNAL(Item_func_internal_table_rows, 5) },
1803+
{ "INTERNAL_AVG_ROW_LENGTH", SQL_FN_LIST_INTERNAL(Item_func_internal_avg_row_length, 5) },
1804+
{ "INTERNAL_DATA_LENGTH", SQL_FN_LIST_INTERNAL(Item_func_internal_data_length, 5) },
1805+
{ "INTERNAL_MAX_DATA_LENGTH", SQL_FN_LIST_INTERNAL(Item_func_internal_max_data_length, 5) },
1806+
{ "INTERNAL_INDEX_LENGTH", SQL_FN_LIST_INTERNAL(Item_func_internal_index_length, 5) },
1807+
{ "INTERNAL_DATA_FREE", SQL_FN_LIST_INTERNAL(Item_func_internal_data_free, 5) },
1808+
{ "INTERNAL_AUTO_INCREMENT", SQL_FN_LIST_INTERNAL(Item_func_internal_auto_increment, 6) },
1809+
{ "INTERNAL_CHECKSUM", SQL_FN_LIST_INTERNAL(Item_func_internal_checksum, 5) },
1810+
{ "INTERNAL_UPDATE_TIME", SQL_FN_LIST_INTERNAL(Item_func_internal_update_time, 5) },
1811+
{ "INTERNAL_CHECK_TIME", SQL_FN_LIST_INTERNAL(Item_func_internal_check_time, 5) },
18121812
{ "INTERNAL_KEYS_DISABLED", SQL_FN_INTERNAL(Item_func_internal_keys_disabled, 1) },
18131813
{ "INTERNAL_INDEX_COLUMN_CARDINALITY", SQL_FN_LIST_INTERNAL(Item_func_internal_index_column_cardinality, 8) },
18141814
{ "INTERNAL_GET_COMMENT_OR_ERROR", SQL_FN_LIST_INTERNAL(Item_func_internal_get_comment_or_error, 5) },

sql/item_func.cc

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9644,9 +9644,16 @@ static ulonglong get_statistics_from_cache(
96449644
String schema_name;
96459645
String table_name;
96469646
String engine_name;
9647+
String ts_se_private_data;
9648+
String tbl_se_private_data;
96479649
String *schema_name_ptr=args[0]->val_str(&schema_name);
96489650
String *table_name_ptr=args[1]->val_str(&table_name);
96499651
String *engine_name_ptr=args[2]->val_str(&engine_name);
9652+
String *ts_se_private_data_ptr= args[4]->val_str(&ts_se_private_data);
9653+
String *tbl_se_private_data_ptr= nullptr;
9654+
if (stype == dd::info_schema::enum_statistics_type::AUTO_INCREMENT)
9655+
tbl_se_private_data_ptr= args[5]->val_str(&tbl_se_private_data);
9656+
96509657
if (schema_name_ptr == nullptr || table_name_ptr == nullptr ||
96519658
engine_name_ptr == nullptr)
96529659
{
@@ -9666,12 +9673,18 @@ static ulonglong get_statistics_from_cache(
96669673
// Read the statistic value from cache.
96679674
THD *thd= current_thd;
96689675
dd::Object_id se_private_id= (dd::Object_id) args[3]->val_uint();
9669-
ulonglong result= thd->lex->m_IS_dyn_stat_cache.read_stat(thd,
9670-
*schema_name_ptr,
9671-
*table_name_ptr,
9672-
*engine_name_ptr,
9673-
se_private_id,
9674-
stype);
9676+
ulonglong result=
9677+
thd->lex->m_IS_dyn_stat_cache.read_stat(thd,
9678+
*schema_name_ptr,
9679+
*table_name_ptr,
9680+
*engine_name_ptr,
9681+
se_private_id,
9682+
(ts_se_private_data_ptr ?
9683+
ts_se_private_data_ptr->c_ptr_safe() : nullptr),
9684+
(tbl_se_private_data_ptr ?
9685+
tbl_se_private_data_ptr->c_ptr_safe() : nullptr),
9686+
stype);
9687+
96759688
DBUG_RETURN(result);
96769689
}
96779690

@@ -9878,6 +9891,8 @@ longlong Item_func_internal_index_column_cardinality::val_int()
98789891
column_ordinal_position - 1,
98799892
*engine_name_ptr,
98809893
se_private_id,
9894+
nullptr,
9895+
nullptr,
98819896
dd::info_schema::enum_statistics_type::INDEX_COLUMN_CARDINALITY);
98829897

98839898
if (result == (ulonglong) -1)

sql/item_func.h

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,9 +2359,9 @@ class Item_func_is_visible_dd_object : public Item_int_func
23592359
class Item_func_internal_table_rows : public Item_int_func
23602360
{
23612361
public:
2362-
Item_func_internal_table_rows(const POS &pos,
2363-
Item *a, Item *b, Item *c, Item *d)
2364-
: Item_int_func(pos, a, b, c, d)
2362+
Item_func_internal_table_rows(
2363+
const POS &pos, PT_item_list *list)
2364+
: Item_int_func(pos, list)
23652365
{}
23662366
longlong val_int() override;
23672367
const char *func_name() const override { return "internal_table_rows"; }
@@ -2376,9 +2376,9 @@ class Item_func_internal_table_rows : public Item_int_func
23762376
class Item_func_internal_avg_row_length : public Item_int_func
23772377
{
23782378
public:
2379-
Item_func_internal_avg_row_length(const POS &pos,
2380-
Item *a, Item *b, Item *c, Item *d)
2381-
: Item_int_func(pos, a, b, c, d)
2379+
Item_func_internal_avg_row_length(
2380+
const POS &pos, PT_item_list *list)
2381+
: Item_int_func(pos, list)
23822382
{}
23832383
longlong val_int() override;
23842384
const char *func_name() const override { return "internal_avg_row_length"; }
@@ -2393,9 +2393,9 @@ class Item_func_internal_avg_row_length : public Item_int_func
23932393
class Item_func_internal_data_length : public Item_int_func
23942394
{
23952395
public:
2396-
Item_func_internal_data_length(const POS &pos,
2397-
Item *a, Item *b, Item *c, Item *d)
2398-
: Item_int_func(pos, a, b, c, d)
2396+
Item_func_internal_data_length(
2397+
const POS &pos, PT_item_list *list)
2398+
: Item_int_func(pos, list)
23992399
{}
24002400
longlong val_int() override;
24012401
const char *func_name() const override { return "internal_data_length"; }
@@ -2410,9 +2410,9 @@ class Item_func_internal_data_length : public Item_int_func
24102410
class Item_func_internal_max_data_length : public Item_int_func
24112411
{
24122412
public:
2413-
Item_func_internal_max_data_length(const POS &pos,
2414-
Item *a, Item *b, Item *c, Item *d)
2415-
: Item_int_func(pos, a, b, c, d)
2413+
Item_func_internal_max_data_length(
2414+
const POS &pos, PT_item_list *list)
2415+
: Item_int_func(pos, list)
24162416
{}
24172417
longlong val_int() override;
24182418
const char *func_name() const override { return "internal_max_data_length"; }
@@ -2427,9 +2427,9 @@ class Item_func_internal_max_data_length : public Item_int_func
24272427
class Item_func_internal_index_length : public Item_int_func
24282428
{
24292429
public:
2430-
Item_func_internal_index_length(const POS &pos,
2431-
Item *a, Item *b, Item *c, Item *d)
2432-
: Item_int_func(pos, a, b, c, d)
2430+
Item_func_internal_index_length(
2431+
const POS &pos, PT_item_list *list)
2432+
: Item_int_func(pos, list)
24332433
{}
24342434
longlong val_int() override;
24352435
const char *func_name() const override { return "internal_index_length"; }
@@ -2444,9 +2444,9 @@ class Item_func_internal_index_length : public Item_int_func
24442444
class Item_func_internal_data_free : public Item_int_func
24452445
{
24462446
public:
2447-
Item_func_internal_data_free(const POS &pos,
2448-
Item *a, Item *b, Item *c, Item *d)
2449-
: Item_int_func(pos, a, b, c, d)
2447+
Item_func_internal_data_free(
2448+
const POS &pos, PT_item_list *list)
2449+
: Item_int_func(pos, list)
24502450
{}
24512451
longlong val_int() override;
24522452
const char *func_name() const override { return "internal_data_free"; }
@@ -2461,9 +2461,9 @@ class Item_func_internal_data_free : public Item_int_func
24612461
class Item_func_internal_auto_increment : public Item_int_func
24622462
{
24632463
public:
2464-
Item_func_internal_auto_increment(const POS &pos,
2465-
Item *a, Item *b, Item *c, Item *d)
2466-
: Item_int_func(pos, a, b, c, d)
2464+
Item_func_internal_auto_increment(
2465+
const POS &pos, PT_item_list *list)
2466+
: Item_int_func(pos, list)
24672467
{}
24682468
longlong val_int() override;
24692469
const char *func_name() const override { return "internal_auto_increment"; }
@@ -2478,9 +2478,9 @@ class Item_func_internal_auto_increment : public Item_int_func
24782478
class Item_func_internal_checksum : public Item_int_func
24792479
{
24802480
public:
2481-
Item_func_internal_checksum(const POS &pos,
2482-
Item *a, Item *b, Item *c, Item *d)
2483-
: Item_int_func(pos, a, b, c, d)
2481+
Item_func_internal_checksum(
2482+
const POS &pos, PT_item_list *list)
2483+
: Item_int_func(pos, list)
24842484
{}
24852485
longlong val_int() override;
24862486
const char *func_name() const override { return "internal_checksum"; }

0 commit comments

Comments
 (0)