MySQL  8.0.20
Source Code Documentation
table_stats.h
Go to the documentation of this file.
1 /* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef DD_INFO_SCHEMA_TABLE_STATS_INCLUDED
24 #define DD_INFO_SCHEMA_TABLE_STATS_INCLUDED
25 
26 #include <sys/types.h>
27 #include <string>
28 
29 #include "sql/dd/object_id.h" // Object_id
30 #include "sql/dd/string_type.h" // dd::String_type
31 #include "sql/handler.h" // ha_statistics
32 #include "sql_string.h" // String
33 
34 class THD;
35 struct TABLE_LIST;
36 
37 namespace dd {
38 namespace info_schema {
39 
40 /**
41  Get dynamic table statistics of a table and store them into
42  mysql.table_stats.
43 
44  @param thd Thread.
45  @param table TABLE_LIST pointing to table info.
46 
47  @returns false on success.
48  true on failure.
49 */
50 bool update_table_stats(THD *thd, TABLE_LIST *table);
51 
52 /**
53  Get dynamic index statistics of a table and store them into
54  mysql.index_stats.
55 
56  @param thd Thread.
57  @param table TABLE_LIST pointing to table info.
58 
59  @returns false on success.
60  true on failure.
61 */
62 bool update_index_stats(THD *thd, TABLE_LIST *table);
63 
64 /**
65  If the db is 'information_schema' then convert 'db' to
66  lowercase and 'table_name' to upper case. Mainly because all
67  information schema tables are stored in upper case in server.
68 
69  @param db Database name
70  @param table_name Table name.
71 
72  @returns true if the conversion was done.
73  false if not.
74 */
75 bool convert_table_name_case(char *db, char *table_name);
76 
77 // Statistics that are cached.
79  TABLE_ROWS,
84  DATA_FREE,
86  CHECKSUM,
88  CHECK_TIME,
90 };
91 
92 /**
93  The class hold dynamic table statistics for a table.
94  This cache is used by internal UDF's defined for the purpose
95  of INFORMATION_SCHEMA queries which retrieve dynamic table
96  statistics. The class caches statistics for just one table.
97 
98  Overall aim of introducing this cache is to avoid making
99  multiple calls to same SE API to retrieve the statistics.
100 */
101 
103  public:
104  Table_statistics() : m_checksum(0), m_read_stats_by_open(false) {}
105 
106  /**
107  Check if the stats are cached for given db.table_name.
108 
109  @param db_name - Schema name.
110  @param table_name - Table name.
111  @param partition_name - Partition name.
112 
113  @return true if stats are cached, else false.
114  */
116  const char *partition_name) {
117  return (m_key == form_key(db_name, table_name, partition_name));
118  }
119 
121  return is_stat_cached_in_mem(db_name, table_name, nullptr);
122  }
123 
124  /**
125  Store the statistics form the given handler
126 
127  @param db_name - Schema name.
128  @param table_name - Table name.
129  @param partition_name - Partition name.
130  @param file - Handler object for the table.
131  */
133  const char *partition_name, handler *file) {
134  m_stats = file->stats;
135  m_checksum = file->checksum();
136  m_error.clear();
137  set_stat_cached(db_name, table_name, partition_name);
138  }
139 
141  handler *file) {
142  cache_stats_in_mem(db_name, table_name, nullptr, file);
143  }
144 
145  /**
146  Store the statistics
147 
148  @param db_name - Schema name.
149  @param table_name - Table name.
150  @param partition_name - Partition name.
151  @param stats - ha_statistics of the table.
152  */
154  const char *partition_name, ha_statistics &stats) {
155  m_stats = stats;
156  m_checksum = 0;
157  m_error.clear();
158  set_stat_cached(db_name, table_name, partition_name);
159  }
160 
162  ha_statistics &stats) {
163  cache_stats_in_mem(db_name, table_name, nullptr, stats);
164  }
165 
166  /**
167  @brief
168  Read dynamic table/index statistics from SE by opening the user table
169  provided OR by reading cached statistics from SELECT_LEX.
170 
171  @param thd - Current thread.
172  @param schema_name_ptr - Schema name of table.
173  @param table_name_ptr - Table name of which we need stats.
174  @param index_name_ptr - Index name of which we need stats.
175  @param partition_name - Partition name.
176  @param column_name_ptr - Column name for index.
177  @param index_ordinal_position - Ordinal position of index in table.
178  @param column_ordinal_position - Ordinal position of column in table.
179  @param engine_name_ptr - Engine of the table.
180  @param se_private_id - se_private_id of the table.
181  @param ts_se_private_data - Tablespace SE private data.
182  @param tbl_se_private_data - Table SE private data.
183  @param table_stat_data - Cached data from mysql.table_stats /
184  mysql.index_stats table
185  @param cached_time - Timestamp value when data was cached.
186  @param stype - Enum specifying the stat we are
187  interested to read.
188 
189  @return ulonglong representing value for the status being read.
190  */
191  ulonglong read_stat(
192  THD *thd, const String &schema_name_ptr, const String &table_name_ptr,
193  const String &index_name_ptr, const char *partition_name,
194  const String &column_name_ptr, uint index_ordinal_position,
195  uint column_ordinal_position, const String &engine_name_ptr,
196  dd::Object_id se_private_id, const char *ts_se_private_data,
197  const char *tbl_se_private_data, const ulonglong &table_stat_data,
198  const ulonglong &cached_time, enum_table_stats_type stype);
199 
200  // Fetch table stats. Invokes the above method.
202  THD *thd, const String &schema_name_ptr, const String &table_name_ptr,
203  const String &engine_name_ptr, const char *partition_name,
204  dd::Object_id se_private_id, const char *ts_se_private_data,
205  const char *tbl_se_private_data, const ulonglong &table_stat_data,
206  const ulonglong &cached_time, enum_table_stats_type stype) {
207  const String tmp;
208  return read_stat(thd, schema_name_ptr, table_name_ptr, tmp, partition_name,
209  tmp, 0, 0, engine_name_ptr, se_private_id,
210  ts_se_private_data, tbl_se_private_data, table_stat_data,
211  cached_time, stype);
212  }
213 
214  // Invalidate the cache.
215  void invalidate_cache(void) {
216  m_key.clear();
217  m_error.clear();
218  }
219 
220  // Get error string. Its empty if a error is not reported.
221  inline String_type error() { return m_error; }
222 
223  /**
224  Set error string for the given key. The combination of (db, table and
225  partition name) forms the key.
226 
227  @param db_name - Schema name.
228  @param table_name - Table name.
229  @param partition_name - Partition name.
230  @param error_msg - Error message.
231 
232  @note We store the error message so that the error message is shown in
233  I_S.TABLES.COMMENT field. Apart from storing the error message, the
234  below function resets the statistics, this will make sure,
235 
236  1. We do not invoke open_tables_for_query() again for other
237  dynamic columns that are fetch from the current row being
238  processed.
239 
240  2. We will not see junk values for statistics in results.
241  */
243  const char *partition_name,
244  const String_type &error_msg) {
245  m_stats = {};
246  m_checksum = 0;
247  m_error = error_msg;
248  m_key = form_key(db_name, table_name, partition_name);
249  }
250 
251  /**
252  Check if we have seen a error.
253 
254  @param db_name Database name.
255  @param table_name Table name.
256 
257  @returns true if there is error reported.
258  false if not.
259  */
260  inline bool check_error_for_key(const String &db_name,
261  const String &table_name) {
262  if (is_stat_cached_in_mem(db_name, table_name) && !m_error.empty())
263  return true;
264 
265  return false;
266  }
267 
268  /// Check if open table in progress.
269  bool is_reading_stats_by_open() const { return m_read_stats_by_open; }
270 
271  private:
272  /**
273  Read dynamic table/index statistics from SE API's OR by reading
274  cached statistics from SELECT_LEX.
275 
276  @param thd - Current thread.
277  @param schema_name_ptr - Schema name of table.
278  @param table_name_ptr - Table name of which we need stats.
279  @param index_name_ptr - Index name of which we need stats.
280  @param column_name_ptr - Column name for index.
281  @param index_ordinal_position - Ordinal position of index in table.
282  @param column_ordinal_position - Ordinal position of column in table.
283  @param se_private_id - se_private_id of the table.
284  @param ts_se_private_data - Tablespace SE private data.
285  @param tbl_se_private_data - Table SE private data.
286  @param stype - Enum specifying the stat we are
287  interested to read.
288  @param hton - Handle to SE for the given table.
289 
290  @return ulonglong representing value for the status being read.
291  */
292  ulonglong read_stat_from_SE(
293  THD *thd, const String &schema_name_ptr, const String &table_name_ptr,
294  const String &index_name_ptr, const String &column_name_ptr,
295  uint index_ordinal_position, uint column_ordinal_position,
296  dd::Object_id se_private_id, const char *ts_se_private_data,
297  const char *tbl_se_private_data, enum_table_stats_type stype,
298  handlerton *hton);
299 
300  /**
301  Read dynamic table/index statistics by opening the table OR by reading
302  cached statistics from SELECT_LEX.
303 
304  @param thd - Current thread.
305  @param schema_name_ptr - Schema name of table.
306  @param table_name_ptr - Table name of which we need stats.
307  @param index_name_ptr - Index name of which we need stats.
308  @param column_name_ptr - Column name for index.
309  @param column_ordinal_position - Ordinal position of column in table.
310  @param partition_name - Partition name.
311  @param stype - Enum specifying the stat we are
312  interested to read.
313 
314  @return ulonglong representing value for the status being read.
315  */
316  ulonglong read_stat_by_open_table(THD *thd, const String &schema_name_ptr,
317  const String &table_name_ptr,
318  const String &index_name_ptr,
319  const char *partition_name,
320  const String &column_name_ptr,
321  uint column_ordinal_position,
322  enum_table_stats_type stype);
323 
324  /**
325  Mark the cache as valid for a given table. This creates a key for the
326  cache element. We store just a single table statistics in this cache.
327 
328  @param db_name - Database name.
329  @param table_name - Table name.
330  @param partition_name - Partition name.
331  */
333  const char *partition_name) {
334  m_key = form_key(db_name, table_name, partition_name);
335  }
336 
338  set_stat_cached(db_name, table_name, nullptr);
339  }
340 
341  /**
342  Build a key representing the table for which stats are cached.
343 
344  @param db_name - Database name.
345  @param table_name - Table name.
346  @param partition_name - Partition name.
347 
348  @returns String_type representing the key.
349  */
351  const char *partition_name) {
352  return String_type(db_name.ptr()) + "." + String_type(table_name.ptr()) +
353  (partition_name ? ("." + String_type(partition_name)) : "");
354  }
355 
356  /**
357  Return statistics of the a given type.
358 
359  @param stat ha_statistics for the current cached table.
360  @param stype Type of statistics requested.
361 
362  @returns ulonglong statistics value.
363  */
364  ulonglong get_stat(ha_statistics &stat, enum_table_stats_type stype);
366  return get_stat(m_stats, stype);
367  }
368 
369  /// Set checksum
370  void set_checksum(ulonglong &&checksum) { m_checksum = checksum; }
371 
372  /// Get checksum
373  ulonglong get_checksum() const { return m_checksum; }
374 
375  /// Set open table in progress.
376  void set_read_stats_by_open(bool status) { m_read_stats_by_open = status; }
377 
378  private:
379  // The cache key
380  String_type m_key; // Format '<db_name>.<table_name>'
381 
382  // Error found when reading statistics.
384 
385  // Table checksum value retrieved from SE.
387 
388  /*
389  Status if opening a table is in progress to read statistics.
390 
391  This is used by heap table, to avoid write a command "DELETE FROM
392  TABLE" to binlog just after server restart. See open_table_entry_fini()
393  for more info.
394  */
396 
397  public:
398  // Cached statistics.
400 };
401 
402 } // namespace info_schema
403 } // namespace dd
404 
405 #endif // DD_INFO_SCHEMA_TABLE_STATS_INCLUDED
bool update_table_stats(THD *thd, TABLE_LIST *table)
Get dynamic table statistics of a table and store them into mysql.table_stats.
Definition: table_stats.cc:278
Table_statistics()
Definition: table_stats.h:104
unsigned long long int ulonglong
Definition: my_inttypes.h:55
ha_statistics m_stats
Definition: table_stats.h:399
Our own string classes, used pervasively throughout the executor.
const char * db_name
Definition: rules_table_service.cc:54
The class hold dynamic table statistics for a table.
Definition: table_stats.h:102
ulonglong get_checksum() const
Get checksum.
Definition: table_stats.h:373
void cache_stats_in_mem(const String &db_name, const String &table_name, ha_statistics &stats)
Definition: table_stats.h:161
void cache_stats_in_mem(const String &db_name, const String &table_name, const char *partition_name, ha_statistics &stats)
Store the statistics.
Definition: table_stats.h:153
Char_string_template< String_type_allocator > String_type
Definition: string_type.h:50
bool update_index_stats(THD *thd, TABLE_LIST *table)
Get dynamic index statistics of a table and store them into mysql.index_stats.
Definition: table_stats.cc:308
void cache_stats_in_mem(const String &db_name, const String &table_name, const char *partition_name, handler *file)
Store the statistics form the given handler.
Definition: table_stats.h:132
bool is_stat_cached_in_mem(const String &db_name, const String &table_name, const char *partition_name)
Check if the stats are cached for given db.table_name.
Definition: table_stats.h:115
void set_read_stats_by_open(bool status)
Set open table in progress.
Definition: table_stats.h:376
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:3986
enum_table_stats_type
Definition: table_stats.h:78
String_type m_error
Definition: table_stats.h:383
Using this class is fraught with peril, and you need to be very careful when doing so...
Definition: sql_string.h:164
ha_statistics stats
Definition: handler.h:4006
void set_checksum(ulonglong &&checksum)
Set checksum.
Definition: table_stats.h:370
virtual ha_checksum checksum() const
Definition: handler.h:5333
String_type form_key(const String &db_name, const String &table_name, const char *partition_name)
Build a key representing the table for which stats are cached.
Definition: table_stats.h:350
void invalidate_cache(void)
Definition: table_stats.h:215
unsigned int uint
Definition: uca-dump.cc:29
void set_stat_cached(const String &db_name, const String &table_name, const char *partition_name)
Mark the cache as valid for a given table.
Definition: table_stats.h:332
unsigned long long Object_id
Definition: object_id.h:30
ulonglong read_stat(THD *thd, const String &schema_name_ptr, const String &table_name_ptr, const String &engine_name_ptr, const char *partition_name, dd::Object_id se_private_id, const char *ts_se_private_data, const char *tbl_se_private_data, const ulonglong &table_stat_data, const ulonglong &cached_time, enum_table_stats_type stype)
Definition: table_stats.h:201
handlerton is a singleton structure - one instance per storage engine - to provide access to storage ...
Definition: handler.h:2269
bool m_read_stats_by_open
Definition: table_stats.h:395
void set_stat_cached(const String &db_name, const String &table_name)
Definition: table_stats.h:337
bool convert_table_name_case(char *db, char *table_name)
If the db is &#39;information_schema&#39; then convert &#39;db&#39; to lowercase and &#39;table_name&#39; to upper case...
Definition: table_stats.cc:354
bool is_reading_stats_by_open() const
Check if open table in progress.
Definition: table_stats.h:269
ulonglong m_checksum
Definition: table_stats.h:386
String_type m_key
Definition: table_stats.h:380
bool is_stat_cached_in_mem(const String &db_name, const String &table_name)
Definition: table_stats.h:120
void store_error_message(const String &db_name, const String &table_name, const char *partition_name, const String_type &error_msg)
Set error string for the given key.
Definition: table_stats.h:242
Global stats.
Definition: mysqlslap.cc:233
void cache_stats_in_mem(const String &db_name, const String &table_name, handler *file)
Definition: table_stats.h:140
Definition: os0file.h:85
ulonglong get_stat(enum_table_stats_type stype)
Definition: table_stats.h:365
The version of the current data dictionary table definitions.
Definition: dictionary_client.h:39
String_type error()
Definition: table_stats.h:221
static STATUS status
Definition: mysql.cc:198
const char * ptr() const
Definition: sql_string.h:246
Definition: table.h:2481
struct stats stats
Definition: mysqlslap.cc:231
Definition: handler.h:3449
#define false
Definition: config_static.h:43
bool check_error_for_key(const String &db_name, const String &table_name)
Check if we have seen a error.
Definition: table_stats.h:260
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:765
const char * table_name
Definition: rules_table_service.cc:55