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 ibdata1
e 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
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,616
bytes 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 é 2605711360
ou aproximadamente 2.5G
, o que aparentemente não é suficiente. Com o cliente do meu empregador anterior, eles tinham 106G
espaço de manobra enão foi suficiente para eles.
SUGESTÃO
Se você quiser deixar todos os seus dados dentro ibdata1
e ibdata2
e 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á.