Niestety nawet kopiowanie w małych partiach po 100 wierszy generuje znaczne opóźnienie po pewnym czasie.
Czy dodajesz jakieś opóźnienie między każdą partią, czy po prostu dodajesz aktualizacje i uruchamiasz każdą partię bezpośrednio po poprzedniej?
Jeśli tak, spróbuj skryptować konwersję w swoim ulubionym języku za pomocą czegoś takiego:
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
Powinno to zapewnić, że konwersja nie zajmie więcej niż mniej więcej połowy pojemności twojego serwera, nawet uwzględniając różnice w obciążeniu nałożone, ponieważ użycie systemu zmienia się z czasem.
Lub jeśli chcesz używać tyle czasu, jak to możliwe, gdy usługa jest stosunkowo bezczynny, ale wycofać (potencjalnie zatrzymując się na dość długi czas), kiedy potrzeby baz popracować dla jego użytkowników, wymienić sleep for as long as the update took
się 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>
. Będzie to oznaczać, że może spokojnie płynąć naprzód, ale całkowicie zatrzyma się, gdy serwer jest zajęty wykonywaniem normalnego obciążenia. Określenie obciążenia będzie zależeć od systemu operacyjnego - w Linuksie i podobnej wartości 1-minutowa średnia wartość obciążenia /proc/loadavg
lub wynik uptime
powinien zrobić. <lower measure>
i <upper measure>
może mieć tę samą wartość, chociaż zwykle w takich kontrolkach występuje różnica, więc proces nie rozpoczyna się od razu, a następnie natychmiast zatrzymuje się z powodu własnego restartu mającego wpływ na miarę obciążenia.
Oczywiście nie działałoby to w przypadku tabel, w których stare wiersze mogą zostać zmodyfikowane, ale działałyby dobrze w przypadku tabeli dziennika takiej jak ta, którą opisujesz.
W tym przypadku będziesz chciał zignorować zwykłą mądrość tworzenia indeksów po zapełnieniu nowej tabeli. Chociaż jest to rzeczywiście bardziej wydajne, jeśli chcesz, aby rzeczy były tak szybkie, jak to możliwe (wpływ na resztę systemu niech będzie przeklęty), w tym przypadku nie chcesz dużego nadmiaru obciążenia na końcu procesu, ponieważ indeksy są całkowicie tworzone za jednym razem, ponieważ jest to proces, którego nie można wstrzymać, gdy wszystko jest zajęte.