Eu tenho dois bancos de dados configurados para teste (portanto, não há dados ou conexões ao vivo).
O primeiro é um banco de dados MySQL 5.5.57
atuando como mestre. O segundo é um banco de dados MySQL 5.7.23
atuando como escravo. Ele está sendo executado Statement Based Replication
no MySQL 5.5 e Row Based Replication
no MySQL 5.7.
Por alguma razão, consultas maiores parecem levar muito mais tempo no MySQL 5.7. Por exemplo, tenho a seguinte tabela:
CREATE TABLE `test1` (
`col0` int(11) DEFAULT NULL,
`col1` int(11) DEFAULT NULL,
`col2` datetime DEFAULT NULL,
`col3 datetime DEFAULT NULL,
`col4` int(11) DEFAULT NULL,
`col5` int(11) DEFAULT NULL,
`col6` int(11) DEFAULT NULL,
`col7` int(4) DEFAULT NULL,
`col8` int(11) DEFAULT NULL,
`col9` datetime DEFAULT NULL,
`col10` datetime DEFAULT NULL,
`UniqRef` int(10) unsigned NOT NULL AUTO_INCREMENT,
`col11` tinyint(1) unsigned NOT NULL DEFAULT '0',
`col12` tinyint(1) unsigned zerofill DEFAULT NULL,
`col13` tinyint(1) unsigned DEFAULT NULL,
PRIMARY KEY (`UniqRef`),
KEY `col0` (`col0`),
KEY `col3` (`col3`),
KEY `col4` (`col4`),
KEY `col8` (`col8`),
KEY `col5` (`col5`),
KEY `col10` (`Deleted`),
KEY `col2` (`col2`),
KEY `col12` (`col12`) USING BTREE,
KEY `col13` (`col13`)
) ENGINE=InnoDB AUTO_INCREMENT=400046649 DEFAULT CHARSET=latin1;
A tabela tem 21 GB de tamanho e contém 83261829 linhas (usando count(*)
).
Se eu executar a consulta:
UPDATE test.test1 SET col9 = NOW() WHERE UniqRef IN ('397958600','397940686','397940704','397940678','397. . . . .
A consulta contém 6945 entradas uniqref. Ele é executado quase instantaneamente no MySQL 5.5, mas depois é replicado no MySQL 5.7 e leva 90 segundos para ser executado.
Alterei várias configurações, mas até agora não fizeram diferença:
SET @@global.slave_compressed_protocol = 0;
SET @@global.sync_binlog = 0;
set @@global.range_optimizer_max_mem_size = 0;
Também tentei alterar read_io_threads
e write_io_threads
para vários valores, além de alterar o número de buffer pool instances
e desabilitar os logs binários.
Existem outras variáveis que podem fazer a diferença para tentar acelerar isso que eu perdi?
ATUALIZAÇÃO 2018-10-17
Consegui acelerar as consultas quando executadas localmente (diretamente no MySQL 5.7) configurando SET @@global.range_optimizer_max_mem_size = 16777216;
. Após isso, as consultas passaram de 90+ segundos para 0 segundos.
No entanto, quando a mesma consulta foi executada no MySQL 5.5 e replicada no MySQL 5.7, ela ainda leva mais de 90 segundos para ser executada.
Parece que encontrei a solução. Simplificando, configurei o MySQL 5.5 para também usar a Replicação baseada em ROW, usando o seguinte processo:
Depois disso, executei a consulta grande no MySQL 5.5 (executou instantaneamente) e, quando replicou para o MySQL 5.7, também foi executada instantaneamente.
Portanto, parece haver algum problema com as consultas de replicação baseadas em instruções de processamento do MySQL 5.7 de um servidor MySQL 5.5.
. . . Mas a trama se complica. Embora o banco de dados MySQL 5.5 alegasse estar usando a replicação baseada em ROW:
SELECT @@GLOBAL.binlog_format;
=ROW
e o fato de que isso parece ter ajudado na replicação para o MySQL 5.7, quando peguei os logs binários mais recentes (uma hora depois ou cerca de 10 logs binários depois) e corri
mysqlbinlog
contra eles, fiquei surpreso ao ver que eles ainda estavam preenchidos comSTATEMENTs
. Foi somente após uma reinicialização completa do banco de dados que os logs binários começaram a produzir o novoROW
formato baseado! ! !