MySQL 8.0.40
Source Code Documentation
dict0stats.cc File Reference

Code used for calculating and manipulating table statistics. More...

#include "my_dbug.h"
#include <mysql_com.h>
#include <algorithm>
#include <map>
#include <vector>
#include "dict0stats.h"
#include "dyn0buf.h"
#include "ha_prototypes.h"
#include "lob0lob.h"
#include "pars0pars.h"
#include "row0sel.h"
#include "trx0trx.h"
#include "univ.i"
#include "ut0new.h"
#include "ut0rnd.h"
#include "ut0ut.h"

Classes

struct  n_diff_data_t
 Input data that is used to calculate dict_index_t::stat_n_diff_key_vals[] for each n-columns prefix (n from 1 to n_uniq). More...
 
struct  index_fetch_t
 Aux struct used to pass a table and a boolean to dict_stats_fetch_index_stats_step(). More...
 

Macros

#define TABLE_STATS_NAME   "mysql/innodb_table_stats"
 
#define TABLE_STATS_NAME_PRINT   "mysql.innodb_table_stats"
 
#define INDEX_STATS_NAME   "mysql/innodb_index_stats"
 
#define INDEX_STATS_NAME_PRINT   "mysql.innodb_index_stats"
 
#define DEBUG_PRINTF(fmt, ...)   /* noop */
 
#define N_SAMPLE_PAGES(index)
 
#define N_DIFF_REQUIRED(index)   (N_SAMPLE_PAGES(index) * 10)
 
#define INDEX_EQ(i1, i2)
 
#define PFX   "n_diff_pfx"
 
#define PFX_LEN   10
 

Typedefs

typedef std::vector< uint64_t, ut::allocator< uint64_t > > boundaries_t
 
typedef ut::allocator< std::pair< const char *const, dict_index_t * > > index_map_t_allocator
 Allocator type used for index_map_t. More...
 
typedef std::map< const char *, dict_index_t *, ut_strcmp_functor, index_map_t_allocatorindex_map_t
 Auxiliary map used for sorting indexes by name in dict_stats_save(). More...
 

Enumerations

enum  page_scan_method_t { COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED , QUIT_ON_FIRST_NON_BORING , COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED }
 aux enum for controlling the behavior of dict_stats_scan_page() More...
 

Functions

static bool dict_stats_should_ignore_index (const dict_index_t *index)
 Checks whether an index should be ignored in stats manipulations: More...
 
static dberr_t dict_stats_exec_sql (pars_info_t *pinfo, const char *sql, trx_t *trx)
 Executes a given SQL statement using the InnoDB internal SQL parser. More...
 
static dict_table_tdict_stats_table_clone_create (const dict_table_t *table)
 Duplicate a table object and its indexes. More...
 
static void dict_stats_table_clone_free (dict_table_t *t)
 Free the resources occupied by an object returned by dict_stats_table_clone_create(). More...
 
static void dict_stats_empty_index (dict_index_t *index)
 Write all zeros (or 1 where it makes sense) into an index statistics members. More...
 
static void dict_stats_empty_table (dict_table_t *table)
 Write all zeros (or 1 where it makes sense) into a table and its indexes' statistics members. More...
 
static void dict_stats_assert_initialized_index (const dict_index_t *index)
 Check whether index's stats are initialized (assert if they are not). More...
 
static void dict_stats_assert_initialized (const dict_table_t *table)
 Check whether table's stats are initialized (assert if they are not). More...
 
static void dict_stats_copy (dict_table_t *dst, const dict_table_t *src)
 Copy table and index statistics from one table to another, including index stats. More...
 
static dict_table_tdict_stats_snapshot_create (dict_table_t *table)
 Duplicate the stats of a table and its indexes. More...
 
static void dict_stats_snapshot_free (dict_table_t *t)
 Free the resources occupied by an object returned by dict_stats_snapshot_create(). More...
 
static void dict_stats_update_transient_for_index (dict_index_t *index)
 Calculates new estimates for index statistics. More...
 
static void dict_stats_update_transient (dict_table_t *table)
 Calculates new estimates for table and index statistics. More...
 
static bool dict_stats_index_long_waiters (dict_index_t *index, std::chrono::steady_clock::time_point &wait_start_time)
 Confirms long waiters for the index lock exist. More...
 
static bool dict_stats_analyze_index_level (dict_index_t *index, ulint level, uint64_t *n_diff, uint64_t *total_recs, uint64_t *total_pages, boundaries_t *n_diff_boundaries, std::chrono::steady_clock::time_point &wait_start_time, mtr_t *mtr)
 Find the total number and the number of distinct keys on a given level in an index. More...
 
static ulintdict_stats_scan_page (const rec_t **out_rec, ulint *offsets1, ulint *offsets2, const dict_index_t *index, const page_t *page, ulint n_prefix, page_scan_method_t scan_method, uint64_t *n_diff, uint64_t *n_external_pages)
 Scan a page, reading records from left to right and counting the number of distinct records (looking only at the first n_prefix columns) and the number of external pages pointed by records from this page. More...
 
static void dict_stats_analyze_index_below_cur (const btr_cur_t *cur, ulint n_prefix, uint64_t *n_diff, uint64_t *n_external_pages)
 Dive below the current position of a cursor and calculate the number of distinct records on the leaf page, when looking at the fist n_prefix columns. More...
 
static bool dict_stats_analyze_index_for_n_prefix (dict_index_t *index, ulint n_prefix, const boundaries_t *boundaries, n_diff_data_t *n_diff_data, std::chrono::steady_clock::time_point &wait_start_time, mtr_t *mtr)
 Estimate the number of different key values in an index when looking at the first n_prefix columns. More...
 
static void dict_stats_index_set_n_diff (const n_diff_data_t *n_diff_data, dict_index_t *index)
 Set dict_index_t::stat_n_diff_key_vals[] and stat_n_sample_sizes[]. More...
 
static bool dict_stats_analyze_index_low (uint64_t &n_sample_pages, dict_index_t *index)
 Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages, based on the specified n_sample_pages. More...
 
static void dict_stats_analyze_index (dict_index_t *index)
 Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages. More...
 
static dberr_t dict_stats_update_persistent (dict_table_t *table)
 Calculates new estimates for table and index statistics. More...
 
static dberr_t dict_stats_save_index_stat (dict_index_t *index, lint last_update, const char *stat_name, uint64_t stat_value, uint64_t *sample_size, const char *stat_description, trx_t *trx)
 Save an individual index's statistic into the persistent statistics storage. More...
 
static dberr_t dict_stats_save (dict_table_t *table_orig, const index_id_t *only_for_index)
 Save the table's statistics into the persistent statistics storage. More...
 
static bool dict_stats_fetch_table_stats_step (void *node_void, void *table_void)
 Called for the row that is selected by SELECT ... FROM mysql.innodb_table_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to it. More...
 
static bool dict_stats_fetch_index_stats_step (void *node_void, void *arg_void)
 Called for the rows that are selected by SELECT ... FROM mysql.innodb_index_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to its indexes. More...
 
static dberr_t dict_stats_fetch_from_ps (dict_table_t *table)
 Read table's statistics from the persistent statistics storage. More...
 
void dict_stats_update_for_index (dict_index_t *index)
 Fetches or calculates new estimates for index statistics. More...
 
dberr_t dict_stats_update (dict_table_t *table, dict_stats_upd_option_t stats_upd_option)
 Calculates new estimates for table and index statistics. More...
 
dberr_t dict_stats_drop_index (const char *db_and_table, const char *iname, char *errstr, ulint errstr_sz)
 Removes the information for a particular index's stats from the persistent storage if it exists and if there is data stored for this index. More...
 
static dberr_t dict_stats_delete_from_table_stats (const char *database_name, const char *table_name)
 Executes DELETE FROM mysql.innodb_table_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More...
 
static dberr_t dict_stats_delete_from_index_stats (const char *database_name, const char *table_name)
 Executes DELETE FROM mysql.innodb_index_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More...
 
dberr_t dict_stats_drop_table (const char *db_and_table, char *errstr, ulint errstr_sz)
 Removes the statistics for a table and all of its indexes from the persistent statistics storage if it exists and if there is data stored for the table. More...
 
static dberr_t dict_stats_rename_table_in_table_stats (const char *old_dbname_utf8mb3, const char *old_tablename_utf8mb3, const char *new_dbname_utf8mb3, const char *new_tablename_utf8mb3)
 Executes UPDATE mysql.innodb_table_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More...
 
static dberr_t dict_stats_rename_table_in_index_stats (const char *old_dbname_utf8mb3, const char *old_tablename_utf8mb3, const char *new_dbname_utf8mb3, const char *new_tablename_utf8mb3)
 Executes UPDATE mysql.innodb_index_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it. More...
 
dberr_t dict_stats_rename_table (const char *old_name, const char *new_name, char *errstr, size_t errstr_sz)
 Renames a table in InnoDB persistent stats storage. More...
 
dberr_t dict_stats_rename_index (const dict_table_t *table, const char *old_index_name, const char *new_index_name)
 Renames an index in InnoDB persistent stats storage. More...
 
void dict_stats_evict_tablespaces ()
 Evict the stats tables if they loaded in tablespace cache and also close the stats .ibd files. More...
 

Detailed Description

Code used for calculating and manipulating table statistics.

Created Jan 06, 2010 Vasil Dimov

Macro Definition Documentation

◆ DEBUG_PRINTF

#define DEBUG_PRINTF (   fmt,
  ... 
)    /* noop */

◆ INDEX_EQ

#define INDEX_EQ (   i1,
  i2 
)
Value:
((i1) != NULL && (i2) != NULL && (i1)->space == (i2)->space && \
(i1)->id == (i2)->id && strcmp((i1)->name, (i2)->name) == 0)
case opt name
Definition: sslopt-case.h:33
#define NULL
Definition: types.h:55

◆ INDEX_STATS_NAME

#define INDEX_STATS_NAME   "mysql/innodb_index_stats"

◆ INDEX_STATS_NAME_PRINT

#define INDEX_STATS_NAME_PRINT   "mysql.innodb_index_stats"

◆ N_DIFF_REQUIRED

#define N_DIFF_REQUIRED (   index)    (N_SAMPLE_PAGES(index) * 10)

◆ N_SAMPLE_PAGES

#define N_SAMPLE_PAGES (   index)
Value:
static_cast<uint64_t>((index)->table->stats_sample_pages != 0 \
? (index)->table->stats_sample_pages \
unsigned long long srv_stats_persistent_sample_pages
Definition: srv0srv.cc:580

◆ PFX

#define PFX   "n_diff_pfx"

◆ PFX_LEN

#define PFX_LEN   10

◆ TABLE_STATS_NAME

#define TABLE_STATS_NAME   "mysql/innodb_table_stats"

◆ TABLE_STATS_NAME_PRINT

#define TABLE_STATS_NAME_PRINT   "mysql.innodb_table_stats"

Typedef Documentation

◆ boundaries_t

typedef std::vector<uint64_t, ut::allocator<uint64_t> > boundaries_t

◆ index_map_t

typedef std::map<const char *, dict_index_t *, ut_strcmp_functor, index_map_t_allocator> index_map_t

Auxiliary map used for sorting indexes by name in dict_stats_save().

◆ index_map_t_allocator

typedef ut::allocator<std::pair<const char *const, dict_index_t *> > index_map_t_allocator

Allocator type used for index_map_t.

Enumeration Type Documentation

◆ page_scan_method_t

aux enum for controlling the behavior of dict_stats_scan_page()

Enumerator
COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED 
QUIT_ON_FIRST_NON_BORING 
COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED 

Function Documentation

◆ dict_stats_analyze_index()

static void dict_stats_analyze_index ( dict_index_t index)
static

Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages.

This function could be slow.

Parameters
indexin/out: index to analyze

◆ dict_stats_analyze_index_below_cur()

static void dict_stats_analyze_index_below_cur ( const btr_cur_t cur,
ulint  n_prefix,
uint64_t *  n_diff,
uint64_t *  n_external_pages 
)
static

Dive below the current position of a cursor and calculate the number of distinct records on the leaf page, when looking at the fist n_prefix columns.

Also calculate the number of external pages pointed by records on the leaf page.

Parameters
[in]curcursor
[in]n_prefixlook at the first n_prefix columns when comparing records
[out]n_diffnumber of distinct records
[out]n_external_pagesnumber of external pages

◆ dict_stats_analyze_index_for_n_prefix()

static bool dict_stats_analyze_index_for_n_prefix ( dict_index_t index,
ulint  n_prefix,
const boundaries_t boundaries,
n_diff_data_t n_diff_data,
std::chrono::steady_clock::time_point &  wait_start_time,
mtr_t mtr 
)
static

Estimate the number of different key values in an index when looking at the first n_prefix columns.

For a given level in an index select n_diff_data->n_leaf_pages_to_analyze records from that level and dive below them to the corresponding leaf pages, then scan those leaf pages and save the sampling results in n_diff_data->n_diff_all_analyzed_pages.

Parameters
[in]indexIndex
[in]n_prefixLook at first 'n_prefix' columns when comparing records
[in]boundariesA vector that contains n_diff_data->n_diff_on_level integers each of which represents the index (on level 'level', counting from left/smallest to right/biggest from 0) of the last record from each group of distinct keys
[in,out]n_diff_datan_diff_all_analyzed_pages and n_external_pages_sum in this structure will be set by this function. The members level, n_diff_on_level and n_leaf_pages_to_analyze must be set by the caller in advance - they are used by some calculations inside this function
[in,out]wait_start_timelast known time index lock wasn't awaited.
[in,out]mtrMini-transaction
Returns
false if aborted

◆ dict_stats_analyze_index_level()

static bool dict_stats_analyze_index_level ( dict_index_t index,
ulint  level,
uint64_t *  n_diff,
uint64_t *  total_recs,
uint64_t *  total_pages,
boundaries_t n_diff_boundaries,
std::chrono::steady_clock::time_point &  wait_start_time,
mtr_t mtr 
)
static

Find the total number and the number of distinct keys on a given level in an index.

Each of the 1..n_uniq prefixes are looked up and the results are saved in the array n_diff[0] .. n_diff[n_uniq - 1]. The total number of records on the level is saved in total_recs. Also, the index of the last record in each group of equal records is saved in n_diff_boundaries[0..n_uniq - 1], records indexing starts from the leftmost record on the level and continues cross pages boundaries, counting from 0.

Returns
false if aborted
Parameters
indexin: index
levelin: level
n_diffout: array for number of distinct keys for all prefixes
total_recsout: total number of records
total_pagesout: total number of pages
n_diff_boundariesout: boundaries of the groups of distinct keys
wait_start_timein/out: last known time index lock wasn't awaited.
mtrin/out: mini-transaction

◆ dict_stats_analyze_index_low()

static bool dict_stats_analyze_index_low ( uint64_t &  n_sample_pages,
dict_index_t index 
)
static

Calculates new statistics for a given index and saves them to the index members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and stat_n_leaf_pages, based on the specified n_sample_pages.

Parameters
[in,out]n_sample_pagesnumber of leaf pages to sample. and suggested next value to retry if aborted.
[in,out]indexindex to analyze.
Returns
false if aborted

◆ dict_stats_assert_initialized()

static void dict_stats_assert_initialized ( const dict_table_t table)
static

Check whether table's stats are initialized (assert if they are not).

Parameters
tablein: table

◆ dict_stats_assert_initialized_index()

static void dict_stats_assert_initialized_index ( const dict_index_t index)
static

Check whether index's stats are initialized (assert if they are not).

Parameters
indexin: index

◆ dict_stats_copy()

static void dict_stats_copy ( dict_table_t dst,
const dict_table_t src 
)
static

Copy table and index statistics from one table to another, including index stats.

Extra indexes in src are ignored and extra indexes in dst are initialized to correspond to an empty index.

Parameters
dstin/out: destination table
srcin: source table

◆ dict_stats_delete_from_index_stats()

static dberr_t dict_stats_delete_from_index_stats ( const char *  database_name,
const char *  table_name 
)
inlinestatic

Executes DELETE FROM mysql.innodb_index_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.

Returns
DB_SUCCESS or error code
Parameters
database_namein: database name, e.g. 'db'
table_namein: table name, e.g. 'table'

◆ dict_stats_delete_from_table_stats()

static dberr_t dict_stats_delete_from_table_stats ( const char *  database_name,
const char *  table_name 
)
inlinestatic

Executes DELETE FROM mysql.innodb_table_stats WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.

Returns
DB_SUCCESS or error code
Parameters
database_namein: database name, e.g. 'db'
table_namein: table name, e.g. 'table'

◆ dict_stats_drop_index()

dberr_t dict_stats_drop_index ( const char *  db_and_table,
const char *  iname,
char *  errstr,
ulint  errstr_sz 
)

Removes the information for a particular index's stats from the persistent storage if it exists and if there is data stored for this index.

This function creates its own trx and commits it. A note from Marko why we cannot edit user and sys_* tables in one trx: marko: The problem is that ibuf merges should be disabled while we are rolling back dict transactions. marko: If ibuf merges are not disabled, we need to scan the *.ibd files. But we shouldn't open *.ibd files before we have rolled back dict transactions and opened the SYS_* records for the *.ibd files.

Returns
DB_SUCCESS or error code
Parameters
db_and_tablein: db and table, e.g. 'db/table'
inamein: index name
errstrout: error message if != DB_SUCCESS is returned
errstr_szin: size of the errstr buffer

◆ dict_stats_drop_table()

dberr_t dict_stats_drop_table ( const char *  db_and_table,
char *  errstr,
ulint  errstr_sz 
)

Removes the statistics for a table and all of its indexes from the persistent statistics storage if it exists and if there is data stored for the table.

Removes the statistics for a table and all of its indexes from the persistent storage if it exists and if there is data stored for the table.

This function creates its own transaction and commits it.

Returns
DB_SUCCESS or error code
Parameters
db_and_tablein: db and table, e.g. 'db/table'
errstrout: error message if != DB_SUCCESS is returned
errstr_szin: size of errstr buffer

◆ dict_stats_empty_index()

static void dict_stats_empty_index ( dict_index_t index)
static

Write all zeros (or 1 where it makes sense) into an index statistics members.

The resulting stats correspond to an empty index. The caller must own index's table stats latch in X mode (dict_table_stats_lock(table, RW_X_LATCH))

Parameters
indexin/out: index

◆ dict_stats_empty_table()

static void dict_stats_empty_table ( dict_table_t table)
static

Write all zeros (or 1 where it makes sense) into a table and its indexes' statistics members.

The resulting stats correspond to an empty table.

Parameters
tablein/out: table

◆ dict_stats_evict_tablespaces()

void dict_stats_evict_tablespaces ( )

Evict the stats tables if they loaded in tablespace cache and also close the stats .ibd files.

We have to close stats tables because 8.0 stats tables will use the same name. We load the stats from 5.7 with a suffix "_backup57" and migrate the statistics.

◆ dict_stats_exec_sql()

static dberr_t dict_stats_exec_sql ( pars_info_t pinfo,
const char *  sql,
trx_t trx 
)
static

Executes a given SQL statement using the InnoDB internal SQL parser.

This function will free the pinfo object.

Parameters
[in,out]pinfopinfo to pass to que_eval_sql() must already have any literals bound to it
[in]sqlSQL string to execute
[in,out]trxin case of NULL the function will allocate and free the trx object. If it is not NULL then it will be rolled back only in the case of error, but not freed.
Returns
DB_SUCCESS or error code

◆ dict_stats_fetch_from_ps()

static dberr_t dict_stats_fetch_from_ps ( dict_table_t table)
static

Read table's statistics from the persistent statistics storage.

Returns
DB_SUCCESS or error code
Parameters
tablein/out: table

◆ dict_stats_fetch_index_stats_step()

static bool dict_stats_fetch_index_stats_step ( void *  node_void,
void *  arg_void 
)
static

Called for the rows that are selected by SELECT ... FROM mysql.innodb_index_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to its indexes.

Let a table has N indexes and each index has Ui unique columns for i=1..N, then mysql.innodb_index_stats will have SUM(Ui) i=1..N rows for that table. So this function will be called SUM(Ui) times where SUM(Ui) is of magnitude N*AVG(Ui). In each call it searches for the currently fetched index into table->indexes linearly, assuming this list is not sorted. Thus, overall, fetching all indexes' stats from mysql.innodb_index_stats is O(N^2) where N is the number of indexes. This can be improved if we sort table->indexes in a temporary area just once and then search in that sorted list. Then the complexity will be O(N*log(N)). We assume a table will not have more than 100 indexes, so we go with the simpler N^2 algorithm.

Returns
non-NULL dummy
Parameters
node_voidin: select node
arg_voidout: table + a flag that tells if we modified anything

◆ dict_stats_fetch_table_stats_step()

static bool dict_stats_fetch_table_stats_step ( void *  node_void,
void *  table_void 
)
static

Called for the row that is selected by SELECT ... FROM mysql.innodb_table_stats WHERE table='...' The second argument is a pointer to the table and the fetched stats are written to it.

Returns
non-NULL dummy
Parameters
node_voidin: select node
table_voidout: table

◆ dict_stats_index_long_waiters()

static bool dict_stats_index_long_waiters ( dict_index_t index,
std::chrono::steady_clock::time_point &  wait_start_time 
)
static

Confirms long waiters for the index lock exist.

Wait time estimation is based on the last call of this function when not exist.

Parameters
[in]indexindex
[in,out]wait_start_timelast known time index lock wasn't awaited. Can be updated by this function if no waiter found now.
Returns
true if long waiters exist

◆ dict_stats_index_set_n_diff()

static void dict_stats_index_set_n_diff ( const n_diff_data_t n_diff_data,
dict_index_t index 
)
inlinestatic

Set dict_index_t::stat_n_diff_key_vals[] and stat_n_sample_sizes[].

Parameters
[in]n_diff_datainput data to use to derive the results
[in,out]indexindex whose stat_n_diff_key_vals[] to set

◆ dict_stats_rename_index()

dberr_t dict_stats_rename_index ( const dict_table_t table,
const char *  old_index_name,
const char *  new_index_name 
)

Renames an index in InnoDB persistent stats storage.

This function creates its own transaction and commits it.

Returns
DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned if the persistent stats do not exist.
Parameters
tablein: table whose index is renamed
old_index_namein: old index name
new_index_namein: new index name

◆ dict_stats_rename_table()

dberr_t dict_stats_rename_table ( const char *  old_name,
const char *  new_name,
char *  errstr,
size_t  errstr_sz 
)

Renames a table in InnoDB persistent stats storage.

This function creates its own transaction and commits it.

Returns
DB_SUCCESS or error code
Parameters
old_namein: old name, e.g. 'db/table'
new_namein: new name, e.g. 'db/table'
errstrout: error string if != DB_SUCCESS is returned
errstr_szin: errstr size

◆ dict_stats_rename_table_in_index_stats()

static dberr_t dict_stats_rename_table_in_index_stats ( const char *  old_dbname_utf8mb3,
const char *  old_tablename_utf8mb3,
const char *  new_dbname_utf8mb3,
const char *  new_tablename_utf8mb3 
)
inlinestatic

Executes UPDATE mysql.innodb_index_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.

Returns
DB_SUCCESS or error code
Parameters
old_dbname_utf8mb3in: database name, e.g. 'olddb'
old_tablename_utf8mb3in: table name, e.g. 'oldtable'
new_dbname_utf8mb3in: database name, e.g. 'newdb'
new_tablename_utf8mb3in: table name, e.g. 'newtable'

◆ dict_stats_rename_table_in_table_stats()

static dberr_t dict_stats_rename_table_in_table_stats ( const char *  old_dbname_utf8mb3,
const char *  old_tablename_utf8mb3,
const char *  new_dbname_utf8mb3,
const char *  new_tablename_utf8mb3 
)
inlinestatic

Executes UPDATE mysql.innodb_table_stats SET database_name = '...', table_name = '...' WHERE database_name = '...' AND table_name = '...'; Creates its own transaction and commits it.

Returns
DB_SUCCESS or error code
Parameters
old_dbname_utf8mb3in: database name, e.g. 'olddb'
old_tablename_utf8mb3in: table name, e.g. 'oldtable'
new_dbname_utf8mb3in: database name, e.g. 'newdb'
new_tablename_utf8mb3in: table name, e.g. 'newtable'

◆ dict_stats_save()

static dberr_t dict_stats_save ( dict_table_t table_orig,
const index_id_t only_for_index 
)
static

Save the table's statistics into the persistent statistics storage.

Parameters
[in]table_origtable whose stats to save
[in]only_for_indexif this is non-NULL, then stats for indexes that are not equal to it will not be saved, if NULL, then all indexes' stats are saved
Returns
DB_SUCCESS or error code

◆ dict_stats_save_index_stat()

static dberr_t dict_stats_save_index_stat ( dict_index_t index,
lint  last_update,
const char *  stat_name,
uint64_t  stat_value,
uint64_t *  sample_size,
const char *  stat_description,
trx_t trx 
)
static

Save an individual index's statistic into the persistent statistics storage.

Parameters
[in]indexindex to be updated
[in]last_updatetimestamp of the stat
[in]stat_namename of the stat
[in]stat_valuevalue of the stat
[in]sample_sizen pages sampled or NULL
[in]stat_descriptiondescription of the stat
[in,out]trxin case of NULL the function will allocate and free the trx object. If it is not NULL then it will be rolled back only in the case of error, but not freed.
Returns
DB_SUCCESS or error code

◆ dict_stats_scan_page()

static ulint * dict_stats_scan_page ( const rec_t **  out_rec,
ulint offsets1,
ulint offsets2,
const dict_index_t index,
const page_t page,
ulint  n_prefix,
page_scan_method_t  scan_method,
uint64_t *  n_diff,
uint64_t *  n_external_pages 
)
inlinestatic

Scan a page, reading records from left to right and counting the number of distinct records (looking only at the first n_prefix columns) and the number of external pages pointed by records from this page.

If scan_method is QUIT_ON_FIRST_NON_BORING then the function will return as soon as it finds a record that does not match its neighbor to the right, which means that in the case of QUIT_ON_FIRST_NON_BORING the returned n_diff can either be 0 (empty page), 1 (the whole page has all keys equal) or 2 (the function found a non-boring record and returned).

Parameters
[out]out_recrecord, or NULL
[out]offsets1rec_get_offsets() working space (must be big enough)
[out]offsets2rec_get_offsets() working space (must be big enough)
[in]indexindex of the page
[in]pagethe page to scan
[in]n_prefixlook at the first n_prefix columns
[in]scan_methodscan to the end of the page or not
[out]n_diffnumber of distinct records encountered
[out]n_external_pagesif this is non-NULL then it will be set to the number of externally stored pages which were encountered
Returns
offsets1 or offsets2 (the offsets of *out_rec), or NULL if the page is empty and does not contain user records.

◆ dict_stats_should_ignore_index()

static bool dict_stats_should_ignore_index ( const dict_index_t index)
inlinestatic

Checks whether an index should be ignored in stats manipulations:

  • stats fetch
  • stats recalc
  • stats save
    Returns
    true if exists and all tables are ok
Parameters
indexin: index

◆ dict_stats_snapshot_create()

static dict_table_t * dict_stats_snapshot_create ( dict_table_t table)
static

Duplicate the stats of a table and its indexes.

This function creates a dummy dict_table_t object and copies the input table's stats into it. The returned table object is not in the dictionary cache and cannot be accessed by any other threads. In addition to the members copied in dict_stats_table_clone_create() this function initializes the following: dict_table_t::stat_initialized dict_table_t::stat_persistent dict_table_t::stat_n_rows dict_table_t::stat_clustered_index_size dict_table_t::stat_sum_of_other_index_sizes dict_table_t::stat_modified_counter dict_index_t::stat_n_diff_key_vals[] dict_index_t::stat_n_sample_sizes[] dict_index_t::stat_n_non_null_key_vals[] dict_index_t::stat_index_size dict_index_t::stat_n_leaf_pages The returned object should be freed with dict_stats_snapshot_free() when no longer needed.

Parameters
[in]tabletable whose stats to copy
Returns
incomplete table object

◆ dict_stats_snapshot_free()

static void dict_stats_snapshot_free ( dict_table_t t)
static

Free the resources occupied by an object returned by dict_stats_snapshot_create().

Parameters
tin: dummy table object to free

◆ dict_stats_table_clone_create()

static dict_table_t * dict_stats_table_clone_create ( const dict_table_t table)
static

Duplicate a table object and its indexes.

This function creates a dummy dict_table_t object and initializes the following table and index members: dict_table_t::id (copied) dict_table_t::heap (newly created) dict_table_t::name (copied) dict_table_t::corrupted (copied) dict_table_t::indexes<> (newly created) dict_table_t::magic_n for each entry in dict_table_t::indexes, the following are initialized: (indexes that have DICT_FTS set in index->type are skipped) dict_index_t::id (copied) dict_index_t::name (copied) dict_index_t::table_name (points to the copied table name) dict_index_t::table (points to the above semi-initialized object) dict_index_t::type (copied) dict_index_t::to_be_dropped (copied) dict_index_t::online_status (copied) dict_index_t::n_uniq (copied) dict_index_t::fields[] (newly created, only first n_uniq, only fields[i].name) dict_index_t::indexes<> (newly created) dict_index_t::stat_n_diff_key_vals[] (only allocated, left uninitialized) dict_index_t::stat_n_sample_sizes[] (only allocated, left uninitialized) dict_index_t::stat_n_non_null_key_vals[] (only allocated, left uninitialized) dict_index_t::magic_n The returned object should be freed with dict_stats_table_clone_free() when no longer needed.

Returns
incomplete table object
Parameters
tablein: table whose stats to copy

◆ dict_stats_table_clone_free()

static void dict_stats_table_clone_free ( dict_table_t t)
static

Free the resources occupied by an object returned by dict_stats_table_clone_create().

Parameters
tin: dummy table object to free

◆ dict_stats_update()

dberr_t dict_stats_update ( dict_table_t table,
dict_stats_upd_option_t  stats_upd_option 
)

Calculates new estimates for table and index statistics.

The statistics are used in query optimization.

Returns
DB_SUCCESS or error code
Parameters
tablein/out: table
stats_upd_optionin: whether to (re) calc the stats or to fetch them from the persistent statistics storage

◆ dict_stats_update_for_index()

void dict_stats_update_for_index ( dict_index_t index)

Fetches or calculates new estimates for index statistics.

in/out: index

Parameters
indexin/out: index

◆ dict_stats_update_persistent()

static dberr_t dict_stats_update_persistent ( dict_table_t table)
static

Calculates new estimates for table and index statistics.

This function is relatively slow and is used to calculate persistent statistics that will be saved on disk.

Returns
DB_SUCCESS or error code
Parameters
tablein/out: table

◆ dict_stats_update_transient()

static void dict_stats_update_transient ( dict_table_t table)
static

Calculates new estimates for table and index statistics.

This function is relatively quick and is used to calculate transient statistics that are not saved on disk. This was the only way to calculate statistics before the Persistent Statistics feature was introduced.

Parameters
tablein/out: table

◆ dict_stats_update_transient_for_index()

static void dict_stats_update_transient_for_index ( dict_index_t index)
static

Calculates new estimates for index statistics.

This function is relatively quick and is used to calculate transient statistics that are not saved on disk. This was the only way to calculate statistics before the Persistent Statistics feature was introduced.

Parameters
indexin/out: index