Malheureusement, même la copie en petits lots de 100 lignes génère un retard important après un certain temps.
Ajoutez-vous un délai entre chaque lot, ou mettez-vous simplement par lot les mises à jour et exécutez-vous chaque lot directement après le précédent?
Si c'est le cas, essayez d'écrire la conversion dans votre langue préférée avec quelque chose comme:
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
Cela devrait garantir que la conversion ne prend pas plus de la moitié de la capacité de votre serveur, même en tenant compte des différences de charge imposées car l'utilisation du système varie avec le temps.
Ou si vous souhaitez utiliser autant de temps que possible lorsque le service est relativement inactif, mais que vous devez le désactiver (en faisant potentiellement une pause pendant une période assez longue) lorsque la base de données doit effectuer un certain travail pour ses utilisateurs, remplacez sleep for as long as the update took
par 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>
. Cela signifie qu'il peut avancer en temps calme, mais s'arrêtera complètement lorsque le serveur est occupé à exécuter sa charge de travail normale. La détermination de la charge dépendra de votre système d'exploitation - sous Linux et similaire, la valeur moyenne de charge d'une minute /proc/loadavg
ou la sortie de uptime
devrait faire. <lower measure>
et <upper measure>
peut avoir la même valeur, bien qu'il soit habituel dans des contrôles comme celui-ci d'avoir une différence de sorte que votre processus ne continue pas à démarrer puis à s'arrêter immédiatement car son propre redémarrage a une influence sur la mesure de charge.
Bien sûr, cela ne fonctionnerait pas pour les tables où les anciennes lignes peuvent être modifiées, mais fonctionnera bien pour une table de journal comme celle que vous décrivez.
Vous voudrez ignorer la sagesse habituelle de créer des index après avoir rempli la nouvelle table dans ce cas. Bien que cela soit en effet plus efficace lorsque vous voulez que les choses soient aussi rapides que possible (l'effet sur le reste du système soit damné), dans ce cas, vous ne voulez pas la grande surabondance de charge à la fin du processus comme le les index sont entièrement créés en une seule fois car il s'agit d'un processus que vous ne pouvez pas interrompre lorsque les choses sont occupées.