Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL/InnoDB e consultas de longa duração


Em primeiro lugar, acho que seria útil como pano de fundo ler sobre controle de simultaneidade de várias versões (MVCC) como pano de fundo para esta resposta.

O InnoDB implementa o MVCC, o que significa que pode usar leituras sem bloqueio para SELECT regulares . Isso não requer a criação de um "snapshot" e de fato o InnoDB não tem nenhum conceito real de um snapshot como um objeto. Em vez disso, cada registro no banco de dados acompanha seu próprio número de versão e mantém um "ponteiro roll" para um registro "undo log" (que pode ou não existir) que modifica a linha para sua versão anterior. Se for necessária uma versão mais antiga de um registro, a versão atual é lida e esses ponteiros de rolagem são seguidos e os registros de desfazer aplicados até que uma versão suficientemente antiga do registro seja produzida.

Normalmente, o sistema está constantemente limpando esses logs de desfazer e reutilizando o espaço que eles consomem.

A qualquer momento, qualquer transação de longa duração (observe, não necessariamente uma única consulta) estiver presente, os logs de desfazer devem ser mantidos (não eliminados) para recriar versões suficientemente antigas de todos os registros para satisfazer essa transação. Em um sistema muito ocupado, esses logs de desfazer podem se acumular muito rapidamente para consumir gigabytes de espaço. Além disso, se registros individuais específicos forem modificados com muita frequência, reverter esse registro para uma versão antiga o suficiente para satisfazer a consulta pode exigir muitos aplicativos de log de desfazer (milhares).

É isso que torna as "consultas de longa duração" caras e desaprovadas. Eles aumentarão o consumo de espaço em disco para manter os logs de undo no tablespace do sistema e terão um desempenho ruim devido ao aplicativo de registro de log de undo para reverter as versões de linha na leitura.

Alguns bancos de dados implementam uma quantidade máxima de espaço de log de undo que pode ser consumido e, quando atingem esse limite, começam a descartar registros de log de undo mais antigos e a invalidar as transações em execução. Isso gera uma mensagem de erro "instantâneo muito antigo" para o usuário. O InnoDB não tem esse limite e permite a acumulação indefinidamente.