powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Deadlock на Interbase2017
19 сообщений из 19, страница 1 из 1
Deadlock на Interbase2017
    #39615509
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переползли на Interbase2017 и сразу возникла интересная проблема.

Есть сервис, в сервисе есть две dll, каждая из которых по старту, в разных потока коннектится к базе (создание коннекта защищено глобальным мьютексом) и вызывают по одной процедуре (каждая dll вызывает свою). Одна процедура обновляет таблицу пользователей вот таким запросом
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  UPDATE users usr SET
    usr."ATTACH_ID" = NULL
  WHERE
    usr."ATTACH_ID" IS NOT NULL AND
    NOT EXISTS (
      SELECT
        1
      FROM
        tmp$attachments att
      WHERE
        usr."ATTACH_ID" = att."TMP$ATTACHMENT_ID" AND
        usr."ATTACH_TIME" = att."TMP$TIMESTAMP"
    );

Вторая вносит изменения в таблицу конфигурации
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  FOR
    SELECT
      cfg."USR_ID"
    FROM
      configs cfg
    WHERE
      cfg."USR_ID" = 3 AND  /* System Admin */
      cfg."SECTION" = 'GLOBAL' AND
      cfg."IDENT" = :in_ident
    INTO
      :var_usr_id
    AS CURSOR
      cur_cfg
  DO
    UPDATE configs cfg SET
      cfg."INT_VALUE" = :in_int_value,
      cfg."FLOAT_VALUE" = :in_float_value,
      cfg."STR_VALUE" = :in_str_value,
      cfg."BLOB_VALUE" = :in_blob_value
    WHERE
      CURRENT OF cur_cfg;

Поле configs."USR_ID" ссылается на user."ID"

И вот эти две процедуры перекрывают друг другу кислород. Проблема появилась только при переходе на Interbase2017. На XE3 проблемы не было.

Вопрос - как может получаться дедлок при работе с двумя разными таблицами? При этом еще, что первая процедура вообще ничего не должна обновлять, т.к. на момент запуска у всех записей usr."ATTACH_ID" IS NULL

И что с этим делать?

Очень похоже, что мешает внешний ключ configs."USR_ID"

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615533
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

1. нафига тут двойные кавычки? Серьезно, откуда они вообще взялись?
2. то есть, вы выполняете два вот этих оператора из разных коннектов, и на ИБ 2017 выдается сообщение об ошибке? Какое?
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615550
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv, и на ИБ 2017 выдается сообщение об ошибке? Какое?deadlock
При этом пробую запускать эти процедуры из двух IBExpert'ов (в разной очередности, не коммитя транзакции) все работает
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615555
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще меня смущает, что при выполнении
_Vasilisk_
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  UPDATE users usr SET
    usr."ATTACH_ID" = NULL
  WHERE
    usr."ATTACH_ID" IS NOT NULL AND
    NOT EXISTS (
      SELECT
        1
      FROM
        tmp$attachments att
      WHERE
        usr."ATTACH_ID" = att."TMP$ATTACHMENT_ID" AND
        usr."ATTACH_TIME" = att."TMP$TIMESTAMP"
    );

IBExpert пишетN 3 record(s) was(were) inserted into TMP$ATTACHMENTSгде N - количество записей в таблице TMP$ATTACHMENTS на момент выполнения запроса
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615569
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Еще меня смущает

А что тебя смущает? У тебя же там условие по времени стоит, причём на строгое равенство, а
где это время в таблицу пользователей заносится я что-то не вижу.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615574
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

это IB как он работает с TMP$ATTACHMENTS фиг его знает. Может заполняет её во время обращение к ней через SELECT и пишет как результат

автор3 record(s) was(were) inserted into TMP$ATTACHMENTS
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615578
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovА что тебя смущает?То, что идет отчет о вставке записей в TMP$ATTACHMENTS. С какого перепугу?
Dimitry Sibiryakovгде это время в таблицу пользователей заносится я что-то не вижу.
sp_e_usr_login
Код: sql
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.
CREATE PROCEDURE sp_e_usr_login (
  in_name VARCHAR(64),
  in_password VARCHAR(16),
  in_trn_id INTEGER)
RETURNS (
  out_id SMALLINT)
AS
  DECLARE VARIABLE var_attach_id INTEGER;
  DECLARE VARIABLE var_attach_time TIMESTAMP;
  DECLARE VARIABLE var_host CHAR(31) CHARACTER SET NONE;
  DECLARE VARIABLE var_msg VARCHAR(32);
BEGIN
  EXECUTE PROCEDURE sp_i_usr_login_garbage;

  EXECUTE PROCEDURE sp_i_trn_attach_info(
    :in_trn_id
  ) RETURNING_VALUES (
    :var_attach_id,
    :var_attach_time,
    :var_host
  );

  SELECT
    usr."ID"
  FROM
    users usr
  WHERE (usr."NAME" = :in_name)
    AND (usr."USER_PASSWORD" = :in_password)
    AND ((usr."ATTACH_ID" IS NULL) OR (usr."LAST_HOST" = :var_host))
  INTO
    :out_id;

  IF (:out_id IS NULL) THEN BEGIN
    SELECT
      usr."ID"
    FROM
      users usr
    WHERE (usr."NAME" = :in_name)
      AND (usr."USER_PASSWORD" = :in_password)
    INTO
      :out_id;
    IF (:out_id IS NULL) THEN
      EXCEPTION ex_usr_not_found;
    ELSE
      EXCEPTION ex_usr_login;
  END ELSE BEGIN
    UPDATE
      users usr
    SET
      usr."ATTACH_ID" = :var_attach_id,
      usr."ATTACH_TIME" = :var_attach_time,
      usr."LAST_HOST" = :var_host
    WHERE
      usr."ID" = :out_id;

    var_msg = CAST(:var_host AS VARCHAR(32));
    EXECUTE PROCEDURE sp_i_usr_ins_log(
      out_id,
      0,  /* ultLogin */
      :var_msg
    );
  END
END

sp_i_usr_login_garbage
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE PROCEDURE sp_i_usr_login_garbage
AS
BEGIN
  UPDATE users usr SET
    usr."ATTACH_ID" = NULL
  WHERE
    usr."ATTACH_ID" IS NOT NULL AND
    NOT EXISTS (
      SELECT
        1
      FROM
        tmp$attachments att
      WHERE
        usr."ATTACH_ID" = att."TMP$ATTACHMENT_ID" AND
        usr."ATTACH_TIME" = att."TMP$TIMESTAMP"
    );
END

sp_i_trn_attach_info
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
CREATE PROCEDURE sp_i_trn_attach_info (
  in_id INTEGER)
RETURNS (
  out_attach_id INTEGER,
  out_attach_time TIMESTAMP,
  out_host CHAR(31) CHARACTER SET none)
AS
BEGIN
  SELECT
    att."TMP$ATTACHMENT_ID",
    att."TMP$TIMESTAMP",
    att."TMP$USER_IP_ADDR"
  FROM
    tmp$transactions trn
    LEFT JOIN tmp$attachments att ON (
      att."TMP$ATTACHMENT_ID" = trn."TMP$ATTACHMENT_ID"
    )
  WHERE
    trn."TMP$TRANSACTION_ID" = :in_id
  INTO
    :out_attach_id,
    :out_attach_time,
    :out_host;
END

sp_i_usr_ins_log
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE PROCEDURE sp_i_usr_ins_log (
  in_id INTEGER,
  in_log_type SMALLINT,
  in_str VARCHAR(1024))
AS
BEGIN
  INSERT INTO stream_obj_logs(
    "OBJ_ID",
    "OBJ_TYPE",
    "LOG_TYPE",
    "USR_ID",
    "LOG_STR"
  ) VALUES (
    :in_id,
    2, /* itUser = 2 */
    :in_log_type,
    :in_id,
    :in_str
  );
END


Ну и для полноты картины полная процедура из второго коннекта
sp_e_cfg_global_upd
Код: sql
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.
CREATE PROCEDURE sp_e_cfg_global_upd (
  in_ident VARCHAR(64),
  in_int_value INTEGER,
  in_float_value DOUBLE PRECISION,
  in_str_value VARCHAR(1024),
  in_blob_value BLOB SUB_TYPE 0 SEGMENT SIZE 80)
AS
  DECLARE VARIABLE var_usr_id SMALLINT;
BEGIN
  var_usr_id = NULL;
  FOR
    SELECT
      cfg."USR_ID"
    FROM
      configs cfg
    WHERE
      cfg."USR_ID" = 3 AND  /* System Admin */
      cfg."SECTION" = 'GLOBAL' AND
      cfg."IDENT" = :in_ident
    INTO
      :var_usr_id
    AS CURSOR
      cur_cfg
  DO
    UPDATE configs cfg SET
      cfg."INT_VALUE" = :in_int_value,
      cfg."FLOAT_VALUE" = :in_float_value,
      cfg."STR_VALUE" = :in_str_value,
      cfg."BLOB_VALUE" = :in_blob_value
    WHERE
      CURRENT OF cur_cfg;

  IF (:var_usr_id IS NULL) THEN
    INSERT INTO configs (
      "USR_ID",
      "SECTION",
      "IDENT",
      "INT_VALUE",
      "FLOAT_VALUE",
      "STR_VALUE",
      "BLOB_VALUE"
    ) VALUES (
      3,  /* System Admin */
      'GLOBAL',
      :in_ident,
      :in_int_value,
      :in_float_value,
      :in_str_value,
      :in_blob_value
    );

    INSERT INTO configs_bk (
      "USR_ID",
      "SECTION",
      "IDENT",
      "TIME",
      "INT_VALUE",
      "FLOAT_VALUE",
      "STR_VALUE",
      "BLOB_VALUE"
    ) VALUES (
      3,  /* System Admin */
      'GLOBAL',
      :in_ident,
      CURRENT_TIMESTAMP,
      :in_int_value,
      :in_float_value,
      :in_str_value,
      :in_blob_value
    );

  POST_EVENT 'EVENT_CFG_GLOBAL';
END

Если в момент дедлока выполнить
Код: sql
1.
SELECT * FROM tmp$statement

то в одном коннекте показывается
Код: sql
1.
EXECUTE PROCEDURE sp_e_usr_login(?, ?, ?)

а во втором
Код: sql
1.
EXECUTE PROCEDURE sp_e_cfg_global_upd(?, ?, ?, ?, ?)
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615587
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_deadlock
прямо вот deadlock и все? не верю.

к слову, TMP$ATTACHMENT_ID не инкрементируется вечно. Он может рестартовать с нуля после отключения всех пользователей.

_Vasilisk_То, что идет отчет о вставке записей в TMP$ATTACHMENTS. С какого перепугу?
ИБ уже давно в этом плане выдает какую-то хрень.

ЗАЧЕМ В ПРИВЕДЕННОМ КОДЕ ДВОЙНЫЕ КАВЫЧКИ!?!?! Они не нужны ведь, и так все большими буквами написано. Кто эту хрень писал?

Код: sql
1.
2.
3.
UPDATE configs cfg SET
      cfg."INT_VALUE" = :in_int_value,
      cfg."FLOAT_VALUE" = :in_float_value,



почему нельзя
Код: sql
1.
2.
3.
  UPDATE configs cfg SET
      cfg.int_value = :in_int_value,
      cfg.float_value = :in_float_value,



Ладно бы "ИденТификАтор" был, но тут же это не надо совсем. Или руки отвалились?

Вообще, обращение к tmp/mon из процедур и триггеров - это зло. Понапридумывают люди себе гемор...
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615611
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvпрямо вот deadlock и все?Угу
kdvне верю.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
sqlWrite: TIBSQL;
.......
procedure TdmTCP.ExecProc;
begin
  sqlWrite.Transaction.StartTransaction;
  try
    sqlWrite.ExecQuery;
    sqlWrite.Transaction.Commit;
  except
    sqlWrite.Transaction.Rollback;
    raise;
  end;
end;

procedure TdmTCP.Process;
begin
  try
    ExecProc;
  except
    on E: Exception do
      WriteToLog(E.Message)
  end
end;


kdvОн может рестартовать с нуля после отключения всех пользователей.И что? Пусть рестартует
_Vasilisk_
Код: sql
1.
2.
3.
      WHERE
        usr."ATTACH_ID" = att."TMP$ATTACHMENT_ID" AND
        usr."ATTACH_TIME" = att."TMP$TIMESTAMP"


kdvЗАЧЕМ В ПРИВЕДЕННОМ КОДЕ ДВОЙНЫЕ КАВЫЧКИ!?!?Чем они мешают?
kdvПонапридумывают люди себе гемор...Хорошо. Исходная задача: нужно обеспечить логин ровно одного пользователя с указанным логином и паролем. Остальные входы с этим логином отвергать пока не разлогинится первый. При этом пользователь может отвалиться не разлогинившись (сеть пропала, уборщица кабель выдернула, сорвали программы через диспетчер задач)...
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615627
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvне верю.
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615628
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще одна картинка
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615653
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понавставлял логирования. Исходное предположение о месте дедлока было неверным. Итак. Одно соединение зависает здесь

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE PROCEDURE sp_e_usr_login (
  in_name VARCHAR(64),
  in_password VARCHAR(16),
  in_trn_id INTEGER)
RETURNS (
  out_id SMALLINT)
AS
  DECLARE VARIABLE var_attach_id INTEGER;
  DECLARE VARIABLE var_attach_time TIMESTAMP;
  DECLARE VARIABLE var_host CHAR(31) CHARACTER SET NONE;
  DECLARE VARIABLE var_msg VARCHAR(32);
BEGIN
   ...........
    UPDATE
      users usr
    SET
      usr."ATTACH_ID" = :var_attach_id,
      usr."ATTACH_TIME" = :var_attach_time,
      usr."LAST_HOST" = :var_host
    WHERE
      usr."ID" = :out_id;
   ..........
END

:out_id = 4, а второе соединение здесь
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE PROCEDURE sp_e_cfg_global_upd (
  .............
    INSERT INTO configs_bk (
      "USR_ID",
      "SECTION",
      "IDENT",
      "TIME",
      "INT_VALUE",
      "FLOAT_VALUE",
      "STR_VALUE",
      "BLOB_VALUE"
    ) VALUES (
      3,  /* System Admin */
      'GLOBAL',
      :in_ident,
      CURRENT_TIMESTAMP,
      :in_int_value,
      :in_float_value,
      :in_str_value,
      :in_blob_value
    );
  ......................
END
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615659
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv_Vasilisk_То, что идет отчет о вставке записей в TMP$ATTACHMENTS. С какого перепугу?
ИБ уже давно в этом плане выдает какую-то хрень.
данные в таблицах мониторинга появляются в момент запроса к ним (первый раз в данной транзакции). В ИБ там в основе лежат честные GTT, поэтому движок в них каждый раз вставляет данные, чтобы они стали видны юзерам. Нафига оно вообще считается в статистике это вопрос конечно актуальный, но все-таки "хренью" я бы называть не стал :-)
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615680
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Одно соединение зависает здесь

У тебя там нет какой-нибудь глупости типа ON UPDATE CASCADE?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615684
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

ну значит это не сообщение от ФБ, а ваш какой-то exception. Потому что у ФБ просто "deadlock" без расшифровки не бывает.
_Vasilisk_Чем они мешают?
1. они лишние
2. невероятно раздражают.
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615687
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv Потому что у ФБ просто "deadlock"
и у ИБ тоже.
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615700
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovУ тебя там нет какой-нибудь глупости типа ON UPDATE CASCADE?Есть. Почему глупость?
kdv2. невероятно раздражают.Меня не раздражают
kdvну значит это не сообщение от ФБ, а ваш какой-то exception. и у ИБ тоже.На последнем скриншоте я показал непосредственный вызов isc_interprete внутри IBX
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615733
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_При этом пользователь может отвалиться не разлогинившись (сеть пропала, уборщица кабель выдернула, сорвали программы через диспетчер задач)...keepalive настроен?
...
Рейтинг: 0 / 0
Deadlock на Interbase2017
    #39615910
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_Pisarevskykeepalive настроен?Установлен DUMMY_PACKET_INTERVAL
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Deadlock на Interbase2017
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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