Alterado max_allowed_packet e ainda recebendo o erro 'Pacote muito grande'

8

Eu uso o mysqldump para criar um arquivo simples para fins de backup. Eu usei esse arquivo para recriar o banco de dados em um servidor alternativo. Executei o processo de importação através do ssh na linha de comando e recebi vários Packet too Largeerros.

Eu reiniciei o mysql com um max_allowed_packet muito maior (ou seja, 1000M) e ainda recebi o erro. Eu até tentei configurar o max_allowed_packet no arquivo de importação, ainda recebi o erro.

Existe uma maneira de garantir que o max_allowed_packet esteja definido e / ou use o mysqldump que criará um arquivo que não causa esse problema?

Para referência:

o arquivo mysqldump descompactado é de ~ 2 GB

tipo de banco de dados é INNODB

Patrick
fonte

Respostas:

5

A primeira que pensei foi sobre o que max_allowed_packet realmente controla. Aqui está o que eu encontrei:

De acordo com a página 99 de "Entendendo o MySQL Internals" (ISBN 0-596-00957-7) , aqui estão os parágrafos 1-3 que explicam:

O código de comunicação de rede do MySQL foi escrito sob a suposição de que as consultas são sempre 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 caber totalmente nele. 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.

Dada a definição de max_allowed_packet, descobri outra coisa no ServerFault: innodb_log_file_size e innodb_log_buffer_size combinados devem ser maiores que dez vezes o seu maior objeto de blob, se você tiver muitos objetos grandes

Mantendo essas duas coisas em mente, eu aumentaria innodb_log_file_size em /etc/my.cnf para o tamanho máximo permitido, 2047M. Obviamente, isso requer o seguinte

service mysql stop
rm -f /var/lib/mysql/ib_logfile*
service mysql start

Isso acomodará todos os grandes blobs que você possa ter em seus dados.

RolandoMySQLDBA
fonte
Curioso para saber de onde vem esse 10x - é apenas uma regra prática ou existe um código no MySQL que aloca 10 buffers fixos para que você precise de 10 para garantir que um deles seja grande o suficiente?
Gaius
Este livro é autoritário?
Pacerier
2

O MySQL max_allowed_packetainda precisa estar dentro dos limites do shell que o iniciou - ulimit -amostra que data seg sizeé ilimitado?

Gaius
fonte
2

Por alguma razão, max_allowed_packeté ignorado por mysqldump- por design ? O complemento real é net_buffer_length. Então tente

mysqldump --net_buffer_length=100k -u root -p databasename > dump.sql
Leopd
fonte
Isso é muito esclarecedor !!! Como o relatório de erros discute a inserção estendida em conjunto com esse problema, talvez fazer --skip-extended-insert possa compensar alguns, mas certamente irá gerar um mysqldump maior. +1 para Você encontrar este diamante em bruto que a Oracle deixará para morrer !!!
RolandoMySQLDBA
--skip-extended-insert definitivamente funciona, mas no meu banco de dados diminuiu a velocidade da restauração em 100x, tornando-a inutilizável.
Leopd
Sinto muito, minhas condolências. Talvez o mysqldump crie arquivos CSV e tente carregá-los novamente usando LOAD DATA INFILE e aumentando bulk_insert_buffer_size para 1G ou 2G. Ei, você nunca sabe !!!
RolandoMySQLDBA