|
Модераторы: skyboy |
|
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Добрый день!
Снова со своими вопросами. Сорри, не очень придумал как топик назвать. Вот предположим, есть движок форума. В нем функция, принимающая ответ в тему. Нужно проверить входящие данные, тра-та-та, и есть еще целый ряд прав на действие. Например, нельзя постить ответ в закрытую тему. Обычно изначально выбираются данные из БД, и потом идет проверка на языке движка форума а-ля if ($result['closed'] == 0)... А бывает идет запрос с условием вида closed=0, и т.д.... Суть в том, что мы сначала проверяем возможность/допустимость добавления ответа в тему, а лишь затем приступаем непосредственно к самому добавлению. Очевидно, что в промежутке между такой проверкой и собственно самим добавлением ответа в тему, эта тема вполне может быть закрыта. Конечно, в случае с форумом такое крайне маловероятно, и даже если произойдет - это вообще ерунда. Но форум тут число дли наглядной иллюстрации сути вопроса. В общем, как быть в такой ситуации, когда мы имеем дело со вставкой / изменением / удалением данных в БД, когда возможность данной операции определяется некоторыми значениями в некоторых таблицах этой БД, и мы хотим быть уверенными в целостности структуры БД после выполнения таких действий? |
|||
|
||||
Akina |
|
|||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
Но возможно и другое - тема закрыта сразу после добавления ответа. Конечное состояние будет таким же. Во втором случае это состояние абсолютно легитимно - во всяком случае с точки зрения целостности структуры БД. Но состояние не содержит информации о пути его получения - значит, и в первом случае состояние легитимно, т.е. никаких проблем с целостностью структуры - нет. Можно попробовать говорить о логической противоречивости - штамп времени последнего сообщения больше штампа времени события закрытия темы. Но в реальности речь пойдёт о секундах или даже долях секунды - явно не повод для беспокойства. Ну и самое время вспомнить о транзакциях. Или, в простейшем варианте, SELECT ... FOR UPDATE. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
Zloxa |
|
|||
Чо? Профиль Группа: Завсегдатай Сообщений: 3470 Регистрация: 12.9.2008 Репутация: 33 Всего: 161 |
Для обеспечения согласованности данных в конкурентной среде используют механизмы: 1) Ограничения целостности 2) Уровни изоляции транзакций. 3) Явные блокировки Ранжировано в порядке предпочтительности. Там, где можно отжаться констрейтами, лучше отжиматься ими, если нет, пробовать отжаться изоляцией, если и тут нет - выстраивать стратегию блокирования самостоятельно. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Akina, блин, ну неудачный пример, хотите придумаю другой - вместо добавления нового поста, пусть запрос на сохранение при редактировании существующего. очевидно, что после закрытия темы, никаких редактирований ее постов уже не стоит допускать. Суть не в примере, а в вопросе. По SELECT ... FOR UPDATE спасибо, сейчас буду читать.
Zloxa, спасибо, но вообще ничего не понял. |
|||
|
||||
Akina |
|
|||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
В таком случае заодно почитай про REPLACE. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Не вспомнить а узнать! Юзаю MyISAM и переходить на всякие-там InnoDB только ради транзакций в ближайшем времени не планирую. Так что пока смотрю в сторону блокировки таблицы средствами СУБД. Всякие поля типа locked для блокировки строк считаю стремными велосипедами. Добавлено через 38 секунд Про него знаю конечно. Но какое он имеет отношение к теме - не пойму? |
|||
|
||||
maxipub |
|
||||||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Народ, читаю про блокировки. Ман, статьи, все что нахожу. Инфы что-то о ней совсем скудно. Есть вопросы.
https://habrahabr.ru/post/46542/ тут пишут:
В рамках блокировки мы можем обращаться только к тем таблицам, на которые выполнялась блокировка? Т.е. надо перечислять все-все-все, что будет использоваться в рамках блокировки, даже если по логике не все эти таблицы требуется блокировать. Или автор ошибся, и имел в виду что мы не сможем добавить новые таблицы в блокировку (поскольку новая блокировка автоматически закрывает существующую, и в этот промежуток опять же кто-то может вклиниться) ??? http://ru.stackoverflow.com/questions/3948...%B5-lock-tables а вот тут в комментарии:
к коду:
А разве данные будут одинаковыми? Я только начинают изучать блокировки. Но насколько понимаю, если поставить LOCK TABLES WRITE, параллельный вызов скрипта "зависнет" на первой строке (LOCK TABLES), будет ждать пока таблица станет доступна для блокировки (закроется текущая блокировка, закончится очередь), и только после этого будет выполняться SELECT во второй строчке... Или нет? |
||||||
|
|||||||
Akina |
|
|||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
Стоп... это я на автомате. SELECT FOR UNDATE и INSERT ON DUPLICATE попутались. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Akina, по предыдущему моему сообщению можете дать комментарии? Мне это важно.
|
|||
|
||||
Akina |
|
||||||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
Автор не ошибся. Действительно надо перечислять всё-всё.
Но если логика позволяет изменение части таблиц в процессе выполнения всего задания, разумнее перед каждым запросом или пачкой запросов выполнять ре-лок, устанавливая или снимая блокировки с нужных или ненужных в очередном запросе таблиц. Правда, следует учитывать, что релок неявно вызывает флаш ВСЕХ таблиц, а не только тех, чем статус блокировки меняется. Да, именно так. Попробуйте самостоятельно на такой же простой модели, но с 2 копиями клиента - увидите. Вот только НАСТОЯТЕЛЬНО рекомендую явно указывать требуемые локи (по отдельности), причём строго в соответствии с документацией - сначала на запись, потом на чтение. Т.е. не
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||||
|
|||||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Akina, круто, благодарю за доходчивые пояснения!
|
|||
|
||||
Zloxa |
|
|||
Чо? Профиль Группа: Завсегдатай Сообщений: 3470 Регистрация: 12.9.2008 Репутация: 33 Всего: 161 |
Afaik MyISAM предназначен для использования в проектах, не накладывющих требований ACID и не предназначен для использования в конкурентном окружении. Использовать этот движок для тренировки обеспечения согласованности в конкурентной среде - как-то очень совесем не то Это сообщение отредактировал(а) Zloxa - 8.12.2016, 12:04 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Zloxa, мне это известно. Но боюсь если начну мигрировать с MyISAM на InnoDB, то наделанных мною косяков будет больше, чем выгоды от такого перехода.
Да и среда там конкурентная, но не высоко конкурентная. Т.е. надо заботиться о целостности данных. Но блокировка всей таблицы не является критической штукой. Как-то так... |
|||
|
||||
Akina |
|
||||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
а где можно накосячить в простейшем запросе
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||
|
|||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Akina, но ведь между этими системами хранения есть отличия, которые надо учитывать. Готовый большой проект, все работает на MyISAM. Если просто поменять MyISAM -> InnoDB, 100% полезут глюки, надо учитывать структуру БД, запросы, логику...
Добавлено через 5 минут и 20 секунд Навскидку вот такой даже примитив https://habrahabr.ru/post/156489/ и уверен есть куча подводных камней. А опыта работы с InnoDB у меня 15 минут. Есть один проект, там CMS самописная (не моя) простая небольшая. Стоит на VPS, который быстренько поднял с полностью чистого образа. Проект небольшой, нагрузка - слезы. Через неделю после поднятия начались глюки - БД висла. Нагрузка минимальная, top показывает avg. 0.05 примерно - чтоб понимали. Начал копаться. Кароче там какой-то баг был из-за того, что в системе не было своп-файла. Так там нагрузка минимальна, 2Гб ОЗУ - зачем своп??? Подключил своп 2Гб, эти глюки пропали. Со временем появились новые. Уже не помню что там было, копался-копался, исправил. Потом еще что-то. Теперь опять БД временами виснет. Почему - непонятно. С MyISAM таких проблем нет. Примитивно, просто, но хорошо. |
|||
|
||||
Akina |
|
|||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
Да не вопрос, делайте транзакции руками. Просто все проблемы типа "примитива по ссылке" - это итог заботливого раскладывания граблей там, где собираешься пройти. Кто мешал вместо ODKU использовать REPLACE? он, кстати, не делает дырок в PK, и триггеры емнип запускает правильно... -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Знал бы где упадешь... Когда я расставлял грабли ODKU, все было вполне логично. Они схожи с REPLACE. Но разница все же есть. ODKU не замещает, а именно обновляет запись, со всеми вытекающими. А именно, это чуть быстрее, и не надо заботиться что где-то вылезет дефолтное значение, обновляется только то, что мы явно указали. Я бы не против перейти на InnoDB. Но опыта с ней нет. Уверен, подобных подводных камней куча будет. А проект рабочий, большой, не для экспериментов. |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Иначе говоря, как можно знать о такой "баге" ODKU, если ты с ним не сталкивался, и не знаешь о нем?
Добавлено через 58 секунд А опыта с InnoDB нет, и таких вот "не знаешь" будет на каждом шагу. Буду тренироваться на кошках каких-нибудь новых небольших проектах. |
|||
|
||||
maxipub |
|
||||||||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Akina, вот и приехали...
Начал добавлять в код LOCK TABLES. Добавил в пару мест, тестирую, ошибки с алиасами... Заглянул еще раз в МАН... http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html Блин, оказывается алиасы таблицы тоже надо блокировать? Что за ерунда??? Мы же блокируем таблицу, логичестки что и все ее алиасы должны быть блокированы, нет? А теперь вопросы: 1. Я использую алиасы в первую очередь для лучшей читаемости запросов (сокращаю длинные имена таблиц). Но никогда не использую алиасы в запросах, где только одна таблица. Теперь получается, если в блокировке используется и таблица по ее имени, и таблица с алиасом, то надо или переделывать все запросы под алиасы, или блокировать и таблицу, и алиас. 1.1. Akina, Вы писали что корректней сначала указывать WRITE, потом READ. А в таком случае надо указывать сначала таблицу, потом алиасы?
Вот так? 1.2. А если получает так, что алиас используется в запросе на запись, а по имени таблицы запрос на чтение.
Корректная такая последовательность? 2. В МАНе http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html Начиная от абзаца "You cannot refer to a locked table multiple times in a single query using the same name. Use aliases instead, and obtain a separate lock for the table and each alias:". Насколько я понял, речь о том, что при блокировке таблицы, в запросе нельзя два раза обращаться к ней про одному имени? Пробовал выполнить INSERT INTO t SELECT * FROM t; без блокировки - выполняется. С блокировкой не хочет. Стремно. 3. И вот тут http://stackoverflow.com/questions/2010722...ing-not-working немного непонятно. У человека не работает запрос:
Решение очень странное, указывать в блокировке и таблицу, и алиас:
Пробовал на MyISAM - работает. Ради интереса на InnoDB - так же работает. Мне кажется, чувак там что-то путает, да? Это сообщение отредактировал(а) maxipub - 13.12.2016, 13:46 |
||||||||
|
|||||||||
Akina |
|
||||||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
Да, должны. Ну вот такая реализация. какие проблемы? заблочил без алиаса, выполнил однотабличный запрос, переблочил с алиасом. выполнил многотабличный запрос, переблочил ещё раз... Да, конечно. Это даже в мануале есть.
Тут нет ничего странного. Представь, что информация о блокировании помещается в таблицу:
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||||
|
|||||||
maxipub |
|
||||||||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
4. Хотелось бы еще уточнить, это нормальная ситуация, когда ставится блокировка по таблице на запись, а по алиасу нам достаточно чтения?
4.1. Что будет в таком случае, если в блокировке сначала идет чтение, а потом запись. Мы прочитаем старые значения, после чего запишем новые? 4.2. А если сначала запись, а потом чтение??? С одной стороны, блокировка на чтение должна блокировать изменения таблицы. С другой стороны, блокировка на запись имеет приоритет перед блокировкой на чтение. Просто не совсем понятно, как эти две разные блокировки по сути одной таблицы будут уживаться друг с другом? Я конечно же провел эксперименты. Запросы выполняются в такой последовательности, в какой они указаны. Но хотелось бы узнать, все же до конца ли корректно такое мое трактование результатов. Возможно, какие-то особенности еще есть с этим? Добавлено через 5 минут и 3 секунды
Так и не понял, почему ничего странного.
Возможно не совсем понятно написал. Это относится как раз к исходному варианту, который у человека якобы не работал, т.е.:
У меня без проблем работает, и на MyISAM, и на InnoDB? И не вижу причин, почему этот код не должен корректно работать. Блокируем таблицу только по алаису, по имени таблицы не блокируем. Но по имени мы к ней в запросах и не обращается, что не так? Добавлено через 6 минут и 36 секунд
Но если мне надо в рамках одной блокировки по логике требуется блокировать и без алиаса, и с алиасом - это нормальная практика, проблем не будет? Или лучше переделывать все запросы на алиасы? |
||||||||
|
|||||||||
Akina |
|
|||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
4-4.1-4.2. Чё за ерунда? какая связь между блокировкой и выполняемой операцией?
Это просто два независимых блокирования. Под ними можно использовать таблицу ни разу, один раз или два раза. И ещё - имя таблицы одновременно есть и её алиас. Так что не "с алиасом и без алиаса", а в любом случае дав алиаса. Просто один совпадает с именем таблицы (а также - существует всегда и не может быть удалён или переопределён). -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
maxipub |
|
|||
Опытный Профиль Группа: Участник Сообщений: 517 Регистрация: 22.10.2009 Репутация: 1 Всего: 1 |
Самому интересно. Немного переспав с этой мыслью, и еще после Вашего напоминания что имя таблицы одновременно и есть ее алиасом. Походу начал понимать суть происходящего. Видимо на уровне движка СУБД блокировка происходит не физически по таблице, а по алиасам. Когда есть блокировка, движок пускает к заблокированным алаисам (и только к ним) "хозяина" блокировки, а всех остальных пускает только к не заблокированным (и только к ним) таблицам. Ну, конечно, с учетом типа блокировки. Просто вчера мне было не понятно, как можно блокировать одну и ту же таблицу в рамках одной блокировки и на чтение, и на запись... Но если на уровне движка блокировка выполняется по алиасу, то все ясно и понятно. |
|||
|
||||
Akina |
|
|||
Советчик Профиль Группа: Модератор Сообщений: 20570 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 453 |
Не блокировка, а УЧЁТ блокировок. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | MySQL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |