powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Deadlock на insret нескольких строк из-за autoincrement
11 сообщений из 36, страница 2 из 2
Deadlock на insret нескольких строк из-за autoincrement
    #39812448
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrowавторто что было наинсерчено батчем 5846 убрал роллбэк убитой дедлоком транзакции.
а что это значит?
забей. меня интересуют пояснения от того кто в курсе что такое дедлок и что он делает с транзакциями.

2All
вопрос все тот же, с чего вдруг 2 делита на разные наборы строк решили поставить record lock на одну и ту же запись ? почему это провоцирует дедлок, а не обычное ожидание ?
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816049
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поставил mysql локально 5.6.39, не работают даже совсем примитивные транзакции.
таблица
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE test1 (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(100),
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;



транзакция 1
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
mysql> SET autocommit = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test1(name) values ('shit1') ;
Query OK, 1 row affected (0.00 sec)



транзакция 2
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)

mysql> SET autocommit = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test1(name) values ('shit2') ;
Query OK, 1 row affected (0.00 sec)



теперь в транзакции 1 удаляем ту самую строку какую вставила эта транзакция
Код: sql
1.
mysql> delete from test1 where name = 'shit1' ;


транзакция 1 уже повисает на блокировке
теперь в транзакции 2 удаляем ее строку

Код: sql
1.
2.
mysql> delete from test1 where name='shit2' ;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction



Код: 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.
------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-05-21 19:00:51 7f61fce4a700
*** (1) TRANSACTION:
TRANSACTION 2010, ACTIVE 76 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 360, 2 row lock(s), undo log entries 2
MySQL thread id 14, OS thread handle 0x7f61fce8c700, query id 305 localhost root updating
delete from test1 where name = 'shit1'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 19 page no 3 n bits 72 index `PRIMARY` of table `db1`.`test1` trx id 2010 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 0000000007db; asc       ;;
 2: len 7; hex af000001ce0110; asc        ;;
 3: len 5; hex 7368697432; asc shit2;;

*** (2) TRANSACTION:
TRANSACTION 2011, ACTIVE 41 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 360, 2 row lock(s), undo log entries 1
MySQL thread id 13, OS thread handle 0x7f61fce4a700, query id 306 localhost root updating
delete from test1 where name='shit2'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 19 page no 3 n bits 72 index `PRIMARY` of table `db1`.`test1` trx id 2011 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 0000000007db; asc       ;;
 2: len 7; hex af000001ce0110; asc        ;;
 3: len 5; hex 7368697432; asc shit2;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 19 page no 3 n bits 72 index `PRIMARY` of table `db1`.`test1` trx id 2011 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
 0: len 4; hex 80000001; asc     ;;
 1: len 6; hex 0000000007da; asc       ;;
 2: len 7; hex 2e000001d10110; asc .      ;;
 3: len 5; hex 7368697431; asc shit1;;

*** WE ROLL BACK TRANSACTION (2)

в mysql 8 чуток реже, но в принципе примерно ту же хрень получаю. как же так !?
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816327
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторкак же так
тут как раз всё просто. без уникального индекса по полю во where надо просмотреть всю таблицу. транзакция 1 уже держит лок на shit1, транзакция 2 на shit2 и они пытаются получить лок друг на друга.
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816347
H5N1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrowавторкак же так
тут как раз всё просто. без уникального индекса по полю во where надо просмотреть всю таблицу. транзакция 1 уже держит лок на shit1, транзакция 2 на shit2 и они пытаются получить лок друг на друга.
не понимаю.
во первых откуда транзакция1 знает о shit2 строке? транзакция2 не закомиченна, выходит что транзакция1 читает грязные данные.
во вторых зачем ставить локи на не входящие в предикат строки ? у транзакции1 предикат name='shit1', даже если она фулсканит таблицу, зачем ставить лок на все подрят ?
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816403
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторо первых откуда транзакция1 знает о shit2 строке? транзакция2 не закомиченна, выходит что транзакция1 читает грязные данные.

чтобы понять что строка не видна текущей транзакции, логично, что надо её прочитать.

автордаже если она фулсканит таблицу, зачем ставить лок на все подрят ?

у нас же row locking, да.
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816481
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrowавторо первых откуда транзакция1 знает о shit2 строке? транзакция2 не закомиченна, выходит что транзакция1 читает грязные данные.

чтобы понять что строка не видна текущей транзакции, логично, что надо её прочитать.

и это объявляется транзакцией? ну да, на одной странице данных есть строки которые транзакция "видит", есть которые не видит. mysql обязан игнорить незакомиченные данные иначе это уже не транзакция. иначе это откровенное нарушение изоляции транзакций.

ScareCrowавтордаже если она фулсканит таблицу, зачем ставить лок на все подрят ?

у нас же row locking, да.
row locking это когда субд блокирует ровно те записи, что необходимо. тут же mysql вместо конкретных записей пытается заблокировать целиком всю таблицу. это уже противоположность row level locks и называется lock escalation.
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816489
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторmysql обязан игнорить незакомиченные данные

как он поймет что это незакоммиченные до того как их прочитает?

автортут же mysql вместо конкретных записей пытается заблокировать целиком всю таблицу

это не так от слова совсем.
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816501
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrowавторmysql обязан игнорить незакомиченные данные

как он поймет что это незакоммиченные до того как их прочитает?

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

ScareCrowавтортут же mysql вместо конкретных записей пытается заблокировать целиком всю таблицу

это не так от слова совсем.
это так. не стоит спорить. если блокируется больше, чем необходимо это не row level locking.
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816516
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторна страницу данных ставится латч
а если там УЖЕ латч?
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816517
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор вот тогда в таблицу блокировок ставиться лок

а если нет таблицы блокировок?
...
Рейтинг: 0 / 0
Deadlock на insret нескольких строк из-за autoincrement
    #39816563
hck1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrowавторна страницу данных ставится латч
а если там УЖЕ латч?
значит читать страницу не безопасно и нужно ждать когда конкурирующий процесс, например записи страницы на диск, отпустит страницу.

ScareCrowавтор вот тогда в таблицу блокировок ставиться лок

а если нет таблицы блокировок?
тогда это оракл, который хранит блокировки на странице данных и "версионность" накладывает не на отдельные строки, а целиком страницу. но это на сколько я знаю не про innodb. innodb хранит в памяти список (таблицу) блокировок.
...
Рейтинг: 0 / 0
11 сообщений из 36, страница 2 из 2
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Deadlock на insret нескольких строк из-за autoincrement
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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