Maison base de données tutoriel mysql MySQL5.6为什么关闭元数据统计信息自动更新&统计信息收集源代码

MySQL5.6为什么关闭元数据统计信息自动更新&统计信息收集源代码

Jun 07, 2016 pm 02:55 PM
Pourquoi 信息 关闭 数据统计 更新 自动

问题描述: MySQL 5.5.15 原sql如下: select constraint_schema,table_name,constraint_name,constraint_type from information_schema.table_constraints where table_schema not in ('information_schema', 'mysql', 'test',‘performance_schema’); 不

问题描述:

MySQL 5.5.15 原sql如下:

select constraint_schema,table_name,constraint_name,constraint_type from information_schema.table_constraints where table_schema not in ('information_schema', 'mysql', 'test',‘performance_schema’);  

 不只是上面提到的table_constraintsinformation_schema库下的一下几个表,访问时候都会触发这个“顺手”操作。

information_schema.TABLES

information_schema.STATISTICS

information_schema.PARTITIONS

information_schema.KEY_COLUMN_USAGE

information_schema.TABLE_CONSTRAINTS

information_schema.REFERENTIAL_CONSTRAINTS

show table status  . .

show index from ...

innodb_stats_on_metadata=on 都会触发自动更新统计信息。

问题:

5.6 开始默认innodb_stats_on_metadata=off,why??? 答:为了防止自动更新统计信息在DB高峰时导致BP的swap;查询性能大幅度抖动。

没有定期更新统计信息了么??答:有啊,而且可以是持久化的。


我看到的MySQL 5.5.15 这个版本还是条件是====>

counter > 2000000000 || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)

下面做了对MySQL 收集统计信息做了扩展:


一.下面针对MySQL community(5.5.15、5.5.36、5.6.16)源代码分析:

1.下面是对MySQL-5.5.15 的源代码的分析:

./storage/innobase/row/row0mysql.c 

/*********************************************************************//**
Updates the table modification counter and calculates new estimates
for table and index statistics if necessary. */
UNIV_INLINE
void
row_update_statistics_if_needed(
/*============================*/
	dict_table_t*	table)	/*!< in: table */
{
	ulint	counter;

	counter = table->stat_modified_counter;

	table->stat_modified_counter = counter + 1;

	/* Calculate new statistics if 1 / 16 of table has been modified
	since the last time a statistics batch was run, or if
	stat_modified_counter > 2 000 000 000 (to avoid wrap-around).
	We calculate statistics at most every 16th round, since we may have
	a counter table which is very small and updated very often. */

	if (counter > 2000000000
	    || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) {

		dict_update_statistics(table, FALSE /* update even if stats
						    are initialized */);
	}
}
Copier après la connexion

从上面可以看出更新统计信息的条件是:

counter > 2000000000 || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)


2.下面是对MySQL-5.5.36 的源代码的分析:

---------------------------------------------------------------------------

#通过更新统计信息stat_modified_counter,每个表都有这个表里来维护:

./storage/innobase/row/row0mysql.c

/*********************************************************************//**
Updates the table modification counter and calculates new estimates
for table and index statistics if necessary. */
UNIV_INLINE
void
row_update_statistics_if_needed(
/*============================*/
        dict_table_t*   table)  /*!< in: table */
{
        ulint   counter;

        counter = table->stat_modified_counter;

        table->stat_modified_counter = counter + 1;

        if (DICT_TABLE_CHANGED_TOO_MUCH(table)) {

                dict_update_statistics(
                        table,
                        FALSE, /* update even if stats are initialized */
                        TRUE /* only update if stats changed too much */);
        }
}

/*********************************************************************/
Copier après la connexion

规则:每一次DML操作导致1 行更新,stat_modified_counter加1,直到满足更新统计信息的条件,stat_modified_counter的值自动重置为0。


#更新统计信息的条件:(有超过1/16的row被更改过会更新表的条件信息

./storage/innobase/include/dict0dict.h

/** Calculate new statistics if 1 / 16 of table has been modified
since the last time a statistics batch was run.
We calculate statistics at most every 16th round, since we may have
a counter table which is very small and updated very often.
@param t table
@return true if the table has changed too much and stats need to be
recalculated
*/
#define DICT_TABLE_CHANGED_TOO_MUCH(t) \
        ((ib_int64_t) (t)->stat_modified_counter > 16 + (t)->stat_n_rows / 16)

/*********************************************************************/
Copier après la connexion


* 这样有个性能问题,若有多个线程同时检测到阈值,也即是并发调用会多次,,会导致dict_update_statistics函数多次的调用,浪费了系统资源。

解决方法在dict_update_statistics{}函数对stat_modified_counter加锁,避免并发执行。


#统计新跟更新函数:dict_update_statistics

./storage/innobase/dict/dict0dict.c

/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics(
/*===================*/
        dict_table_t*   table,          /*!< in/out: table */
        ibool           only_calc_if_missing_stats,/*!< in: only
                                        update/recalc the stats if they have
                                        not been initialized yet, otherwise
                                        do nothing */
        ibool           only_calc_if_changed_too_much)/*!< in: only
                                        update/recalc the stats if the table
                                        has been changed too much since the
                                        last stats update/recalc */
{
        dict_index_t*   index;
        ulint           sum_of_index_sizes      = 0;

        DBUG_EXECUTE_IF("skip_innodb_statistics", return;);
-----------------------------------------------------------------------------
Copier après la connexion

可以优化成:

---------------------------------------------------------------------------

1) x

2) 索引统计

3) stat_modified_counter 0

4) 解锁

---------------------------------------------------------------------------

3.下面我们来看下对MySQL 5.6.16 的源代码的分析:

MySQL版本:MySQL 5.6.16-log。

./storage/innobase/row/row0mysql.cc

void
row_update_statistics_if_needed(
/*============================*/
        dict_table_t*   table)  /*!< in: table */
{
        ib_uint64_t     counter;
        ib_uint64_t     n_rows;

        if (!table->stat_initialized) {
                DBUG_EXECUTE_IF(
                        "test_upd_stats_if_needed_not_inited",
                        fprintf(stderr, "test_upd_stats_if_needed_not_inited "
                                "was executed\n");
                );
                return;
        }

        counter = table->stat_modified_counter++;
        n_rows = dict_table_get_n_rows(table);

        if (dict_stats_is_persistent_enabled(table)) {
                if (counter > n_rows / 10 /* 10% */
                    && dict_stats_auto_recalc_is_enabled(table)) {

                        dict_stats_recalc_pool_add(table);
                        table->stat_modified_counter = 0;
                }
                return;
        }

        /* Calculate new statistics if 1 / 16 of table has been modified
        since the last time a statistics batch was run.
        We calculate statistics at most every 16th round, since we may have
        a counter table which is very small and updated very often. */

        if (counter > 16 + n_rows / 16 /* 6.25% */) {

                ut_ad(!mutex_own(&dict_sys->mutex));
                /* this will reset table->stat_modified_counter to 0 */
                dict_stats_update(table, DICT_STATS_RECALC_TRANSIENT);
        }
}

/*********************************************************************/
Copier après la connexion

从上面的代码看可以看出:

1.对InnoDB表统计信息持久化时,表的row发生变化大于10%(counter > n_rows / 10 /* 10%)并且<span style="color:rgb(79,129,189);">innodb_stats_auto_recalc</span><span style="color:rgb(79,129,189);">=on,统计信信息会更新(虽然</span><span style="color:rgb(79,129,189);">innodb_stats_auto_recalc</span><span style="color:rgb(79,129,189);"><span style="color:rgb(2,103,137);font-family:'Courier New', Courier, fixed, monospace;font-size:13.63636302948px;font-weight:bold;line-height:25.2000007629395px;background-color:rgb(255,255,255);">=on是自动重新计算,但是也是异步的,可能会延时,比如当瞬间的DML批量操作就可能有延时</span>)</span>

2.统计信息非持久化还是和5.5 一致的(表的row发生变化大于1/16时更新统计信息

3.切记:不能完全依赖于MySQL本身的机制来更新统计信息,线上一些表不及时更新统计信息的我遇到过多次,针对这样的表,我在夜间定期analyze table xxx;


二.MySQL 5.6的改进:

可以配置统计信息的持久化和非持久化(非持久化:5.6之前都是这种)

相关参数:

持久化:

innodb_stats_persistent:on(1)

innodb_stats_persistent_sample_pages:20

非持久化:

innodb_stats_sample_pages:8

相关表:

mysql.innodb_index_stats

mysql.innodb_table_stats

From 5.6.6 开始,统计信息默认是持久化的(即innodb_stats_persistent=on),使用参数innodb_stats_persistent_sample_pages的值,来采样,此时非持久化的参数innodb_stats_sample_pages就无效。

From 5.6.6 开始,使用非持久化的统计信息:

1.set innodb_stats_persistent=0;

2.create|alter table stats_persistent=0;

对单个表开启:

create|alter table...STATS_PERSISTENT [=] {DEFAULT|0|1}
Copier après la connexion

DEFAULT:table的统计信息是否持久化由参数 innodb_stats_persistent 决定。\

总结:From 5.6.6 开始,要么开启统计信息持久化,要么是还用以前的非持久化,二者选一。


参考相关参数:

innodb_stats_method: nulls_equalnulls_unequal, and nulls_ignored
myisam_stats_method:nulls_equalnulls_unequal, and nulls_ignored

<span style="font-size:19px;">--------------------------------------------------------------</span>

<span style="color:#488CF2;">基数即value group=N/s (N:表行数 S:average group size)<br>基数(VG)|值组为不重复的值的个数<br></span>

<span style="color:#488CF2;">nulls_equal:所有的NULL都相等,算作一个值组,这样一旦null值很多的情况下,<span style="font-size:13.6000003814697px;line-height:25.2000007629395px;">average group size偏大,导致基数偏小。</span></span>

<span style="color:#488CF2;">nulls_unequal:<span style="font-size:13.6000003814697px;line-height:25.2000007629395px;">每一个NULL都相等,算作一个值组,这样一旦null值很多的情况下,如果non-null值组大,而null的值组过多,导致average group size偏小,导致基数偏大,可能导致误走索引</span></span>

<span style="color:#488CF2;">nulls_ignored:所有的null都忽略,不记录索引。</span>

<span style="font-size:19px;">--------------------------------------------------------------</span>

参考:

# http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_stats_method

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

La production de pages H5 nécessite-t-elle une maintenance continue? La production de pages H5 nécessite-t-elle une maintenance continue? Apr 05, 2025 pm 11:27 PM

La page H5 doit être maintenue en continu, en raison de facteurs tels que les vulnérabilités du code, la compatibilité des navigateurs, l'optimisation des performances, les mises à jour de sécurité et les améliorations de l'expérience utilisateur. Des méthodes de maintenance efficaces comprennent l'établissement d'un système de test complet, à l'aide d'outils de contrôle de version, de surveiller régulièrement les performances de la page, de collecter les commentaires des utilisateurs et de formuler des plans de maintenance.

JS peut-il fonctionner sans H5? JS peut-il fonctionner sans H5? Apr 06, 2025 am 09:06 AM

JavaScript est-il disponible pour s'exécuter sans HTML5? Le moteur JavaScript lui-même peut fonctionner indépendamment. L'exécution de JavaScript dans un environnement de navigateur dépend de HTML5 car il fournit l'environnement standardisé requis pour charger et exécuter du code. Les API et les fonctionnalités fournies par HTML5 sont cruciales pour les frameworks et bibliothèques JavaScript modernes. Sans environnements HTML5, de nombreuses fonctionnalités JavaScript sont difficiles à implémenter ou ne peuvent pas être implémentées.

Pourquoi les zones réduites pourpre dans la disposition Flex sont-elles considérées à tort «espace de débordement»? Pourquoi les zones réduites pourpre dans la disposition Flex sont-elles considérées à tort «espace de débordement»? Apr 05, 2025 pm 05:51 PM

Questions sur les zones de slash violet dans les dispositions flexibles Lorsque vous utilisez des dispositions flexibles, vous pouvez rencontrer des phénomènes déroutants, comme dans les outils du développeur (D ...

Pourquoi les feuilles de style personnalisées peuvent-elles prendre effet sur les pages Web locales de Safari mais pas sur les pages Baidu? Pourquoi les feuilles de style personnalisées peuvent-elles prendre effet sur les pages Web locales de Safari mais pas sur les pages Baidu? Apr 05, 2025 pm 05:15 PM

Discussion sur l'utilisation de styles de style personnalisés dans Safari aujourd'hui, nous allons discuter d'une question sur l'application de feuilles de style personnalisées pour le navigateur Safari. Novice frontal ...

Quels sont les avantages de la production de pages H5 Quels sont les avantages de la production de pages H5 Apr 05, 2025 pm 11:48 PM

Les avantages de la production de pages H5 comprennent: une expérience légère, une vitesse de chargement rapide et une amélioration de la rétention des utilisateurs. Compatibilité multiplateforme, pas besoin de s'adapter à différentes plates-formes, améliorant l'efficacité du développement. Flexibilité et mises à jour dynamiques, aucun audit requis, ce qui facilite la modification et la mise à jour du contenu. Les coûts de développement rentables et économiques que les applications natives.

Impossible de se connecter à MySQL en tant que racine Impossible de se connecter à MySQL en tant que racine Apr 08, 2025 pm 04:54 PM

Les principales raisons pour lesquelles vous ne pouvez pas vous connecter à MySQL en tant que racines sont des problèmes d'autorisation, des erreurs de fichier de configuration, des problèmes de mot de passe incohérents, des problèmes de fichiers de socket ou une interception de pare-feu. La solution comprend: vérifiez si le paramètre Bind-Address dans le fichier de configuration est configuré correctement. Vérifiez si les autorisations de l'utilisateur racine ont été modifiées ou supprimées et réinitialisées. Vérifiez que le mot de passe est précis, y compris les cas et les caractères spéciaux. Vérifiez les paramètres et les chemins d'autorisation du fichier de socket. Vérifiez que le pare-feu bloque les connexions au serveur MySQL.

Pourquoi un élément div spécifique dans le navigateur Edge ne s'affiche-t-il pas? Comment résoudre ce problème? Pourquoi un élément div spécifique dans le navigateur Edge ne s'affiche-t-il pas? Comment résoudre ce problème? Apr 05, 2025 pm 08:21 PM

Comment résoudre le problème d'affichage causé par les feuilles de style d'agent utilisateur? Lorsque vous utilisez le navigateur Edge, un élément DIV du projet ne peut pas être affiché. Après avoir vérifié, j'ai posté ...

Pourquoi mon image marquée A télécharge-t-elle automatiquement lorsqu'elle est liée à l'image d'origine homosexuelle? Pourquoi mon image marquée A télécharge-t-elle automatiquement lorsqu'elle est liée à l'image d'origine homosexuelle? Apr 05, 2025 pm 03:39 PM

En ce qui concerne le problème de téléchargement automatique des images lorsque les liens de balises avec la même origine, de nombreux développeurs rencontreront l'image après avoir cliqué lors de l'utilisation de liens de balise avec la même origine ...

See all articles