Qual max_allowed_packet é grande o suficiente e por que preciso alterá-lo?

14

Eu tenho o MySQL (5.5) na configuração master-slave e criei outro servidor slave.

Parei o escravo original, joguei os dados, copiei e reimportei e funcionou bem. Observei a posição master_log do escravo original e usei esses comandos para configurá-lo no novo escravo

CHANGE MASTER TO MASTER_HOST='<ipaddress>', 
MASTER_USER='<username>', MASTER_PASSWORD='<password>', 
MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000851', 
MASTER_LOG_POS=15824150, 
MASTER_CONNECT_RETRY=10;

Quando eu comecei o novo escravo eu recebi

Last_IO_Error: erro fatal 1236 do mestre ao ler dados do log binário: 'a entrada do evento de log excedeu max_allowed_packet; Aumentar max_allowed_packet no master '

No entanto, quando iniciei o escravo original, ele alcançou muito bem e agora está sincronizado.

Então as perguntas:

  • o valor atual é 16 milhões, como sei qual o tamanho máximo? (Prefiro evitar tentativa e erro com um servidor de produção).

  • por que preciso aumentar o valor do mestre quando o escravo original lidou muito bem? O problema poderia realmente estar com o novo escravo?

atualizar

Aumentei o max_allowed_packet para 1073741824, como Rolando sugeriu no mestre, no antigo escravo e no novo escravo, e os reiniciei ( SET GLOBAL max_allowed_packet = 1073741824;por algum motivo não pareceu levar)

agora o último erro de IO é o mesmo de antes, mas agora vejo

Last_SQL_Error: falha na leitura do log de retransmissão: não foi possível analisar a entrada do evento do log de retransmissão. As possíveis razões são: o log binário do mestre está corrompido (você pode verificar isso executando 'mysqlbinlog' no log binário), o log de retransmissão do escravo está corrompido (você pode verificar isso executando 'mysqlbinlog' no log de retransmissão), problema de rede ou um erro no código MySQL do mestre ou escravo. Se você quiser verificar o registro binário do mestre ou o relé do escravo, poderá saber seus nomes emitindo 'SHOW SLAVE STATUS' neste escravo.

Se eu faço um mysqlbinlog no arquivo do mestre, ele passa com comandos muito felizes por séculos - o arquivo é 722M - se eu fizer isso no log de retransmissão do escravo, recebo

ERRO: Erro no Log_event :: read_log_event (): 'Falha na verificação de integridade', data_len: 38916267, event_type: 69

ERRO: Não foi possível ler a entrada no deslocamento 253: Erro no formato do log ou erro de leitura.

Eu verifiquei as variáveis ​​e as alterações funcionaram no entanto

mysql> show variable LIKE '% max_allowed_packet%';

no novo escravo mostrou max_allowed_packetE slave_max_allowed_packetonde, como no mestre, só temmax_allowed_packet

então eu fiz uma verificação de versão no master:

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 1.1.6                                |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.11-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

e no novo escravo

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 5.5.32                               |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.32-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

Essas duas versões estão muito distantes?

CodeMonkey
fonte
Há algo interessante aqui . Espero que isso seja útil.
Sathish D

Respostas:

18

Não há problema em maximizar o max_allowed_packet1G. Sempre que um pacote MySQL é construído, ele não salta para 1G desde o início. Por quê?

Primeiro você precisa saber o que é um pacote MySQL. Página 99 do Livro

Entendendo o MySQL Internals

explica nos parágrafos 1 a 3 da seguinte maneira:

O código de comunicação de rede do MySQL foi escrito sob a premissa de que as consultas sempre são razoavelmente curtas e, portanto, podem ser enviadas e processadas pelo servidor em um pedaço, chamado de pacote na terminologia do MySQL. O servidor aloca a memória para um buffer temporário para armazenar o pacote e solicita o suficiente para ajustá-lo inteiramente. Essa arquitetura requer uma precaução para evitar que o servidor fique sem memória - um limite para o tamanho do pacote, que essa opção realiza.

O código de interesse em relação a esta opção é encontrado em sql / net_serv.cc . Dê uma olhada em my_net_read () , siga a chamada para my_real_read () e preste atenção especial a net_realloc () .

Essa variável também limita o comprimento de um resultado de muitas funções de string. Veja sql / field.cc e sql / intem_strfunc.cc para obter detalhes.

Compare isso com a documentação do MySQL em max_allowed_packet:

O tamanho máximo de um pacote ou qualquer sequência gerada / intermediária ou qualquer parâmetro enviado pela função da API C mysql_stmt_send_long_data (). O padrão é 4 MB no MySQL 5.6.6, 1 MB antes disso.

O buffer da mensagem do pacote é inicializado para net_buffer_length bytes, mas pode crescer até max_allowed_packet bytes quando necessário. Esse valor por padrão é pequeno, para capturar pacotes grandes (possivelmente incorretos).

Você deve aumentar esse valor se estiver usando colunas BLOB grandes ou cadeias longas. Deve ser do tamanho do maior BLOB que você deseja usar. O limite do protocolo para max_allowed_packet é de 1 GB. O valor deve ser um múltiplo de 1024; os não múltiplos são arredondados para o múltiplo mais próximo.

Ao alterar o tamanho do buffer da mensagem alterando o valor da variável max_allowed_packet, você também deve alterar o tamanho do buffer no lado do cliente, se o seu programa cliente permitir. No lado do cliente, max_allowed_packet possui um padrão de 1 GB. Alguns programas, como o mysql e o mysqldump, permitem alterar o valor do lado do cliente, configurando max_allowed_packet na linha de comandos ou em um arquivo de opções.

Dada essa informação, você deve estar satisfeito com o fato de o MySQL expandir e contratar o pacote MySQL conforme necessário. Portanto, vá em frente e

Mestre e Escravo devem corresponder em termos de quem eles transmitem dados, especialmente dados BLOB.

UPDATE 2013-07-04 07:03 EDT

Nas suas mensagens sobre o log de retransmissão, parece que você tem o seguinte

  • um log de retransmissão corrompido
  • um bom log mestre

SUGESTÃO

SHOW SLAVE STATUS\G
STOP SLAVE;
CHANGE MASTER TO
MASTER_LOG_FILE='(Relay_Master_Log_File from SHOW SLAVE STATUS\G)',
MASTER_LOG_POS=(Exec_Master_Log_Pos from SHOW SLAVE STATUS\G);
START SLAVE;

A execução CHANGE MASTER TOlimpa todos os logs de retransmissão e começa com um novo. Você estará replicando a partir do Último Evento BinLog Principal (BinLog, Position) que foi executado no Escravo.

De uma chance !!!

RolandoMySQLDBA
fonte
obrigado, é ótimo que seja seguro; mas ainda não entendo por que preciso alterá-lo quando o valor atual corresponde ao mestre e ao outro escravo que está funcionando perfeitamente?
CodeMonkey 4/13/13
alguma coisa está acontecendo, eu adicionei mais detalhes
codemonkey
1
Apenas para sua informação: isso ocorreu quando redefini o processo de replicação e acidentalmente digitei o MASTER_LOG_FILEnome errado . Por exemplo, usado mysql-bin.000001quando eu deveria ter usado a mysql-bin.000003partir SHOW MASTER STATUSde CHANGE MASTER TO.
Mikko Ohtamaa
8

De certa forma embaraçoso, o problema eram nomes de arquivos incorretos para logs, causando resultados estranhos, reimportados com os nomes de arquivos corretos e estava tudo bem com a cabeça envergonhada

CodeMonkey
fonte
Muito obrigado! Você não foi o único a cometer esse erro.
Mikko Ohtamaa
3
Sempre vale a pena postar a resposta, mesmo que seja bobo. Todo mundo comete erros bobos, pois somos todos humanos. Além daqueles que são robôs.
John Hunt