Infelizmente, mesmo a cópia em pequenos lotes de 100 linhas gera um atraso significativo após algum tempo.
Você está adicionando algum atraso entre cada lote ou apenas fazendo o lote das atualizações e executando cada lote diretamente após o anterior?
Nesse caso, tente criar um script da conversão no seu idioma favorito com algo como:
repeat
copy oldest 100 rows that haven't been copied yet to new table
sleep for as long as that update took
until there are <100 rows unprocessed
stop logging service
move the last few rows
rename tables
restart logging
delete the old table when you are sure the conversion has worked
Isso deve garantir que a conversão não ocupe mais ou menos a metade da capacidade do servidor, permitindo diferenças de carga impostas, pois o uso do sistema varia com o tempo.
Ou, se você desejar usar o máximo de tempo possível quando o serviço estiver relativamente inativo, mas recuar (potencialmente fazer uma pausa por um longo período de tempo) quando o banco de dados precisar fazer algum trabalho para seus usuários, substitua sleep for as long as the update took
por if the server's load is above <upper measure>, sleep for some seconds then check again, loop around the sleep/check until the load drops below <lower measure>
. Isso significa que ele pode avançar em tempos de silêncio, mas será interrompido completamente quando o servidor estiver ocupado executando sua carga de trabalho normal. A determinação da carga dependerá do seu sistema operacional - no Linux e semelhante ao valor médio de carga de 1 minuto /proc/loadavg
ou a saída de uptime
deve fazer. <lower measure>
e <upper measure>
pode ter o mesmo valor, embora seja comum em controles como esse ter uma diferença, para que seu processo não continue e depois imediatamente para uma pausa, pois sua própria reinicialização influencia a medida de carga.
Obviamente, isso não funcionaria para tabelas nas quais as linhas antigas podem ser modificadas, mas funcionará bem para uma tabela de log como a que você descreve.
Você desejará ignorar a sabedoria usual de criar índices depois de preencher a nova tabela nesse caso. Embora isso seja realmente mais eficiente quando você deseja que as coisas sejam o mais rápido possível (o efeito no restante do sistema seja danificado), nesse caso, você não deseja o grande excesso de carga no final do processo como o os índices são completamente criados de uma só vez, pois esse é um processo que você não pode parar quando as coisas ficam ocupadas.