Arquitetura InnoDB

Arquitetura InnoDB

Olá, eu uso bacula e uma das tabelas está cheia:

JobId 8946: Fatal error: sql_create.c:860 Fill File table Query failed: INSERT INTO File (FileIndex, JobId, PathId, FilenameId, LStat, MD5, DeltaSeq) SELECT batch.FileIndex, batch.JobId, Path.PathId, Filename.FilenameId,batch.LStat, batch.MD5, batch.DeltaSeq FROM batch JOIN Path ON (batch.Path = Path.Path) JOIN Filename ON (batch.Name = Filename.Name): ERR=The table 'File' is full

Então eu corro:

mysql> show table status from current_bacula like 'File';
+------+--------+---------+------------+----------+----------------+-------------+-----------------+--------------+------------+----------------+---------------------+-------------+------------+-------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows     | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free  | Auto_increment | Create_time         | Update_time | Check_time | Collation         | Checksum | Create_options | Comment |
+------+--------+---------+------------+----------+----------------+-------------+-----------------+--------------+------------+----------------+---------------------+-------------+------------+-------------------+----------+----------------+---------+
| File | InnoDB |      10 | Compact    | 52153488 |            142 |  7419723776 |               0 |   2593128448 | 2605711360 |      569929045 | 2013-04-15 21:03:59 | NULL        | NULL       | latin1_swedish_ci |     NULL |                |         |
+------+--------+---------+------------+----------+----------------+-------------+-----------------+--------------+------------+----------------+---------------------+-------------+------------+-------------------+----------+----------------+---------+
1 row in set (0.31 sec)

O arquivo my.cnf possui:

innodb_data_file_path = ibdata1:128M;ibdata2:50M:autoextend:max:12800M

Pelo que entendi o comando:

ALTER TABLE tbl_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;

funciona apenas para o mecanismo MyISAM, não? (Por favor me corrija se eu estiver errado)

Então minha pergunta é: Posso modificarapenaso las autotextend:max por exemplo, algo assim:

innodb_data_file_path = ibdata1:128M;ibdata2:50M:autoextend:max:76800M

Devo realizar outra ação além de reiniciar o serviço. é seguro? Eu sei que posso definir outro arquivo ibdataN, mas gostaria de impactar o mínimo possível os outros bancos de dados em execução no servidor.

O que você me recomenda?

Eu tenho mysql-5.1.67-1.el6_3.x86_64 no CentOS 6.4

Desde já, obrigado!

Responder1

Você poderia iniciar outro arquivo ibdata

No entanto, antes de fazer isso, você precisa saber o que ocupa o ibdata1e ibdata2.

  • Dados da tabela (seinnodb_file_per_tableestá desabilitado)
  • Índices de tabela (seinnodb_file_per_tableestá desabilitado)
  • Dados MVCC (controle de simultaneidade multiversionamento)
  • Metadados da tabela
  • Segmentos de reversão
  • Desfazer registros
  • Buffer de gravação duplo

Arquitetura InnoDB

Arquitetura InnoDB

Eu já havia lidado com a adição de ibdata3 no passado com um dos clientes do meu ex-empregador (veja minha postagem do DBA StackExchangeComo resolver “A tabela… está cheia” com “innodb_file_per_table”?). Foi necessário porque o ibdata2 atingiu o limite máximo de 2,196,875,759,616bytes do ext3. Você não tem essa situação.

Você poderia seguir sua ideia

innodb_data_file_path = ibdata1:128M;ibdata2:50M:autoextend:max:76800M

mas é melhor remover o máximo completamente

innodb_data_file_path = ibdata1:128M;ibdata2:50M:autoextend

EMBARGO

O motivo pelo qual você ficou sem espaço foi devido aos registros de desfazer. O arquivo ibdata contém 1.023 logs de desfazer. Esses registros exigem espaço de manobra para operar. Sem essa margem de manobra interna, as informações do MVCC não poderão conter instantâneos de dados no caso de uma reversão. Sua margem de manobra interna é 2605711360ou aproximadamente 2.5G, o que aparentemente não é suficiente. Com o cliente do meu empregador anterior, eles tinham 106Gespaço de manobra enão foi suficiente para eles.

SUGESTÃO

Se você quiser deixar todos os seus dados dentro ibdata1e ibdata2e alterar a configuração para

innodb_data_file_path = ibdata1:128M;ibdata2:50M:autoextend:max:76800M

você precisa monitorar a sala de manobra.

Você poderia monitorá-lo assim

IBDATA_FILESIZE=8187281408
#
# 8187281408 is 7680M + 128M
#
SQL="SELECT SUM(data_length+index_length)"
SQL="${SQL} FROM information_schema.tables WHERE ENGINE='InnoDB'"
IBDATA_DATAINDEX=`mysql -uroot -p... -ANe"${SQL}"`
(( WIGGLE_ROOM = IBDATA_FILESIZE - IBDATA_DATAINDEX )))
echo ${WIGGLE_ROOM}

Cada vez que você executar isso, saberá quanto espaço livre. Você não precisará saber qual tabela está envolvida porque qualquer tabela do InnoDB tem o potencial de reclamar que está cheia quando o espaço de manobra (espaço para informações de desfazer) não estiver lá.

informação relacionada