Comments 58
2. Транзакции совсем не обязательно должны быть независимы, нужно просто коммитить зависимые транзакции вместе.
2PL работает совсем на другом уровне. Плюс тут же вопрос даже не в коммите. Коммит — это просто записать в журнал, что транзакция с таким-то LSN закоммичена. В WAL пишется всё подряд и однопоточно. И реализовать запись корректной последовательной цепочки всех изменений с достаточной надёжностью и хитрой обработкой параллельность пока ни в одной СУБД, видимо, не смогли.
В том же MS SQL небольшой кэш для транзакций есть (см тут), но он для другого случая, когда транзакция записывает много данных.
В любом случае статья не о том, как "можно было бы сделать СУБД", а о том "как те СУБД которые есть заставить работать". При нормальном разбиении дисков 5к-20к TPS выжать на продакшн вполне можно. С оговорками про конкретную задачу и бюджет.
Запись LSN в журнал — всего лишь одна из возможных реализаций коммита. Кроме того писать в WAL все подряд нет необходимости — это опять же всего лишь одна из возможных реализаций.
Более того, даже если допустить, что все существующие БД пишут в WAL все подряд, это совершенно никаким образом не запрещает объединить несколько обновлений WAL в 1 IO. Элементарно, в какой-то момент БД должна определить, что нужно записать в журнал. Все что нужно это просто подождать какое-то время перед тем как непосредственно выполнять эту запись и собрать данные с нескольких транзакций. Максимальная задержка может возрасти, но и параллельность при это тоже возрастет. Ничего хитрого в этом нет, простая пакетная обработка и амортизация затрат времени.
postgrespro.ru/docs/postgrespro/10/wal-configuration
К слову, буква-в-букву эти требования не выполняются почти нигде и никогда, а в распределённых системах просто никогда (CAP-теорема мешает).
CAP теорема и ACID — это ортогональные вещи, и одно другому не мешает. См. Spanner, Cockroach DB, YT. Поэтому про "никогда" я бы не говорил в таком разрезе.
А вообще, все СУБД (и распределённые и нет) достаточно «творчески» подходят к ACID, нераспределенные особенно к I — isolation (любые уровни изоляции отличные от SERIALIZABLE нарушают изоляцию), распределенные к C и D (плюс там хитрый вопрос что такое раньше/позже).
Для 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 бросите в общий котёл, то ничего этого не получите. Там полно в очереди таких, которым «только справочку получить».
Надо только напомнить, что встав на ножи с меркетингом, приходится помнить о том, чтобы вовремя менять батарейки и если уйти в отпуск, то придется прилететь в течение 48 часов, чтобы включить машины, иначе батарейки сядут.
Но в общем — то получается экономия как минимум пол миллиона долларов ( самый дешевый SAN ). Хватает на 5 позиций инженеров :) Есть за что бороться.
Да, СХД типа 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с? Остальное же быстро! (/сарказм).
Что является источником такой проблемы?
Хотя я тоже пока подожду готовых решений. Может в жизни всё и не так радужно.
Ну во-первых WAL это всё-таки не random, а seq. Во-вторых WAL может быть и не 4k за порцию, а меньше. Но я согласен, что SSD и тут может давать выбросы. И, кстати, на выделенных HDD многие СХД выжимают очень и очень хорошую производительность в этом режиме, так что упираются в каналы.
И, как заметил предыдущий комментатор, я расчитываю на прорыв Intel Optane. Посмотрите мой PS про SSD. Более того, если оптаны не обладают каким-то скрытым изъяном, то те скорости (задержки), которые они дают, делают спорным применение SAN/СХД на критичных к производительности приложениях. На VMax/VNC и подобных СХД пока еще никто не заморачивается на roundtrip до конечного приложения в десятки микросекунд.
А моё личное мнение, что для СУБД все эти «интеллектуальные» кеши уровня СХД — больше геморроя, чем пользы.
Детали тут: longwhiteclouds.com/2017/11/14/1-million-iops-in-1-vm-world-first-for-hci-with-nutanix
Вот вам миллион рандомных IOPS блоком 8K в fio при 0,11ms IO latency.
Это просто не все гиперконвергенции одинаковы :)
Это ж классика
Моя задача заключается в правильном применении секретной формулы.
Чистая арифметика.
Классическая задачка из учебника.
Если новая машина, произведенная компанией, на которую я работаю, выехала из Чикаго со скоростью шестьдесят миль в час, и тут у нее заклинило дифференциал, и она улетела в кювет, разбилась, бензобак взорвался и все, кто были в салоне, сгорели заживо, должна ли компания отозвать все проданные автомобили этой модели на доработку?
Возьмите общее количество проданных на настоящий момент автомобилей (А), умножьте на среднее количество серьезных отказов (В), а затем умножьте произведение на среднюю стоимость урегулирования иска родственников пострадавших во внесудебном порядке (С).
А х В х С = X. Вот во сколько нам обойдется проблема, если мы не будем отзывать модель на доработку.
Если Х превышает стоимость доработки, томы производим доработку, и аварий больше не бывает.
Если Х меньше, чем стоимость доработки, то мы доработку не производим.
Чак Паланик, "Бойцовский клуб"
Если у нас 0.01% операций (на самом деле цифра ниже, примерно одна из 100000) занимает 10 секунд, а оставшиеся — 5мс, то средняя latency — 5ms. И медианная latency — 5ms. И даже 99.99% персентиль — 5ms. Но при этом каждый пользователь высоконагруженной системы сталкнётся с задержками в 10с. Почему? Потому что любое устройство в продакшене обслуживает куда больше, чем 1000000 операций за своё время. Некоторые столько обслуживают за час, или даже за 10 минут.
И вот субд, которая раз в десять минут фризится на 10 секунд.
Тут же проблема не в «производители мудаки», а «покупатели не на ту метрику смотрят».
Так что аналогия с автомобилем, тут скорее другая будет, что конструкторы рассчитывают, что за миллион поворотов руля только один раз произойдет поломка.
Ну так покажите распределение латентности, а не average (причем желательно не случайное чтение с очередью 32, а последовательную запись с очередью 1), и не нужны будут никакие аналогии. А так приведенные вами цифры в свете озвученных в статье проблем не значат ровным счетом ничего.
Отличная статья! Очень полезно и познавательно!
Пишите еще — уверен, вам есть, чем поделиться :)
«20 тысяч IOPS на узел — хорошие показатели с учётом задержек в 5 мс». Для OLTP — нет