A replicação paralela no MySQL evoluiu significativamente, permitindo que as réplicas processem transações de forma simultânea para reduzir o atraso (lag) em relação ao servidor primário. O método baseado em writeset é uma das formas mais eficientes de rastrear dependências de transações no MySQL 8.0, permitindo um paralelismo maior do que o tradicional baseada em commit groups.
1. Configuração do Mecanismo de Writeset no Servidor Primário
Para habilitar a geração de dependências baseada em writesets no primário, é necessário ajustar a variável binlog_transaction_dependency_tracking. O motor utiliza hashes das linhas modificadas para determinar se transações diferentes podem ser aplicadas concorrentemente na réplica sem violar a consistência.
-- Verificando o algoritmo de extração de hashes (padrão XXHASH64)
SHOW VARIABLES LIKE 'transaction_write_set_extraction';
-- Alterando o rastreio de dependência para WRITESET
SET GLOBAL binlog_transaction_dependency_tracking = 'WRITESET';
2. Configuração da Réplica para Processamento Paralelo
No lado da réplica, o multithreaded slave (MTS) deve ser configurado para utilizar o tipo LOGICAL_CLOCK. Isso permite que o SQL Thread distribua as tarefas entre múltiplos workers.
-- Interrompendo o processamento SQL para configuração
STOP SLAVE SQL_THREAD;
-- Definindo o tipo de paralelismo e a quantidade de threads de trabalho
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
SET GLOBAL slave_parallel_workers = 8;
-- Reiniciando o processamento
START SLAVE SQL_THREAD;
3. Análise de Desempenho e Redução de Latência
Sem a replicação paralela ativa, em cenários de alta carga no primário, a réplica frequentemente apresenta um aumento no Seconds_Behind_Master, operando de forma sequencial mesmo possuindo recursos de hardware disponíveis.
-- Exemplo de status com alta latência antes da otimização
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.50
Master_Log_File: binlog.000124
Read_Master_Log_Pos: 847293
Relay_Log_File: relay-bin.000008
Relay_Log_Pos: 452
Seconds_Behind_Master: 840
Slave_SQL_Running: Yes
Slave_SQL_Running_State: Applying batch of row changes (write)
Com a ativação das múltiplas threads de trabalho, é possível observar o status do processo distribuído através do comando SHOW PROCESSLIST, onde vários workers estarão aplicando alterações simultaneamente:
SHOW PROCESSLIST;
-- Resultado simplificado:
-- Id: 100, User: system user, State: Waiting for slave workers to process their queues
-- Id: 101, User: system user, State: Applying batch of row changes (write)
-- Id: 102, User: system user, State: Applying batch of row changes (write)
-- Id: 103, User: system user, State: Applying batch of row changes (write)
4. Verificação de Dependências no Binlog
Para confirmar que o servidor primário está marcando corretamente as transações para execução paralela, podemos analisar o log binário. O valor de last_committed idêntico em diferentes sequence_number indica que essas transações podem ser executadas ao mesmo tempo.
# Analisando o binlog para observar o agrupamento de commits
mysqlbinlog mysql-bin.000124 | grep -E "last_committed|GTID_NEXT" | head -n 15
# Saída esperada demonstrando paralelismo:
# GTID last_committed=1 sequence_number=2
# GTID last_committed=1 sequence_number=3
# GTID last_committed=1 sequence_number=4
# GTID last_committed=1 sequence_number=5
# GTID last_committed=4 sequence_number=6
# GTID last_committed=4 sequence_number=7
Neste exemplo, as transações com last_committed=1 podem ser prcoessadas em paralelo pela réplica, resulatndo em uma drenagem de fila muito mais veloz e eliminando o gargalo de thread única.