FATOS
Você disse que está usando ext4
. O limite de tamanho do arquivo é 16 TB. Assim, Sample.ibd
não deve estar cheio.
Você disse que innodb_data_file_path
é ibdata1:10M:autoextend
. Portanto, o próprio arquivo ibdata1 não tem limite para seu tamanho, exceto no sistema operacional.
Por que esta mensagem está chegando? Observe que a mensagem é "A tabela ... está cheia", não "O disco ... está cheio". Esta condição de tabela completa é do ponto de vista lógico . Pense no InnoDB. Que interações estão acontecendo?
Meu palpite é que o InnoDB está tentando carregar 93 GB de dados como uma única transação. De onde Table is Full
emanaria a mensagem? Eu examinaria o ibdata1, não em termos de tamanho físico (que você já descartou), mas em termos de quais limites de transação estão sendo atingidos.
O que há no ibdata1 quando innodb_file_per_table está ativado e você carrega novos dados no MySQL?
Minhas suspeitas me dizem que os logs de desfazer e / ou refazer são os culpados.
O que são esses logs? De acordo com o livro
Os parágrafos 3,4 do capítulo 10 dizem o seguinte:
O mecanismo do InnoDB mantém dois tipos de logs: um log de desfazer e um log de refazer. O objetivo de um log de desfazer é reverter as transações, bem como exibir as versões mais antigas dos dados para consultas em execução no nível de isolamento de transações que exige isso. O código que manipula o log de desfazer pode ser encontrado em storage / innobase / buf / log / log0log.c .
O objetivo do log de refazer é armazenar as informações a serem usadas na recuperação de falhas. Ele permite que o processo de recuperação execute novamente as transações que podem ou não ter sido concluídas antes da falha. Depois de reexecutar essas transações, o banco de dados é levado a um estado consistente. O código que trata do redo log pode ser encontrado em storage / innobase / log / log0recv.c .
ANÁLISE
Existem 1023 logs de desfazer dentro do ibdata1 (consulte Segmentos de reversão e espaço de desfazer) . Como os logs de desfazer mantêm cópias dos dados como apareceram antes do recarregamento, todos os 1023 Undo Logs atingiram seu limite. De outra perspectiva, todos os 1023 Undo Logs podem ser dedicados à transação que carrega a Sample
tabela.
MAS ESPERE...
Você provavelmente está dizendo "Estou carregando uma Sample
mesa vazia ". Como estão envolvidos os desfazer logs? Antes da Sample
tabela ter sido carregada com 93 GB de dados, ela estava vazia. A representação de todas as linhas que não existiam deve ocupar algum espaço de limpeza nos logs de desfazer. O preenchimento de 1023 Desfazer Logs parece trivial, dada a quantidade de dados que é derramada ibdata1
. Eu não sou a primeira pessoa a suspeitar disso:
Na documentação do MySQL 4.1, observe Posted by Chris Calender on September 4 2009 4:25pm
:
Observe que no 5.0 (pré-5.0.85) e no 5.1 (pré-5.1.38), você pode receber o erro "tabela está cheia" para uma tabela do InnoDB se o InnoDB ficar sem slots de desfazer (bug # 18828).
Aqui está o relatório de erros do MySQL 5.0: http://bugs.mysql.com/bug.php?id=18828
SUGESTÕES
Quando você cria o mysqldump da Sample
tabela, use --no-autocommit
mysqldump --no-autocommit ... mydb Sample > Sample.sql
Isso colocará um explícito COMMIT;
depois de cada INSERT
. Em seguida, recarregue a tabela.
Se isso não funcionar ( você não vai gostar disso ), faça isso
mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql
Isso fará com que cada INSERT tenha apenas uma linha. O mysqldump será muito maior (mais de 10 vezes maior) e poderá levar de 10 a 100 vezes mais para recarregar.
Em ambos os casos, isso evitará que os logs de desfazer sejam inundados.
De uma chance !!!
UPDATE 2013-06-03 13:05 EDT
SUGESTÃO ADICIONAL
Se a tabela do sistema InnoDB (também conhecida como ibdata1) atingir um limite de tamanho de arquivo e o Desfazer logs não puder ser usado, você poderá adicionar outro espaço de tabela do sistema (ibdata2).
Acabei de encontrar esta situação há apenas dois dias. Atualizei minha postagem antiga com o que fiz: Consulte Design do banco de dados - Criando vários bancos de dados para evitar a dor de cabeça do limite no tamanho da tabela
Em essência, é necessário alterar innodb_data_file_path para acomodar um novo arquivo de espaço de tabela do sistema. Deixe-me explicar como:
CENÁRIO
No disco (ext3), o servidor do meu cliente tinha o seguinte:
[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql 362807296 Jun 2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun 2 00:15 ibdata2
A configuração era
innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M
Observe que ibdata2
cresceu para 2196875759616, o que é 2145386484M
.
Eu tive que incorporar o tamanho do arquivo ibdata2
no innodb_data_file_path e adicionaribdata3
innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend
Quando reiniciei o mysqld, funcionou:
[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql 362807296 Jun 3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun 3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql 32315015168 Jun 3 17:02 ibdata3
Em 40 horas, ibdata3
cresceu para 31G. O MySQL estava mais uma vez trabalhando.