SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 28.01.2020 23:50:46

vsadykov
Участник
Зарегистрирован: 28.01.2020
Сообщений: 3

Глюк LAST_INSERT_ID

Коллеги, приветствую!
Может кто сталкивался, но я в замешательстве.

В базу данных записывается заказ в инет-магазине. После INSERT сразу вызываю SELECT LAST_INSERT_ID(), чтобы получить номер заказа из автоинкрементного поля. И вот за последние пару месяцев второй раз LAST_INSERT_ID() возвращает ID из ДРУГОЙ(!) таблицы, в которую в этот момент что-то записывается в другой сессии другим посетителем.

Сам удивился, но факт остается фактом.
Вот две строчки из лога доступа
109.184.238.76 - - [25/Jan/2020:13:59:52 +0300] "GET /search/?search=%D0%90%D1%86%D0%B5%D1%82%D0%B0%D1%82 HTTP/1.0" 200 13909
87.117.58.119 - - [25/Jan/2020:13:59:52 +0300] "POST /processing/orderget.php HTTP/1.0" 302 20

Первая строка - поиск по сайту, и поисковый запрос записывается в таблицу fc__search. Вставился он с id 133807
Вторая - запись заказа в таблицу fc__orders, и заказ судя по оповещению, пришедшему на почту,  был создан под номером 133807, хотя в таблицу он не записался, а по автоинкременту должен был иметь номер 2785.
А первый случай был в декабре, когда пришло оповещение о заказе с нереально огромным номером 11798141, сейчас посмотрел таблицы и нашел, что в одной из них действительно была запись с таким идентификатором примерно в то время, когда произошел сбой.

Версия СУБД - mariaDB 10.2.30.

Глюк MySQL?

Неактивен

 

#2 29.01.2020 14:29:35

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Глюк LAST_INSERT_ID

Смотрите: LAST_INSERT_ID() возвращает последний id, вставленный в текущем потоке, подключенном к MySQL. Если у вас используется какой-нибудь connection pool или какое-то кэширование подключений (aka persistent connections), то в этом месте есть гонка, которую можно или выиграть, или проиграть.

Попробуйте посмотреть в эту сторону. Вероятность ошибки в БД обычно ниже, чем вероятность ошибки в собственном коде.

Также удобно использовать https://www.php.net/manual/ru/mysqli.insert-id.php вместо отдельного запроса.

Неактивен

 

#3 29.01.2020 23:02:25

vsadykov
Участник
Зарегистрирован: 28.01.2020
Сообщений: 3

Re: Глюк LAST_INSERT_ID

paulus написал:

Смотрите: LAST_INSERT_ID() возвращает последний id, вставленный в текущем потоке, подключенном к MySQL. Если у вас используется какой-нибудь connection pool или какое-то кэширование подключений (aka persistent connections), то в этом месте есть гонка, которую можно или выиграть, или проиграть.

Попробуйте посмотреть в эту сторону. Вероятность ошибки в БД обычно ниже, чем вероятность ошибки в собственном коде.

Да никаких пулов или кеширований у меня нет, вполне себе примитивный код работы с базой - нагрузка на сайт небольшая, не было смысла что-то городить.

paulus написал:

Также удобно использовать https://www.php.net/manual/ru/mysqli.insert-id.php вместо отдельного запроса.

Что удобно - да, но ведь по сути эта функция все равно этот запрос выполняет после выполнения инсёрта. И сокращения интервала времени между инсёртом и запросом id скорее всего не произойдет. Так ведь?

Неактивен

 

#4 03.02.2020 15:38:15

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Глюк LAST_INSERT_ID

Насколько я понимаю, нет, там в протоколе есть низкоуровневый метод, который не дергает запрос напрямую:
https://dev.mysql.com/doc/refman/8.0/en … rt-id.html

Если не поможет, то тогда надо выделять воспроизводимый кейс и отправлять в апстрим. Для выделения может помочь включение general log — увидите все запросы и последовательность выполнения.

Неактивен

 

#5 03.02.2020 23:04:45

vsadykov
Участник
Зарегистрирован: 28.01.2020
Сообщений: 3

Re: Глюк LAST_INSERT_ID

paulus написал:

Насколько я понимаю, нет, там в протоколе есть низкоуровневый метод, который не дергает запрос напрямую:
https://dev.mysql.com/doc/refman/8.0/en … rt-id.html

А это любопытно, спасибо!

paulus написал:

Если не поможет, то тогда надо выделять воспроизводимый кейс и отправлять в апстрим. Для выделения может помочь включение general log — увидите все запросы и последовательность выполнения.

Увы , это виртуальный хостинг, там логи не включают sad(

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson