История Физического Удаления 300 Миллионов Записей В Mysql



Введение Привет. Я ningenMe, веб-разработчик.

Как следует из названия, моя история — это история физического удаления 300 миллионов записей в MySQL. Меня это заинтересовало, поэтому я решил сделать памятку (инструкцию).



Главная страница - Оповещение

Пакетный сервер, который я использую и обслуживаю, имеет регулярный процесс, который собирает данные за последний месяц из MySQL один раз в день.

Обычно этот процесс завершается примерно за 1 час, но в этот раз он не завершился за 7 или 8 часов, а оповещение не переставало выскакивать.



Поиск причины

Я попробовал перезапустить процесс и посмотреть логи, но ничего плохого не увидел.

Запрос был проиндексирован правильно.

Но когда я задумался о том, что происходит не так, то понял, что размер базы данных довольно велик.

  
  
  
   

hoge_table | 350'000'000 |

350 миллионов записей.

Индексирование вроде бы работало правильно, но очень медленно.

Требуемый сбор данных в месяц составил примерно 12 000 000 записей.

Похоже, команда выбора выполнялась долго и транзакция долго не выполнялась.



Д.

Б.

По сути, это таблица, которая увеличивается примерно на 400 000 записей каждый день.

База данных должна была собирать данные только за последний месяц, поэтому ожидалось, что она выдержит именно такой объем данных, но, к сожалению, операция ротации не была включена.

Эта база данных разрабатывалась не мной.

Я взял его у другого разработчика, так что это все еще казалось техническим долгом.

Наступил момент, когда объем данных, вставляемых ежедневно, стал большим и наконец достиг своего предела.

Предполагается, что при работе с таким большим объемом данных потребуется их разделение, но этого, к сожалению, сделано не было.

И тогда я приступил к делу.



Коррекция

Рациональнее было уменьшить размер самой базы данных и сократить время ее обработки, чем менять саму логику.

Ситуация должна существенно измениться, если стереть 300 миллионов записей, поэтому я решил сделать так.

хх, я думал, это точно сработает.

Действие 1

Подготовив надежную резервную копию, я наконец начал отправлять запросы.

「Отправка запроса」

DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';

「.

」 「.

」 «Хм… Нет ответа.

Может быть, процесс занимает много времениЭ» — подумал я, но на всякий случай посмотрел графану и увидел, что нагрузка на диск растет очень быстро.

«Опасно», — подумал я еще раз и тут же прекратил просьбу.



Акт 2

Проанализировав все, я понял, что объем данных слишком велик, чтобы удалить все сразу.

Я решил написать скрипт, который мог бы удалять около 1 000 000 записей и запустил его.

「Я реализую сценарий」 «Теперь это точно сработает», — подумал я.



Акт 3

Второй способ сработал, но оказался очень трудоемким.

Чтобы сделать все аккуратно, без лишних нервов, понадобится около двух недель.

Но все равно этот сценарий не соответствовал требованиям сервиса, поэтому пришлось от него отойти.

Итак, вот что я решил сделать:

Скопируйте таблицу и переименуйте ее

Из предыдущего шага я понял, что удаление такого большого объёма данных создаёт столь же большую нагрузку.

Поэтому я решил создать новую таблицу с нуля с помощью вставки и переместить в нее данные, которые собирался удалить.



| hoge_table | 350'000'000| | tmp_hoge_table | 50'000'000|

Если вы сделаете новую таблицу такого же размера, как указано выше, скорость обработки данных также увеличится на 1/7. Создав таблицу и переименовав ее, я начал использовать ее в качестве главной таблицы.

Теперь, если я удалю таблицу с 300 миллионами записей, все будет в порядке.

Я обнаружил, что усечение или удаление создает меньше накладных расходов, чем удаление, и решил использовать этот метод.

Производительность

「Отправка запроса」

INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';

「.

」 「.

」 "Эм.

?"

Акт 4

Я думал, что предыдущая идея сработает, но после отправки запроса на вставку появилось несколько ошибок.

MySQL не прощает ошибок.

Я уже настолько устал, что начал думать, что больше не хочу этим заниматься.

Я посидел, подумал и понял, что, возможно, запросов на вставку было слишком много за один раз.

Я попробовал отправить запрос на вставку объема данных, который база данных должна обработать за 1 день.

Случилось! Ну а после этого продолжаем отправлять запросы на тот же объем данных.

Поскольку нам нужно удалить данные за месяц, повторяем эту операцию примерно 35 раз.



Переименование таблицы

Здесь удача была на моей стороне: все прошло гладко.



Оповещение пропало

Скорость пакетной обработки увеличилась.

Раньше этот процесс занимал около часа, теперь — около 2 минут. После того, как я убедился, что все проблемы решены, я сбросил 300 миллионов записей.

Я удалил таблицу и почувствовал себя заново рожденным.



Краткое содержание

Я понял, что в пакетной обработке отсутствует обработка вращения, и это была основная проблема.

Такого рода архитектурная ошибка приводит к пустой трате времени.

Задумываетесь ли вы о нагрузке при репликации данных при удалении записей из базы данных? Давайте не будем перегружать MySQL. Те, кто хорошо разбирается в базах данных, с такой проблемой точно не столкнутся.

Для остальных, я надеюсь, эта статья была полезна.

Спасибо за прочтение! Мы будем очень рады, если вы расскажете, понравилась ли вам эта статья, понятен ли перевод, была ли она вам полезна? Теги: #программирование #Хранение данных #базы данных #Администрирование баз данных #sql #MySQL #база данных

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.