Pull to refresh

Comments 58

Пусть задержка по записи 5мс и мы пишем в журнал всегда последовательно. Если в базе данных параллельно выполняется N независимых транзакций, кто мешает объединить эти транзакции в одну запись в журнал? Если зависимость по данным отсутствует (и даже иногда когда она присутствует, но мы можем опустить этот случай для простоты) писать каждую транзакцию отдельным IO в журнал нет необходимости. Т. е. даже если каждая отдельная запись в журнал это 5мс, если эта запись коммитит сразу несколько транзакций то можно получить больше чем 200 транзакций в секунду и IO очередь при этом не нужна.
Я не знаю даже теоретического разумного решения, как определить, что транзакции независимы. То, что сейчас у них записи в разные таблицы — не показатель. Наверное, теоретически можно прикрутить какую-то эвристику, но сейчас ни в одной СУБД этого нет. Гораздо чаще, как в упомянутом Delayed Transaction Durability, идеальное соблюдение принципа приносится в жертву производительности.
1. Теоретически и даже практически разумные решения существуют и существовали довольно долгое время, например, классический 2PL автоматически заблокирует транзакцию, которая обращается к данным используемым другой транзакцией. Ниакой эвристики не нужно.
2. Транзакции совсем не обязательно должны быть независимы, нужно просто коммитить зависимые транзакции вместе.

2PL работает совсем на другом уровне. Плюс тут же вопрос даже не в коммите. Коммит — это просто записать в журнал, что транзакция с таким-то LSN закоммичена. В WAL пишется всё подряд и однопоточно. И реализовать запись корректной последовательной цепочки всех изменений с достаточной надёжностью и хитрой обработкой параллельность пока ни в одной СУБД, видимо, не смогли.
В том же MS SQL небольшой кэш для транзакций есть (см тут), но он для другого случая, когда транзакция записывает много данных.


В любом случае статья не о том, как "можно было бы сделать СУБД", а о том "как те СУБД которые есть заставить работать". При нормальном разбиении дисков 5к-20к TPS выжать на продакшн вполне можно. С оговорками про конкретную задачу и бюджет.

2PL работает на том уровне на котором его реализуют, так что я не очень понял на каком таком другом уровне он работет? Если он работает на уровне записей базы данных, то этого вполне достаточно.

Запись LSN в журнал — всего лишь одна из возможных реализаций коммита. Кроме того писать в WAL все подряд нет необходимости — это опять же всего лишь одна из возможных реализаций.

Более того, даже если допустить, что все существующие БД пишут в WAL все подряд, это совершенно никаким образом не запрещает объединить несколько обновлений WAL в 1 IO. Элементарно, в какой-то момент БД должна определить, что нужно записать в журнал. Все что нужно это просто подождать какое-то время перед тем как непосредственно выполнять эту запись и собрать данные с нескольких транзакций. Максимальная задержка может возрасти, но и параллельность при это тоже возрастет. Ничего хитрого в этом нет, простая пакетная обработка и амортизация затрат времени.
Так и работают уже давно все современные БД. Только этого не достаточно. Логика существенной части ПО выстроена на большом количестве (напр 400 в сек) последовательных транзакций для самых элементарных вещей. И там приходится всегда ждать физического окончания комита.
Это уже другая история. Одно дело сказать, что БД впринципе не может выполнять больше 200 транзакций в секунду, другое дело, что вам для одного логического действия нужно выполнять много последовательных транзакций. Одно утверждение указывает на проблему в БД и сторадже, другое на проблему в ПО, которое использует эту БД.
на самом деле оракл еще с глубокой древности имел возможность поднимать несколько процессов пишущих в REDO лог. то была фича когда еще была распространена NUMA архитектура и предлагали на каждой партиции NUMA свой процесс писанинины в лог поднимать. другое дело что особо смысла это не имеет, т.к. нормально настроенный REDO запросто на hdd успевает писать десятки миллионов транзакций однопоточно. в тестах tpc.org и поболее есть тесты, при этом один процесс и hdd справляются.
Пардон, что значит «была распространена NUMA архитектура»? Какая, по вашему, архитектура у современных двух- и более процессорных систем? С собственным контроллером памяти у каждого процессора и относительно медленными соединениями между ними? Другой вопрос, что в 2-/4-процессорных системах, из которых, в основном, сейчас строятся кластеры, накладные расходы относительно невелики. Но они есть и «special care must be taken in vCPU and vNUMA configuration to ensure performance is optimized»
В PostgreSQL есть подобное. Только записи WAL не объединяются, а просто процесс, который собирается сделать fsync на WAL, может подождать других. См. параметры commit_delay и commit_siblings.
postgrespro.ru/docs/postgrespro/10/wal-configuration
Из описания это не совсем то что я имел ввиду, или даже совсем не то, что я имел ввиду. Контрольные точки отмечают моменты в которых достоверно известно, что все предшествующие записи в журнале больше не нужны и могут быть удалены, между контрольными точками журнал все еще пишется и количество использованых IO операций при этом никак не контроллируется этими контрольными точками.
А хотя нет, вы правы, commit_delay на самом деле как раз то что я описывал выше, прошу прщения за невнимательное чтение.
К слову, буква-в-букву эти требования не выполняются почти нигде и никогда, а в распределённых системах просто никогда (CAP-теорема мешает).

CAP теорема и ACID — это ортогональные вещи, и одно другому не мешает. См. Spanner, Cockroach DB, YT. Поэтому про "никогда" я бы не говорил в таком разрезе.

Я и согласен и нет. Про ортогональность: хотя буква C в CAP (consistency, availability, partition tolerance) и означает совсем не то, что C в ACID, но эти темы не ортогональны. C в CAP по значению почти эквивалент значению буквы D из ACID. Так, что вы в целом правы, что «не мешает», но вот с «ортогональны» я не соглашусь.
А вообще, все СУБД (и распределённые и нет) достаточно «творчески» подходят к ACID, нераспределенные особенно к I — isolation (любые уровни изоляции отличные от SERIALIZABLE нарушают изоляцию), распределенные к C и D (плюс там хитрый вопрос что такое раньше/позже).
C в CAP и D в ACID имеют очень мало чего общего (кроме того что они соседние буквы в алфавите), любой мусор можно зафиксировать на диске, сообственно есть системы хранения которые так и делают. Кроме того когда вы говорите о невозможности и упоминаете CAP, вам нужно найти соответсвия сразу C и A из CAP в ACID, в противном случае CAP без C или A не особо что-то ограничивает. Т. е. даже если мы на секунду забудем что C из CAP не имеет соответсвий в ACID, то нам все еще придется разобраться с A из CAP и наоборот.
Для OLTP систем на разделе с WAL/журналами транзакций 5 мс это недопустимый показатель

А вот в доке EMC, на которую вы ссылаетесь, написано, что 5 мс — это Excellent для данных, и Very good — для транлогов. Кому верить?
Кому верить?

Никому. Серьёзно. У EMC цифры "что такое хорошо" меняются год от года. Сколько могут прямо щас — столько и Excellent. Вот в H12341 (октябрь 2013) и H14621 (декабрь 2015):

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

И за эти 5 лет как раз почти всюду в high load стали использоваться All flash SSD решения. Тут надо не верить, а смотреть на конкретную СХД и выжимать из неё производительность. 1 мс было отлично 5 лет назад, но это не значит, что сейчас нельзя достигнуть большего.

Даже цифра в 5 мс десять лет не меняется.
Это примерно соответствует 12'000 оборотов в минуту — если считать, что задержка равна одному обороту диска. Ну и с чего ей меняться, если диаметр диска не меняется, и скорость звука тоже?

Советы по диагностике SQL Server
Это для любого SQL-сервера? Или для какого-то одного?

Никаких кешей, никакой перестановки операций в очереди, а иначе не будет целостности!
Вообще говоря, перестановки возможны. Но там надо тщательно следить за тем, чтобы перестановки были не любые, а только допустимые. И я не уверен, что дисковой подсистеме (отдельному диску и/или СХД) можно объяснить, что можно переставлять, а что нельзя.

чтобы знать, что записывать — надо прочитать
Можно выравнивать записи СУБД на размер сектора. Правда, с индексами будет тяжко — они маленькие…
Но кстати — прочитанное можно свободно кэшировать и использовать повторно.

На одну даже маленькую транзакцию потребуется 5-10 операций записи.
Давайте попробуем раскидать по дискам? Ой, а нам надо всё равно дожидаться пока предыдущий запишется и параллельность в итоге отсутствует.
Операции одной транзакции — свободно раскидываются по дискам.

Если наш журнал положить на отдельный диск и писать записи последовательно
А если разделить журнал на несколько дисков?

за счет того, что не требуется постоянно перепозиционировать головки диска
Дело не в позиционировании головок. А в ожидании прихода под головку нужного сектора.

Во всех распространенных СУБД запись в журнал строго последовательна.
А что мешает нескольким процессорам готовить записи для журнала и складывать их главному процессору для записи? Главный процессор окажется вообще не нагружен — узким местом будет диск.

Всё ещё — никаких кешей ОС, никаких перестановок операций.
Это не страшно, если транзакции будут накапливаться в очереди и записываться на диск одним большим блоком (одной большой операцией записи).

администраторы уже умеют PowerShell
А почему не Bash?
Ну и с чего ей меняться, если диаметр диска не меняется, и скорость звука тоже?

Например, с того, что сейчас почти везде используются SSD. Впрочем, 10 лет назад разделение по дискам имело более критичное значение.


Это для любого SQL-сервера?

Я не знаю другого продукта на рынке, который называется именно "SQL Server" кроме произведенного Microsoft. Но, согласен, лучше было уточнить.


… Вообще говоря, перестановки возможны…
… выравнивать записи…
… свободно раскидываются по дискам...

Наверное, возможно многое. Но сейчас write-ahead logging является одним из основных ограничений производительности. И эта бодяга тянется как минимум с 1992 года.


А если разделить журнал на несколько дисков?

Иногда приходится, но очень-очень редко нужно больше двух параллельных дисков (точнее 4 потому что обычно это RAID10). Что нужно сделать чтобы узким местом стал отдельный SSD для WAL я даже не представляю.


Это не страшно, если транзакции будут накапливаться в очереди и записываться на диск одним большим блоком (одной большой операцией записи).

Страшно. Реально страшно. Вы собираетесь ответить пользователю, что транзакция зафиксирована, а на самом деле нет. При сбое вы потом целостность не соберете.


А почему не Bash?

Поздравляю, вы нашли пасхалку :) Именно PowerShell написано осознанно. Администрировать linux, не зная bash — невозможно. А называться администратором Windows не зная PowerShell — сложно, но возможно.

Это не страшно, если транзакции будут накапливаться в очереди и записываться на диск одним большим блоком (одной большой операцией записи).

Страшно. Реально страшно. Вы собираетесь ответить пользователю, что транзакция зафиксирована, а на самом деле нет. При сбое вы потом целостность не соберете.
********
Нет, WAL это не совсем то, что Вы говорите. Противоречие начинается в вилке, где сходится энергонезависимая память и построчная запись. Поэтому при настройке системы, даже самый глупый, но аккуратный зануда инженер, без диплома ВУЗа ( как я ) первым делом
1. проверяет, если есть энергонезависимая память, её размеры, и рассчитывает, на краешке рукава, сколько её может / будет использоваться при условии, что система испытывает расчетные нагрузки ( их выясняют у бизнеса )
2. принимают решение, пользоваться или нет этим устройством. И если отказываются, то все как в статье, которую Вы написали, а если принимают, то дальше очень интересно, и совсем иначе. Образ этой кэши выстраивается отдельным устройством. И оно имеет права на параллельные процессы. Которые в свою очередь субъект различных правил оптимизации. И если правила достаточно просты ( прослеживая варианты сочетания транзакций ), а система блокировок верно рассчитана, то тогда все очень хорошо на очень не дорогих запоминающих устройствах. И тогда начинается грызня с маркетингом, которые лишаются тех самых процентов от сделки при покупке СХД.
Если WAL лежит отдельно, то есть много вариантов, как хранилищу отчитаться в ОС, что всё сделано. Многие СХД и RAID-контроллеры отвечают, что «всё записано», когда реально данные только попали в память «с батарейкой». 100% записи, последовательной. Там гора вариантов.
Если вы нагрузку WAL бросите в общий котёл, то ничего этого не получите. Там полно в очереди таких, которым «только справочку получить».
Все так, и в комментарии все по — моему расставлено по местам.

Надо только напомнить, что встав на ножи с меркетингом, приходится помнить о том, чтобы вовремя менять батарейки и если уйти в отпуск, то придется прилететь в течение 48 часов, чтобы включить машины, иначе батарейки сядут.

Но в общем — то получается экономия как минимум пол миллиона долларов ( самый дешевый SAN ). Хватает на 5 позиций инженеров :) Есть за что бороться.
Последовательная запись, как правило проходит мимо весьма небольшого и драгоценного кэша, СХД это чуть большее чем рейд-контроллер из 90х
На самом деле это уже частности. Главная идея в том, что задержка на LUN (или другое вендор-зависимое название) с 100% последовательной записи на порядок меньше, чем когда есть случайные чтения и записи в тот же LUN. Как конкретно железяка подключена, как эта железяка делает быструю запись мне не настолько важно (пока есть доверие, что записано значит может быть прочитано).
Да, СХД типа VNC или VMax это больше, сложнее и дороже, чем рейд-контроллер. Но по большому счету в этой разнице latency «виновата» не СХД, а ОС, которая для одного «физического» с её точки зрения будет держать одну очередь.
Например, с того, что сейчас почти везде используются SSD.
Я слабо слежу за темой. Но мне кажется, SSD приличного размера (пригодного для корпоративных БД) всё ещё имеют неприличную цену.

Я не знаю другого продукта на рынке, который называется именно «SQL Server» кроме произведенного Microsoft.
«SQL-Server» — это название категории серверов. Аналогично: «FTP-Server». Это как название «хищник» — включает в себя много видов.
Т.к. M$явные маркетологи любят брать название категории для своего продукта — следует уточнять, говорим ли мы о всей категории или же о M$явном продукте.

Иногда приходится, но очень-очень редко нужно больше двух параллельных дисков (точнее 4 потому что обычно это RAID10).
Да не нужен там RAID0 (RAID1 нужен для надёжности). RAID0 даже плох — тормозит в случае, если очередная запись ляжет на два диска (пересечёт границу stripe-блока).

Страшно. Реально страшно. Вы собираетесь ответить пользователю, что транзакция зафиксирована, а на самом деле нет. При сбое вы потом целостность не соберете.
LoL, где я предлагал «ответить пользователю до записи на диск»? Делаем так:
* Запросы на проведение транзакций копятся в RAM-памяти. Клиентам сообщается: «запрос принят в обработку (т.е. повторно слать не надо), но запрос ещё не завершён».
* Запросы/транзакции, не конфликтующие по доступу к данным, объединяются в блоки.
* Затем, при освобождении диска — блок транзакций пишется на диск одной операцией записи. И после этого клиенту можно сказать «транзакция зафиксирована в БД».

Тут есть тонкость: при сбое питания на сервере — клиент должен определить, что принятый в обработку запрос пропал. И сделать это так, чтобы если запрос не пропал — чтобы он не выполнился дважды.
Это решается присвоением каждому запросу уникального id (как обеспечить уникальность — отдельный вопрос; например, с использованием уникального имени клиента и нумерации запросов силами клиента). Повторный запрос с этим же id — распознаётся сервером как повторный; независимо от того, был ли этот запрос выполнен или пока ещё висит очереди. А если первый запрос погиб при сбое питания — то выполняется как новый.
Статья конечно очень хорошая. Но единственный вопрос который у меня остался после её прочтения, как этот парень выжил. Таких ведь больше не делают.
Статья и да, и нет.

Да — если вы мне продадите устройства, у которых в fsync-режиме (iodepth=1, block=4k, random write 100%) гарантированная минимальная latency 5ms, я буду просто счастлив. Почему? Потому что на современных устройствах (SSD, NVME), пики в реальных бенчмарках оказываются в районе секунд, в идеальных случаях — в районе многих сотен милисекунд.

fsync — критическое. Например, первый попавшийся SSD диск выдаёт мне 50кIOPS на запись. sustained, iodepht=32, span=100%, randow write 100%, blocksize=4k.

Но стоит в конфиг теста написать fsync=1, как скорость падает до 300-350IOPS с огромными пиками по latency.

Если что-то тормозит, надо включить writeback. Если что-то теряет данные и портит базу данных — надо выключить writeback.

Т.е. я хочу сказать, что max 5ms write latency как SLA, это безумно круто. Проблема в том, что редко кто готов дать SLA на max, обычно это либо avg, либо (у самых честных) — 99% персентиль. А что такого, если 0.01% операций тупит по 10с? Остальное же быстро! (/сарказм).
Говорят, эту проблему решает Intel Optane.
Пока не щупал, но то что официалы говорят — не очень. Так же средняя latency. Которая стала ниже, но… Вот стоит субд, мурыжит тысячи операций в секунду. Тут, раз, задержка в 10с на одно IO. Как такое объяснять? «База данных ушла на базу. Вас много, я одна».
Т.е., по-вашему, это проблема в СУБД, а не в железе?
Что является источником такой проблемы?
Нет, конечно. Это проблема дисков снизу. Но для пользователя всё равно виновата база, потому что «тормозит». Причём на тестах ССД хорошо, а потом херак транзакиция и человек своими глазами видит, как insert в пустую таблицу на 1кб выполняется 10с с localhost'а.
Судя по тестам, там задержка не сильно ниже, но она на очереди 1 близка к константе. Там нет хитроштопанной логики и кешей и нет жирных CoW, как на SSD. Обычные SSD «на коротких дистанциях» компенсируют это кэшем, и именно поэтому в обычных тестах оптаны показывают себя очень близко к обычным хорошим SSD. А выигрывают в проигрышных для SSD вариантах типа 100% random write 4kQ1.

Хотя я тоже пока подожду готовых решений. Может в жизни всё и не так радужно.

Ну во-первых WAL это всё-таки не random, а seq. Во-вторых WAL может быть и не 4k за порцию, а меньше. Но я согласен, что SSD и тут может давать выбросы. И, кстати, на выделенных HDD многие СХД выжимают очень и очень хорошую производительность в этом режиме, так что упираются в каналы.


И, как заметил предыдущий комментатор, я расчитываю на прорыв Intel Optane. Посмотрите мой PS про SSD. Более того, если оптаны не обладают каким-то скрытым изъяном, то те скорости (задержки), которые они дают, делают спорным применение SAN/СХД на критичных к производительности приложениях. На VMax/VNC и подобных СХД пока еще никто не заморачивается на roundtrip до конечного приложения в десятки микросекунд.

Мне удавалось получить адские задержки на последовательном IO тоже. Ключевое — fsync. Поскольку ssd не может записать внутри себя 4к блок, то там всё равно происходит CoW (copy on write), который может утыкаться в GC и тормозить всё. Как раз жёсткие диски в линейной записи чувствуют себя круче, чем SSD.

Мы об одном и том же :)


на выделенных HDD многие СХД выжимают очень и очень хорошую производительность [в режиме seq write]

и


Как раз жёсткие диски в линейной записи чувствуют себя круче, чем SSD.
а как эти навороченные схд сочетаются с оптимизаторами субд? регулярно наблюдаю проблемы когда оптимизатор оракла собрал статистику в момент когда датафайлы активно использовались и сидели в кеше/ssd, а когда пришло время запускать ночной джоб блоки таблиц вытеснились на тормозные hdd. в результате то что оптимизатор считал, что вычитает за 2 минуты нестед-лупом, в реальности долбит хдд часами.
Звучит загадочно. Таблица просто так не расползается по HDD и SSD. Она находится внутри tablespace, который хранит данные в файлах. Вероятнее всего, в вашем случае речь идет либо о кривой конфигурации, либо о неверных выводах.
в навороченных схд несколько уровней кеширования. «горячие» блоки гуляют по ssd и прочим кешам. поэтому скорость чтения датафайла утром и ночью запросто различаются на порядок.
Нет никакой загадки. Простейший и типичный кейс. Есть уровень, который хранится на HDD 7200 (tier2), и есть его кеш примерно на 10% по объёму на SSD (tier1). Ночью запускается обслуживание БД: резервное копирование, перестроение индексов, пересчет статистик. В итоге утром в tier1 какая-то хрень, а не нужные данные. Просто потому что СХД не обладает достаточной информацией о значении данных.
Кто блин мешает закрепить файлы БД на быстрых дисках то? Autotiering — маркетинговая уловка всего лишь.
Есть такая проблема, для каждого вида нагрузки нужны фактически свои политики гуляния по tier'ам. Но вендоры СХД обычно предоставляют рекомендации.
А моё личное мнение, что для СУБД все эти «интеллектуальные» кеши уровня СХД — больше геморроя, чем пользы.
в навороченных схд несколько уровней кеширования. «горячие» блоки гуляют по ssd и прочим кешам. поэтому скорость чтения датафайла утром и ночью запросто различаются на порядок.
А когда fio закончит, покажите-ка его вывод с latency. Интересует max.
Тест шел сутки, это — средние steady результаты. За сутки там уж конечно что-то в max выстрелило, но это непоказательно.
Вы знаете, если бы дизайнеры автомобилей так делали, то было бы «за три года вождения max latency на повороте руля выстрелила несколько раз, но это не показательно. 99.9% поворотов руля отрабатывают за меньше чем 5мс, а что 0.01% — больше нескольких секунд — ну кого эти аварии волнуют?»

Это ж классика


Моя задача заключается в правильном применении секретной формулы.
Чистая арифметика.
Классическая задачка из учебника.
Если новая машина, произведенная компанией, на которую я работаю, выехала из Чикаго со скоростью шестьдесят миль в час, и тут у нее заклинило дифференциал, и она улетела в кювет, разбилась, бензобак взорвался и все, кто были в салоне, сгорели заживо, должна ли компания отозвать все проданные автомобили этой модели на доработку?
Возьмите общее количество проданных на настоящий момент автомобилей (А), умножьте на среднее количество серьезных отказов (В), а затем умножьте произведение на среднюю стоимость урегулирования иска родственников пострадавших во внесудебном порядке (С).
А х В х С = X. Вот во сколько нам обойдется проблема, если мы не будем отзывать модель на доработку.
Если Х превышает стоимость доработки, томы производим доработку, и аварий больше не бывает.
Если Х меньше, чем стоимость доработки, то мы доработку не производим.

Чак Паланик, "Бойцовский клуб"

Вы передёргиваете цифры.

Если у нас 0.01% операций (на самом деле цифра ниже, примерно одна из 100000) занимает 10 секунд, а оставшиеся — 5мс, то средняя latency — 5ms. И медианная latency — 5ms. И даже 99.99% персентиль — 5ms. Но при этом каждый пользователь высоконагруженной системы сталкнётся с задержками в 10с. Почему? Потому что любое устройство в продакшене обслуживает куда больше, чем 1000000 операций за своё время. Некоторые столько обслуживают за час, или даже за 10 минут.

И вот субд, которая раз в десять минут фризится на 10 секунд.

Тут же проблема не в «производители мудаки», а «покупатели не на ту метрику смотрят».
У меня в комменте не было ни одной цифры, я не мог их передернуть. У меня было только вспомненное место из художественной книги :)
Да еще и наглядно иллюстрирующее подход.

Или я что-то не понял?
«Плохая аналогия — это хуже, чем никакой аналогии». В данном случае аналогия явно хромает. Если вы увидите, что после 24-часового теста значение max — полсекунды, например, при этом — это значение пришлось на первые три секунды с момента старта 24-часового теста, то само по себе что это вам даст полезного?
Так что аналогия с автомобилем, тут скорее другая будет, что конструкторы рассчитывают, что за миллион поворотов руля только один раз произойдет поломка.

Ну так покажите распределение латентности, а не average (причем желательно не случайное чтение с очередью 32, а последовательную запись с очередью 1), и не нужны будут никакие аналогии. А так приведенные вами цифры в свете озвученных в статье проблем не значат ровным счетом ничего.

В приличных тест-сценариях принято прогревать оборудование тестовой нагрузкой некоторое время перед началом собственно измерений.
Именно это и было сделано. Но речь идет про «покажите вывод fio по max latency»
Сегодня нашел вашу статью, случайно, по ссылке в комментарии к другой статье.
Отличная статья! Очень полезно и познавательно!
Пишите еще — уверен, вам есть, чем поделиться :)
Чем поделиться есть. Времени — нет :)
Sign up to leave a comment.

Articles