Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Забавное поведение rec_version в wait-транзакциях / 25 сообщений из 74, страница 1 из 3
25.07.2016, 19:26
    #39279890
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Здравствуйте. Заметил интересное поведение сервера отдаленно напоминающее ошибку:

FB 2.5.5 Super x64, fbclient x32 из этого же дистрибутива, Win64, Delphi XE5, FIB
2 коннекта, у каждого по транзакции:
isc_tpb_read_committed
isc_tpb_rec_version
isc_tpb_wait
isc_tpb_lock_timeout

Выполняется апдейт одной и той же записи (update t set f='NewValue' where Id=:pId), никакой обвязки на таблице, даже PK нет.

tr1.Start
tr2.Start
update1.exec
update2.exec

Если последовательно - всё ожидаемо, update2 через 5 секунд вываливается с "Lock time-out on wait transaction. Deadlock. Update conflicts with concurrent update."

А вот если коннекты разделены по потокам (коннект+транзакция+апдейт), и запустить потоки паралельно (очень паралельно, потоки привязанные к разным ядрам слушают один эвент и стартуют апдейт), жертва вылетает сразу (без ожидания 5 сек) вот так: "Deadlock. Update conflicts with concurrent update."

Лечится установкой no_rec_version. В результате последовательно и паралельно работает одинаково (с ожиданием).
Мне это кажется странным. wait должен или работать полностью в транзакциях с rec_version или не работать в таких транзакциях совсем.

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

P.S. Да, в реальном приложении такой ситуации (двойной паралельный апдейт одной записи) не возникнет, это тестовое приложение, оно эмулирует работу комплекса приложений в котором даже невозможное возможно.
P.P.S. Да, я знаю, что супер 2.5 не очень SMP. Тестироваться будет и FB 3.0 и какой-нибудь MSSQL, просто начал с FB 2.5 как с самой знакомой платформы.
...
Рейтинг: 0 / 0
25.07.2016, 19:29
    #39279892
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_wait должен или работать полностью в транзакциях с rec_version или не работать в таких
транзакциях совсем.

Он и работает. Просто первый поток завершает транзакцию мгновенно и второй таки дожидается
этого момента.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25.07.2016, 23:13
    #39279982
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_оно эмулирует работу комплекса приложений в котором даже невозможное возможно
дабл_таблоид детектед :)
...
Рейтинг: 0 / 0
26.07.2016, 01:06
    #39279995
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry SibiryakovОн и работает.Мне кажется - нет. С rec_version поведение при паралельном исполнении и при последовательном отличается. А с no_rec_version поведение одинаковое.
Если бы первывй поток "завершал транзакцию мгновенно", то поведение ни чем не отличалось бы от последовательного.

Докдабл_таблоид детектед :) Не я такой, ТЗ такое :) Хотя это конечно не оправдание.
...
Рейтинг: 0 / 0
26.07.2016, 11:41
    #39280178
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_Мне кажется - нет.
Когда кажется - надо включать аудит и изучать последовательность операций на сервере по нему.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.07.2016, 12:07
    #39280214
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry SibiryakovКогда кажется - надо включать аудит и изучать последовательность операций на сервере по нему.А вот и спасибо, про вариант отладки с этой стороны я позабыл. На недельке займусь и отпишу тут. Пока меня устроит no_rec_version для update-транзакций.
...
Рейтинг: 0 / 0
26.07.2016, 17:16
    #39280529
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Решил таки доковырять проблему.

Итого rec_version ведет себя таки адекватно - дожидаясь завершения блокирующей транзакции и после этого вываливаясь с исключением. Как при низком уровне паралельности, так и при высоком. Снимаю шляпу, был не прав.

А вот с no_rec_version возникли вопросы. И, к сожалению, именно no_rec_version мне нужен будет в реальной системе. Или select for update, но это печально.
В случае низкой паралельности запросов (кнопочками из двух приложений апдейты/комиты кормлю серверу) транзакция2 спокойно апдейтит запись, которую изменила транзакция1, после комита транзакции1.
В случае высокой паралельности (паралельные потоки по ивенту отправляющие апдейты на одну запись) транзакция2 вылетает с "update conflicts with concurrent update" при комите транзакции1. И в логах сервера это подтверждается. Логи во вложении.

P.S. Коннект по 127.0.0.1, по этому про плохую сеть даже не пофантазировать.
P.P.S. тыц и тыц изучены. Первый тыц подтверждает мою теорию, но у меня такое даже на 2 транзакциях воспроизводится стабильно, а у товарища на 3.
P.P.P.S. Я конечно это проверю и на FB 3.0, но если там поведение такое-же... мне остается только оборочивать апдейты в try...except в банальном тестовом приложении. А когда адепты MSSQL посмотрят в мой код и спросят "А зачем это у тебя так? Оно что, может свалиться?", я не буду знать что ответить.

Такие дела. Жду Ваших комментариев :)
...
Рейтинг: 0 / 0
26.07.2016, 17:22
    #39280535
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_И, к сожалению, именно no_rec_version мне нужен будет в реальной системе.

http://www.gunsmoker.ru/2008/10/x-y-z.html detected
Тебе надо не обрабатывать конфликты, а предотвращать их. А это требует определённой
архитектуры как БД так и приложения.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.07.2016, 17:46
    #39280566
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry SibiryakovТебе надо не обрабатывать конфликты, а предотвращать их. А это требует определённой
архитектуры как БД так и приложения.Да... но нет.
Во первых потому что такая разница в поведении - это ошибка.
Во вторых потому что системы бывают не только новые, но и существующие. Причем существующие уже давно и, как следствие, имеющие очень высокую цену на изменение архитектуры. Пробежаться по коду и заменить X на Y легко, но сколько итераций полнофункционального тестирования для данного изменения будет, это болезненный вопрос.
...
Рейтинг: 0 / 0
26.07.2016, 20:18
    #39280651
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_Или select for update, но это печально.И что тут печального ?
...
Рейтинг: 0 / 0
26.07.2016, 21:06
    #39280670
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
hvladAndrey_Или select for update, но это печально.И что тут печального ?Два запроса вместо одного. Ну, или хранимку апдейтящую на каждый чих, или холостой апдейт. И всё это вместо нативного no_rec_version.
...
Рейтинг: 0 / 0
26.07.2016, 21:19
    #39280673
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
...
Рейтинг: 0 / 0
27.07.2016, 00:02
    #39280713
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry SibiryakovЧисто для ознакомления: http://www.sql.ru/forum/964534/hranimye-agregaty-bez-konfliktov-i-blokirovok-recept Спасибо, познавательно, возможно после детального изучения куда-то и применю. Но не моя ситуация, у меня нет агрегатов и они не нужны. По крайне мере я пока не вижу куда их применить.
...
Рейтинг: 0 / 0
27.07.2016, 01:41
    #39280726
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_hvladпропущено...
И что тут печального ?Два запроса вместо одного.EXEC BLOCK, если к процедурам аллергия

PS в "проблему" не вникал
...
Рейтинг: 0 / 0
27.07.2016, 11:53
    #39280990
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_не моя ситуация, у меня нет агрегатов
Тогда как ты умудряешься получать update conflict?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.07.2016, 12:50
    #39281101
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
hvladAndrey_Два запроса вместо одного.EXEC BLOCK, если к процедурам аллергияВ целом те же яйца, что и процедура. В итоге при апдейте мне нужно просить сервер выполнить два запроса вместо одного. Всегда. Конечно с where current of это полтора запроса, а не два, но всеравно больше чем один.

hvladPS в "проблему" не вникалИ это тоже печалит.


Dimitry SibiryakovТогда как ты умудряешься получать update conflict?
Псэудокоде Делфисайл
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Thread0
  FWakeupEvent := CreateEvent(nil, true, false, '')
  Thread1.Create(false)
  Thread2.Create(false)
  подождать пока Thread1 и Thread2 дойдут до WaitForSingleObject
  SetEvent(FWakeupEvent)
Thread1
  CPUAffinity(2);
  create Connect, Transaction, Query
  connect
  WaitForSingleObject(FWakeupEvent)
  StartTransaction
  Execute(update)
  Commit
Thread2
  CPUAffinity(4);
  create Connect, Transaction, Query
  connect
  WaitForSingleObject(FWakeupEvent)
  StartTransaction
  Execute(update)
  Commit

Это то что я называю "высокий паралельность". Когда запросы действительно идут одновременно. После нескольких итераций (а иногда и на первой итерации) апдейт, который пришел на сервер чуть позже сразу вылетает с update conflict. Без ожидания. На всякий случай:
Параметры транзакций
Код: sql
1.
2.
3.
4.
isc_tpb_read_committed
isc_tpb_no_rec_version
isc_tpb_wait
isc_tpb_lock_timeout=7

Логи сервера я уже выкладывал выше, и для последовательных запросов и для паралельных.


На релизе FB 3.0 (Super/SuperClassic) проверил - поведение не отличается. А после N-ого количества итераций теста при select из тестовой таблицы получил "database file appears corrupt (D:\DB\RDBTEST_3.0.FDB).
wrong page type.
page 177 is of wrong type (expected data, found unknown (89))."
Сценария порчи базы не нашел.
...
Рейтинг: 0 / 0
27.07.2016, 12:57
    #39281112
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_Это то что я называю "высокий паралельность".

Я это называю "крайний дебилизм".

Ты мне по-простому, на пальцах объясни: вот лежит в БД "Иванов Иван Иванович" и внезапно
один пользователь БД решил переименовать его в Петрова, а второй, так же внезапно, в ту же
миллисекунду - в Сидорова. Вопрос: с какого перепою и кто им разрешил это делать?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.07.2016, 13:09
    #39281131
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry SibiryakovЯ это называю "крайний дебилизм".

Ты мне по-простому, на пальцах объясни: вот лежит в БД "Иванов Иван Иванович" и внезапно
один пользователь БД решил переименовать его в Петрова, а второй, так же внезапно, в ту же
миллисекунду - в Сидорова. Вопрос: с какого перепою и кто им разрешил это делать?
А... ну да, дибилизм. Когда в таблице одно поле, конечно дибилизм. Но иногда бывает, что в таблице больше одного поля, и один "пользователь" меняет одно поле, а другой другое поле. Конечно это всё решается, если разделить поля по разным таблицам связанным 1:1. Но это тот самый вопрос смены архитектуры существующей системы, который уже обсуждали.
...
Рейтинг: 0 / 0
27.07.2016, 13:13
    #39281138
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_один "пользователь" меняет одно поле, а другой другое поле.

И опять возникает вопрос: с какого перепою и на каком основании?

PS: И таки да, разведение этих полей по разным таблицам есть правильное действие,
поскольку при ближайшем рассмотрении скорее всего окажется, что это аттрибуты разных
сущностей.

PPS: Для смены архитектуры существующей системы существует такая удобная вещь как view.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.07.2016, 13:13
    #39281139
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry Sibiryakov,
+1

Andrey_ ,

ты можешь привести реальный пример когда это требуется, а не абстрактные размышления?
...
Рейтинг: 0 / 0
27.07.2016, 14:25
    #39281232
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_В целом те же яйца, что и процедура. В итоге при апдейте мне нужно просить сервер выполнить два запроса вместо одного. Всегда. Конечно с where current of это полтора запроса, а не два, но всеравно больше чем один.Тебе шашечки, или ехать ? В конкурентном мире подходы не совпадают с последовательным, такова селяви. Собственно подходов два:
1. оптимистичный: прочитали, проверили - если подходит, пробуем взять себе, не получилось - повторяем
2. пессимистичный: захватили, потом проверяем

SELECT WITH LOCK - как раз второй подход. Что выбрать - решать тебе.

И вообще - с чего ты взял, что no_rec_version хоть как-то влияет на update ?
Оно обещает (и делает) подождать при чтении (селекте), если тр-ция записи активна.
Но никто не обещал делать этого при записи (апдейте).

Andrey_На релизе FB 3.0 (Super/SuperClassic) проверил - поведение не отличается. А после N-ого количества итераций теста при select из тестовой таблицы получил "database file appears corrupt (D:\DB\RDBTEST_3.0.FDB).
wrong page type.
page 177 is of wrong type (expected data, found unknown (89))."А вот это я очень хотел бы воспроизвести.
...
Рейтинг: 0 / 0
27.07.2016, 15:10
    #39281290
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Dimitry SibiryakovИ опять возникает вопрос: с какого перепою и на каком основании?Симонов Денисты можешь привести реальный пример когда это требуется, а не абстрактные размышления?
Реальный примерДано:
Диспетчерская такси. У этой диспетчерской есть водители и заказы. У водителей есть смартфоны. С помощью приложений на смартфонах водители коммуницируют с диспетчерской.
Сценарий:
Водитель выполнил заказ и в приложении на смартфоне поставил галку "Свободен"
Приложение со смартфона записало эту информацию в базу FB (через третье звено или на прямую - не важно)
Каким-то волшебным образом (ведь в FB нельзя привязывать к ивентам идентификаторы) все подсистемы диспетчерской узнали что водитель выполнил заказ. И начинается карусель:
Подсистема 1 выполняет поиск подходящего заказа для этого водителя и записывает ID заказа в запись водителя.
Подсистема 2 выполняет перерасчет баланса водителя (и всякой другой фин.информации) и записывает ее в запись водителя.
Подсистема 3 выполняет актуализацию геоданных водителя (полученных с того же смартфона) и записывает ее в запись водителя
И в это же время асинхронно работают другие шедулеры выполняющие другие действия над водителями...

А еще, перед тем как поставить галку "Свободен" водитель позвонил в диспетчерскую и попросил поставить его в какой-то сектор. И диспетчер ручками меняет запись водителя через свое приложение.

Все эти действия происходят асинхронно. И любые 2 и более могут совпасть по времени. И да, это всё нужно паралелить, потому что это не более 20% от всей функциональности, а в пиковые моменты число заказов измеряется десятками в секунду


Но! Но. В превую это может понадобится потому что работа под высокой нагрузкой и под низкой нагрузкой должна отличатся только временем отклика, но никак не сценарием поведения СУБД. Это делает СУБД предсказуемой.


Dimitry SibiryakovPS: И таки да, разведение этих полей по разным таблицам есть правильное действие,
поскольку при ближайшем рассмотрении скорее всего окажется, что это аттрибуты разных
сущностей.

PPS: Для смены архитектуры существующей системы существует такая удобная вещь как view.Да всё что угодно можно разделить, даже одну сущность по нескольким таблицам размазать, и даже может быстрее некоторые операции будут работать (записи то узкими станут). Правда другие операции станут гораздо медленнее. Потому что нужно будет или писать тригеры на вьюху (если с клиентов мы апдейтим вьюху) и в них проверять что же изменилось и делать соответствующие апдейты таблиц, или писать тригеры на таблицы (если мы с клиентов апдейтим таблицы а не вьюху) и в них собирать запись из кусков размазаных по разным таблицам чтобы проверить какое-то условие, поля которого "не относятся к данной сущности". Вопрос не в этом.


hvladТебе шашечки, или ехать ?Мне ехать. Ехать так как работает no_rec_version при низкой нагрузке.

hvladИ вообще - с чего ты взял, что no_rec_version хоть как-то влияет на update ?
Оно обещает (и делает) подождать при чтении (селекте), если тр-ция записи активна.
Но никто не обещал делать этого при записи (апдейте).Ну... не смотря на то что этого никто не обещал, по моим наблюдениям (которые подтверждаются логами сервера) и при апдейте влияет. rec_version - всегда дожидается своего таймаута/завершения конкурента. no_rec_version обычно дожидается завершения конкурента, но иногда вылетает сразу.

hvladА вот это я очень хотел бы воспроизвести.На недельке повращаю базу по разному. Но ничего не обещаю.
...
Рейтинг: 0 / 0
27.07.2016, 15:19
    #39281300
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_Подсистема 1 выполняет поиск подходящего заказа для этого водителя и записывает ID заказа в запись водителя.
Подсистема 2 выполняет перерасчет баланса водителя (и всякой другой фин.информации) и записывает ее в запись водителя.
Подсистема 3 выполняет актуализацию геоданных водителя (полученных с того же смартфона) и записывает ее в запись водителя
И в это же время асинхронно работают другие шедулеры выполняющие другие действия над водителями...

с какого бодуна все эти подсистемы работают с одной таблицей? Это же разные сущности.
Всегда считал что это ID водителя должно в заказ писаться, а не наоборот.

Andrey_выполняет перерасчет баланса водителя (и всякой другой фин.информации) и записывает ее в запись водителя.

а говорил агрегатов нет...
...
Рейтинг: 0 / 0
27.07.2016, 15:20
    #39281301
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Andrey_Реальный пример
И тут-то из всех щелей полезли балансы, текущий заказ и прочие хранимые агрегаты, которых
"нет".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.07.2016, 15:36
    #39281316
Andrey_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Забавное поведение rec_version в wait-транзакциях
Господа, как вы на слово "баланс" то накинулись :)
Повторюсь, у меня нет агрегатов и смысла в них не вижу. Считайте, что это не баланс, а количество выполненных заказов (банальный X=X+1). Так будет легче.

Но, не спорю, для уменьшения конкуренции можно это всё складывать в отдельную табличку, а потом когда-нибудь ночью агрегировать. Но зачем? В случае баланса у меня нет конкурентных обновлений одного поля.

И да, в водителе таки должен храниться заказ, т.к. способов назначить заказ водителю существует минимум 6 (всё что сходу вспомнил) и большинство из них могут конкурировать между собой. Поле это нужно чтобы конкуренты не перезаписали друг друга. Просто update Driver set OrderId=:pOrderId where DriverId=:pDriverId and OrderId is null
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Забавное поведение rec_version в wait-транзакциях / 25 сообщений из 74, страница 1 из 3
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]