В простых базах данных изменение структуры таблицы (например, добавление или удаление поля) обычно приводит к полной перезаписи всей таблицы в соответствии с новой структурой. Если записей много, процесс может занять длительное время, в течение которого таблица будет недоступна.
Informix поддерживает отложенное изменение структуры таблицы (in-place alters). Эта возможность встроена в СУБД и используется для того, чтобы минимизировать время, необходимое для реструктуризации таблицы.
Суть этой возможности заключается в том, что при изменении структуры таблицы вместо полной перезаписи неявно создаётся ещё одна версия той же таблицы, но с новой структурой. В первый момент после этого новая версия таблицы остаётся пустой. Далее записи постепенно переносятся из старой версии в новую, и это происходит во время обычной работы:
Таким образом, для перемещения отдельной записи в новую версию нужно явным образом - с помощью UPDATE - обновить эту запись.
Когда в старой версии таблицы не останется ни одной записи, эта версия будет автоматически удалена. Физическое удаление пустой старой версии происходит во время контрольной точки СУБД.
Пока все имеющиеся записи не будут модифицированы или удалены, старые версии сами по себе не исчезнут.
Отложенное изменение структуры таблицы возможно в следующих случаях:
У отложенного изменения таблиц имеются недостатки, связанные с некоторым уменьшением производительности.
execute procedure get_pending_ipa();
Хранимая процедура get_pending_ipa не является стандартной процедурой Informix и должна быть создана в базе самостоятельно. Для вызова процедуры требуются права администратора (informix), так как часть используемых в этой процедуре системных таблиц недоступны для обычного пользователя. Пример листинга результата:
Имя БД | Таблица | Фрагмент | Тип | Partnum | Lock | Версии | Страниц |
---|---|---|---|---|---|---|---|
devbase | descriptions | descriptions | Table | 3152319 | 3152319 | 0 | 7922 |
devbase | dtypes | dtypes | Table | 3152321 | 3152321 | 0 | 1 |
devbase | wlg_bug | wlg_bug | Table | 3152747 | 3152747 | 0 | 4 |
probase | rez_group_sign | rez_group_sign | Table | 3172646 | 3172646 | 0 | 2 |
probase | sro | sro | Table | 3171982 | 3171982 | 0 | 2 |
probase | part_numbers_ext | part_numbers_ext | Table | 3172219 | 3172219 | 0 | 4573 |
probase | part_numbers_ext | part_numbers_ext | Table | 3172219 | 3172219 | 2 | 2 |
probase | prf_params | prf_params | Table | 3180792 | 3180792 | 0 | 1 |
probase | sm_norm_pv | sm_norm_pv | Table | 6297125 | 6297125 | 0 | 1055 |
probase | tmp_out_data_by_year | tmp_out_data_by_year | Table | 8392577 | 8392577 | 0 | 39596 |
probase | grafic | grafic | Table | 3173290 | 3173290 | 0 | 1 |
probase | grafic | grafic | Table | 3173290 | 3173290 | 2 | 1 |
probase | grafics_version | grafics_version | Table | 3173291 | 3173291 | 0 | 2 |
probase | elem_l_trb | elem_l_trb | Table | 3172298 | 3172298 | 0 | 12 |
probase | station_area_lnk | station_area_lnk | Table | 3173472 | 3173472 | 0 | 1 |
В листинге перечислены все таблицы всех имеющихся баз данных, в которых имеется больше одной версии таблицы. Можно заметить, что таблицы part_numbers_ext и grafic встречаются в списке дважды - следовательно, каждая из них содержит три версии.
Для приведения всех версий таблицы к одной и той же версии нужно любым способом модифицировать записи таблицы, относящиеся к ранним версиям. Так как выбрать только старые записи непросто, можно вместо этого модифицировать все записи таблицы. Это можно сделать двумя способами:
Метод 1. Фиктивно обновить все записи таблицы с помощью UPDATE, не меняя содержимого - напримерupdate таблица set поле = поле where 1 = 1;
Тогда перемещение записей из старых версий в новые - это побочный эффект.
Если в этой таблице нет триггеров на update, то такое обновление записей можно делать в любое время - в том числе во время работы других пользователей.
Если в таблице есть активные (включённые) триггеры на update, то на время обновления эти триггеры следует отключить и затем по окончании обновления включить снова. Во все время, пока триггеры временно отключены, пользователи не должны иметь доступ к таблице.
Метод 2. С помощью ALTER FRAGMENT переместить нефрагментированную таблицу в другое пространство (или в то же самое пространство).alter fragment on table таблица init in пространство;
При этом все записи перестраиваются в соответствии с актуальной структурой, и отложенные изменённые записи активизируются автоматически
Выполнение ALTER FRAGMENT может привести к тому, что ранее транслированные запросы, использующие эту таблицу, становятся неактуальными и потребуют повторной перетрансляции. Если вы не уверены, что ни одна сессия не использует нужную таблицу, лучше выполнять ALTER FRAGMENT в монопольном режиме.
После обновления любым способом нужно либо дождаться очередной контрольной точки СУБД, либо вызвать контрольную точку принудительно (командой onmode -c). Только тогда все обработанные таблицы уйдут из списка.
Процедура get_pending_ipa представлена Fernando Nunes - domusonline@gmail.com
1. get_pending_ipa - поиск множественных версий таблиц
get_pending_ipa.sql ; 12308 байт