Changement dynamique en innodb_flush_log_at_trx_commit

11

Ceci est lié à cette question . Cela aide à obtenir de meilleures performances pour les tables InnoDB.

Selon le manuel MySQL , innodb_flush_log_at_trx_commitest une variable dynamique globale. Ainsi, je peux le changer en utilisant la commande SET GLOBAL et cela semble fonctionner.

mysql> SET GLOBAL innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected

mysql> SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set

Mais, cela n'a pas modifié le paramètre MySQL réel. Lorsque j'ai mis à jour my.cnf et redémarré le serveur MySQL, cela a fonctionné. Donc, je ne peux pas changer la variable globale au moment de l'exécution?

Je préfère la valeur par défaut innodb_flush_log_at_trx_commit=1, mais je dois la changer à 2 avant d'exécuter un processus de restauration pour une grande base de données pour obtenir plus rapidement. Mais une fois le processus terminé, je souhaite redéfinir la valeur sur 1. Est-il possible de le faire au moment de l'exécution?

Je n'ai pas accès à my.cnf sur mon serveur d'hébergement partagé.

Sithu
la source

Réponses:

12

Bien que je sois d'accord avec la recommandation de Rolando de changer innodb_flush_method, je ne savais pas à 100% ce que vous vouliez dire par:

il n'a pas modifié le paramètre MySQL réel

Je tiens à souligner la mise en garde selon laquelle une modification de la variable GLOBAL affecte toutes les nouvelles connexions, mais ne modifie pas la session en cours (c'est moi qui souligne):

La modification de la variable globale n'affecte pas la variable de session pour tout client actuellement connecté ( pas même celui du client qui émet l'instruction SET GLOBAL ).

Donc pour vérifier que:

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)


mysql> SHOW SESSION VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> SHOW SESSION VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> connect;
Connection id:    6
Current database: *** NONE ***

mysql> SHOW SESSION VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.00 sec)
Derek Downey
la source
2
Cette réponse est logique. La documentation ( dev.mysql.com/doc/refman/5.5/en/… ) ne dit pas que la variable au niveau de la session peut être modifiée, seulement le niveau global. J'ai expérimenté que de nombreuses fois changer max_connections avec SET GLOBAL max_connections = 1000;et quand je cours SHOW VARIABLES LIKE 'max_connections';pour voir l'ancienne valeur conduirait à des écrous méchants jusqu'à ce que je me déconnecte et me reconnecte . +1 pour ce point de vue qui est tenu pour acquis et souvent oublié.
RolandoMySQLDBA
@Rolando moi aussi! aussi, j'étais content quand j'ai découvert que je pouvais «me connecter»; au lieu de vous déconnecter puis de vous reconnecter. Gagnez du temps!
Derek Downey
Ce concept de fonctionnement connectest en fait nouveau pour moi dans MySQL. Je l'ai fait un million de fois dans PostgreSQL et Oracle. Je n'ai jamais pensé à MySQL permettant cela
RolandoMySQLDBA
@DTest, Merci pour votre réponse. Selon mon test approfondi, cela a fonctionné de manière dynamique. Dans mon localhost, la variable de session a été modifiée sans exécuter connect (j'ai eu une erreur lors du problème connect). Avec la valeur 2, l'importation de 2 241 319 enregistrements a pris 27 minutes 43 secondes, alors qu'il a fallu environ 1 jour avec la valeur 1. Le paramètre semble fonctionner dans la session en cours, mais il a restauré le paramètre d'origine (à partir de my.cnf) après le redémarrage.
Sithu
@DerekDowney, Est-ce juste pour certains paramètres comme innodb_flush_log_at_trx_commit? Ou est-ce que pour tous les paramètres, la définition de globaln'affecterait pas la session en cours?
Pacerier
7

En définissant innodb_flush_log_at_trx_commit , vous risquez de confondre avec l'interopérabilité mysqld / OS. Je dis cela parce que le système d'exploitation est approuvé pour effectuer le vidage.

Notez la prudence dans la documentation MySQL

De nombreux systèmes d'exploitation et du matériel disque trompent l'opération de vidage sur disque. Ils peuvent dire à mysqld que la vidange a eu lieu, même si ce n'est pas le cas. Ensuite, la durabilité des transactions n'est pas garantie même avec le paramètre 1, et dans le pire des cas, une panne de courant peut même corrompre la base de données InnoDB. L'utilisation d'un cache disque sauvegardé par batterie dans le contrôleur de disque SCSI ou dans le disque lui-même accélère les vidages de fichiers et rend l'opération plus sûre. Vous pouvez également essayer d'utiliser la commande Unix hdparm pour désactiver la mise en cache des écritures sur disque dans les caches matériels, ou utiliser une autre commande spécifique au fournisseur de matériel.

Ce que cela dit est le suivant: l'OS peut mentir comme un mari qui triche. Le système d'exploitation indique qu'il videra le disque et ne le fera tout simplement pas. Par conséquent, même si vous définissez innodb_flush_log_at_trx_commit, vous devez dissocier le vidage du système d'exploitation sur le disque du vidage de mysqld sur le disque.

Essayez de définir innodb_flush_method sur O_DIRECT si vous ne l'avez pas déjà fait. Vous pouvez voir une différence parce que la méthode de vidage diffère considérablement (voir ma Mar 04, 2011publication Clarification sur la variable innodb_flush_method de MySQL ).

CAVEAT

Comme vous l'avez mentionné, vous n'y avez pas accès my.cnf. Veuillez contacter le SysAdmin de votre fournisseur et faire modifier innodb_flush_method .

MISE À JOUR 2012-12-10 12:45 EDT

J'utilise actuellement MySQL 5.5.12 sur mon PC. Quand je me connecte et que show variables like 'innodb_flush_method';je cours, je reçois

mysql> show variables like 'innodb_flush_method';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| innodb_flush_method |       |
+---------------------+-------+
1 row in set (0.05 sec)

mysql>

Puisqu'il est vide, cela indique simplement que le paramètre par défaut est utilisé. Veuillez lire mon article du 04 mars 2011 pour des clarifications sur la variable MySQL innodb_flush_method

RolandoMySQLDBA
la source
J'ai d'abord testé dans mon localhost. Je ne pouvais pas trouver innodb_flush_methoddans my.ini(non my.cnf). Informations sur le serveur - Apache 2.4.1, PHP 5.4.4, MySQL 5.5
Sithu
J'ai remarqué que quelle que soit la version du serveur ou ini / cnf, le fichier de configuration n'a pas de innodb_flush_methodparamètre et SHOW VARIABLESne l'affiche pas.
Sithu
Merci pour votre MISE À JOUR, je l'ai eu aussi, je me demandais juste pourquoi nous ne pouvons pas voir sa valeur. Comme je n'ai pas pu le trouver dans my.iniou my.cnfet que ce n'est pas une variable dynamique, je ne sais pas comment je peux le configurer.
Sithu