Синхронизация:Алгоритм действий если не работает синхронизация
Содержание
- 1 Порядок действий
- 2 Частые вопросы
- 2.1 Как синхронизировать таблицу
- 2.2 Можно ли вручную перенести записи если они не приходят по синхронизации?
- 2.3 Пустые наименования
- 2.4 Нужно чтобы закрытая аптека не висела бы на sinhro но чтобы данные по ней отображались в своднике
- 2.5 На sinhro пишется ошибка загрузки пакета и дата очень старая а по docs дата недавняя
- 2.6 Что можно удалить если синхронизация много весит (каталог wamp занимаем очень много места, больше 1гб)?
- 2.7 Как переотправить накладную требования/перемещение/переоценки по синхронизации
- 3 Частые ошибки
Порядок действий
На стороне клиента
- Обновить Distribute Client.
- Убрать настройку перезапуск раз в n циклов.
- Убрать галку хранить историю в g$distribute.
- Проверить таймауты, ограничения пакетов.
- Удалить все лишнее из папки с dtclient'ом (*.zip и *.rcvd файлы).
- Выключить брэндмауэр и антивирус.
- Запустить exe с ключом +detail
- Запустить программу от имени администратора
- Проверить, что дата/время на компьютере установлена верно.
- Поискать запись по d$uuid в g$distribute в первой, серверной и второй базах, чтобы определить между какими базами проблема.
select * from g$distribute g where g.uuid="..."
- Посмотреть когда были последние данные, которые пришли по синхронизации:
select * from g$distribute g order by g.serverpacket desc
- Если запись не ушла из первой базы в серверную, то сравните поле packet, а если она из серверной не дошла до второй базы, то сравните поле serverpacket.
- Проверяем, что на странице [http://192.168.67.30/sinhro/] данный профиль не светится с флагом -1, иначе ошибка на сервере.
- Проверить, что dt клиент включен.
- url адрес который прописан в клиенте, открывается в браузере и выдает no input data
- если не работает, проверить, что на сервере включен wamp.
- иначе если URL начинается с 10, проверить, что поднят open vpn.
- dt клиент не выдает ошибок при скачивании.
- dt клиент что-то скачивет, пишется объем траффика.
- если процесс скачивания идет очень долго, запустить dt клиент с ключом +detail и посмотреть на каких запросах тормозит.
- если проблема с таблицей по старой синхронизации, взять максимальное значение поля packet по этой таблице по этому профилю на сервере:
select max(packet) from :table where g$profile=:profle
и подставить его в генератор поля packet этой таблицы в клиентской базе:
GEN_%TABLE%_PACKET
- проапдейтить необходимые записи.
- Посмотреть за какое число сейчас пытается скачать даннные клиент. Берем uuid последней записи:
select g.uuid from g$distribute g order by g.serverpacket desc
Затем выполняем на сервере:
select g.insertdt, g.updatedt from g$distribute g where g.uuid="..."
Если даты старые (больше недели), то проверяем актуален ли serverpacket на клиенте. Выполняем на сервере:
select serverpacket from g$distribute where from_profile_id=:profile_id order by serverpacket desc
Выполняем на клиенте:
select serverpacket from g$distribute where 1=1 order by serverpacket desc
Сравниваем. Если на сервере значение меньше, то обновляем на клиенте:
update g$distribute set serverpacket=:serverpacket where serverpacket=(select max(g.serverpacket) from g$distribute g)
- Проверить базу на ошибки.
Снова запускаем синхронизацию.
На сервере
- Сервер доступен
- Поискать запись по d$uuid в g$distribute в первой, серверной и второй базах, чтобы определить между какими базами проблема.
select * from g$distribute g where g.uuid="..."
- Посмотреть когда были последние данные, которые пришли по синхронизации:
select * from g$distribute g where g.from_profile_id=:profile_id order by g.serverpacket desc
- в таблице g$queue есть свежие данные:
select * from g$queue q where q.profile_id=:profile_id order by q.insertdt desc
- в таблице docs есть свежие данные
select * from docs d where d.g$profile_id=:profile_id order by d.commitdate desc
Посмотрите на поле endflag: если там -1, значит ошибка.
- профиль прописан в g$profiles, status=0, dbsecurekey not null, остальные колонки как у других подобных профилей.
- в таблице G$DISTRIBUTE_VECTORS есть строчка с tablename нужной таблицы, где to_profile_id либо 0, либо номер базы, куда данные должны уйти.
- в таблице G$DISTRIBUTE_X_TABLES по данному профилю настройки такие же как и у других профилей и там верно указано какой таблице на сервере соответствует таблица на клиенте.
select * from docs order by docdate desc
- если есть таблица g$queue, смотрим когда были последние пакеты и есть ли по ним ошибки.
select * from g$queue q where q.profile_id=:profile_id
- Firebird работает. Если linux, то
/etc/init.d/firebird<Tab> status
если нужно перезапустить:
/etc/init.d/firebird<Tab> restart
- Wamp включен. Если linux, то
/etc/init.d/apache<Tab> status
если нужно перезапустить
/etc/init.d/apache<Tab> stop /etc/init.d/apache<Tab> start
- Удалить все содержимое каталогов users и queue. Если linux, то
cd ... <путь до скриптов> cd users <убедитесь, что вы точно зашли в папку users> rm -R ./* -v cd ../queue <убедитесь, что вы зашли в папку queue> rm -R ./* -v
- Проверить, что дата/время на компьютере установлено верно. Если linux, то
date
если нужно установить время:
date +%T -s "11:14:00"
- Проверить настройки в declare.php. Если linux, то
cd ... <путь до скриптов> nano declare.php
- Служба очереди работает.
Частые вопросы
Как синхронизировать таблицу
В скриптах ниже нужно исправить MY_TABLE на название вашей таблицы.
В клиентской базе
- Добавляем поля D$UUID и D$SRVUPDDT
ALTER TABLE MY_TABLE ADD D$UUID DM_UUID; ALTER TABLE MY_TABLE ADD D$SRVUPDDT DM_DATETIME;
- Делаем первичный ключ на поле d$uuid:
ALTER TABLE MY_TABLE ADD CONSTRAINT PK_MY_TABLE PRIMARY KEY (D$UUID);
- Генерируем значения поля d$uuid:
update MY_TABLE set d$uuid=UUID_TO_CHAR(GEN_UUID()), d$srvupddt='2000-01-01';
- Создаем триггеры:
SET SQL DIALECT 3; SET TERM ^ ; CREATE OR ALTER TRIGGER MY_TABLE_BI_DISTR FOR MY_TABLE ACTIVE BEFORE INSERT POSITION 0 AS begin if (new.d$uuid is null) then begin new.d$uuid=UUID_TO_CHAR(GEN_UUID()); update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('MY_TABLE',new.d$uuid,0,null) matching (TABLENAME,UUID); end if (new.d$srvupddt is null) then new.d$srvupddt='2000-01-01'; end ^ CREATE OR ALTER TRIGGER MY_TABLE_BU_DISTR FOR MY_TABLE ACTIVE BEFORE UPDATE POSITION 0 AS begin if (new.D$SRVUPDDT=old.D$SRVUPDDT) then update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('MY_TABLE',new.d$uuid,1,null) matching (TABLENAME,UUID); end ^ CREATE OR ALTER TRIGGER MY_TABLE_AD_DISTR FOR MY_TABLE ACTIVE AFTER DELETE POSITION 0 AS begin update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('MY_TABLE',old.d$uuid,2,null) matching (TABLENAME,UUID); end ^ SET TERM ; ^
- Делаем update, чтобы отправить данные на сервер:
update MY_TABLE where 1=1;
Настраиваем одностороннюю синхронизацию на сервере
- Создаем таблицу с той структурой, которую сделали в клиентских базах (переносим только структуру).
- Не забываем сделать поле d$uuid уникальным:
ALTER TABLE DOCS ADD CONSTRAINT PK_MY_TABLE PRIMARY KEY (D$UUID);
- Добавляем поле G$PROFILE_ID
ALTER TABLE MY_TABLE ADD G$PROFILE_ID DM_ID;
- Создаем триггеры:
SET SQL DIALECT 3; SET TERM ^ ; CREATE OR ALTER TRIGGER MY_TABLE_BI_SRVSYNC FOR MY_TABLE ACTIVE BEFORE INSERT POSITION 0 AS begin select from_profile_id from g$distribute where uuid=new.d$uuid into new.g$profile_id; end ^ CREATE OR ALTER TRIGGER MY_TABLE_BU_SRVSYNC FOR MY_TABLE ACTIVE BEFORE UPDATE POSITION 0 AS begin select from_profile_id from g$distribute where uuid=new.d$uuid into new.g$profile_id; end ^ SET TERM ; ^
Настраиваем двухстороннюю синхронизацию на сервере
- Создаем таблицу с той структурой, которую сделали в клиентских базах (переносим только структуру).
- Не забываем сделать поле d$uuid уникальным:
ALTER TABLE MY_TABLE ADD CONSTRAINT PK_MY_TABLE PRIMARY KEY (D$UUID);
- Добавляем триггеры:
SET SQL DIALECT 3; SET TERM ^ ; CREATE OR ALTER TRIGGER MY_TABLE_AD0_DISTR FOR MY_TABLE ACTIVE AFTER DELETE POSITION 0 AS begin update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('MY_TABLE',old.d$uuid,2,0) matching (TABLENAME,UUID); end ^ CREATE OR ALTER TRIGGER MY_TABLE_BI_DISTR FOR MY_TABLE ACTIVE BEFORE INSERT POSITION 0 AS begin if (new.d$uuid is null) then begin new.d$uuid=UUID_TO_CHAR(GEN_UUID()); update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('MY_TABLE',new.d$uuid,0,0) matching (TABLENAME,UUID); end if (new.d$srvupddt is null) then new.d$srvupddt='2000-01-01'; end ^ CREATE OR ALTER TRIGGER MY_TABLE_BU0_DISTR FOR MY_TABLE ACTIVE BEFORE UPDATE POSITION 0 AS begin if (new.D$SRVUPDDT=old.D$SRVUPDDT) then update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('MY_TABLE',new.d$uuid,1,0) matching (TABLENAME,UUID); end ^ SET TERM ; ^
- Добавляем информацию о нашей таблице в G$DISTRIBUTE_VECTORS
INSERT INTO G$DISTRIBUTE_VECTORS (FROM_PROFILE_ID, TO_PROFILE_ID, TABLENAME, PERMISSION) VALUES (0, 0, 'MY_TABLE', 0);
Можно ли вручную перенести записи если они не приходят по синхронизации?
Теоретически если записи по непонятным причинам не доходят по синхронизации, а нужно, чтобы эти данные срочно появились в нужной базе, то теоретически можно вручную скопировать эти записи и вставить их в базу вручную через ibexpert. Главное перед этим посмотреть: данная таблица синхронизируется в одну сторону, или в обе стороны, т.е. в клиентской базе данные только этой базы, или вообще всей сети?
- в первом случае при вставке записей не нужно заполнять поле d$uuid для того, чтобы оно сгенерировалось бы заново.
- во втором случае нужно обязательно заполнить поле d$uuid оригинальными значениями.
Если сделать наоборот, то затем, когда записи, которые должны были дойти по синхронизации, дойдут, а они со временем обязательно дойдут, в базах будут возникать конфликты при вставке записей, связанные с пересечением ключей.
Пустые наименования
- Сначала нужно определиться чего именно не хватает. Партия цепляет варес, варес цепляет валс. Обычно не хватает или вареса или валса. Бывает, что все есть, но в валсе пустое значение (в этом случае нужно в менеджере два раза нажать на наименование и вставить оригинальное значение товара).
- Бывают случаи, когда наименование привелось к пустому значению, т.е. проблема в приведении. Попробуйте поискать связки:
select 'WARES', V.SVALUE from WARES WL left join VALS V on WL.NAME_ID = V.ID where WL.ID = :ware_id union select 'WARES_LOG', V.SVALUE from WARES_LOG WL left join VALS V on WL.NAME_ID = V.ID where WL.ID = :ware_id
- Когда определись чего не хватает в текущей базе, попробовать поискать этот валс или варес в другой серверной, сводной или клиентской базе по его id.
- Если проблема была в варесе, то скорей всего он есть где то в другой базе и его достаточно проапдейтить:
update wares w where w.id=:id
- Если проблема с валсом, то нужно перепривязать данное поле вареса, которое на него ссылается, на другое значение (другой валс). Если, например, проблема с наименованием, а оригинальное наименование ссылается на другое значение, то возьмите его и вставьте в название.
update wares w set w.name_id=(select wa.orig_name_id from wares wa where wa.id=:ID) where w.id=:ID
Нужно чтобы закрытая аптека не висела бы на sinhro но чтобы данные по ней отображались в своднике
Поставить dbsecurekey в таблицы g$profiles в null.
На sinhro пишется ошибка загрузки пакета и дата очень старая а по docs дата недавняя
На sinhro берется дата по последнему пакету таблицы g$queue, но из этой таблицы очищаются данные по положительным пакетам старше 3х дней. Поэтому, если последние 3 дня вообще не было синхронизации, то из таблицы сотрутся все данные по неошибочным пакетам и самой последней строчкой будет - самый последний ошибочный пакет. Поэтому, если пишется "ошибка загрузки пакета", но дата старше 3х дней, то это совсем не значит, что ошибка при загрузке на сервер.
Что можно удалить если синхронизация много весит (каталог wamp занимаем очень много места, больше 1гб)?
- В папке queue можно чистить все кроме последних 2х дней.
- В папке users можно чистить все.
Как переотправить накладную требования/перемещение/переоценки по синхронизации
- Нужно подключиться к базе, с которой была отправлена накладная.
- Найти doc_id нужного документа по его номеру:
select * from docs d where d.caption containing :docnum
- Переотправить накладную спомощью процедуры:
execute procedure GM$PR_PRIHOD_DOC_TREB(:doc_id);
Частые ошибки
Column unknown
Ошибка, возникающая на сервере. Означает, что у клиента в синхронизируемой таблице есть колонка, которой нет в этой таблице на серверной базе. Нужно либо добавить данную колонку на сервере, либо если она не нужна, или она есть не во всех клиентских базах, то добавить ее в список XFIELDS(xfields, xfields0, xfields1) в declare.php.
Violation of PRIMARY or UNIQUE KEY constraint
Ошибка, возникающая когда на момент вставки записи в таблицу, в ней уже есть строчка с таким же d$uuid, но с другим сочетанием id и g$profile_id. Нужно либо перегенерировать d$uuid у той строчки, которая уже есть, либо удалить запись, у которой совпадают id и g$profile_id.
Foreign key... At trigger DOCS_TREB_BI
Cначала попробуйте удалить старые накладные требования (сделав бэкап).
delete from doc_detail_active_treb ddat where ddat.insertdt <= current_date-7;
delete from docs_treb dt where dt.insertdt <= current_date-7;
Проверьте в таблицы docs нет ли документов с rguid той записи, на которую ругается. Если такой документ уже есть, то измените ему rguid.
update docs d set d.rguid=replace(UUID_TO_CHAR( GEN_UUID()),'-','') where d.rguid=:rguid;
Multiple rows... PR_SETPARTREALQUANT... DOC_DETAIL_AI_WB
Ошибка на сервере. Возможно в таблице warebase_g две строчки с part_id той записи, на которую ругается синхронизация. Удалите одну из них.
Querypackets2013 Не найдена запись
Ошибка на клиенте, говорит о том, что на сервере в g$distribute запись есть, а в соответствующей таблице на сервере такой записи нет. Возможны два случая:
- Данную запись ктото случайно удалил. В этом случае нужно посмотреть на сервере с какого профиля она пришла (поле from_profile_id в g$distribute), подключиться к этой базе (также можно поискать в других сводных базах), найти эту запись, проапдейтить. В результате она должна придти на сервер и синхронизация снова пойдет.
- Данной записи нигде нет. Возможно она очень старая и поэтому ее удалили специально. Вопрос: почему наша база пытается ее скачать? Возможно в нашей базе сбилось поле serverpacket, точнее ктото неправильно почистил g$distribute, и теперь эта база пытается скачать вообще все с нуля. Надо проверить: это новая база? Нужно определить актуальность данных проблемной базы. Выполняем запрос на сервере:
select * from g$distribute where from_profile_id=:profile_id order by serverpacket desc
Проверяем максимальное значение serverpacket в проблемной базе:
select max(g.serverpacket) from g$distribute g;
Оно должно быть меньше того что мы получили на сервере. Надо его заменить. Если в проблемной базе эта таблица вообще пустая, тогда берем запись с сервера и вставляем ее там. Затем снова запускаем синхронизацию. удалить запись можно запросом :
delete from g$distribute g where g.soper <> 2 and g.tablename='имя таблицы' and not exists(select id from имя таблицы d where d.d$uuid = g.uuid)
Если просит удалить более 1000 записей, ток внедрению
Connection reset by peer
- Проверить таймауты
- Проверить ограничения пакетов
- Выключить антивирус
- Выключить брэндмауэр
- Проверить системное время
- Выключить роутер на 15 минут
- Почистить таблицу g$distribute.
Incomplete Zip File
Ошибка бывает на клиенте.
- Скорей всего связана с блокировками синхронизации антивирусом.
- Проверить правильность написания URL
wrong page type
Ошибка wrong page type page 79332 is of wrong type (expected 7, found 5)... падение базы. выполнить: mend - backup - restore.