AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.12.2010, 14:29   #1  
Alenka is offline
Alenka
Участник
 
58 / 25 (1) +++
Регистрация: 19.04.2006
Миф об уникальности RecId?
Axapta 3.0 SP3

Добрый день.
Хочу опять поднять вопрос о RecId.
Дело в том, что мы столкнулись с проблемой заканчивающихся номеров RecId, т.е. мы уже давно перешли на отрицательные значения и в течение ближайших месяцев снова должны достигнуть 0. На форуме уже обсуждалась эта проблема и высказывались предположения о том, что же произойдет после того, как будет достигнто нулевой значение. При этом высказывалась мысль о том, что при создании новой записи в таблице будет искаться неиспользованное значение RecId, т.е. будут заполняться пустоты в нумерации. Было также предположение, что никакого поиска не будет, а при вставки новой записи с существующим RecId будет возникать ошибка.

Я решила промоделировать эту ситуацию на тестовой базе. Сдвинула NextVal в SystemSequences на значение, близкое к нулю. Как и ожидалось, RecId снова стало принимать положительные значения. Но! стали появляться записи с уже существующими RecId.

Хотелось бы услышать ваше мнение по данному вопросу. Получается, что уникальность RecId - это миф?
Старый 07.12.2010, 14:37   #2  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Alenka Посмотреть сообщение
Получается, что уникальность RecId - это миф?
Миф - это идея о том, что в системе есть функциональность, которая будет искать свободные "дырки" в диапазонах выделенных значений RecId
А уникальность RecId в таблице при наличии уникального индекса по этому полю - не миф
см. Как выполнять дефрагментирование RecID
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: Alenka (1).
Старый 07.12.2010, 14:41   #3  
Alenka is offline
Alenka
Участник
 
58 / 25 (1) +++
Регистрация: 19.04.2006
Дефрагментация стандартными способами на нашей базе невозможна из-за ее размера (около 500Гб) и потере целостности (стандартный метод не правит те ссылки на RecId, которые хранятся в таблицах).
Как же уникальность не миф, когда я получила по крайней мере 2 записи с одинаковыми RecId?
Старый 07.12.2010, 14:41   #4  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Вы все неправильно понимаете. Смотрите, для 3.0 ситуация такая. Генерация Аксаптой нового RecId проста как три копейки. Аксапта грубо говоря (опустим сейчас не значащие для нас нюансы) берет соответствующее последнее значение из номерной серии и прибавляет к нему единицу. Все, данное значение и записывается в таблицу. Разумеется, Аксапта не проверяет никакую уникальность, и не пытается найти неиспользуемый номер. Представляете, с какой бы скоростью она работала, если бы каждый раз это делала?!

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

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

А вообще, возникающие проблемы и возможные способы решения уже обсуждались и не один раз.
За это сообщение автора поблагодарили: Alenka (1).
Старый 07.12.2010, 14:44   #5  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Alenka Посмотреть сообщение
Дефрагментация стандартными способами на нашей базе невозможна из-за ее размера (около 500Гб) и потере целостности (стандартный метод не правит те ссылки на RecId, которые хранятся в таблицах)
Поразительно, как быстро Вы прочли всю ветку по ссылке из первого моего сообщения
Стандартный метод корректно правит ссылки в пределах одной компании там, где они оформлены корректно (с использованием правильных EDT)
Делает он это неторопливо, но даже в Вашем случае за сутки отработать должен может
__________________
-ТСЯ или -ТЬСЯ ?
Старый 07.12.2010, 14:57   #6  
Alenka is offline
Alenka
Участник
 
58 / 25 (1) +++
Регистрация: 19.04.2006
2 Vadik : Просто я ее уже читала раньше.
2 oip: Все правильно, я неверно понимала понятие уникальности. Ошибка при вставке и сообщение о существующей записи появляются при создании записи с существующим RecId в этой же таблице. При этом запись все-таки создается со следующим RecId.

Спасибо за помощь и наставления .
Старый 07.12.2010, 15:05   #7  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Alenka Посмотреть сообщение
2 Vadik : Просто я ее уже читала раньше
Значит невнимательно читали, потому что Ваши выводы и аргументация ошибочны
Цитата:
Дефрагментация стандартными способами на нашей базе невозможна из-за ее размера (около 500Гб) и потере целостности (стандартный метод не правит те ссылки на RecId, которые хранятся в таблицах)
__________________
-ТСЯ или -ТЬСЯ ?
Старый 07.12.2010, 15:35   #8  
egorych is offline
egorych
Участник
Самостоятельные клиенты AX
Oracle
 
761 / 154 (7) ++++++
Регистрация: 09.11.2006
Адрес: Краснодарский край
Цитата:
Сообщение от Alenka Посмотреть сообщение
Дефрагментация стандартными способами на нашей базе невозможна из-за ее размера (около 500Гб) и потере целостности (стандартный метод не правит те ссылки на RecId, которые хранятся в таблицах).
Надо просто найти поля где хранятся ссылки на RecID и исправить EDT поля на RefRecId - тогда обновляться все будет корректно.
Старый 07.12.2010, 16:19   #9  
Alenka is offline
Alenka
Участник
 
58 / 25 (1) +++
Регистрация: 19.04.2006
Согласна, целостность может и не потеряется (нельзя ручаться за правильность EDT всех полей, использующих RecId), но время, требующееся для дефрагментации такой базы, по-моему вы указали сомнительное. Хотя продолжать дискуссию на эту тему - дело неблагодарное, т.к. проверить время выполнения дефрагментации на нашей базе не представляется возможным. Но в той же ветке, что вы указали есть примеры, когда 40Гб база дефрагментировалась несколько дней. Оптимизма это не прибавляет.
Старый 07.12.2010, 16:46   #10  
KiselevSA is offline
KiselevSA
Злыдни
Аватар для KiselevSA
Злыдни
Лучший по профессии 2015
 
958 / 333 (13) ++++++
Регистрация: 25.01.2002
Адрес: Москва
Скорость дефрагментации RecId очень сильно зависит от производительноти сервера и скорости работы дисковой подсистемы. Лет 5 назад проводил дефрагментацию на базе размером в 25 Гигов. Сервер с двумя старенькими Xeon-ами, 4Gb оперативки и SCSI подсстемой (RAID-10) пережевал дефрагментацию за час с небольшим. При этом не должны работать пользователи и пакетники. Я думаю, что в Вашем случае все должно уложиться в один выходной день. Можете, во избежании случайных подключений, запустить дефрагментацию в двухуровневой конфигурации.
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании.
Старый 07.12.2010, 16:59   #11  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Alenka Посмотреть сообщение
Согласна, целостность может и не потеряется (нельзя ручаться за правильность EDT всех полей, использующих RecId)
И проверить корректность EDT в своих кастомизациях тоже не представляется возможным, и вспомогательных джобов для этого на форуме не постили
Цитата:
.. но время, требующееся для дефрагментации такой базы, по-моему вы указали сомнительное
Ну, Вы сомневаться-то сомневайтесь, но грязных намеков делать не надо - время самое что ни на есть реальное. Всего-то чуть менее полугода в отладчике и Query analizer-е
Цитата:
Хотя продолжать дискуссию на эту тему - дело неблагодарное, т.к. проверить время выполнения дефрагментации на нашей базе не представляется возможным
Ну как обычно - ни проверить, ни попробовать, ни исправить ошибки не представляется возможным, остается сидеть на попе и горевать о несовершенстве мира подобно Марвину. Ну нельзя же так - позитивнее как-то надо
Цитата:
Но в той же ветке, что вы указали есть примеры, когда 40Гб база дефрагментировалась несколько дней. Оптимизма это не прибавляет.
Да чего там - мы все умрем, Гольфстрим остановился (Маззи писал уже)
__________________
-ТСЯ или -ТЬСЯ ?
Старый 07.12.2010, 17:12   #12  
Alenka is offline
Alenka
Участник
 
58 / 25 (1) +++
Регистрация: 19.04.2006
2 KiselevSA: Откуда такая уверенность, что линейное увеличение размеров базы приведет к линейному увеличению времени дефрагментации? Если 25Гб пересчитывалась 1 час, то это не значит, что база в 20 раз больше будет обрабатываться в 20 раз дольше.
2 Vadik: Если бы сидели на попе ровно, то вообще бы эта тема не появилась
Старый 07.12.2010, 19:14   #13  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Alenka Посмотреть сообщение
2 Vadik: Если бы сидели на попе ровно, то вообще бы эта тема не появилась
Ну это уже прогресс.. Рассказывайте,
- что уже сделали (попробовали, проверили)
- что собираетесь делать (пробовать, проверять)
- сколько компаний
- есть ли виртуальные
- версия СУБД

Цитата:
Если 25Гб пересчитывалась 1 час
пять лет назад
__________________
-ТСЯ или -ТЬСЯ ?
Старый 07.12.2010, 19:47   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Не помню, был ли где уже подобный совет, поэтому, возможно, повторюсь.

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

Все таблицы смотреть не обязательно, достаточно посмотреть таблицу, в которой наиболее часто создают новые записи (например, InventTrans). Причем создаются не раз в месяц большими партиями (закрытие склада), а достаточно регулярно. Тут важен именно момент создания, а не модификации. Ну, простейший запрос вида

Код:
select dataAreaId, round(RecId/1000000,0), count(*)
from InventTrans with (nolock)
group by dataAreaId, round(RecId/1000000,0)
order by 1,2
Если такие разрывы есть, то можно просто установить счетчик RecId на значение, с которого начинается этот "разрыв" и на некоторое время отодвинуть вопрос дефрагментации

Правда, такой совет подойдет, скорее, для виртуальных компаний, где не так уж и много таблиц и относительно легко найти "дыры" в последовательности значений. Для "обычных" компаний придется писать скрипт по перебору всех таблиц (не сложно, но "муторно"), чтобы убедиться, что найденная "дыра" действительно "дыра" RecId, а не просто большая группа удаленных записей в одной..двух таблицах.

PS: Ага, была озвучена эта идея

http://axforum.info/forums/showthrea...992#post110992

Цитата:
По результатам телефонного митинга с John McBride (менеджер команды разработки) и Mathieu Kemenovic (глобальная служба поддержки) мне подтвердили что они ничего менять в 3.0 не будут (и даже не будут делать private hot-fix) и предоставлили набор SQL-скриптов, которые ищут большие "дырки" последовательности идентификаторов записей и используют их. Данные скрипты неавтоматические и необходимо выполнять ряд шаманских танцев с бубнами...
Старый 07.12.2010, 20:22   #15  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2156 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Возможно, у автора появился повод для перехода на новую версию?
__________________
Ivanhoe as is..
Старый 07.12.2010, 21:10   #16  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
В порядке эксперимента - автоматическое использование дыр RecId
Эх, готовил материал для сообщения в блоге (где-то уже с года полтора назад), все собирался нормально оформить и выложить, да, чувствую, если сейчас не сообщу, то для "трёшки" уже совсем никому не надо будет. Поэтому несколько сумбурно, схематично, но выкладываю. Ветка, вроде, подходящая

Честно скажу, в промышленной эксплуатации не пользовал (не припёрло), но на тестовой всё отрабатывало довольно прилично. Axapta - 3.0 SP4, СУБД - Oracle 10.

Общий смысл такой - заставить Аксапту автоматически использовать имеющиеся дыры RecId. Для этого нужно провести подготовительную работу: при помощи самописного скрипта пробежаться по всем таблицам системы и собрать информацию о неиспользованных интервалах RecId. Для Ax 3.0 (двухзвенка, без АОС) имеет смысл отбирать только непрерывные диапазоны размером не менее 25, т.е. не меньше размера кэша. Далее грузим полученные диапазоны в таблицу дыр (не аксаптовскую, просто созданную на уровне БД в той же схеме):
Код:
CREATE TABLE RECIDHOLES
(
  FROMRECID NUMBER(10),
  TORECID   NUMBER(10)
)
Для пущей убедительности добавим проверочку на размер диапазона не менее 25 упомянутых выше идентификаторов
Код:
ALTER TABLE RECIDHOLES ADD (
  CHECK (TORECID-FROMRECID+1>=25))
Ну и наконец на таблицу SystemSequences вешаем триггер BEFORE UPDATE:
Код:
CREATE OR REPLACE TRIGGER SystemSequences_TBU
BEFORE UPDATE
ON SYSTEMSEQUENCES REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
WHEN (
SUBSTR(NLS_LOWER(Old.DataAreaId),1,3) = 'ppp' 
      AND Old.Id = -1 
      AND Old.TabId = 0
      )
DECLARE
    currNextVal NUMBER(10);
    cntBetween  NUMBER(10);
    cntAbove    NUMBER(10);   
    minDelta    NUMBER(10);
    b4switching NUMBER(10);
    holesRange  RecIdHoles%ROWTYPE;
    
BEGIN
    b4switching := 1118091751; -- NextVal перед переключением (передвинуть с запасом на 100-200, чтобы не схватили)
    minDelta    := 25; -- Axapta 3.0 Cache Size
    
    currNextVal := :New.NextVal; -- значение, которое собирается вставить Аксапта
    
    -- если здесь 1, то более ничего не делаем - :New.NextVal проходит в таблицу
    SELECT COUNT(*) INTO cntBetween 
        FROM RecIdHoles h 
        WHERE currNextVal BETWEEN h.FromRecId AND h.ToRecId
          AND h.ToRecId - currNextVal + 1 >= minDelta;  

    IF cntBetween = 0 THEN    
        -- иначе попадаем сюда и устанавливаем новое значение, равное FromId следующего диапазона
        SELECT COUNT(*) INTO cntAbove 
            FROM RecIdHoles h 
            WHERE h.FromRecId > currNextVal
              AND h.ToRecId - h.FromRecId + 1 >= minDelta; -- на всякий случай

        IF cntAbove > 0 THEN -- если мы в диапазонах, охватываемых таблицей дыр RecIdHoles
    
            SELECT * INTO holesRange
                FROM (SELECT * FROM RecIdHoles h 
                      WHERE h.FromRecId > currNextVal
                        AND h.ToRecId - h.FromRecId + 1 >= minDelta -- на всякий случай                 
                      ORDER BY h.FromRecId)
                WHERE ROWNUM = 1;
            
            currNextVal := holesRange.FromRecId;
            
        ELSE -- если уже нет
         
            IF currNextVal <= b4switching THEN -- значит кончились записи в таблице дыр RecIdHoles
                currNextVal := b4switching;
            END IF;
            -- если currNextVal > b4switching, то уже всё поехало нормально
            
        END IF;
        
        :New.NextVal := currNextVal;             
    END IF;              

   EXCEPTION
     WHEN OTHERS THEN
       -- Consider logging the error and then re-raise
       RAISE;
END SystemSequences_TBU;
Всё! Аксапта начинает генерить RecId под управлением диапазонов таблицы RECIDHOLES.

P.S. ОГРАНИЧЕНИЯ:

1. В текущей редакции триггер можно использовать на монотонно возрастающем участке генерации RecId, достаточно далеком от крайних значений, т.е. перевалка через максимальное значение (2G) и продолжение с минимального (-2G) текущим алгоритмом не предусмотрена.

2. У таблицы SystemSequence в Ax 3.0 имеется метод setCacheSize, позволяющий установить размер кэша иным, нежели 25. Перед использованием триггера рекомендуется проверить код приложения Аксапты на присутствие вызовов этого метода (у меня не было ни одного). При необходимости можно увеличить minDelta в триггере до значения максимального параметра этих вызовов, либо (более муторно) в триггере предусмотреть генерирование ошибки (исключения) при попытке Аксапты сделать шаг больше, чем 25. По иронии судьбы в Ax 4.0 метод setCacheSize отсутствует, но в "четверке" уже и подобный триггер не нужен

Последний раз редактировалось Gustav; 08.12.2010 в 11:13.
За это сообщение автора поблагодарили: fed (3), Vadik (1), Владимир Максимов (10), gl00mie (10), Alenka (1), Mileyko (1).
Старый 08.12.2010, 00:17   #17  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
А код, который отыщет свободные диапазоны RecId в компании на объеме данных, сопоставимом с постановкой задачи (500Гб) - будет?
__________________
-ТСЯ или -ТЬСЯ ?
Старый 08.12.2010, 00:22   #18  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Ivanhoe Посмотреть сообщение
Возможно, у автора появился повод для перехода на новую версию?
- неспортивно
- неуплаченная "дань за двенадцать лет" (поддержка) зело велика будет
- перевод тройки на 2009 - челлендж покруче любой дефрагментации RecId
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: CDR (1).
Старый 08.12.2010, 10:14   #19  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2156 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Цитата:
Сообщение от Vadik Посмотреть сообщение
- неспортивно
- неуплаченная "дань за двенадцать лет" (поддержка) зело велика будет
- перевод тройки на 2009 - челлендж покруче любой дефрагментации RecId
1. Ну а что делать Повод просто хороший. Для заинтересованной стороны. С таким объемом на тройке пора бы задуматься о переходе, imho. На 6.0 переходить будет еще сложнее. AX2009 сейчас уже более-менее оттестирована - два SP и кучка RU вышла.
2. Про неуплаченную дань не в курсе, я что-то пропустил? =)
3. Ну, можно вообще дождаться чьего-нибудь пожелания перейти на SAP - мне кажется с т.з. сотрудников поддержки Ax это еще большее зло
__________________
Ivanhoe as is..
Старый 08.12.2010, 10:19   #20  
Alexius is offline
Alexius
Участник
Аватар для Alexius
 
461 / 248 (9) ++++++
Регистрация: 13.12.2001
А нет ли в базе чего-нибудь "лишнего" ? Типа :
1. InventSettlement (Cancelled == true)
2. InventSumLogTTS (не используется сводное планирование)
3. SysDataBaseLog и прочие логи
4. SalesParmTable и подобные *Parm*
5. и т.д.

Может можно почистить базу и облегчить АХ задачу по дефрагментации ?
Теги
ax3.0, recid, дефрагментирование recid, законченный пример, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
if (record) vs if (record.RecId) kashperuk DAX: Программирование 18 27.11.2008 18:53
поля, содержащие RecId somebody DAX: Программирование 15 16.05.2008 17:50
Что лучше select RecId или select TableId Logger DAX: Программирование 9 02.06.2007 15:13
aEremenko: Дефрагментация RecID Blog bot DAX Blogs 2 06.03.2007 22:25
Два RecId у одной записи таблицы sparur DAX: Программирование 33 18.12.2006 15:56

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:10.