К сожалению, даже копирование небольшими партиями по 100 строк приводит к значительному отставанию через некоторое время.
Добавляете ли вы какую-либо задержку между каждым пакетом или просто пакетируете обновления и запускаете каждый пакет сразу после предыдущего?
Если это так, попробуйте написать сценарий преобразования на вашем любимом языке, например:
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
Это должно обеспечить, чтобы преобразование не занимало более или менее половины емкости вашего сервера, даже учитывая различия в нагрузке, налагаемой по мере того, как использование системы меняется со временем.
Или, если вы хотите использовать как можно больше времени, когда служба относительно простаивает, но отключается (потенциально может быть приостановлена на длительный период времени), когда базе данных необходимо выполнить некоторую работу для своих пользователей, замените ее sleep for as long as the update took
на 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>
. Это будет означать, что он может двигаться вперед в спокойное время, но полностью остановится, когда сервер занят выполнением своей нормальной рабочей нагрузки. Определение нагрузки будет зависеть от вашей ОС - в Linux и аналогичных значениях средней загрузки за 1 минуту /proc/loadavg
или выходных данных uptime
. <lower measure>
и <upper measure>
может иметь одинаковое значение, хотя обычно в элементах управления, подобных этому, есть различие, поэтому ваш процесс не продолжает запускаться, а затем сразу приостанавливается из-за того, что его собственный перезапуск влияет на показатель нагрузки.
Конечно, это не будет работать для таблиц, где старые строки могут быть изменены, но будет работать нормально для таблицы журнала, подобной той, которую вы описываете.
Вы захотите игнорировать обычную мудрость создания индексов после заполнения новой таблицы в этом случае. Хотя это действительно более эффективно, когда вы хотите, чтобы все было как можно быстрее (проклятие влияет на остальную часть системы), в этом случае вам не нужно большое перенасыщение нагрузки в конце процесса, поскольку индексы полностью создаются за один раз, так как это процесс, который вы не можете приостановить, когда что-то загружается.