sevasel
Дата: 30.09.2015 11:05:31
Необходимо выгрузить данные из некоторой БД с некоторым преобразованием, т.е.в другом формате относительно формата хранения. БД адресная. Выгрузка была реализована в виде службы с несколькими потоками, каждый из которых дергал pipelined-функцию с входным параметром - код региона. Так работала полная выгрузка. Но появилась необходимость реализовать инкрементную выгрузку наряду с полной, что повлекло за собой необходимость подправить и полную. Проблема в том, что теперь крайне важно чтобы данные, выдаваемые этими pipelined-функциями содержали данные исключительно на определенный момент времени и даже не на момент своего старта. в Oracle не силен, потому обращаюсь за советом к вам. Подойдет ли AS OF TIMESTAMP ? может вообще подскажите иной способ распараллеливания задачи на старте?
Крайне важный момент что при инициации полной выгрузки сначала запускается очередное инкрементное, по его завершении и нужно как-то запустить эту массовую полную так, чтобы туда не попали данные из последующего инкрементного..
ArtNick
Дата: 30.09.2015 11:23:43
sevasel,
плохая идея использовать AS OF TIMESTAMP, почему бы не расширить данные?
JDS
Дата: 30.09.2015 11:26:44
sevasel, может чего-то не понял, возможно, как вариант, просто проставлять id выгрузки (дату выгрузки и т.п.) и по ним ориентироваться, что когда выгружалось и что еще надо выгрузить.
sevasel
Дата: 30.09.2015 11:29:46
ArtNick, не понял( что значит расширить данные?
!Z!
Дата: 30.09.2015 11:42:06
sevasel,
|
---|
исключительно на определенный момент времени |
Какой момент времени часы, дни, недели или достаточно 5 минут?
JDS
Дата: 30.09.2015 11:49:42
sevasel |
---|
Крайне важный момент что при инициации полной выгрузки сначала запускается очередное инкрементное, по его завершении и нужно как-то запустить эту массовую полную так, чтобы туда не попали данные из последующего инкрементного... |
Короче просто рулим флагами, что уже выгружалось, что еще нет, что выгружалось инкрементно, что в общей выгрузке, когда выгружалось - как душе угодно, все в ваших руках же )
Насчет упорядоченного вызова полной и инкрем. - создаешь и запускаешь процедуру (или тоже службу), которая сначала запускает инкрем. выгрузку, потом полную )
sevasel
Дата: 30.09.2015 11:56:14
JDS, вы натолкнули на мысль. не могу пока понять верную ли.
Общая инфа про технологию:
На сервере всегда должны лежать пакеты данных с инкрементными выгрузками и один пакет полной.
приложение само принимает решение загружает ли оно полное (например при своей первоначальной установке) или добивает имеющиеся данные свежими инкрементными.
Зависимость между двумя типами выгрузок обусловлена тем, что данные не должны пересекаться в пакетах.
Синхронизировать их запуск не проблема.
Инкрементность отслеживается вновь добавленным полем audit_mark. Триггер на таблицу.
Понятно, что триггер это плохая идея, но влезть в приложение, которое работает с этой базой, возможности нет.
Триггер проставляет audit_mark в 1 при insert, 2 - update, 3 - delete (т.к. физическое удаление записи не происходит),
есть еще 4 - если после insert сразу delete, чтобы игнорировать эти записи вообще.
Таким макаром я отделяю обработанные в новом периоде строки.
Процесс инкрементной выгрузки забирает их и по окончании audit_mark обnullяет.
Инкрементная и полная выгрузки работают по расписанию. И не могут идти одновременно.
Но при старте полной нужно прежде, как и вы сказали, запустить инкрементную.
Я думал обеспечить повторяемое чтение для всех последующих потоков с помощью AS OF TIMESTAMP.
Но кажется достаточно будет забирать все строки с audit_mark = null.
Пользователи продолжают работать, за счет этого у модифицированных ими записей audit_mark НЕ null.
Мои потоки и не увидят эти изменения когда бы ни были запущены в составе полной выгрузки.
JDS
Дата: 30.09.2015 12:01:33
sevasel, ну там уже вам виднее, разберетесь ) а под "расширить данные" ArtNick наверно, подобное и имел в виду.
kva6513
Дата: 30.09.2015 12:03:20
sevasel |
---|
кажется достаточно будет забирать все строки с audit_mark = null. |
Рискуете потерять множественные последовательные UPDATE в инкрементах, IMHO.
sevasel
Дата: 30.09.2015 12:12:17
kva6513 |
---|
sevasel |
---|
кажется достаточно будет забирать все строки с audit_mark = null. |
Рискуете потерять множественные последовательные UPDATE в инкрементах, IMHO. |
почему?.. не спорю, хочу понять.
первый update записи установит ее audit_mark в 2, последующие тоже, вернее триггер посмотрит, что там уже 2 и не станет ничего делать.
при старте инкрементной выгрузки делаю SELECT FOR UPDATE, т.е. блокирую записи. по окончании инкрементной выгрузки audit_mark=null. допустим параллельно кто-то делал update одной из залоченных записей, он ждет завершения моей транзакции. потом срабатывают его обновления, триггер меняет audit_mark. а служба запускает сбор строк для полного снимка данных по условию audit_mark=null. эти обновленные записи попадут в следующий пакет инкрементной выгрузки. разве не так? или вы о другой ситуации?