Servidor MySQL desapareceu obstruindo importação de grandes lixões

14

Estou tentando importar um grande despejo de sql (2 GB) para o meu mysql local no meu mac. Consegui fazer isso no passado (eu estava usando o MAMP), mas agora recebo um ERRO 2006 (HY000) na linha 7758: O servidor MySQL desapareceu toda vez que tento importar o despejo. O banco de dados contém tabelas innodb.

Tentei copiar o arquivo my-innodb-heavy-4G.cnf para o meu my.cnf para ver se essas configurações ajudariam, mas sem sorte.

Alguma idéia sobre o que ajustar?

Estou usando o "Mac OS X versão 10.6 (x86, 64 bits), DMG Archive" aqui: http://dev.mysql.com/downloads/mysql/

naxoc
fonte

Respostas:

15

Um dos assassinos silenciosos do MySQL Connections é o MySQL Packet. Até o segmento de E / S da replicação do MySQL pode ser vítima disso.

De acordo com a documentação do MySQL

  • Você também pode obter esses erros se enviar uma consulta ao servidor incorreta ou muito grande. Se o mysqld recebe um pacote muito grande ou fora de ordem, assume que algo deu errado com o cliente e fecha a conexão. Se você precisar de grandes consultas (por exemplo, se estiver trabalhando com grandes colunas BLOB), poderá aumentar o limite de consultas definindo a variável max_allowed_packet do servidor, que possui um valor padrão de 1 MB. Também pode ser necessário aumentar o tamanho máximo do pacote no lado do cliente. Mais informações sobre a configuração do tamanho do pacote são fornecidas na Seção C.5.2.10, “Pacotes muito grandes”.

  • Uma instrução INSERT ou REPLACE que insere muitas linhas também pode causar esse tipo de erro. Qualquer uma dessas instruções envia uma única solicitação ao servidor, independentemente do número de linhas a serem inseridas; portanto, muitas vezes você pode evitar o erro reduzindo o número de linhas enviadas por INSERT ou REPLACE.

No mínimo, você deve certificar-se de que os tamanhos dos pacotes para a máquina da qual você mysqldump e a máquina que você está carregando sejam idênticos.

Pode haver duas (2) abordagens que você pode adotar:

ABORDAGEM # 1: Execute o mysqldump usando --skip-extended-insert

Isso garantirá que o pacote MySQL não seja inundado com vários campos BLOBs, TEXT. Dessa forma, os SQL INSERTs são executados um de cada vez. As principais desvantagens são

  1. o mysqldump é muito maior
  2. recarregar esse despejo leva muito mais tempo.

ABORDAGEM 2: Aumentar max_allowed_packet

Esta pode ser a abordagem preferida porque implementar isso é apenas uma reinicialização do mysql. Entender o que é o pacote MySQL pode esclarecer isso.

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 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.

Dada essa explicação, criar INSERTs em massa carregará / descarregará um pacote MySQL rapidamente. Isso é especialmente verdadeiro quando max_allowed_packet é muito pequeno para a carga de dados fornecida.

CONCLUSÃO

Na maioria das instalações do MySQL, costumo definir isso para 256M ou 512M. Você deve experimentar valores maiores quando o carregamento de dados produzir erros "O MySQL se foi".

RolandoMySQLDBA
fonte
Tentei ajustar max_allowed_packetpara 900M e estava usando --skip-extended-insert(e você está certo - isso faz com db-dumps huuuge), mas ainda falha. Estou suspeitando de uma linha específica no despejo agora que provavelmente posso contornar. Mas ainda é estranho - o dump pode ser importado corretamente no meu servidor CentOS.
naxoc 02/09/11
Acabei removendo uma inserção do dump sql que era uma linha muito, muito longa. Isso foi corrigido (e a linha não era necessária).
Naxoc 3/09
Entre, certifique-se de que o caractere padrão para o despejo de dados possa ser suportado no sistema operacional MacOSX e no MySQL.
RolandoMySQLDBA
@ Naxov - Estou apenas curioso sobre a linha que você suspeita no lixão. Existem campos TEXTO ou BLOB envolvidos ??
RolandoMySQLDBA
Sim, um campo de texto muito longo.
naxoc
2

Quanto tempo isso dura antes de atingir o tempo limite? A primeira etapa seria apostar para verificar as configurações wait_timeoute interactive_timeoutpara garantir que elas sejam grandes o suficiente para sua importação:

SHOW VARIABLES LIKE '%_timeout';
SET SESSION wait_timeout=28800;

O padrão é 8 horas (28800), então esse não é o problema potencial. Outras indicações desse problema podem ser encontradas aqui . Um que se destaca é o seguinte:

Um aplicativo cliente em execução em um host diferente não possui os privilégios necessários para conectar-se ao servidor MySQL desse host.

Verifique as permissões primeiro, mas depois analise a lista de possíveis problemas.

Derek Downey
fonte
É tudo no host local, então ou eu não entendo o que você quer dizer ou não é o problema. Você quis dizer permissões como privilégios no mysql?
naxoc 02/09/11
2

Sim, geralmente jogar com wait_timeout e max_allowed_packets também me permite contornar a mensagem de erro.

p4guru
fonte
Isso não funcionou para mim. Eu tive que editar o sql no arquivo de despejo e remover uma linha muito longa que estava causando o problema.
Naxoc 3/09
não se deve brincar com alguns parâmetros que não entende
Jeredepp
2

Pode não ser a coisa "correta" a ser feita, mas pode funcionar (pronto, certo?):

Tente dividir seu arquivo grande em vários arquivos e executá-los um de cada vez em sequência. Minha abordagem seria quebrá-lo ao meio e testar. Em seguida, quebre cada metade ao meio, teste novamente e assim por diante.

Estou um pouco curioso se a quantidade de RAM que você tem na sua caixa pode ter algo a ver com isso. O MySQL carrega todo o despejo na memória quando ele é executado? Não sei ... mas se você tiver apenas 2 GB de RAM e parte dela estiver em execução com o sistema operacional e outros aplicativos, esse pode ser o problema.

Dia Davis Waterbury
fonte
2

Aqueles que não tiveram sucesso com as outras sugestões podem considerar dar uma olhada no script importador de despejos de MySQL do BigDump PHP .

É uma solução alternativa para importar grandes despejos de banco de dados no MySQL. Eu o usei com sucesso para importar um grande dump do MySQL para o meu ambiente de desenvolvimento local (estou usando o MAMP neste caso).

Marcus Barnes
fonte