маленький монстрик

Вопросы и ответы к несостоявшемуся событию "Экспертная сессия вопросов и ответов от Светы Смирновой"

В эти выходные я должна была ехать в Минск проводить Percona Meetup "Экспертная сессия вопросов и ответов от Светы Смирновой". По независящим от меня причинам поездка не состоялась. Однако вопросов люди успели прислать. Отвечу на них здесь.

Вопросы помечу жирным курсивом. Ответы будут обычным текстом.

Света, Добрый день. По вашему мнению какая схема работы Percona XtraDB Cluster наиболее предпочтительная? Возможно ли в качестве фронтенда для кластера добавить балансировщик нагрузки (HAProxy)? Каким образом организовать бекап БД? Какое "железо" исходя из практики наиболее предпочтительнее? Какие подводные камни могут быть исходя из предложенных исходных данных? Исходные данные: 1) Есть 3 дата-центра, между которым организован хороший канал передачи данных (3 ноды mysql сервера в каждая отдельном ДЦ). 2) База данных размером 90ГБ. 3) 7000 одновременных (конкурентных) запросов в БД.

В трёх дата-центрах (ДЦ) однозначно не нужно. Дело в том, что Percona XtraDB Cluster (PXC) синхронный. Это значит, что COMMIT не завершится, пока не получит подтверждение от всех нод, что изменения дошли. То есть нода в одном ДЦ будет ждать ответа от двух других. Это обычно достаточно долго. Если вы всё-таки решите делать такое решение, увеличьте переменные, отвечающие за ожидаемый delay между нодами (см. полный список здесь). В противном случае кластер будет регулярно "терять" то одну, то другую ноду и приходить в нерабочее состояние.

PXC обычно используют для масштабирования чтения и синхронизации записи, если необходимо писать на всех нодах. Обычно, если ноды используются в различных ДЦ, логика как-то разделяется. Например, по географическому признаку. В этом случае можно и нужно использовать обычную асинхронную репликацию. При этом можно настроить асинхронную репликацию между тремя кластерами, установленными в каждом датацентре.

HAProxy использовать не только можно, но и нужно. Это рекомендуемое классическое решения для балансировки нагрузки.

По железу рекомендации обычные: быстрый диск, память должна вмещать активный набор данных. Кстати, у вас сравнительно небольшой объём данных и вы можете поместить его полностью в память (в InnoDB Buffer Pool) и сильно сэкономить на скорости диска.

За конкурентные запросы отвечает CPU. Чем больше ядер, тем больше кокурентных запросов вы сможете обработать. Но тут нужно отличать количество запросов, которые посылает приложение, и количество запросов, обрабатываемых внутри InnoDB: последнее обычно меньше даже при большой нагрузке за счёт того, что часть соединений находится в спящем режиме пока приложение получает или обрабатывает данные.

Если у вас реально 7000 активных соединений, имеет смысл присмотреться к Thread Pool Plugin

Когда будет исправлен баг https://bugs.mysql.com/bug.php?id=11472 ? И почему его так долго не исправляют?

Этот вопрос нужно задать менеджерам и разработчикам Oracle. Но я подозреваю, что требуется согласование работы между InnoDB и Runtime. Дело в том, что за внешние ключи отвечает движок (InnoDB), а за исполнение триггеров - Runtime. И, чтобы исправить этот баг, по уму нужно реализовать несколько коммуникаций между движком и Runtime. Для одного InnoDB это, возможно, сделать проще. Но MySQL поддерживает несколько движков и правильно делать именно через абстрактный интерфейс. Я думаю, что баг будет исправлен, когда появятся внешние ключи на уровне сервера. В версии 8.0 есть подвижки в этом направлении. Хотя, насколько я могу судить, до исправления именно данного бага ещё очень далеко.

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

Такое впечатление, что вы говорите о PXC, на вопрос про который я отвечала в начале поста. Это отдельный продукт. Также как и Galera, и новая фича MySQL Group Replication.

Репликация же по умолчанию в MySQL асинхронная. И в случае асинхронной репликации мастер ничьих ответов ждать не будет. Я делала презентацию для Highload++ в этом году про отладку репликации MySQL. Там есть несколько слайдов именно про то, какая бывает репликация, надёжное ли такое решение или быстрое.

Насчёт других СУБД: я бы не сказала, что там репликация решена ненадёжно. Просто нужно хорошо понимать особенности того или иного решения.

Какие инструменты Вы можете посоветовать для отладки запросов к MySQL. Как понять что надо исправить, чтобы запрос стал быстрее? Надо ли добавить ключ или полностью переписать запрос?

Нужно использовать EXPLAIN для понимания того, как планируется выполнение запроса; статистику движка и таблицу INFORMATION_SCHEMA.OPTIMIZER_TRACE, чтобы узнать, что именно происходило во время выполнения; и просматривать статистику таблицы.

По поводу добавления ключа или модификации запроса общего ответа нет: каждый случай решается в индивидуальном порядке.

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

Сильно ли тормозит нормализация структуры БД? И до какой степени стоит ее проводить?

Сама по себе нормализация не тормозит. Иногда могут требоваться сложные JOIN-ы между несколькими таблицами, которые по каким-то причинам не могут быть оптимизированы (JOIN-ы сами по себе тоже не тормозят). В таком случае имеет смысл денормализировать структуру. Однако нужно понимать, что в этом случае вы будете писать больше данных. Также появятся дополнительные блокировки, которые негативно скажутся на общем времени записи: там, где в нормилизированной структуре у вас будет уникальный ключ плюс блокировка одной строки, в денормализированной будет либо блокировка всей таблицы, либо нескольких строк.

Как и в других случаях, универсального ответа "где остановиться" не существует.

Как работают триггеры БД? И насколько целесообразно их использовать. Тормозят ли они работу БД? Есть ли какие-нибудь best practice для триггеров?

Сами по себе триггеры не тормозят. В MySQL триггеры вызываются для каждой изменяемой строки. Соответственно, если вы будете выполнять тяжёлую операцию в триггере, она будет выполняться для каждой изменяемой строки. То есть изменять 10,000 строк в какой-то таблице триггером не стоит. Касательно best practice: нужно помнить о блокировках. Например, если вы хотите в триггере на таблицу Foo обращаться к таблице Bar, следует писать команды таким образом, чтобы они не блокировали друг друга при конкурентных запросах к таблице Foo.

Здравствуйте, были ли в вашей практике проблемы, связанные с использованием многих databases в рамках одного сервера MySQL? Насколько хорошо MySQL работает, когда таких баз уже под 2000 и когда стоит начать думать о втором сервере?

Есть две проблемы.

Первая: лимиты операционной системы. Каждую базу MySQL хранит в отдельном каталоге. Соответственно, если таких каталогов много, файловой системе будет сложно с ними работать. Но там сильно большие числа нужны, 2000 проблем не вызовут.

Вторая: дизайн Information Schema до версии 8.0. При обращении к некоторым таблицам будет заметно подтормаживать из-за того, что в ней нет индексов. А так как большинство SHOW команд слинкованы с Information Schema, отладка будет затруднена. Также есть Java frameworks, которые злоупотребляют командами SHOW при создании соединений. Но тут, опять-таки, будет ещё зависеть от количества таблиц в базах. Если по 10 таблиц это будет full scan 20,000 "строк": не очень приятно, но ответа дождаться можно; если же их тоже по 2000, то 4,000,000, что намного хуже.
маленький монстрик

И яБрут

воскликнула "Почему на ПХП пишут хреновые программы?", пытаясь понять где она отваливается с "Got timeout reading communication packet" Со стороны MySQL мы уже всё что можно подкрутили до каких-то совершенно insane размеров.

Оказалось, что авторы, реализовав MVC с классом, используемым для соединения с MySQL при помощи mysqli, в месте, где отваливается, поместили прекрасное.

Поначалу ничто не предвещало:


337 $connection = Propel::getConnection( 'workflow' );
338 $oStatement = $connection->prepareStatement( "CREATE TABLE IF NOT EXISTS
...
365 $workSpace = new workspaceTools( $workSpace );
366 $workSpace->getDBInfo();


И вдруг так неожиданно на следующей строке:


368 $link = @mysql_pconnect( $workSpace->dbHost, $workSpace->dbUser, $workSpace->dbPass) or die( "Could not connect" );
маленький монстрик

Как?

Разговаривала сегодня в чате с клиентом. Помогала запустить slave после крэша. Скорее всего этот баг. Показываю ему один workaround из бага, другой. Запускает: снова ошибка 1872. Причём copy-paste в чат делает, команды правильные. Спустя какое-то время решили, что лучше мне зайти к ним на машину и самой попробовать. Я набираю те же самые команды и slave стартует.
  • Current Mood
    confused confused
  • Tags
маленький монстрик

(no subject)

Когда я читаю про последний снос ларьков (впервые!) я жалею, что в 1993 году, когда убирали официально проплаченную минимум на месяц вперёд точку моего мужа с Арбата я не догадалась раздобыть фотоаппарат и поехать туда снимать. Сочувствия люди, вместо работы на заводе продававшие Родину аж целыми матрёшками, у москвичей тогда не вызвали. Как не вызвали и хозяева киосков на Новом Арбате, да, впрочем, и в других местах Москвы, снесённых примерно в то же время. Снесли их, кстати, вот точно также как и сейчас: в один день. С тем, чтобы заменить на новые, не портящие облик города. Не портящие облик города киоски были из зеленоватого металла и, на мой неискушённый взгляд, были пострашнее некоторых из тех, чему они пришли на замену. Зато они были явно с одного завода. Москвичи ликовали: эти вандалы, поправшие облик города, получили своё!

Впрочем, облагороженные киоски просуществовали не более двух лет до лета 1994 или 1995 года. Их заменили павильоны. Сочувствия к владельцам киосков, вынужденных враз их переехать в более дорогое и менее доступное торговое место у москвичей в то время тоже не было.

В промежутке между зелёными киосками и павильонами весной 1994 года запретили торговлю книгами в метро. (Про сочувствие можно не комментировать, да?) Впрочем это касалось только точек, расположенных после турникетов. На станциях точки оставались.

На смену павильонам (тут я уже года не помню, конец 90-х) пришли вот эти торговые центры, которые сейчас снесли. Все опять были рады.

Дальше я уже совсем забыла хронологию: закрыли под общее ликование ужасные рынки, много лет кормившие и одевавшие москвичей; в начале срока Собянина убрали торговлю в переходах метро (тогда впервые я услышала, что кому-то, непосредственно киоском не владевшему, это не нравится); что-то по мелочи.

И вот когда сегодня я вижу в топе "Когда пришли за владельцами палаток..." я чувствую некоторое злорадство модели "где же вы были раньше!". И одновременно радость, что наконец-то подобный снос не радует пусть 11-30% разным способом опрошенных и некоторое количество моих друзей. Цифра небольшая, но не 0 как было всего лишь несколько лет назад.

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

Зачем Support Engineer-у знакомство с исходным кодом

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

Вообще во время собеседований меня постоянно спрашивали что я делаю на текущей работе. Я отвечала, что основная моя обязанность - это верификация баг репортов. Настоящая компания не была исключением. Мы обсудили что такое верификация, как я её делала. А затем они стали спрашивать про мои знания MySQL и знакомство с кодом. Я ответила: "А как же?" И тут они мне задали тот самый вопрос: "А зачем вам нужно знать код, вы же занимались black box testing?" К сожалению в тот день у меня не было хорошего примера зачем нужно знакомство с исходниками. Пример появился буквально на следующий день!

Вообще говоря bug verification - это не всегда black box testing, а просто подтверждение бага любыми доступными способами.

Bug #75706 "alter table import tablespace creates a temporary table"

Фактически это feature request: это значит, что функциональность отсутствует и решение появится только в следующей мажорной версии. То есть это не прям такой серьёзный баг, который нужно верифицировать уже сегодня и чем раньше, тем лучше. Тем не менее подтвердить его нужно. И чтобы его подтвердить возможны варианты:

  1. Brute force. Тот самый black box testing. То есть нужно создать достаточно большую таблицу и сделать ALTER, затем отслеживать создалась ли временная табличка. Минус этого способа очевидный: очень долго, очень много тупой работы и чем быстрее диск - тем большую нужно создавать таблицу. Соответственно возможны варианты, что на моём лаптопе создание временной таблицы можно будет увидеть легко, а на сервере разработчика - уже нет.

  2. Поставить breakpoint в месте, где создаются временные таблицы и отследить его в gdb, например. Но тут уже нужно знать код.

  3. Просто прочитать код.


Способы 2 и 3, на мой взгляд, сильно эффективнее "black box ради black box" способа 1. В данном случае я применила способ 3. Если бы это был баг применила бы способ 2: с ним проще доказать, что баг в наличии.

Пример использования способа 2 попался буквально на днях на новой работе. Это Bug #1452397 "Gaps in Retrieved_Gtid_Set while no gaps in Executed_Gtid_Set" или Bug #76959 "Gaps in Retrieved_Gtid_Set while no gaps in Executed_Gtid_Set". Клиент предоставил relay log файлы, которые приводили к описанному поведению. В принципе когда я поняла почему ошибка происходит достаточно было запустить mysqlbinlog на них и баг репорт был бы готов. Проблема в том, что Percona Server - это fork Oracle MySQL Server и по-хорошему баг нужно было слать и в Oracle тоже. И, как вы понимаете, relay логи клиента Percona я в Oracle послать не могу. Поэтому пришлось придумывать как их создать. Опять-таки, можно было манипулировать максимальным размером логов и посылаемыми запросами из мастера, но при появлении любых дополнительных служебных данных, записываемых в binary log в любой из последующих версий, тест бы поломался и нельзя было бы точно сказать баг ли устранили или просто формат binary log поменяли. Да и долго размер запросов подбирать! Поэтому я применила более эффективный способ: Test Synchronization и DBUG_EXECUTE_IF. Что, опять-таки, без знакомства с кодом MySQL было бы невозможно.
маленький монстрик

Oracle is easy

Пожалуй самым звёздным MySQL-продуктом на прошедшей OOW были JSON UDFs MySQL Plugin for Oracle Enterprise Manager (OEM). Проще всего потестировать плагин, установив OEM на виртуальную машину. Однако здесь есть нюансы.

Я устанавливала OEM для всей комнады MySQL Support и это стоило мне немножко нервов, усиленных временами медленным VPN.

Собственно нюансы. Я предпочитала, где возможно, пользоваться командной строкой.
Collapse )
Да, установку OEM и последующую настройку, особенно на удалённой машине, лучше проводить вот в такой маечке:



Как настроить MySQL Plugin я рассказывать не буду: вот здесь всё подробно. Никаких сложностей не вызывает. Можно мониторить как сервер, находящийся на той же машине, так и удалённый. Лучше покажу немного screenshot-ов.
Collapse )
маленький монстрик

Ещё раз про бесправных пользователей

Несколько дней назад я писала пост о том как MySQL пользователь с минимальными правами доступа может получить очень много ресурсов. Честно говоря, мотивацией для написания статьи было не столько желание вас попугать, сколько желание ещё раз показать memory tables в Performance Schema.

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

Collapse )
маленький монстрик

svetasmirnova@github

Вот тут пишут, что без профиля на GitHub в приличное общество уже не принимают. Он у меня, оказывается, был, но я его не использовала. Тем временем MySQL Server мигрировал с Launchpad на GitHub и все мои скрипты для автоматической сборки и тестирования на двух лаптопах и нескольких Oracle-овых машинах полетели. git pull сделать, несомненно, удобнее, чем ручками, так что вот Почитать о скрипте для тестирования на английском языке можно здесь
маленький монстрик

Performance Schema memory tables и бесправные пользователи

В своих семинарах и тренингах, посвящённых отладке, я люблю повторять мантру: "Не раздавайте логины в базу кому попало!" Казалось бы, что в этом такого, можно же настроить минимальные привилегии и спать спокойно.

Проблема в том, что даже минимальные привилегии в MySQL позволяют изменять сессионные переменные, в том числе те, которые регулируют потребляемые ресурсы. Мой любимый пример: убей сервер при помощи join_buffer_size. Однако до версии 5.7 проверить как это работает было сложнее. Сейчас же, при помощи memory summary tables,  можно наглядно увидеть как непривилегированный пользователь может заставить сервер уйти, например, в swap.

Collapse )
маленький монстрик

Таблицы memory summary в Performance Schema в версии 5.7

Здесь я писала о значительных нововведениях в MySQL 5.7.

И, конечно, как troubleshooting freak я не могу не написать отдельно про своё любимое: memory summary tables в Performance Schema. И соответсвтующие представления в sys schema.

Вообще до версии 5.7 у нас были очень ограниченные средства диагностики проблем с памятью MySQL. Мы могли использовать vmstat, top, free и прочие инструменты, предоставляемые операционной системой, но узнать что же конкретно происходит и на что именно ушла память было практически невозможно. В новой версии ситуация изменилась.
Collapse )