|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
Имею задачу которую в общем виде можно описать так: - Клиенты выгребают из таблицы строки которые изменились с определенного момента - Признак что строка изменилась является поле типа timestamp (time_change) - Есть отдельная таблица которая хранит время до какого момента клиент уже получил измененные данные - Строки изменяются в транзакции, которая может длится достаточно долго (пусть 5 минут на изменение многих таблиц) - В транзакции срабатывает триггер на установку момента изменения строки - Возникают ситуации когда транзакция изменяющая данные уже идет, клиент подключился, посмотрел, что для него данных нет, записал в таблицу время когда проверял наличие новых данных и отключился. В это время закончилась транзакция которая обновляла данные и закоммитилось время раньше чем клиент проверял. - При таком раскладе гарантированно клиент не получает часть обновленных данных Начал делать примерно следующее pg_dump Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60.
Тестирую так: Код: plsql 1. 2. 3.
Да, триггер выполняется один раз (в том числе благодаря костылю updated, но с этим можно смириться). Только time_change измененных строк после коммита имеет разницу в несколько секунд, что есть проблема. Есть ли способ для версий ниже 10 получить в процедуре готовый список строк и установить им time_change одним запросом чтобы время у всех строк было одинаковое и равнялось моменту коммита? Возможно есть какой-то более правильный способ делать то, что я хочу не изобретая велосипед? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 01:56 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
YP977, imho всё неправильно. вам нужна отдельная таблица/запись "по какой момент (номер транзакции) клиент имеет право читать". == "с какого момента (номера транзакции) джобы имеют право читать". использование клок-таймстампа вместо каррента неоправдано почти никогда. да и вообще замыкаться на время -- не правильно. (время сервера иногда меняется). вернее пользоваться ид-транзакций(TXID) и видимостями (SNAPSHOT). https://www.postgresql.org/docs/10/functions-info.html#FUNCTIONS-TXID-SNAPSHOT чтобы ее (табличку тхидов) правильно вести надо почитать как устроены видимости в пж. ну или писать всё в сериалайзебл уровне изоляции, как некоторые тут любят советовать. на крайняк пользуйтесь pgq -- там всё готово ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 10:08 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
qwwq, О, как-то не думал об этом. Спасибо покопаю в эту сторону. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 13:17 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
qwwq, Еще раз спасибо!! Разобрался с TXID, почитал документацию и проникся. Понял, что работа с временем - это очень кривое решение, велосипед еще тот :) В целом сейчас выборка нужных мне записей свелась к запросу Код: plsql 1.
А номер транзакции получаю через txid_current(); Поиграюсь с большими таблицами и большими выборками, но не думаю, что это будет медленные чем выборка по индексированному timestamp. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 18:51 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
YP977, не забудьте проверить работу при wraparound. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 19:58 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
Melkij, Спасибо за подсказку. Проверю. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 21:13 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
В документации версии 9.6 написано следующее Внутренний тип идентификаторов транзакций (xid) имеет размер 32 бита, поэтому они повторяются через 4 миллиарда транзакций. Однако эти функции выдают 64-битные значения, дополненные счётчиком «эпохи», так что эти значения останутся уникальными на протяжении всей жизни сервера. 64 бита точно хватит Но что-то закрались сомнения. Посмотрел на сервера которые достаточно старые и там значения txid_current() какие-то маленькие... 479 903 869 375 192 752 523 133 340 Это у меня сервера не нагруженные или что-то не так с документацией? Какие у вас выдаются значения? Есть больше 4 294 967 296? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 21:47 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
YP977, Самое интересное будет когда вы во время апгрейда сделаете дамп базы и загрузите его в новую версию. И, внезапно, txid_current() будет возвращать значения меньше, чем те, что у вас в таблицах зафиксированы. Это похоже на эффект от wraparound. Завязываясь на системные колонки базы вы вступаете на путь удивительных открытий! ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 22:07 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
vyegorov, Да это так. Логика работы приложения в целом позволяет такому случиться. Это не будет приятно, но не смертельно. Все равно пока лучшего решения у меня нет... ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 22:14 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
vyegorovYP977, Самое интересное будет когда вы во время апгрейда сделаете дамп базы и загрузите его в новую версию. И, внезапно, txid_current() будет возвращать значения меньше, чем те, что у вас в таблицах зафиксированы. Это похоже на эффект от wraparound. Завязываясь на системные колонки базы вы вступаете на путь удивительных открытий! это лечится выставлением эпохи кластера. подробности лень искать. (про перенос пгку) неудобство -- требует останова. если не знать -- можно сильно побиться при переезде ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 23:47 |
|
Триггер AFTER с получением списка измененных строк (версия < 10)
|
|||
---|---|---|---|
#18+
На всякий случай. Я нашел таки сервер у которого txid_current() больше чем 2^32 Конкретное значение = 4 578 378 203 Так что можно спать спокойно. Если не переносить базу на другой сервер/кластер все будет ок. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2019, 16:11 |
|
|
start [/forum/topic.php?fid=53&fpage=43&tid=1995311]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
39ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
55ms |
get tp. blocked users: |
2ms |
others: | 17ms |
total: | 153ms |
0 / 0 |