Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
(по мотивам рассказов об удивительных фокусах с нарушениями ПК там, где они "ну никак и никогда" не могли происходить). Товарищи! Прошу поднять бокалы, ибо "зарегистрировано открытие"! Допустим, Tх-1 делает в достаточно длительном цикле: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Если курсорный цикл споткнётся на 100500-й итерации обо что-то (да хоть бы на лок-конфликт), то управление прыгнет в when-блок. Ввиду наличия в этом блоке команды 'exception;' начнётся выполнение откатов всех 100499 изменений, а именно: * отмена вставок ключей в индексы таблицы t_target; * отмена вставок собственно данных в таблицу t_target; * отмена удалений в таблице t_source. На обычной windows-тачке (рабочей станции) эти действия будут выполняться для 200 тыс строк около 5 сек. Ключевой ВОПРОС: в какой последовательности будут выполнены откаты, то есть будут ли они идти в порядке, обратном хронологии этих изменений ? Если подробно, то интересовало: 1) на уровне отдельной записи таблицы -- будет ли соблюден "реверс" для вставок ключей в индексы и собственно данных (т.е. если при insert'e сначала корректировали страницу с данными, а затем полезли в индексы, то что при отмене будет первым и что вторым ?); 2) на уровне всех изменявшихся строк некоторой таблицы -- будет ли соблюден "реверс" для того порядка, в котором обрабатывали строки ? например, если обработали строки в следующем порядке id: 752, 284, 911 -- то будет ли откат в обратном порядке: 911 ==> 284 ==> 752 ? 3) на уровне отдельных таблиц: если сначала поменяли в T1, затем в T2, а после стартовали изменения в T3, но они обломались - будут ли откаты идти в порядке Т3 ==> T2 ==> T1 ? 4) на уровне стейтментов -- будет ли соблюден "реверс" порядка выполненных операторов (т.е. если делали так: {delete, insert}, то откатываем так: {insert, delete} - да или нет ?) Эмпирически была получена догадка, подтверждённая затем в интенсивной переписке "Э & K" и и теперь ставшая ОТВЕТОМ: 1) при откате изменений уровня записи -- реверса никакого нет , но порядок таки есть : сначала бекаут записи, потом сборка мусора в индексах -- т.е. порядок точно такой же "прямой" , как и при выполнении самого insert/update-стейтмента; 2) при откате изменений уровня строк -- изменения, скорее всего , будут по возрастанию rdb$db_key, но для приложения это всё равно, что "непредсказуемо"; 3) при откате уровня таблиц -- изменения, скорее всего , будут по возрастанию rdb$relation_id. Для приложения это тоже самое, что и в предыдущем пункте - "непредсказемо"; 4) при откате уровня стейтментов -- никакого порядка нет Всё вышесказанное означает, что вот этот код внутри цикла (см выше): Код: plaintext 1. 2. -- может привести при конкурентной работе даже двух транзакций к тому, что Тх-2 получит исключение PK-violation на операторе insert into t_target(...). И произойдёт это в том случае, когда обломавшаяся конкурентка Тх-1: 1) начала делать откаты своих 100500 изменений; 2) уже отменила удаление некоторой записи ("delete from t_source ..."); 3) еще НЕ успела отменить наличие ключей в таблице t_target, которые были всунуты туда командой "insert into t_target(...)". Постулат о том, что НЕЛЬЗЯ рассчитывать на какой-либо осмысленный порядок отмен изменений, на удивление легко подтвердился. DDL: 1) две таблицы (`ts` & `tt`) с одинаковой структурой и индексами, в одну заливаем "много строк", вторая пуста. 2) процедурка p_handle, переносящая все строки из `ts` в `tt`, и гарантированно обламывающаяся на последней итерации курсора 3) when-блок в p_handle, содержащий exception. Именно этот exception будет выполнять откаты длительностью в несколько секунд, что позволит спокойно переключиться в другое окно и попробовать там сделать "доброе дело" Код: plaintext 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. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. Теперь запускаем три окна. session #0 : трейс с бублированием вывода в лог, конфиг трейса: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. session #1 : ISQL и в нём всё готово для выполнения команды Код: plaintext -- где "ts-tt-del1.sql" есть: Код: plaintext 1. 2. 3. 4. 5. 6. 7. session #2 : ISQL и в нём всё готово для выполнения скрипта "ts-tt-test.sql": Код: plaintext 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. Теперь - поехали! session #1: Код: plaintext session #0: (окно трейса) ждём, пока в нём не появится вот это: Код: plaintext 1. 2. 3. -- после чего быстро переключаемся в session #2 и жмякаем там Ентер. Если всё сделать быстро, то в session #2 получим сначала по лбу: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ##################################################################################### А теперь, почтеннейшая публика, ВНИМАНИЕ! БЫСТРО повторяем ввод предыдущей команды в session #2 , несколько раз. И получаем там: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ЗЫ. Я искал из-за этого PK-violation ошибку в своём коде несколько недель. Затем стал терзаться сомнениями, что это в ФБ глюкобаг, т.к. исключение лезло только на 3.0 SC и никогда не встречалось в 3.0 SS. Но теперь спокойно воспроизвожу и там, и там - надо было просто дровишек побольше для SS подкинуть. ЗЗЫ. Пойду напьюсь, что ле... Гора с плеч же, блин! :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 19:47 |
|
||
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
Таблоидполучена догадка, подтверждённая затем в интенсивной переписке "Э & K" и и теперь ставшая ОТВЕТОМ: 1) Да, так и есть. 2) Да, так и есть. 3) Нет, откат идёт потаблично в порядке, обратном "потрогиванию" этих таблиц в сейфпоинте, поскольку каждая новая затронутая таблица включается в голову списка. 4) Нет никакого "отката уровня стейтментов". Естественно, NO WAIT транзакция получит PK violation если параллельная транзакция уже добавила в таблицу запись с таким значением. Вне зависимости от того что та будет делать потом - откатываться, коммититься или плясать джигу. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 20:27 |
|
||
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov4) Нет никакого "отката уровня стейтментов". Поясню для особо упёртых: есть только сейпоинт и его undo log. Этот сейфпоинт может принадлежать (оборачивать его) стейтменту, блоку, явному пользовательскому сейфпоинту или транзакции. Что в свете сабжа совершенно пофиг, поскольку любой сейфпоинт откатывается абсолютно одинаково вне зависимости от принадлежности. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 20:33 |
|
||
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
Достаточно неожиданно, что отмены идут не в обратном порядке. Наверное, это сделано было ради скорости, не знаю. Dimitry Sibiryakov 3) ["если сначала поменяли в T1, затем в T2, а после стартовали изменения в T3, но они обломались - будут ли откаты идти в порядке Т3 ==> T2 ==> T1 ?"] Нет, откат идёт потаблично в порядке, обратном "потрогиванию" этих таблиц в сейфпоинте, поскольку каждая новая затронутая таблица включается в голову списка. Может, оно и так. Но вот эту вот фразу:Dimitry Sibiryakov2) [при откате изменений уровня строк -- изменения, скорее всего, будут по возрастанию rdb$db_key , но для приложения это всё равно, что "непредсказуемо";] Да, так и есть. -- на фанере таки выжгу. И закреплю четырьмя винтами М8 с гроверными шайбами. ЗЫ. Интересно, будет ли сиё когда-нить описано в офиц. доке... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 20:52 |
|
||
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
ТаблоидДостаточно неожиданно, что отмены идут не в обратном порядке. В отквоченном тобой случае они будут действительно идти в обратном порядке (т.е. Т3-Т2-Т1), но это частный случай и жизнь гораздо непредсказуемее. В частности, порядок зависит и от числа сейфпоинтов, которые смержиись прежде чем начался откат. То есть он довольно сложно предсказуемый, но никак не связан ни со случайность, ни с RELATION_ID. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 21:22 |
|
||
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakovпорядок зависит и от числа сейфпоинтов, которые смержиись прежде чем начался откат.А где это (про то, как ФБ отмены начинает делать) в исходниках посмотреть ? Ибо заинтриговало как-то зело... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 22:06 |
|
||
|
Последствия "непредсказуемо-непоследовательных" откатов изменений при exception
|
|||
|---|---|---|---|
|
#18+
Таблоид, имею мнение, что оно тебе не надо :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2015, 22:21 |
|
||
|
|

start [/forum/topic.php?fid=40&gotonew=1&tid=1563034]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
190ms |
get topic data: |
8ms |
get first new msg: |
6ms |
get forum data: |
2ms |
get page messages: |
36ms |
get tp. blocked users: |
1ms |
| others: | 282ms |
| total: | 555ms |

| 0 / 0 |
