Как осуществить изменение типов полей MySQL на продашене?

Здравствуйте.
Передо мной встала задача по оптимизации работы mysql, которая была довольно криво спроектирована и сейчас выглядит довольно таки монструозным чудовищем (2,5гб), первое на что решил обратить внимание - индексы.
Составил список запросов, которые хочу запустить ночью (см. ниже).
Подскажите пожалуйста каковы риски потерять данные или возможные подводные камни есть в этой процедуре, при применении на продакшене и критичности аптайма?
На что еще стоит обратить внимание (почитать) при оптимизации/ускорению работы mysql

#Удаляю дубликат внешнего ключа (было два одинаковых).
ALTER TABLE `clients_ph` DROP FOREIGN KEY `clients_ph_ibfk_3`;
#Изменяю поля, относительно выборок.
ALTER TABLE `statistic_not_active` MODIFY COLUMN `client_id` INT(11) NOT NULL;
ALTER TABLE `statistic_not_active` ADD INDEX `idx_statistic_not_active_client_id` ( `client_id` );
ALTER TABLE `statistic_not_active` MODIFY COLUMN `call_id` BIGINT(20) NOT NULL;
ALTER TABLE `statistic_not_active` ADD INDEX `idx_statistic_not_active_call_id` ( `call_id` );
ALTER TABLE `internet_tar_plan_clients_ph` ADD INDEX (`billing_tar_id`);
ALTER TABLE `list_tar_plan` ADD INDEX (`billing_tar_id`);
ALTER TABLE `internet_tar_plan_clients_ph` ADD INDEX (`billing_tar_id`, `last_tar_id`);
ALTER TABLE `internet_tar_plan_clients_ph` MODIFY COLUMN `billing_tar_id` int(11) NOT NULL AFTER `tar_id`, MODIFY COLUMN `last_tar_id`  int(11) NOT NULL AFTER `billing_tar_id`;
ALTER TABLE `internet_tar_plan_clients_ph` ADD FOREIGN KEY (`billing_tar_id`) REFERENCES `list_tar_plan` (`billing_tar_id`) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE `clients_ph` ADD INDEX `agrm_id` USING BTREE (`agrm_id`) ;
  • Вопрос задан
  • 3108 просмотров
Решения вопроса 2
AxisPod
@AxisPod
Блин, 2.5Гб - монстр, а что тогда за БД на 120Гб (у нас сейчас такая, на одном из проектов, бывают и гораздо больше)?

Вообще сначала перетащите структуру БД куда-нить и выполните запросы. Проверьте работоспособность. Сделайте затем временную таблицу со строкой и пишите в эту таблицу между запросами какой-нить текст, в случае падения надо будет прочекать последнюю таблицу, отремонтировать и запустить запросы дальше.

Это как вариант. Ну и проверьте сначала выборками, влезут ли текущие данные в новые типы. В идеале стянуть бы бэкап локально и прогнать сначала на нём всё это.
Ответ написан
Melkij
@Melkij
PostgreSQL DBA
Объедините запросы по одной таблице в один запрос - быстрее перестоится.
И мне кажется, вы забыли проставить unsigned полям. `client_id` наверняка ведь FK к стандартному автоинкременту.

innodb всё, надеюсь?
innodb перестраивается так:
таблица блокируется на запись, создаётся временная таблица с новой структурой, копируются все данные, старая таблица замещается новой.
Поэтому потерять данные сложно - в случае проблем запрос вернёт ошибку, снимет блокировку на запись в таблицу и всё. Таблица даже физически не затронута будет.

Но read-only на некоторое пропорциональное размеру таблицы время будет.
(mysql 5.6 умеет перестраивать без блокировки, не знаю точно, как там поставлен процесс)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы