XOOPS Brasil

 

A.4. Assuntos Relacionados a Administração

A.4.1. O Que Fazer Se o MySQL Continua Falhando

Todas as versões do MySQL são testadas em muitas plataformas antes de serem distribuídas. Isto não significa que não existe nenhum erro no MySQL, mas significa que se houver erros, eles são poucos e podem ser difíceis de encontrar. Se você tiver u problema, sempre ajudará se você tentar encontrar exatamente o que falhou em seu sistema e assim você terá uma chance muito maior de tê-lo corrigido rapidamente.

Primeiro, você deve tentar descobrir o problema é que o daemon do mysqld morre ou se o seu problema é relativo ao seu cliente. Você pode verificar o quanto tempo o seu servidor mysqld está em execução utilizando o mysqladmin version. Se o mysqld morrer, você pode encontrar a causa disto no arquivo mysql-data-directory/`nome_maquina`.err. Veja mais informações sobre isto na Seção 4.10.1, “O Log de Erros”.

Em alguns sistemas você pode encontrar neste arquivo um stack trace de onde o mysqld finalizou e assim você pode resolver com resolve_back_stack. Veja mais informações sobre isto na Seção E.1.4, “Usando Stack Trace”. Note qte os valores da variável escrita no arquivo .err não podem sempre estar 100% corretas.

Muitas falhas do MySQL são causadas por arquivos de índices/dados corrompidos. O MySQL atualizará os dados em disco, com a chamada de sistema write(), depois de todas as intruções SQL e antes do ser notificado sobre o resultado. (Isto não é verdade se você estiver executando com delay_key_write, caso no qual apenas o dado é escrito.) Insto significa que o dado é salvo mesmo se o mysqld falhar, já que o SO se certificará de que o dado não descarregado esta escrito em disco. Você pode forçar o MySQL a sincronizar tudo para o disco depois de todo comando SQL inicando o mysqld com --flush.

O exposto acimo significa que normalmente você não deve ter tabelas corrompidas a menos que:

  • Alguém/algo finalize o mysqld ou a máquina no meio de uma atualização.

  • Você encontrou um bug no mysqld que faça com que ele finalize no meio de uma atualização.

  • Alguém está manipulando os arquivos de dados/índices de fora do mysqld sem o bloqueio de tabela apropriado.

  • Se você estiver executando muitos servidores mysqld no mesmo dado em um sistema que não suporta bons bloqueios de sistema de arquivos (normalmente tartando o daemon lockd) ou se você está executando multiplos servidores com --skip-external-locking

  • Você tem um arquivo de dados/índices que contem muitos dados errados que deixam o mysqld confuso.

  • Você encontrou um bug no código de armazenamento do dado. Isto não é desejável mas é possível. Neste caso você ode tentar alterar o tipo de arquivo para outro mecanismo de armazenamento usando ALTER TABLE em uma cópia corrigida da tabela!

Por ser muito difícil saber o motivo das falhas, tente primeiro verificar se o que está funcionando para outros está falhando com você. Por favor, tente o seguinte:

Finalize o daemon mysqld com mysqladmin shutdown, execute myisamchk --silent --force */*.MYI em todas as tabelas e reinicie o daemon mysqld. Isto irá assegurar que você está executando de um estado ``limpo''. Veja mais informações sobre isto na Capítulo 4, Administração do Bancos de Dados MySQL.

  • Use mysqld --log e tente determinar a partir da informação no log se alguma consulta específica finalizou o servidor. Aproximadamente 95% de todos os erros são relacionados com um consulta em particular! Normalmente ela é uma das últimas consultas no arquivo de log antes do MySQL reiniciar Veja mais informações sobre isto na Seção 4.10.2, “O Log de Consultas”. Se você puder finalizar o MySQL repetidamente com uma das consultas, mesmo quando você tiver verificado todas as tabelas logo antes de realizá-la, então você estará apto a localizar o bug e deve fazer um relatório de bug para isto! Veja mais informações sobre isto na Seção 1.7.1.3, “Como relatar erros ou problemas”.

  • Tente fazer um caso de teste que possamos utilizar para reproduzir o problema. Veja mais informações sobre isto na Seção E.1.6, “Fazendo um Caso de Teste Se Ocorre um Corrompimento de Tabela”.

  • Tente executar o teste incluso mysql-test e o benchmark do MySQL. Veja mais informações sobre isto na Seção 14.1.2, “Pacotes de Teste do MySQL”. Eles devem testar o MySQL bem. Você também pode adicionar ao benchmark um código que simule a sua aplicação! O benchmark pode ser encontrado no diretório bench na distribuição fonte ou, em uma distribuição binária, no diretório sql-bench sob o diretório de instalação do seu MySQL.

  • Experimente fork_test.pl e fork2_test.pl.

  • Se você configurar o MySQL para depuração, será muito mais fácil para obter informações sobre possíveis erros se alguma coisa der errado. Reconfigure o MySQL com a opção --with-debug ou --with-debug=full no configure e então recompile-o. Veja mais informações sobre isto na Seção E.1, “Depurando um Servidor MySQL”.

  • Configurar o MySQL para depuração faz com que um alocador de memória seja incluído para que se possa encontrar alguns erros. Ele também fornece muita informação sobre o que está acontecendo.

  • Você aplicou todas as últimas correções para o seu sistema operacional?

  • Use a opção --skip-external-locking com o mysqld. Em alguns sistemas, o gerenciador de bloqueios lockd não funciona de forma apropriada; a opção --skip-external-locking faz com que mysqld não utilize bloqueio externo. (Isto significa que você não pode executar 2 servidores mysqld sobre o memo dado e que você deve ser cuidadoso ao utilizar myisamchk, mas pode ser instrutivo tentar a opção como teste).

  • Você tentou mysqladmin -u root processlist quando o mysqld parecia estar rodando mas não respondia? Algumas vezes o mysqld não está <<comatose>> mesmo quando você acha que não. O problema pode ser que todas as conexões estão em uso, o pode haver algum problema interno de bloqueio. mysqladmin processlist normalmente estará apto a fazer uma conexão mesmo nestes casos e pode fornecer informação útil sobre o número conexões atuais e os seus estados.

  • Execute o comando mysqladmin -i 5 status ou mysqladmin -i 5 -r status ou em uma janela separada para produzir estatísticas enquanto você executa outras consultas.

  • Experimente o seguinte:

    1. Inicie o mysqld a partir do gdb (ou em outro depurador). Veja mais informações sobre isto na Seção E.1.3, “Depurando o mysqld no gdb”.

    2. Execute o seu script de testes.

    3. Imprima o <<backtrace>> e as varáveis locais nos 3 níveis mais baixos. No gdb você pode fazê-lo com o seguinte comando quando o mysqld falhar dentro do gdb:

      backtrace
      info local
      up
      info local
      up
      info local
      

      Com gdb você também pode examinar quais threads existem com info threads e troca para uma thread específica com thread #, onde # é a ID da thread.

  • Tente simular a sua aplicação com um script Perl para forçar o MySQL a falhar o mudar o seu comportamento.

  • Envie um relatório de bug normal. Veja mais informações sobre isto na Seção 1.7.1.3, “Como relatar erros ou problemas”. Seja mais detalhista que o normal. Como o MySQL funciona para muitas pessoas, pode ser que as falhas resultem de algo que exista apenas em seu computador (por exemplo, um erro que é relacionado a suas bibliotecas de sistemas em particular).

  • Se você tiver um problema em tabelas com registros do tamanho dinâmico e você não está usando colunas BLOB/TEXT (mas apenas colunas VARCHAR, você pode tentar alterar todas as colunas VARCHAR para CHAR com ALTER TABLE. Isto forçara o MySQL a usar linhas de tamanho fixo. Linhas de tamanho fixo utilizam um pouco mais de espaço extra, mas são muito mais tolerante a corrompimento.

    O código de registro dinâmico atual foi usado pela MySQL AB por pelo menos 3 anos em qualquer problema, mas por natureza os registro de tamanho dinâmico são mais propensos a erros, assim pode ser uma boa idéia tentar o exposto acima para ver se ajuda.

A.4.2. Como Recuperar uma Senha de Root Esquecida

Se você nunca definiu um senha de root para o MySQL, então o servidor não irá exigir uma senha para a conexão como root. É recomendado que sempre seja definida uma senha para cada utilizador. Veja mais informações sobre isto na Seção 4.3.2, “Como Tornar o MySQL Seguro contra Crackers”.

Se você tiver definido um senha de root, mas a esqueceu, você pode definir uma nova senha com o seguinte procedimento:

  1. Finalize o daemon mysqld enviando um kill (não kill -9) para o servidor mysqld. O pid é armazenado em um arquivo .pid, que normalmente está no diretório de banco de dados do MySQL:

    shell> kill `cat /mysql-data-directory/hostname.pid`
    

    Você deve ser o utilizador root do Unix ou o mesmo utilizador com o qual o mysqld está executando para fazer isto.

  2. Reinicie o mysqld com a opção --skip-grant-tables.

  3. Defina uma nova senha com o comando mysqladmin password:

    shell> mysqladmin -u root password 'mynewpassword'
    

  4. Agora você também pode parar o mysqld e reiniciá-lo normalmente, ou apenas carregue a tabela de privilégios com:

    shell> mysqladmin -h hostname flush-privileges
    

  5. Depois disto, você deve estar apto para conectar usando a nova senha.

De forma alternativa, você pode definir a nova senha usando o cliente mysql:

  1. Finalize e reinicie o mysqld com a opção --skip-grant-tables com descrito acima.

  2. Conecte ao servidor mysqld com:

    shell> mysql -u root mysql
    

  3. Dispare os seguintes comandos no cliente mysql:

    mysql> UPDATE user SET Password=PASSWORD('minhanovasenha')
    -> WHERE User='root';
    mysql> FLUSH PRIVILEGES;
    

  4. Depois disto, você deve estar apto a conectar usando a nova senha.

  5. Você agora pode parar o mysqld e reiniciá-lo normalmente.

A.4.3. Como o MySQL Trata de Discos Sem Espaço

Quando o ocorre uma condição de disco sem espaço, o MySQL faz seguinte:

  • Ele verifica a cada minuto para ver se existe espaço suficiente para escrever a linha atual. Se houver espaço suficiente, ele continua como se nada tivesse aconteciso.

  • A cada 6 minutos ele grava uma entrada no log de arquivo avisando sobre a condição de disco cheio.

Para aliviar o problema, você pode realizar as seguintes ações:

  • Para continuar, você só tem que liberar espaço suficiente em disco para inserir todos os registros.

  • Para abortar a thread, você deve enviar um mysqladmin kill para a thread. A thread será abortada a próxima vez que ele verificar o disco (em 1 minuto).

  • Note que outra thread pode estar esperando pelas tabelas que provocaram a condição de disco cheio. Se você tiver diversas theads ``bloqueadas'', matar a que está esperando pela condição de disco cheio irá permitir as outras threads de continuar.

A exceção ao comportamento acima é quando você usa REPAIR ou OPTIMIZE ou quando os índices são criados em um grupo antes de um LOAD DATA INFILE ou depois de uma instrução ALTER TABLE.

Todos os comandos acima podem usar arquivos temporários grandes que por si próprios poderiam causar grandes problemas para o resto do sistema. Se o MySQL ficar sem espaço em disco enquanto faz qualquer uma das operações acima, ele removerá o arquivo temporário grande e indicara que houve falha na tabela (exceto para ALTER TABLE, no qual a tabela antiga ficará inalterada).

A.4.4. Onde o MySQL Armazena Arquivos Temporários

O MySQL usa o valor da variável de ambiente TMPDIR como caminho para o diretória que aramzena os arquivos temporários. Se você não tiver definido TMPDIR, o MySQL usa o padrão do sistema, que normalmente é /tmp ou /usr/tmp. Se o sistema de arquivo contendo o seu diretório de arquivo temporário é muito pequeno, você deve editar o mysqld_safe para configurar TMPDIR para apontar para um diretório onde você tenha espaço suficiente! Você também pode definir o diretório temporário usando a opção --tmpdir com mysqld.

O MySQL cria todos os arquivos temporários como arquivos ocultos. Isto assegura que os arquivos temporários serão removidos se o mysqld for terminado. A desvantagem de usar arquivos ocultos é que você não verá um arquivo temporário grande que enche o sistema de arquivos no qual o diretório de arquivos temporários está localizado.

Ao ordenar (ORDER BY ou GROUP BY), o MySQL normalmente usa um ou dois arquivos temporários. O espaço em disco máximo que você precisa é:

(tamanho do que é ordenado + sizeof(apontador do banco de dados))
* números de linhas encontradas
* 2

sizeof(apontados do banco de dados) normalmene é 4, mas pode crescer no futuro para tabelas realmente grandes.

Para algumas consultas SELECT, o MySQL também cria tabelas SQL temporárias. Elas não são ocultas e têm nomes da forma SQL_*.

ALTER TABLE cria uam tabela temporária no mesmo diretório da tabela original.

Se você está usando o MySQL 4.1 ou posterior você pode espalhar a carga entre vários discos físicos definindo --tmpdir com uma lista de caminhos separados por dois pontos : (ponto e vírgula ; no Windows). Eles serão feitos através de escalonamento round-robin. Nota: Estes caminhos devem ser de diferentes discos físicos, e não partições diferentes do mesmo disco.

A.4.5. Como Proteger ou AlterarHow to Protect or Change the MySQL Socket File /tmp/mysql.sock

Se você tiver problemas com o fato que de que qualquer um pode deletar o socket de comunicação /tmp/mysql.sock do MySQL, você pode, na maioria das versões Unix, protejer o seu sistema de arquivos /tmp definindo o bit sticky. Conecte como root e faça o seguinte:

shell> chmod +t /tmp

Isto protejerá o seu sistema de arquivos /tmp para que os arquivos só possam ser deletados pelo seus donos ou pelo superutilizador (root).

Você pode verificar se o bit sticky está setado executando ls -ld /tmp. Se o último bit de permissão é t, o bit está configurado

Você pode alterar o local onde o MySQL usa/coloca o arquivo de socket da seguinte maneira:

  • Especifique o caminho em uma arquivo de opção local ou global. Por exemplo, coloque em /etc/my.cnf:

    [client]
    socket=path-for-socket-file
    [mysqld]
    socket=path-for-socket-file
    

    Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Especificando isto na linha de comando para o mysqld_safe e na maioria dos clientes com a opção --socket=path-for-socket-file.

  • Especifique o caminho para o socket na variável de ambiente MYSQL_UNIX_PORT.

  • Definindo o caminho com a opção --with-unix-socket-path=path-for-socket-file do configure. Veja mais informações sobre isto na Seção 2.3.3, “Opções típicas do configure.

Você pode testar se o socket funciona com o seguinte comando:

shell> mysqladmin --socket=/path/to/socket version

A.4.6. Problemas Com Fuso Horário

Se você tiver problema com SELECT NOW() retornando valores em GMT e não em sua hora local, você terá que definir a variável de ambinte TZ com a seu fuso horário atual. Isto deve ser feito no ambiente no qual o servidor é executado, por exemplo, em mysqld_safe ou mysql.server. Veja mais informações sobre isto na Apêndice F, Variáveis de Ambientes do MySQL.