Jump to content
Local
Alexey Osipov

Переработка модуля хранения MySQL

Recommended Posts

Как внезапно выяснилось здесь у модуля MySQL нет постоянного сопровождающего разработчика:

 

... я давно уже говорю о том что плагин для MySQL использовать не рекомендуется. Написан он сторонними разработчиками и плохо. Поддерживать его толком некому.

 

Я, как постоянный пользователь этого модуля, знакомый с C, C++ и MySQL, мог бы взяться за его поддержку.

 

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

 

То, что бросилось в глаза мне, когда я читал код:

  • Не используются "prepared statements"
  • Результаты запросов преобразовывются из строки
  • Нет механизма автоматической конвертации схемы БД из предыдущих версий

 

Отдельно хотелось бы обсудить таблицы detailstat_MM_YYYY и logs_MM_YYYY, которые же нифига не вписываются в 3-НФ?! Попробуй потом их проанализировать одним SQL запросом. Или всем пофик?. :)

Я догадываюсь, что сделано это было, видимо, с целью увеличения производительности, поскольку таблицы эти довольно тяжелые. Но кто-нибудь в действительно проверял, насколько это быстрее работает, чем одна большая таблица? В конце концов "эффективно масштабироваться" - забота СУБД.

Share this post


Link to post
Share on other sites

Это оффтоп, конечно, но я бы не завязывался на MySQL больше. Для использования в коммерческих целях - нужна лицензия. Использование в биллинге - это коммерческие цели. Возможно это не так критично для маленьких, то те кто побольше - должны понимать это, а так же понимать последствия..

сейчас лучше завязываться на PostgreSQL, IMHO.

Share this post


Link to post
Share on other sites
Но кто-нибудь в действительно проверял, насколько это быстрее работает, чем одна большая таблица?

А вы попробуйте бенчмаркнуть выборку по одной табличке где скажем 50М записей или по табличке где 500к - думаю разницу очень хорошо прочувствуете =)

 

Размазывание данных разной степени используемости, по разным табличкам - неплохой перфоменс ход, и называется нормализацией. Хотя детальная статистика которая там пишется черти-как и у 99.99% нормальных людей - отключена, она в этом модуле далеко не самая глобальная проблема.

 

А prepared statements выглядит удачно в данном контексте, хотя подозреваю что просто так, мускуль не будет кешировать идущие не подряд /не всегда единообразные запросы, тем более в рамках нескольких сесий.

 

Это оффтоп, конечно, но я бы не завязывался на MySQL больше. Для использования в коммерческих целях - нужна лицензия.

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

Share this post


Link to post
Share on other sites

Как внезапно выяснилось здесь у модуля MySQL нет постоянного сопровождающего разработчика:

 

... я давно уже говорю о том что плагин для MySQL использовать не рекомендуется. Написан он сторонними разработчиками и плохо. Поддерживать его толком некому.

 

Я, как постоянный пользователь этого модуля, знакомый с C, C++ и MySQL, мог бы взяться за его поддержку.

 

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

 

То, что бросилось в глаза мне, когда я читал код:

  • Не используются "prepared statements"
  • Результаты запросов преобразовывются из строки
  • Нет механизма автоматической конвертации схемы БД из предыдущих версий

 

Отдельно хотелось бы обсудить таблицы detailstat_MM_YYYY и logs_MM_YYYY, которые же нифига не вписываются в 3-НФ?! Попробуй потом их проанализировать одним SQL запросом. Или всем пофик?. :)

Я догадываюсь, что сделано это было, видимо, с целью увеличения производительности, поскольку таблицы эти довольно тяжелые. Но кто-нибудь в действительно проверял, насколько это быстрее работает, чем одна большая таблица? В конце концов "эффективно масштабироваться" - забота СУБД.

1. Большинство падений в модуле вызвано тем что не происходит проверка кода возврата функций.

2. Страшная система реконнектов: фактически, при каждом запросе соединение с базой устанавливается заново.

3. Структура БД, кажется, даже НФ1 не соответствует (ее просто скопировали с файлового модуля).

4. detail_stats_MM_YYYY - это такое "ручное секционирование", закат Солнца вручную. Есть более правильные штатные средства секционирования.

5. Модуль написан в большей степени на C чем на C++.

Вот от этих пяти пунктов хотелось бы избавиться. Предлагаю придерживаться той структуры БД которая используется в mod_store_firebird и mod_store_postgresql. В PostgreSQL более "свежая" структура. Могу дать даже еще более свежую, к оторой я наконец-то решил нормально проблему хранения текущих данных о трафике и помесячных (скорее всего я пока не буду включать ее в rc3 и релиз, но у меня на работе она успешно работает).

Share this post


Link to post
Share on other sites

Это оффтоп, конечно, но я бы не завязывался на MySQL больше. Для использования в коммерческих целях - нужна лицензия. Использование в биллинге - это коммерческие цели. Возможно это не так критично для маленьких, то те кто побольше - должны понимать это, а так же понимать последствия..

сейчас лучше завязываться на PostgreSQL, IMHO.

На сколько я помню, так было раньше. Потом MySQL стал нормальным GPL. Правда, в виду покупки Oracle'ом, я бы поостерегся.

Share this post


Link to post
Share on other sites
Но кто-нибудь в действительно проверял, насколько это быстрее работает, чем одна большая таблица?

А вы попробуйте бенчмаркнуть выборку по одной табличке где скажем 50М записей или по табличке где 500к - думаю разницу очень хорошо прочувствуете =)

 

Размазывание данных разной степени используемости, по разным табличкам - неплохой перфоменс ход, и называется нормализацией. Хотя детальная статистика которая там пишется черти-как и у 99.99% нормальных людей - отключена, она в этом модуле далеко не самая глобальная проблема.

Не "нормализацией" а "секционированием". Т.к. по сути это денормализация.

 

А prepared statements выглядит удачно в данном контексте, хотя подозреваю что просто так, мускуль не будет кешировать идущие не подряд /не всегда единообразные запросы, тем более в рамках нескольких сесий.

 

Это оффтоп, конечно, но я бы не завязывался на MySQL больше. Для использования в коммерческих целях - нужна лицензия.

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

Prepared Statements тут не будут иметь особого эффекта. Разве что при записи детальной статистики и данных о трафике - там идет пачка однотипных запросов. Я по этому поводу думал, в будущем, пересмотреть подходы к работе с БД. Все-таки изначально все ориентировалось на работу с файлами.

Share this post


Link to post
Share on other sites

Как внезапно выяснилось...

Старожилы форума знают что я постоянно ворчу на MySQL :)

Share this post


Link to post
Share on other sites
Старожилы форума знают что я постоянно ворчу на MySQL

а он цуко все живет и живет... :)

Share this post


Link to post
Share on other sites

Alexey Osipov, при падении/рестарте мускула падает стг, вот этот баг хотелось бы исправить

Share this post


Link to post
Share on other sites

А что делать еще старгейзеру при невозможности почитать/пописать в базу?

Share this post


Link to post
Share on other sites

стг при старте читает из базы ВСЕ необходимые ему данные...

 

при работе он туда ТОЛЬКО ПИШЕТ

 

как часто он это делает - это вопрос сохранности данных при падении стг или сервера - но на работу самого стг это никоим образом не влияет

 

так что если нет связи с БД - стг желательно бы просто ждать...

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

на ФБ я удачного подключение после отсутствия БД не видел - это меня огорчает :)

Share this post


Link to post
Share on other sites

стг при старте читает из базы ВСЕ необходимые ему данные...

 

при работе он туда ТОЛЬКО ПИШЕТ

 

как часто он это делает - это вопрос сохранности данных при падении стг или сервера - но на работу самого стг это никоим образом не влияет

 

так что если нет связи с БД - стг желательно бы просто ждать...

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

на ФБ я удачного подключение после отсутствия БД не видел - это меня огорчает :)

Да, так и есть. Недосмотрел.

Share this post


Link to post
Share on other sites
так что если нет связи с БД - стг желательно бы просто ждать...

тобишь тихонько повиснуть в надежде что мускуль перестанет огорчатся и вернется?

 

а данные в это время он куда должен девать?

Share this post


Link to post
Share on other sites
так что если нет связи с БД - стг желательно бы просто ждать...

тобишь тихонько повиснуть в надежде что мускуль перестанет огорчатся и вернется?

 

а данные в это время он куда должен девать?

В памяти хранить. Он сейчас так и делает, просто для Firebird нет реконнекта, а для MySQL он криво сделан и часто тупо падает.

Share this post


Link to post
Share on other sites

в памяти хранить в смысле "утечь"?

Share this post


Link to post
Share on other sites

в памяти хранить в смысле "утечь"?

У нас как-то 3 дня работало без БД пока я этого не заметил. И ничего, сильно не натекло :)

Share this post


Link to post
Share on other sites

О я смотрю тут спецы собрались по MySQL. Оффтоп дикий, но все же..

не подскажите как в трехуровневом LVS(Linux Virtual Server) кластере вынести MySQLбазу данных нодов на сетевое хранилище. А то с самим Apache'м вроде все ясно, с директором кластера тоже, а вот как синхронизировать БД, что бы всем нодам была доступна актуальная информация не совсем понятно :)

Share this post


Link to post
Share on other sites

в памяти хранить в смысле "утечь"?

У нас как-то 3 дня работало без БД пока я этого не заметил. И ничего, сильно не натекло :)

 

Чтоб не текло можно хранить в бинарном файлике данные при достижении порога записей/обьема. У нас БД хранится в памяти полностью, и пишутся журналы. Упала база - подымаем дампы, потом журналы и погнали.

Правда у нас немного другого класса биллинг, но думаю писать журналы работы в файлик который потом подымать при реконнекте в случае если он есть - вполне реализуемо. А тем более если это биллинг - ни одна запись не должна потеряться. Соответственно - это мастхев.

Share this post


Link to post
Share on other sites

Это вариант хранить данные в бинарнос файле(дереве) до запуска базы.

 

Хотелось бы оптимизации таблиц в базе. Например в `users` колонка `Tariff`. Почему бы не сделать TariffID и связать FOREIGN KEY ? Ну и чего уж тут, InnoDB.

А так, с отключенной детаилстат, падений за 1.5 года небыло

 

 

З.Ы.

MySQL имеет двойное лицензирование. MySQL может распространяться в соответствии с условиями лицензии GPL. Однако по условиям GPL, если какая-либо программа включает исходные коды MySQL, то она тоже должна распространяться по лицензии GPL. Это может расходиться с планами разработчиков, не желающих открывать исходные тексты своих программ. Для таких случаев предусмотрена коммерческая лицензия, которая также обеспечивает качественную сервисную поддержку.

http://ru.wikipedia.org/wiki/MySQL

Share this post


Link to post
Share on other sites

при чем тут утечь?!

 

стг в процессе своей работы обмениваецо данными с памятью, запись в БД - это только для сохранности данных

 

из соображений скорости работы - это самый лучший вариант

 

если реконект будет сделан кошерно - моему счастью не будет предела...

Share this post


Link to post
Share on other sites
Но кто-нибудь в действительно проверял, насколько это быстрее работает, чем одна большая таблица?

А вы попробуйте бенчмаркнуть выборку по одной табличке где скажем 50М записей или по табличке где 500к - думаю разницу очень хорошо прочувствуете =)

Нет у меня двух таблиц с одинаковой структурой и таким количеством данных. Старенький сервер сделал "SELECT * FROM ... ORDER BY ..." за 3 секунды на таблице из 2М записей. Не знаю, много это или мало, но я не думаю, что анализ детальной статистики - такая уж частая операция, чтобы лишние 5 секунд были критичными. Я не прав?

 

А prepared statements выглядит удачно в данном контексте, хотя подозреваю что просто так, мускуль не будет кешировать идущие не подряд /не всегда единообразные запросы, тем более в рамках нескольких сесий.

Prepared Statements тут не будут иметь особого эффекта. Разве что при записи детальной статистики и данных о трафике - там идет пачка однотипных запросов. Я по этому поводу думал, в будущем, пересмотреть подходы к работе с БД. Все-таки изначально все ориентировалось на работу с файлами.

А мне prepared statements нравятся даже не из-за того, что они кешируются, а из-за того, что отпадает необходимость ручной ковертации данных "из строки" и "в строку": достаточно сделать mysql_stmt_bind_result()/_param() на обычные C-переменные и вуаля.

 

4. detail_stats_MM_YYYY - это такое "ручное секционирование", закат Солнца вручную. Есть более правильные штатные средства секционирования.

Вот. Я тоже думаю, что должнжо же быть что-то предусмотрено. А какие штатные средства?

 

5. Модуль написан в большей степени на C чем на C++.

Клиентская библиотека MySQL предоставляет C API, а не C++, поэтому я не знаю, как его можно написать "совсем на C++". std::string, как я заметил, там используется. ;)

 

Предлагаю придерживаться той структуры БД которая используется в mod_store_firebird и mod_store_postgresql. В PostgreSQL более "свежая" структура. Могу дать даже еще более свежую, к оторой я наконец-то решил нормально проблему хранения текущих данных о трафике и помесячных (скорее всего я пока не буду включать ее в rc3 и релиз, но у меня на работе она успешно работает).

Согласен. Давай самую последнюю.

 

Чтоб не текло можно хранить в бинарном файлике данные при достижении порога записей/обьема. У нас БД хранится в памяти полностью, и пишутся журналы. Упала база - подымаем дампы, потом журналы и погнали.

Правда у нас немного другого класса биллинг, но думаю писать журналы работы в файлик который потом подымать при реконнекте в случае если он есть - вполне реализуемо. А тем более если это биллинг - ни одна запись не должна потеряться. Соответственно - это мастхев.

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

 

Хотелось бы оптимизации таблиц в базе. Например в `users` колонка `Tariff`. Почему бы не сделать TariffID и связать FOREIGN KEY ? Ну и чего уж тут, InnoDB.

Можно.

 

Итого, резюмирую текущий план работ:

  1. Нормальный реконнект (решит проблемы с падениями)
  2. "Прочный" (robust) код (предсказуемая реакция на ошибки)
  3. НФ-3 для схемы БД (+ переход на InnoDB и транзакции)
  4. prepared statements
  5. автоматическое (или автоматизированное) обновление схемы БД

Share this post


Link to post
Share on other sites

Ну, ждемс релиза ;)

Share this post


Link to post
Share on other sites
Нет у меня двух таблиц с одинаковой структурой и таким количеством данных.

Тыкнуть инсерт с рандомными данными в цикл помагает чтобы получить заданные условия.

 

Не знаю, много это или мало

Допустим это еще "более-менее", ну плюс еще можно нормально поальтерить индексы и получить что-то около полутора секунд.

 

Теперь считаем на наглядном примере. У меня детальная статистика ведется только для пользователей "по траффику" которых где-то 0.1% от общего числа. На текущее число табличка detailstat_03_2011 весит всего-то 625 мег и имеет около 6М записей. Селект с веаром по индексным полям получается что-то около 10 секунд на дуальном зеоне. Теперь смотрим в топ и пугаемся при осознании того как весь этот процес будет выглядеть если табличка будет называться просто detailstat_2011 ;)

 

Года 3 назад модной была практика показывать пользователям на трафико-заточеных тарифах их детальную статистику (ну чтобы небыло глупых вопросов куда бабло утекает) собственно после второго укладывания мускуля баиньки все закончилось костылем кешированием в статику раз в сутки, ночью, скриптом. В финале и от этого отказались и выдаем детальную стату только по запросу. Вот такие вот реалии ;)

Share this post


Link to post
Share on other sites

в памяти хранить в смысле "утечь"?

У нас как-то 3 дня работало без БД пока я этого не заметил. И ничего, сильно не натекло ;)

 

Чтоб не текло можно хранить в бинарном файлике данные при достижении порога записей/обьема. У нас БД хранится в памяти полностью, и пишутся журналы. Упала база - подымаем дампы, потом журналы и погнали.

Правда у нас немного другого класса биллинг, но думаю писать журналы работы в файлик который потом подымать при реконнекте в случае если он есть - вполне реализуемо. А тем более если это биллинг - ни одна запись не должна потеряться. Соответственно - это мастхев.

Да, как вариант это возможно, но не думаю что целесообразно. 3 дня лежачей БД - это крайний случай, обычно это обнаружевается раньше и быстро исправляется. И то даже в этом случае все нормально в памяти уместилось.

Share this post


Link to post
Share on other sites

О я смотрю тут спецы собрались по MySQL. Оффтоп дикий, но все же..

не подскажите как в трехуровневом LVS(Linux Virtual Server) кластере вынести MySQLбазу данных нодов на сетевое хранилище. А то с самим Apache'м вроде все ясно, с директором кластера тоже, а вот как синхронизировать БД, что бы всем нодам была доступна актуальная информация не совсем понятно ;)

Я думаю это скорее вопрос по LVS чем по MySQL. Я про LVS только читал, но думаю что возможно оставить на каждом узле статически сконфигурированную "серую" подсеть как раз для таких нужд.

 

при чем тут утечь?!

 

стг в процессе своей работы обмениваецо данными с памятью, запись в БД - это только для сохранности данных

 

из соображений скорости работы - это самый лучший вариант

 

если реконект будет сделан кошерно - моему счастью не будет предела...

Будет. Когда - не знаю, но будет.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×