Столкнулся с проблемой производительности СУБД.
Есть некий сервер под управлением Windows Server 2008 R2, с самого начала (несколько лет, другой человек ставил) на нём работает некоторый софт, который хранит в ней кое-какие данные.
Пару недель назад софт перестал строить отчёты, выводил пустой отчёт из-за превышения времени ожидания ответа. Увеличил таймут, заработало.
Сегодня нашёл время разобраться немного в ситуации.
Итак: MySQL значительно грузит ЦП, даже достаточно простые запросы к этой базе выполняются оочень долго. Среди файлов из директории этой базы файл ibdata весит 35Гб. ibdata хранит innoDB хранилище собственно.
После некоторых манипуляций вытащил пароль root`а (изменить было нельзя, т.к. root используется софтом, так уж сложилось, а он канул вместе с уходом сотрудника, который ранее этим занимался) и подключился к базе. В базе есть таблицы, содержащие журналы работы софтины с самого начала, они занимают от 2 до 17ГБ (база не обслуживалась с момента создания, очевидно никто не следил). Просто снести таблицы нельзя, они связанные, несмотря на то, что это всего лишь логи (и используются при формировании отчётов).
Сделал копию базы (если вдруг потребуется сделать отчёт за какой-нибудь давний период, разверну по необходимости), нашёл на офсайте разработчика софта процедуру очистки базы от данных, старше определённой даты создания, гарантирующую целостность данных, взял запросы, но не смог использовать.
Хотел удалить данные поэтапно, отдельными запросами для каждой таблицы, но в текущем состоянии, похоже, это сделать нельзя. Очистка самой маленькой таблицы из тех, что следует вычистить, заняла 2 минуты. Эта таблица не связана с другими и содержит дату создания каждой записи (простой запрос типа "DELETE FROM `table_1` WHERE `table_1`.`Time`< '12.12.2012'"), с остальными будет сложнее намного (а с той, что содержит 17ГБ данных вообще не выйдет ничего).
Софт держит информацию за последние сутки во встроенной СУБД (каждую ночь (опционально) удаляет все записи старше 1 дня), с MySQL синхронизировался ранее каждые 15 минут (и повтор через 10 минут в случае сбоя). Установил интервал 25 минут и устранил запись лишнего мусора в базу (а повтор так и остался 10 минут). Но просто подсунуть чистую базу (в т.ч. со структурой) нельзя, боюсь при синхронизации в этом случае возникнет сбой из-за каких-нибудь номеров транзакций или ещё чего (таблиц много, возможно там и конфиги кое-какие хранятся в т.ч; не смотрел запросы софта к базе, да и нечем).
Как избавиться от мусора в базе и не повредить данные от начала текущего календарного года?
И да, останавливать ничего нельзя, сильно нагружать чем-либо и без того нагруженные ЦП тоже не стоит. Копия базы есть (просто файлы, резервирование не настроено, но эти файлы можно подсунуть в такую же СУБД на моей машине, но т.к. она слабее (пк), то и с MySQL будет ещё больше проблем).
Было в мыслях вытащить актуальную информацию из копии, затем на время остановить MySQL, подсунуть обработанные данные и снова запустить, но если что-то пойдёт не так, то закончится это печально.
Ведь часто такие ситуации бывают, как такое решается?
Почему MySQL тормозит, точно ли проблема в размере базы? Как диагностировать? Быть может сама база повреждена?
PS. Ах да, этот софт можно не останавливая переключить на другую базу, если потребуется. Есть возможность прописать внешней базе другой IP, порт, имя базы, логин, пароль и всякие мелочи. Постоянно соединение с внешней базой он не держит. В целом ничто не мешает синхронизацию с внешней базой вообще выключить на разумное время (она ни для чего, кроме отчётов и не используется), чтобы высвободить процессорное время (но СУБД сильно быстрее работать не начнёт, с ней какие-то проблемы).
PPS. Заметил, что не очень ясно обрисовал картину: СУБД и софт, который её использует, работают на одном физическом сервере. Можно базу перетащить на другой сервер, если потребуется.