Por que a TRUNCATE TABLE
declaração trava às vezes? Quais são as razões para este tipo de problema?
Estou migrando do MySQL para o MariaDB. Este problema não acontece com o MySQL, apenas com o MariaDB.
A declaração suspensa é simplesmente:
TRUNCATE TABLE sampledb.datatable;
O que pode fazer com que isso aconteça e como posso corrigi-lo?
Outra observação é se a tabela tiver alguns dados, pode ser uma ou duas linhas, então a consulta truncada funciona com sucesso. Caso contrário, a tabela tem muitos dados, a consulta fica travada.
A razão pela qual você experimenta degradação de desempenho ou trava durante a execução
TRUNCATE TABLE
é um problema conhecido com esta declaração. Consulte o Bug #68184:Truncate table causa innodb stalls. Existem outros números de bugs abertos para versões anteriores também.Você pode usar:
Fica complicado para tabelas com
AUTO_INCREMENT
valores: uma nova tabela é criada com umAUTO_INCREMENT
valor que é imediatamente obtido na tabela de trabalho. Se você não quiser usar os mesmos valores, você pode:Você deve lembrar que TRUNCATE TABLE é DDL e não DML.
Em vez de descobrir onde no encanamento do TRUNCATE TABLE ele está ficando preso, você pode ter que resolver o problema com suas próprias mãos, substituindo este
com isso
Isso pode apenas desligar o problema (talvez pendurado no
DROP TABLE
), mas a tabela fica disponível rapidamente.DROP TABLE
foi melhorado no MySQL 5.5.23 .Eu discuti TRUNCATE TABLE em meus posts anteriores
Jul 09, 2012
: O que pode fazer com que TRUNCATE TABLE demore muito tempo?Jan 17, 2012
; Problema com os tamanhos de arquivo "por tabela" do InnoDBSep 28, 2011
: Como recuperar uma tabela InnoDB cujos arquivos foram movidosDe uma chance !!!
Há um bug de longa data no InnoDB que afeta tanto o MySQL ( #98869 ) quanto o MariaDB ( MDEV-9459 ) que resulta em longas paralisações, proporcionais ao tamanho de seu pool de buffers (normalmente cerca de 1 segundo por 32 GB de pool de buffers, dependendo do o desempenho de sua CPU e largura de banda de memória de seu servidor).
Isso foi corrigido no MySQL 8.0.23 e MariaDB 10.2.19. Se a atualização não for uma opção (e eu entendo que para muitos pode não ser uma opção palatável por vários motivos), existem mitigações e soluções alternativas que podem ser aplicadas para esses stalls DROP/TRUNCATE com MySQL e MariaDB .
Por exemplo, o bug não se manifesta de você DELETE todas as linhas da tabela antes de fazer um DROP. Se isso estiver afetando você no contexto de uso de tabelas temporárias, você pode alternar seu mecanismo de tabela temporária padrão para MyISAM (ou especificar MyISAM explicitamente ao criar suas tabelas temporárias).
Sem mais informações, é difícil dizer, e não sou especialista especificamente em MySQL/MariaDB, mas os motivos gerais para uma consulta inesperadamente demorar mais do que o normal para ser executado são:
Em mariadb truncate table atua como uma tabela de descarte e recriação implícita da tabela vazia. No entanto, as operações de truncamento não podem ser executadas se a sessão tiver um bloqueio de tabela ativo.
Somente com a tabela InnoDB, o InnoDB processa
TRUNCATE TABLE
excluindo as linhas uma a uma se houver algumaFOREIGN KEY
restrição que faça referência à tabela. Se não houverFOREIGN KEY
restrições, o InnoDB executa um truncamento rápido, eliminando a tabela original e criando uma vazia com a mesma definição. Como você afirma que se uma tabela tiver poucos registros truncar é rápido e se você tiver muitos registros truncar é infinito, posso supor que você tenha InnoDB e FK.Além disso, antes de truncar sua tabela, tente
IS_FREE_LOCK(str)
a função para verificar se a tabela está bloqueada. Em caso afirmativo, existe aIS_USED_LOCK
função de recuperar o thread que está segurando o bloqueio.O
TRUNCATE
pode travar, porque outros processos podem usar esta tabela, portanto, para verificar, execute no shell:Em seguida, mate as consultas que estão usando (mude
123
para Id do processo):Também rodando:
também pode ajudar a investigar qualquer travamento.
Relacionado: Como depurar o tempo limite de espera de bloqueio excedido?
Eu enfrentei o mesmo problema e foi resolvido reiniciando o servidor mysql.
Eu sei que esta não é uma solução esperada, mas se você estiver preso, poderá reiniciar o servidor mysql.