Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Deadlock на Interbase2017 / 19 сообщений из 19, страница 1 из 1
15.03.2018, 15:59
    #39615509
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
Переползли на 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
15.03.2018, 16:36
    #39615533
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
_Vasilisk_,

1. нафига тут двойные кавычки? Серьезно, откуда они вообще взялись?
2. то есть, вы выполняете два вот этих оператора из разных коннектов, и на ИБ 2017 выдается сообщение об ошибке? Какое?
...
Рейтинг: 0 / 0
15.03.2018, 17:04
    #39615550
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
kdv, и на ИБ 2017 выдается сообщение об ошибке? Какое?deadlock
При этом пробую запускать эти процедуры из двух IBExpert'ов (в разной очередности, не коммитя транзакции) все работает
...
Рейтинг: 0 / 0
15.03.2018, 17:08
    #39615555
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
Еще меня смущает, что при выполнении
_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
15.03.2018, 17:20
    #39615569
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
_Vasilisk_Еще меня смущает

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

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

автор3 record(s) was(were) inserted into TMP$ATTACHMENTS
...
Рейтинг: 0 / 0
15.03.2018, 17:33
    #39615578
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
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
15.03.2018, 17:46
    #39615587
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
_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
15.03.2018, 18:17
    #39615611
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
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
15.03.2018, 18:40
    #39615627
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
kdvне верю.
...
Рейтинг: 0 / 0
15.03.2018, 18:46
    #39615628
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
И еще одна картинка
...
Рейтинг: 0 / 0
15.03.2018, 20:29
    #39615653
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
Понавставлял логирования. Исходное предположение о месте дедлока было неверным. Итак. Одно соединение зависает здесь

Код: 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
15.03.2018, 20:46
    #39615659
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
kdv_Vasilisk_То, что идет отчет о вставке записей в TMP$ATTACHMENTS. С какого перепугу?
ИБ уже давно в этом плане выдает какую-то хрень.
данные в таблицах мониторинга появляются в момент запроса к ним (первый раз в данной транзакции). В ИБ там в основе лежат честные GTT, поэтому движок в них каждый раз вставляет данные, чтобы они стали видны юзерам. Нафига оно вообще считается в статистике это вопрос конечно актуальный, но все-таки "хренью" я бы называть не стал :-)
...
Рейтинг: 0 / 0
15.03.2018, 22:09
    #39615680
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Deadlock на Interbase2017
_Vasilisk_Одно соединение зависает здесь

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

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


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