Потеря данных при репликации, IB 7.5
Добавлено: 16 авг 2007, 16:34
Столкнулся с потерей данных при репликации. Не решал ли кто-либо подобную проблему? Вот описание:
IB 7.5, режиим SuperServer, Win Server 2003, HyperThread включен.
Есть две базы - Оперативная и Аналитическая. В Оперативной данные текущего дня, в Аналитческой базе данные за год. Нынешний объем Аналитической базы 8 гигов. Ведется непрерываная репликация данных с Оперативной на Аналитическую. Кол-во перекачиваемых записей в сутки ~500.000. Пиковая нагрузка при перекачке ~30-50 записей/сек. Одновременных соединений с базой Оперативной ~50. С Аналитической ~10-15. Backup-restore Аналитической базы выполняется крайне редко, слишком долгая процедура.
Описание структуры данных базы на пальцах.
Есть таблица T_BENTITY (состояние бизнес-объекта, primary key field BEID). На эту таблицу ссылаются все таблицы с бизнес-объектами, у них тоже есть ссылочное поле BEID. Все изменения во всех таблицах Оперативной базы через механизм триггеров попадают в очередь репликации (одно изменение-одна запись в очереди). В очередь репликации записи обычно вываливаются небольшими блоками (1-1000 записей). Оттуда репликатор их последовательно проталкивает в Аналитическую базу.
Репликатор свой, работает непрерывно, режим работы транзакций ReadComitted, Wait. Использует компоненты IBX 6.08. На каждую запись в очереди репликации в обоих базах (Аналитике и в Оперативной) открывается по отдельной транзакции. Успешно прокачанной запись считается, если:
а) соотв. запрос в Аналитике прошел без exception. Если запрос типа update и закончился без exception, но ничего в Аналитической базе не поменял, то запись считается ошибочной;
б) запись успешно удалена из очереди репликации.
Поcле успешного окончания запись удаляется из очереди репликации.
По каждой записи ведётся лог - прошла или не прошла - во внешнем текстовом файле. Примечание: кол-во изменных записей в update запросах считывается через свойствo RowsAffected компонента TIBSQL.
Теперь описание проблемы.
Один из типичных случаев, выдран из лог-файла репликатора, как пример.
Рассматриваем две таблицы T_BENTITY (бизнес-сущность), T_RGOODS (прибывший товар). T_RGOODS ссылается на T_BEID по полю BEID.
16.08 3:09:58 Тип: Ok
SEQID: 27711
SQL: INSERT INTO T_BENTITY (BTIME,BCLASSID,BOWNERBEID,BSTATEID,BUSERBEID,BEID) VALUES ('2007-08-15 23:38:13.0000',310,1,11,1,2072261010057931)
SQLCHECK:
ЗЫ: INSERT INTO T_BENTITY в Аналитическую базу прошел успешно,
транзакция закрыта нормально.
16.08 3:09:58 Тип: Ok
SEQID: 27712
SQL: INSERT INTO T_RGOODS (RSALES,DUMMY,BARCODE,BEID,GDATE,GTIME,RECELINEID,UNKNOWNF,WDATE,RGOODSID,LOTID,UnMarked,MDATE,PARTNERID) VALUES (0,0,951763070814,2072261010057931,'2007-08-15','23:38:00.0000',2072261000000838,0,'2007-08-15',2072261000014885,1,0,'2007-08-15',2061861000000052)
SQLCHECK:
ЗЫ: INSERT INTO T_RGOODS прошел успешно, эта запись ссылается на только что вставленную запись в T_BENTITY
далее разрыв в пять часов, ссылок и обращений в логе на эту запись не было, т.е. репликатор удалить её не мог.
16.08 8:50:24 Тип: Внимание!
SEQID: 180354
SQL: UPDATE T_BENTITY SET BTIME='2007-08-16 08:50:07.0000', BCLASSID=310, BOWNERBEID=1, BSTATEID=15, BUSERBEID=1 WHERE BEID=2072261010057931
SQLCHECK: SELECT BEID FROM T_BENTITY WHERE BEID=2072261010057931
Update(delete) запрос не подействовал
ЗЫ попытка update записи в T_BENTITY. НО!!!! запись не найдена, update не выполнен, выдана ошибка. Репликатор сразу пытается исправить ошибку в базе и заново вставить пропавшую запись, есть у него такое умение. Вставка проходит успешно. Т.е. записи в Аналитической базе действительно не было, т.к. при исправляющей вставке не было ошибки по главному ключу. В предыдущих версиях репликатора исправляющей вставки не было, и обычно далее следовали ошибки при update-ах записей ссылающихся на T_BENTITY (в рассматриваемом случае это T_RGOODS)
Странная какая-то картинка. Такая ситуация была бы допустима, если какое-то рабочее место удалит запись в T_BENTITY из Аналитики, но это возможно только в том случае, если удалят ссылающуюся на неё T_RGOODS. А её никто не удалял, она в базе есть, это проверено.
Ошибок в логе IB за рассматриваемы промежуток времени не было. Были только INET/inet_error: read errno = 10054 - потеря коннекта с клиентом.
И еще IB был перезапущен за три минуты перед первоначальной вставкой, вот сообщение в логе
DC-DBS2 (Server) Thu Aug 16 03:03:11 2007
SERVER/set_process_affinity: hyper-threading ProcessAffinityMask is 3
DC-DBS2 (Server) Thu Aug 16 03:03:11 2007
SERVER/set_process_affinity: setting ProcessAffinityMask to 3
DC-DBS2 (Server) Thu Aug 16 03:03:11 2007
Server: setting SWEEP_QUANTUM to 250, USER_QUANTUM to 500,
SWEEP_YIELD_TIME to 0 ms, and MAX_THREADS to 1000
SQL_COMPILER_RECURSION to 2000
В-общем, прошу помощи!
IB 7.5, режиим SuperServer, Win Server 2003, HyperThread включен.
Есть две базы - Оперативная и Аналитическая. В Оперативной данные текущего дня, в Аналитческой базе данные за год. Нынешний объем Аналитической базы 8 гигов. Ведется непрерываная репликация данных с Оперативной на Аналитическую. Кол-во перекачиваемых записей в сутки ~500.000. Пиковая нагрузка при перекачке ~30-50 записей/сек. Одновременных соединений с базой Оперативной ~50. С Аналитической ~10-15. Backup-restore Аналитической базы выполняется крайне редко, слишком долгая процедура.
Описание структуры данных базы на пальцах.
Есть таблица T_BENTITY (состояние бизнес-объекта, primary key field BEID). На эту таблицу ссылаются все таблицы с бизнес-объектами, у них тоже есть ссылочное поле BEID. Все изменения во всех таблицах Оперативной базы через механизм триггеров попадают в очередь репликации (одно изменение-одна запись в очереди). В очередь репликации записи обычно вываливаются небольшими блоками (1-1000 записей). Оттуда репликатор их последовательно проталкивает в Аналитическую базу.
Репликатор свой, работает непрерывно, режим работы транзакций ReadComitted, Wait. Использует компоненты IBX 6.08. На каждую запись в очереди репликации в обоих базах (Аналитике и в Оперативной) открывается по отдельной транзакции. Успешно прокачанной запись считается, если:
а) соотв. запрос в Аналитике прошел без exception. Если запрос типа update и закончился без exception, но ничего в Аналитической базе не поменял, то запись считается ошибочной;
б) запись успешно удалена из очереди репликации.
Поcле успешного окончания запись удаляется из очереди репликации.
По каждой записи ведётся лог - прошла или не прошла - во внешнем текстовом файле. Примечание: кол-во изменных записей в update запросах считывается через свойствo RowsAffected компонента TIBSQL.
Теперь описание проблемы.
Один из типичных случаев, выдран из лог-файла репликатора, как пример.
Рассматриваем две таблицы T_BENTITY (бизнес-сущность), T_RGOODS (прибывший товар). T_RGOODS ссылается на T_BEID по полю BEID.
16.08 3:09:58 Тип: Ok
SEQID: 27711
SQL: INSERT INTO T_BENTITY (BTIME,BCLASSID,BOWNERBEID,BSTATEID,BUSERBEID,BEID) VALUES ('2007-08-15 23:38:13.0000',310,1,11,1,2072261010057931)
SQLCHECK:
ЗЫ: INSERT INTO T_BENTITY в Аналитическую базу прошел успешно,
транзакция закрыта нормально.
16.08 3:09:58 Тип: Ok
SEQID: 27712
SQL: INSERT INTO T_RGOODS (RSALES,DUMMY,BARCODE,BEID,GDATE,GTIME,RECELINEID,UNKNOWNF,WDATE,RGOODSID,LOTID,UnMarked,MDATE,PARTNERID) VALUES (0,0,951763070814,2072261010057931,'2007-08-15','23:38:00.0000',2072261000000838,0,'2007-08-15',2072261000014885,1,0,'2007-08-15',2061861000000052)
SQLCHECK:
ЗЫ: INSERT INTO T_RGOODS прошел успешно, эта запись ссылается на только что вставленную запись в T_BENTITY
далее разрыв в пять часов, ссылок и обращений в логе на эту запись не было, т.е. репликатор удалить её не мог.
16.08 8:50:24 Тип: Внимание!
SEQID: 180354
SQL: UPDATE T_BENTITY SET BTIME='2007-08-16 08:50:07.0000', BCLASSID=310, BOWNERBEID=1, BSTATEID=15, BUSERBEID=1 WHERE BEID=2072261010057931
SQLCHECK: SELECT BEID FROM T_BENTITY WHERE BEID=2072261010057931
Update(delete) запрос не подействовал
ЗЫ попытка update записи в T_BENTITY. НО!!!! запись не найдена, update не выполнен, выдана ошибка. Репликатор сразу пытается исправить ошибку в базе и заново вставить пропавшую запись, есть у него такое умение. Вставка проходит успешно. Т.е. записи в Аналитической базе действительно не было, т.к. при исправляющей вставке не было ошибки по главному ключу. В предыдущих версиях репликатора исправляющей вставки не было, и обычно далее следовали ошибки при update-ах записей ссылающихся на T_BENTITY (в рассматриваемом случае это T_RGOODS)
Странная какая-то картинка. Такая ситуация была бы допустима, если какое-то рабочее место удалит запись в T_BENTITY из Аналитики, но это возможно только в том случае, если удалят ссылающуюся на неё T_RGOODS. А её никто не удалял, она в базе есть, это проверено.
Ошибок в логе IB за рассматриваемы промежуток времени не было. Были только INET/inet_error: read errno = 10054 - потеря коннекта с клиентом.
И еще IB был перезапущен за три минуты перед первоначальной вставкой, вот сообщение в логе
DC-DBS2 (Server) Thu Aug 16 03:03:11 2007
SERVER/set_process_affinity: hyper-threading ProcessAffinityMask is 3
DC-DBS2 (Server) Thu Aug 16 03:03:11 2007
SERVER/set_process_affinity: setting ProcessAffinityMask to 3
DC-DBS2 (Server) Thu Aug 16 03:03:11 2007
Server: setting SWEEP_QUANTUM to 250, USER_QUANTUM to 500,
SWEEP_YIELD_TIME to 0 ms, and MAX_THREADS to 1000
SQL_COMPILER_RECURSION to 2000
В-общем, прошу помощи!