#php #mysql #archiving #mysql-backup
#php #mysql #архивирование #mysql-резервное копирование
Вопрос:
У меня есть база данных MySQL, которая получает много данных из источника раз в неделю в определенный день недели в заданное время (около 1,2 миллиона строк) и сохраняет их в, назовем это, «живой» таблице.
Я хочу скопировать все данные из «текущей» таблицы в архив и обрезать текущую таблицу, чтобы освободить место для следующих «текущих данных», которые поступят на следующей неделе.
Кто-нибудь может предложить эффективный способ сделать это. Я действительно пытаюсь избежать — insert into archive_table select * from live — . Я хотел бы иметь возможность запускать этот архиватор с использованием PHP, поэтому я не могу использовать Maatkit. Есть предложения?
РЕДАКТИРОВАТЬ: Кроме того, архивированные данные должны быть легко доступны. Поскольку каждая вставка имеет временную метку, если я хочу найти данные за прошлый месяц, я могу просто выполнить поиск по ним в архивах
Комментарии:
1. Как насчет задания cron, которое выполняет mysqldump в файл, который может получить ваш PHP?
Ответ №1:
Хитрый способ:
Не копируйте записи заново. Это занимает слишком много времени.
Вместо этого просто переименуйте текущую таблицу и создайте заново:
RENAME TABLE live_table TO archive_table;
CREATE TABLE live_table (...);
Это должно быть довольно быстро и безболезненно.
РЕДАКТИРОВАТЬ: Метод, который я описал, работает лучше всего, если вы хотите архивировать таблицу за период ротации. Если вы хотите поддерживать единую архивную таблицу, возможно, потребуется усложнить. Однако, если вы просто хотите выполнять специальные запросы к историческим данным, вы, вероятно, можете просто использовать UNION.
Если вы хотите сохранить данные только за несколько периодов, вы могли бы выполнить переименование несколько раз, аналогично ротации журнала. Затем вы могли бы определить представление, которое объединяет архивные таблицы в одну большую гудящую таблицу.
ПРАВКА 2: Если вы хотите поддерживать автоматическое увеличение, вы можете попытаться:
RENAME TABLE live TO archive1;
CREATE TABLE live (...);
ALTER TABLE LIVE AUTO_INCREMENT = (SELECT MAX(id) FROM archive1);
но, к сожалению, это не сработает. Однако, если вы управляете процессом с помощью PHP, это довольно легко обойти.
Комментарии:
1. Могу ли я сделать это с живой таблицей, которая, возможно, получает около 100 строк в секунду, затем переместите переименованную таблицу в другую базу данных, пока новая таблица все еще находится в живой базе данных, и не потеряйте никаких вставок, и начнется ли автоматическое увеличение, я просто пытаюсь поступить правильно, спасибо 🙂
Ответ №2:
Напишите скрипт для запуска в качестве задания cron для:
- Выгружайте архивные данные из «живой» таблицы (вероятно, это более эффективно с использованием mysqldump из сценария оболочки)
- Усекайте текущую таблицу
- Измените инструкции INSERT в файле дампа так, чтобы имя таблицы ссылалось на архивную таблицу, а не на текущую таблицу
- Добавляйте архивные данные в архивную таблицу (опять же, можно просто импортировать из файла дампа с помощью сценария оболочки, например, mysql dbname < dumpfile.sql)
Комментарии:
1. что ж, у живой таблицы есть авто_инкремент (также первичный ключ), и данные из live выгружаются в файл sql, затем усечение живой таблицы приведет к сбросу авто_инкремента, а затем при следующей вставке архива произойдет сбой.
2. @Rohit — На шаге 3 удалите первичный ключ из инструкции insert и разрешите архивной таблице назначить его автоматически. Кроме того, удаление строк не влияет на значение автоматического увеличения таблицы. Единственный способ изменить автоматическое увеличение — DDL: dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
3. Ну, я просто попробовал это, чтобы убедиться, что TRUNCATE TABLE ‘x’ сбрасывает значение auto_increment на 1
Ответ №3:
Это будет зависеть от того, что вы будете делать с данными после их архивирования, но рассматривали ли вы возможность использования репликации MySQL?
Вы могли бы настроить другой сервер в качестве подчиненного устройства репликации, и как только все данные будут реплицированы, выполните удаление или усечение с SET BIN-LOG 0
перед ним, чтобы избежать репликации этого оператора.
Комментарии:
1. Я рассматривал возможность репликации, но на данный момент другой сервер не подходит: (
2. Кроме того, архивированные данные должны быть легко доступны. Поскольку каждая вставка имеет временную метку, если я хочу найти данные за прошлый месяц, я могу просто выполнить поиск по ним
3. Должен признать, что отсутствие сервера для использования немного мешает 🙂 Если бы у вас было все это в одной таблице, я не думаю, что возможность поиска была бы большой проблемой, если только я чего-то не упустил.