Por que as tabelas do MySQL falham? Como evito isso?


9

Sou o administrador de um site Moodle que teve sua tabela Usuários corrompida e ficou inutilizável.

Felizmente, um simples REPAIR TABLE mdl_userfez funcionar novamente. O fato é que não sei por que ele realmente travou e o tornou inutilizável, e quero ter certeza de que estou melhor preparado da próxima vez.

Eu não sou um DBA experiente - sou apenas um desenvolvedor que faz um monte de coisas, então, por favor, tenha paciência comigo.

Eu poderia apenas restaurar um backup, mas acho que existem maneiras de evitar falhas.

Essas tabelas são utf8_general_ci e usam MyISAM.

Por que uma tabela do MySQL falha? O que posso fazer para impedir que isso aconteça?

Respostas:


11

É bastante fácil para uma tabela do MyISAM falhar.

No cabeçalho de todas as tabelas MyISAM, há um contador que rastreia quantos identificadores de arquivos abertos existem na tabela.

Se você iniciar o mysql e o número no cabeçalho não corresponder ao número real de identificadores de arquivos, o mysqld tratará a tabela como travada.

Se um simples REPAIR TABLE mdl_userfaz com que ele funcione novamente todas as vezes sem perda de dados, isso pode indicar que você tem um site com tráfego muito alto que grava mdl_user.

Se dezenas de tabelas exigirem isso REPAIR TABLE, eu converteria todas as tabelas para o InnoDB. No entanto, se a mdl_usertabela é a única tabela com esse problema, há algo que você pode fazer (neste exemplo, digamos que o banco de dados seja moodle);

Se você deseja que todas as tabelas sejam deixadas como MyISAM

PASSO 01: Criar um script de tabela de reparo

echo "REPAIR TABLE moodle.mdl_user;" > /var/lib/mysql/MoodleStartUp.sql

PASSO 02: Declarar o script de reparo como o arquivo de inicialização

Adicione isso ao /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql

PASSO 03: Reinicie o mysql

Toda reinicialização do mysql acionará o Script da Tabela de Reparos

Se você deseja que todas as tabelas se tornem InnoDB

Execute esse código para criar um script de conversão em massa das tabelas MyISAM para o InnoDB e visualize-o

MYSQL_USER=root
MYSQL_PASS=password
MYSQL_CONN="-u${MYSQL_USER} -p ${MYSQL_PASS}"
echo "SET SQL_LOG_BIN = 0;" > /root/ConvertMyISAMToInnoDB.sql
mysql ${MYSQL_CONN} -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" > /root/ConvertMyISAMToInnoDB.sql
less /root/ConvertMyISAMToInnoDB.sql

Quando estiver satisfeito com o conteúdo do script de conversão, execute-o

mysql ${MYSQL_CONN} < /root/ConvertMyISAMToInnoDB.sql

ATUALIZAÇÃO 15-03-2012 14:00 EDT

@ Kevin , enquanto estiver usando o MyISAM, e se ficar sem espaço em disco é seu problema?

Aqui está algo a considerar: De acordo com o MySQL 5.0 Certification Study Guide ,

insira a descrição da imagem aqui

bulletpoint # 11 diz o seguinte nas páginas 408.409 Seção 29.2:

Se você ficar sem espaço em disco ao adicionar linhas a uma tabela MyISAM, nenhum erro ocorrerá. O servidor suspende a operação até que o espaço fique disponível e, em seguida, conclui a operação.

Quando você ficar sem espaço em disco, não basta desligar ou matar o mysql. A contagem de identificadores de arquivos abertos em qualquer MyISAM usado atualmente não será limpa. Assim, a tabela MyISAM está marcada como travada. Se você pode liberar espaço em disco no volume de dados com o mysqld ainda em execução, o mysqld será ativado assim que o espaço em disco for disponibilizado.


Excelente resposta. Você não sabia a parte dos manipuladores de arquivos e já resolveu como posso impedir (ou reparar automaticamente) caso algo dê errado. Alguma sugestão de segurança se o site realmente faz muitas gravações no mdl_user (ou em qualquer outra tabela)?
AeroCross

Você deve fazer três coisas: 1) aumentar a RAM, 2) aumentar o max_connections, 3) mudar para o InnoDB.
RolandoMySQLDBA 15/03/12

Noob aqui. Onde eu "executo" esse código? De um arquivo carregado no servidor ou de alguma linha de comando?
UncaughtTypeError

0

Eu também administro um site moodle no mysql, e a causa mais comum de corrupção de tabela para nós é ficar sem espaço em disco.


@RolandoMySQLDBA - sim, espaço em disco é certamente o problema (relacionado a alguns outros processos e à filosofia de gerenciamento em geral). Infelizmente, não vemos o problema se resolver quando o espaço é liberado ou não se resolve com rapidez suficiente. Minha resposta foi apenas apontar que, com nossa instância do moodle / mysql, problemas de espaço em disco podem causar falhas na tabela, independentemente do que o mysql / myisam deva fazer.
Kevin

-3

Encontrei uma boa linha para converter todas as tabelas para o InnoDB:

mysql -u root -p dbName -e "show table status where Engine='MyISAM';" | 
    awk 'NR>1 {print "ALTER TABLE "$1" ENGINE = InnoDB;"}'  | 
    mysql -u root -p dbName

O código pode estar ok para isso, mas não responde à pergunta da primeira parte (por que uma tabela do MySQL trava?). Se você quer dizer que ele responde à segunda parte (como evitá-lo?), Adicione mais explicações, por favor.
ypercubeᵀᴹ

Adicione também mais detalhes. A execução disso converterá todas as tabelas em um banco de dados? Ou todo o servidor? O que acontecerá se uma tabela falhar na conversão e recebermos um erro? É possível que acabemos com algumas tabelas convertidas e outras deixadas no MyiSAM? Em geral, que outras coisas um DBA deve considerar antes de executar isso?
ypercubeᵀᴹ
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.