Alteração dinâmica para innodb_flush_log_at_trx_commit


11

Isso está relacionado a esta questão . Ajuda a obter melhor desempenho para tabelas do InnoDB.

De acordo com o manual do MySQL , innodb_flush_log_at_trx_commité uma variável dinâmica global. Assim, eu posso alterá-lo usando o comando SET GLOBAL e parece estar funcionando.

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

Mas isso não alterou a configuração real do MySQL. Quando atualizei o my.cnf e reiniciei o servidor MySQL, ele funcionou. Então, não posso alterar a variável global em tempo de execução?

Prefiro o valor padrão innodb_flush_log_at_trx_commit=1, mas preciso alterá-lo para 2 antes de executar um processo de restauração para que um banco de dados grande fique mais rápido. Mas quando o processo terminar, quero alterar o valor novamente para 1. É possível fazer isso em tempo de execução?

Não tenho acesso ao my.cnf no meu servidor de hospedagem compartilhada.

Respostas:


12

Embora eu concorde com a recomendação de mudança de Rolando innodb_flush_method, não fiquei 100% claro do que você quis dizer com:

não alterou a configuração real do MySQL

Quero ressaltar a ressalva de que fazer uma alteração na variável GLOBAL afeta novas conexões, mas não modifica a sessão atual (ênfase minha):

A alteração da variável global não afeta a variável da sessão para qualquer cliente conectado no momento ( nem mesmo o cliente que emite a instrução SET GLOBAL ).

Então, para verificar isso:

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)

2
Essa resposta faz sentido. A documentação ( dev.mysql.com/doc/refman/5.5/en/… ) não diz que a variável no nível da sessão pode ser alterada, apenas o nível global. Eu experimentei que muitas vezes alterar max_connections com SET GLOBAL max_connections = 1000;e quando corro SHOW VARIABLES LIKE 'max_connections';para ver o valor antigo deixaria mal-humorado até eu sair e entrar novamente. +1 para esse ponto de vista que é dado como certo e muitas vezes esquecido.
RolandoMySQLDBA

@Rolando me também! também fiquei feliz quando descobri que podia 'me conectar'; em vez de sair e voltar. Economiza tempo!
Derek Downey

Esse conceito de execução connecté realmente novo para mim no MySQL. Eu já fiz isso um milhão de vezes no PostgreSQL e Oracle. Eu nunca pensei de MySQL permitindo que
RolandoMySQLDBA

@ Test, Obrigado pela sua resposta. De acordo com meu teste profundo, funcionou dinamicamente. No meu host local, a variável de sessão foi alterada sem executar o connect (recebi um erro ao emitir connect). Com o valor 2, a importação de 2.241.319 registros levou 27 minutos e 43 segundos, enquanto levou cerca de 1 dias com o valor 1. A configuração parece estar funcionando na sessão atual, mas restaurou a configuração original (de my.cnf) após a reinicialização.
Sithu

@DerekDowney, isso é apenas para determinadas configurações, como innodb_flush_log_at_trx_commit? Ou será que, para todas as configurações, definir o globalnão afetaria a sessão atual?
Pacerier 9/04

7

Ao definir innodb_flush_log_at_trx_commit , você corre o risco de confusão com a interoperabilidade do mysqld / OS. Digo isso porque o sistema operacional está sendo confiável para executar o flush.

Observe o cuidado na documentação do MySQL

Muitos sistemas operacionais e alguns hardwares de disco enganam a operação de liberação em disco. Eles podem dizer ao mysqld que o flush ocorreu, mesmo que não tenha ocorrido. Portanto, a durabilidade das transações não é garantida, mesmo com a configuração 1, e, na pior das hipóteses, uma queda de energia pode até danificar o banco de dados do InnoDB. O uso de um cache de disco com bateria no controlador de disco SCSI ou no próprio disco acelera a liberação de arquivos e torna a operação mais segura. Você também pode tentar usar o comando Unix hdparm para desativar o armazenamento em cache de gravações de disco em caches de hardware ou usar algum outro comando específico do fornecedor de hardware.

O que isso diz é o seguinte: O sistema operacional pode mentir como um marido traidor. O sistema operacional diz que vai liberar para o disco e simplesmente não faz isso. Portanto, mesmo que você defina innodb_flush_log_at_trx_commit, você deve separar a liberação do SO para o disco da liberação do mysqld para o disco.

Tente definir innodb_flush_method como O_DIRECT se você ainda não o fez. Você pode ver uma diferença porque o método flush difere bastante (veja meu Mar 04, 2011post sobre esclarecimentos sobre a variável innodb_flush_method do MySQL ).

EMBARGO

Como você mencionou, você não tem acesso my.cnf. Entre em contato com o SysAdmin do seu provedor e altere o innodb_flush_method .

UPDATE 2012-12-10 12:45 EDT

Atualmente, estou executando o MySQL 5.5.12 no meu PC. Quando conecto e corro show variables like 'innodb_flush_method';, recebo

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

mysql>

Como está em branco, apenas indica que a configuração padrão é usada. Por favor, leia minha postagem em 04/03/2011 para esclarecimentos sobre a variável innodb_flush_method do MySQL


Eu testei no meu localhost primeiro. Não consegui encontrar innodb_flush_methodem my.ini(não my.cnf). Informações do servidor - Apache 2.4.1, PHP 5.4.4, MySQL 5.5
Sithu

Percebi que, independentemente da versão do servidor ou ini / cnf, o arquivo de configuração não possui innodb_flush_methodconfiguração e SHOW VARIABLESnão a mostra.
Sithu

Obrigado por sua atualização, eu também entendi, eu só queria saber por que não podemos ver o seu valor. Como não consegui encontrá-lo my.iniou my.cnfnão é uma variável dinâmica, não sei como configurá-lo.
Sithu
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.