| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > MySQL > Непонятное поведение auto_increment |
| Автор: HeliosArt 10.11.2010, 16:08 | ||||||||
| Столкнулся со странностью работы auto_increment в xtradb-таблице. Суть в следующем: Есть две таблицы:
и
В первой таблице хранится 827 записей. Мне нужно вставить во вторую таблицу по 2 записи на каждую запись в первой. Для этого выполняю 2 идентичных запроса:
и
Запросы выполняются подряд, в это время к серверу никаких других запросов не производится, он работает, можно сказать, в однопользовательском режиме. В итоге после первого запроса в таблице attribute_group появляется 827 записей с id от 1 до 827. После второго запроса также добавляется 827 записей, но их id начинаются не с 828, как ожидалось, а с 1024. Первой мыслью было то, что такая работа - это какой-то патч для повышения производительности в самой xtradb - слишком уж 1024 похоже на какое-то двоичное выравнивание. Но на поверку оказалось, что в стандартном innodb ситуация такая же. Никаких сведений в документации по этому поводу не нашел. В общем-то ситуация некритичная, уникальность id сохраняется, но хотелось бы знать, что это: баг или фича?) |
| Автор: skyboy 10.11.2010, 16:42 |
| сходу ничего не нашел. кроме самого факт, что воспроизводится проблема-то. |
| Автор: Akina 10.11.2010, 17:00 |
| Я не понял... а какое собсно твоё дело, какой автоинкремент сгенерён? он не для работы, а только для обеспечения целостности и связей. |
| Автор: HeliosArt 10.11.2010, 17:07 | ||
Не знаю как вам, но мне не очень комфортно работать с системами, логика работы которых мне не ясна. Вот я эту логику и пытаюсь узнать и понять. ЗЫ: Как я уже сказал, баг не критичен, но это не повод приходить и грубить в топике, в котором вы не знаете что ответить. |
| Автор: skyboy 10.11.2010, 17:08 |
| Akina, ты знаешь причину "пропусков"? Добавлено через 35 секунд спокойно. никто не грубит. Добавлено через 2 минуты и 6 секунд зависит от причин этих проявлений. возможно, это симптомы бага/фичи, из-за которых не стоит использовать конструкцию insert ... select. к примеру. |
| Автор: Zloxa 11.11.2010, 13:05 |
| Сразу(в очередной раз) скажу, в MySQL не шарю, но гипотезу таки изложу, ибо скучаю. InnDB, в отличии от MyISAM, если я не путаю, позволяет конкурентный доступ к таблице. Соответственно должен както обеспечивать возможности одновременной вставки несколькими процессами. Однако, что если таблица имеет автоинкрементное поле? Для двух вставляющих процессов это будет разделяемый ресурс. Если мы будем наращивать счетчик по единичке, на этом ресурсе будут постоянно толкаться две конкурирующие сессии и никакого профита от паралеллелизма мы не увидим. Потому, многие системы наращивают счетчики не на еденичку, забирают под сессию/*транзакцию*/ сразу некий диапазон, как только диапазон выработался, забирают новый. Это позволяет более эффективно испльзовать разделяемый ресурс. В оракле размер кэша последовательности - настраиваемый параметр. Думаю, проявление этого, или же чегото сродни, и предстало перед нашими очами. |
| Автор: Akina 11.11.2010, 13:29 | ||
В соответствии с документацией
Т.е. УНИКАЛЬНЫЙ. И не более. Можете обрыть всю документацию - но нигде не удастся применительно к нему найти слово ПОСЛЕДОВАТЕЛЬНЫЙ (consecutive, cascade, consistent, sequential, serial и т.п.). И это относится не только к MySQL - то же будет и для любого другого сервера БД. |
| Автор: Zloxa 11.11.2010, 13:40 |
| Akina, у меня создается ощущение что ТС не настаивает на том, что MySQL обязан ему выдать непрерывную последовательность. Ему, мне кажется, лишь интересны причины, обуславливающие ее прерывистость. Добавлено через 58 секунд А холивор на тему обеспечения бездырочной нумирации, таки да, уже приелся. Но тут, мне кажется, не тот случай. |
| Автор: Akina 11.11.2010, 14:02 | ||
Но если его при этом не устраивает версия "by design" - то есть два пути. Либо рыть самому, либо искать результаты того, кто рыл до него. Первое ему не нравится, кажется, а что до второго... я лично видел такие копания, но где именно - не помню. Да и было это давно, по-моему, ещё аж для 3-й версии... |
| Автор: Zloxa 11.11.2010, 14:08 |
| Akina, ИМХО, ТС лишь погорячился использовать слово "баг". Меня тоже это малость покоробило, но, видать у меня настрой сегодня несколько добродушный, я на это слово не саггрился. Нак бы там ни было, думаю надо таки навести статускво http://segfault.kiev.ua/smart-questions-ru.html#itsabug |
| Автор: HeliosArt 11.11.2010, 14:10 | ||
| Да, сам факт того, что пропущены ID меня мало волнует. Интересны только причины такого нестандартного поведения. Предположение о кеше транзакции тут вряд ли подойдет, т.к. запросы выполнялись в рамках одной транзакции. Хотя все может быть. Версия by design меня бы устроила, если бы база так вела себя всегда. Тут же получается, что случай нестандартный, иначе на него уже бы давно обратили внимание. Этот топик как раз и создан чтобы узнать, рыл ли кто-то ранее и что узнали в результате.
Так и есть |
| Автор: Zloxa 11.11.2010, 14:15 | ||||
не думаю. большинство разработчиков БД, как уже верно заметил Akina, озабочено обеспечением уникальности первичного ключа. Его непрерывностью озабочены лишь пытливые мозги ищущих новичков. Да и то - далеко не всех. Я вот с ностальгией вспоминаю те полные наива времена, когда еще на фоксе, в девяностые годы, на производственной практике бился с обеспечением непрерывности нумерации ключа при удалении.
ну хрен сним, заменим слово "транзакция" на "стейтмент"(или как биш оно на руский то переводится) что это меняет? |
| Автор: Akina 11.11.2010, 16:03 | ||
И что в нём нестандартного? как известно, всё, что не описано явно, имеет право быть как угодно, и каждый раз как угодно как угодно. |
| Автор: HeliosArt 11.11.2010, 17:06 | ||||||||
Согласно http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html:
Т.е. в документации механизм работы auto_increment описан явно и "каждый раз как угодно как угодно." тут не прокатит. Причина же пропуска нашлась, и догадка Zloxa оказалась верной, ибо среди кучи текста о последовательности и предсказуемости нашлось следующее:
Только при этом логика разработчиков мне все равно не ясна: если уж AUTO-INC lock висит на таблице до завершения всего statement'а и в ходе запроса новые значения выделяются row-by-row, то почему по завершении не вписать в счетчик последнее использованное значение? Для этого даже файловые операции не понадобятся - он только в памяти хранится. Но это уже не для этого форума вопрос |
| Автор: Zloxa 11.11.2010, 17:27 | ||
Ну, если еще пороешь, то может и нароешь, что для бульков лок отпускается и, возможно, перезахватывается по мере нужды Иначе, действительно, такая логика была бы странна. Делалость то с целью оптимизации. А оптимизация зачастую требует в качестве жертвы пренебрежения фундаментальными правилами. Вообще радует, что в документации о том чтото сказано. Хоть и прикопано основательно. Я был о масиной документации худшего мнения ;) |
| Автор: HeliosArt 11.11.2010, 17:48 |
| Так в том-то и суть, что не отпускается. Отпускают его только в interleaved(innodb_autoinc_lock_mode = 2), но там о разрывах и непоследовательности значений предупреждают сразу. В остальных же режимах: traditional (innodb_autoinc_lock_mode = 0): лок висит до конца при любой вставке consecutive (innodb_autoinc_lock_mode = 1, стоит по умолчанию): при bulk-insert лок висит до конца, но для простых вставок вместо него используется mutex и таблица не блокируется вовсе |
| Автор: Zloxa 11.11.2010, 17:54 |
| Проверить есть возможность? Пустить какуюнить бульку минут на десять, и, тем временем, попытаться вставиться другой сессией? Добавлено через 2 минуты и 1 секунду правда надо еще как то убедиться что на той самой блокировке стоим..... а то мало ли на каком еще локе постоять доведется.... |
| Автор: HeliosArt 11.11.2010, 18:32 | ||
| Проверил в режиме consecutive: запустил 2 параллельных bulk-insert'а, первым более тяжелый, вторым попроще. В результате второй выполнился только после того, как был полностью закончен первый. Причем в это время SHOW ENGINE INNODB STATUS по второму запросу показывал следующее:
То есть лок висит до конца, как и описано в документации |
| Автор: Zloxa 11.11.2010, 21:17 |
| Премило. Спасибо Добавлено через 2 минуты и 6 секунд я бы тот что попроще пускал не булком... чтоб совсем просто... ну да ладно. Это очень интересный результат. Еще раз спасибо. |