Ошибка при добавлении в БД строки

FiRеFоX

V.I.P.
Регистрация
07.08.2010
Сообщения
744
Всем привет! Имеется таблица, например вот такая:
Код:
CREATE TABLE `user_z` (
  `id` mediumint UNSIGNED NOT NULL,
  `id_login` mediumint UNSIGNED NOT NULL DEFAULT '0',
  `ip` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `soft` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `hoster` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `data` int UNSIGNED NOT NULL DEFAULT '0',
  `ip_proxy` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `hoster_proxy` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
Индексы к ней:
Код:
ALTER TABLE `user_z`
  ADD PRIMARY KEY (`id`),
  ADD KEY `ip` (`ip`),
  ADD KEY `id_login` (`id_login`);
На поле "id" установлен A.I.
Проблема следующая:
- В таблицу всё прекрасно пишется, добавляется, удаляется и обновляется (сайт работает, всё работает в штатном режиме)
- Потом ХУ..К и ошибка "Duplicate entry '1' for key 'user_z.PRIMARY'" при добавлении записи в ШТАТНОМ режиме, который использовался 1000 раз до этого
Какого кхм.. *** он пытается запихать в таблицу ключ (id) 1, если там уже записей 1000 и id 1 есть. В запросе я его НЕ указываю.
Пример запроса:
Код:
INSERT INTO
`user_z`
(`id_login`, `ip`, `soft`, `data`, `hoster`, `ip_proxy`, `hoster_proxy`)
VALUES
(10712, '127.0.0.1', 'Mozilla/5.0', 1631796083, 'host.ru', '', '')
Как я понял, то сбрасывается AI и начинается заново с единицы. А так как в таблице уже есть миллион записей, то естественно он не добавит записей до этого миллиона.
И возникает эта фигулина не только в этой таблице, но и в других.
Началось всё (предположительно) после обновления с пхп 5 до 7.4 + там обновился mysql и апач.
Из-за чего это происходит и как исправить? Хотя бы предположения? Может в настройках mysqlнадо покопаться или ещё что...
 

BaNru

Пацифизжу
Команда форума
Регистрация
13.11.2010
Сообщения
4 138
Я в БД не силён, но основное попробую посоветовать:
- Какая длина значения? INT 32? Посмотри на каком значение "сбрасывается и начинает сначала". Я так понял у тебя пишутся логи пользователя. Вполне может быть что раньше было 1.5 землекова в день на сайте, а теперь тысячи и таблица просто переполняется.
- Попробуй через PHPMYADMIN добавить в момент ошибки новое поле и/или вообще там вызвать эту же ошибку и посмотри запрос который он делает.
- Попробуй через PMA сделать оптимизацию. Там вроде есть что-то связанное с оптимизацией индексации (не помню точно).
 

FiRеFоX

V.I.P.
Регистрация
07.08.2010
Сообщения
744
Я в БД не силён, но основное попробую посоветовать:
- Какая длина значения? INT 32? Посмотри на каком значение "сбрасывается и начинает сначала". Я так понял у тебя пишутся логи пользователя. Вполне может быть что раньше было 1.5 землекова в день на сайте, а теперь тысячи и таблица просто переполняется.
- Попробуй через PHPMYADMIN добавить в момент ошибки новое поле и/или вообще там вызвать эту же ошибку и посмотри запрос который он делает.
- Попробуй через PMA сделать оптимизацию. Там вроде есть что-то связанное с оптимизацией индексации (не помню точно).
Длина значения mediumint. В прошлый раз сбросился, когда записей было около 30 - да и появилось это на локалхост :)
Через PMA тоже не добавляются записи и выдается та-же самая ошибка. Кстати, если заглянуть в "Операции" у этой таблицы, то там почему то стоит AI намного меньше (например 4), хотя в таблице записей тысяча (например).
Да, после оптимизации/дефрагметнации ошибка исправляется.
Кстати, после перезапуска всего Openserva (а я на нем делаю) ошибка не пропадает (вроде бы как после перезапуска mysql в таблицах INNODB должен сбрасываться AI и начинаться заново с максимального max() т.к он хранится в памяти). https://www.sql.ru/forum/808984/sbrasyvaetsya-znachenie-auto-increment
В общем, после того, как исправил AI в настройках таблицы эта ошибка больше не проявлялась, но вот как и из-за чего она появилась для меня остается тайной... Уже и весь процесс поместил в цикл и запускал параллельно эти циклы имитируя массовый доступ пользователей, но ошибки больше не было.
Есть подозрение, что это из-за обновления до mysql 8.0, в ней другой режим блокировки таблиц. ( innodb_autoinc_lock_mode), а я их как раз использую для транзакций
https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html
Для innodb_autoinc_lock_mode переменной есть три возможных значения . Настройки: 0, 1 или 2 для « традиционного » , « последовательного » или « чередующегося » режима блокировки соответственно. Начиная с MySQL 8.0, режим блокировки с чередованием ( innodb_autoinc_lock_mode=2) является настройкой по умолчанию. До MySQL 8.0 режим последовательной блокировки был по умолчанию ( innodb_autoinc_lock_mode=1).
Там также написано, что могут быть проблемы с AI в режиме, который используется в mysql 8.0 по умолчанию (innodb_autoinc_lock_mode=2).
Будем разбираться)
 
Верх Низ