В Гедымине есть своя "проблема 2000 года", а точнее проблема 32-х битного идентификатора бизнес-объекта. Чтобы быть еще более точным, не самого идентификатора а генератора GD_G_UNIQUE, с помощью которого идентификаторы добываются.
Данный генератор стартует со значения 147 000 000 и увеличивается по мере запроса новых идентификаторов. Причем, для сокращения количества запросов к серверу, увеличиение идет с шагом в 100, а неиспользованный на момент завершения программы интервал сохраняется в системном реестре.
Так как у нас ИД объекта -- это знаковое 32-х битное целое, то всего доступно чуть более 2-х миллиардов идентификаторов (мы не учитываем первые 147 миллионов, которые выделены под системные объекты платформы).
Два миллиарда число большое. Скажем, если непрерывно получать по одному идентификатору в секунду, то такого диапазона хватит на 63 года. Однако сам генератор ничем не защищен от некорректного использования, уже не говоря про то, что его можно просто "подвинуть" вперед вручную на произвольную величину. Нам встречался код, где генератор использовался для упорядочивания записей в выборке. Естественно, каждое перестроение запроса приводило к пустому расходу сотен, если не тысяч значений генератора.
Таким образом у нас появились первые клиенты, у которых значение генератора подошло вплотную к физическому лимиту.
Что делать?
Теоретически есть два варианта решения проблемы. Первый -- это сдвинуть, утрамбовать все идентификаторы "вниз" на выявленные пустые пробелы. Затем изменить значение генератора в соответствии с максимальным ИД в базе.
Технически, для этого придется выполнить следующую последовательность шагов:
- Сохранить все существующие ИД в некоторой структуре.
- Построить таблицу соответствия старый ИД -- новый ИД.
- Отключить все внешние и первичные ключи.
- Обновить ВСЕ записи в базе данных, заменяя старые идентификаторы на новые.
- После предыдущего шага желательно выполнить бэкап-восстановление БД для чистки мусора.
- Восстановить все первичные и внешние ключи.
Второй вариант:
- Создать таблицу для доступных интервалов идентификаторов GD_AVAILABLE_ID.
- При обращении к функции gdcBaseManager.GetNextID проверять не приблизились ли мы к опасной черте.
- Если нет, то работать по-старому -- через генератор.
- Если уже пора, то заполняем таблицу и по-мере необходимости берем очередной интервал из нее.
Если спохватиться во-время, то остатка генератора хватит на работу устаревших экзешников (в сети большого предприятия трудно выявить и заменить все программы сразу) и кода, который получает занчение идентификатора менуя функцию GetNextID.
Комментариев нет:
Отправить комментарий