/dev/null is an ACID compliant database 🔥 Горячее 💬 Длинная дискуссия
/dev/null в Unix-системах с юмором представлена как база данных, полностью соответствующая принципам ACID. Атомарность обеспечивается тем, что любые записанные данные либо полностью исчезают, либо не записываются вовсе. Согласованность поддерживается инвариантом пустоты — файл всегда остаётся в одинаковом состоянии, независимо от операций. Изолированность проявляется в том, что множественные процессы могут одновременно писать в /dev/null без конфликтов, так как данные никогда не сохраняются. Долговечность гарантирует, что после сбоя система сохраняет своё главное свойство — полное отсутствие данных.
Эта шуточная статья подчёркивает, что /dev/null идеально соответствует всем требованиям ACID-совместимой базы данных, с единственным недостатком — нулевым объёмом хранения. Автор иронизирует, что для расширения пространства нужно обратиться в "корпоративные продажи", которые на самом деле являются им самим. Этот пример демонстрирует, как технические концепции можно рассматривать с неожиданной и забавной стороны.
Комментарии (168)
- Обсуждение вокруг /dev/null как "база данных" выявило, что это скорее метафора, чем реальная технология, и подчеркнуло важность различать хранилище и СУБД.
- Участники обсуждали, что /dev/null не является базой данных, но при этом подчеркнули, что он обеспечивает ACID-свойства и масштабируемость.
- Были подняты вопросы о масштабируемости, отказоустойчивости и соответствии с ACID, а также о том, что такое "база данных" и как она отличается от просто носителя.
- Участники также обсудили, что /dev/null действительно обеспечивает высокую доступность и согласованность, но не является базой данных в строгом смысле.
Build your own database 🔥 Горячее
Статья представляет пошаговое руководство по созданию простой key-value базы данных с нуля. Начальный подход предполагает хранение данных в обычном файле, где каждая строка содержит пару ключ-значение. Однако такой метод неэффективен для обновлений и удалений, так как требует перемещения всех последующих данных. Решением становится использование append-only файла, где записи являются неизменяемыми, а обновления и удаления обрабатываются через добавление новых записей и специальные "надгробные" метки.
Основные проблемы этого подхода — неограниченный рост файла и медленный поиск, так как для нахождения ключа может потребоваться просмотреть все записи. В примере показано, что файл базы данных может содержать множество записей, но только небольшая часть из них представляет актуальные данные, в то время как остальные являются удаленными или устаревшими. Для решения проблемы роста файла необходим механизм периодического "сжатия", который бы удалял нерелевантные данные и уменьшал размер файла.
Комментарии (78)
- Обсуждение охватывает вопросы от дизайна и UX до фундаментальных концепций, таких как ACID, индексы и LSM-деревья, и даже до того, что не стоит писать свою СУБД, если можно использовать готовую.
- Участники обмениваются советами по инструментам вроде riak_core и Bitcask, обсуждают проблемы репликации и отказоустойчивости, и делятся личными историями о том, как они писали свои собственные базы данных.
- Некоторые комментарии поднимают вопросы о правильном подходе к обучению и документации, а также о том, как сделать так, чтобы читатели могли бы легко следить за обсуждением и не теряли нитку.
- Некоторые участники делятся ссылками на полезные ресурсы, такие как "Designing Data-Intensive Applications" и "Build Your Own Database".
- Некоторые участники поднимают вопросы о том, как лучше всего подавать контент, чтобы он был интерактивным и в то же время не перегружал читателя, и обсуждают, как лучше всего структурировать и визуализировать информацию.
- Некоторые участники делятся личными историями о том, как они писали свои собственные базы данных, и обсуждают, какие вызовы они встретились и как они их преодолели.
SQLite (with WAL) doesn't do `fsync` on each commit under default settings
SQLite в режиме WAL по умолчанию не вызывает fsync после каждого COMMIT.
- Параметр
PRAGMA synchronous=NORMAL(значение по умолчанию) не гарантирует сохранность транзакции при внезапном отключении питания. - В этом режиме
fsyncвыполняется лишь:
– перед контрольной точкой WAL;
– после завершения контрольной точки;
– при повторном использовании WAL-файла. - Для жёсткой гарантии сохранности нужно:
Тогда после каждогоPRAGMA synchronous = FULL;COMMITбудет вызыватьсяfsyncWAL-файла.
Комментарии (70)
- По умолчанию SQLite компилируется с
synchronous=FULL, но дистрибутивы или обёртки могут изменить это. - Не стоит полагаться на умолчания — явно задавайте параметры, особенно если нужна надёжность.
- WAL-режим ускоряет работу, но требует общей памяти и нарушает ACID для attached БД.
- На macOS для гарантированной надёжности нужен
F_FULLFSYNC, но Apple использует собственную реализацию. - Litestream рекомендует
synchronous=NORMAL, так как и так делает регулярные бэкапы.
ClickHouse matches PG for single-row UPDATEs and 4000 x faster for bulk UPDATEs
ClickHouse vs PostgreSQL: UPDATE-скорость
- Коротко: на одном железе ClickHouse догоняет PostgreSQL в одиночных UPDATE и в 4 000 раз быстрее при массовых.
- Почему: колоночное хранилище + параллелизм ClickHouse выигрывает у строкового PostgreSQL при поиске и перезаписи миллионов строк.
- Но: PostgreSQL всегда транзакционен; ClickHouse — нет, поэтому сравнение по «родным» режимам, а не по ACID.
Что мерили
- 1 строка:
UPDATE orders SET status='shipped' WHERE id=1234567 - 1 млн строк:
UPDATE orders SET discount=0.1 WHERE order_date<'2023-01-01'
Аппаратура
- c6i.8xlarge (32 vCPU, 64 ГБ RAM, gp3 SSD)
- PostgreSQL 16.4 (дефолт +
fillfactor=90,checkpoint_timeout=30 min) - ClickHouse 25.7 (дефолт)
Результаты
| метрика | PostgreSQL | ClickHouse |
|---|---|---|
| 1 строка, мс | 0.12 | 0.11 |
| 1 млн строк, сек | 120 | 0.03 |
| CPU, % | 100 | 2800 |
| чтение, ГБ | 30 | 0.8 |
Почему так
- Поиск: ClickHouse читает только нужные колонки, фильтрует за счёт индексов и распараллеливает на все ядра.
- Запись: обе СУБД пишут новые версии строк (MVCC), но PostgreSQL переписывает целые страницы, а ClickHouse — только изменённые куски колонок.
- Фоновая работа: PostgreSQL ждёт checkpoint’а, ClickHouse сразу сортирует и сжимает куски.
Когда выбирать
- Нужны транзакции и row-level locks → PostgreSQL.
- Нужны массовые обновления аналитических данных → ClickHouse.
Код и данные
Комментарии (33)
- ClickHouse показывает огромный выигрыш в скорости обновлений, но это «яблоки-к-апельсинам»: PostgreSQL по умолчанию полностью транзакционен, а CH — нет.
- Если данные можно терять или обновления редки, CH идеален; если нужна строгая согласованность, PostgreSQL остаётся безальтернативным.
- Многие пользователи CH считают обновления адом: приходится использовать ReplacingMergeTree, версии или event-sourcing; прямых UPDATE-ов до недавнего времени вообще не было.
- Часть комментаторов предлагает сравнивать CH с DuckDB, Vertica или ScyllaDB, а также настроить PostgreSQL (synchronous_commit = off, COPY) для более честного бенчмарка.
- Авторы поста подчёркивают: цель не «победить» PostgreSQL, а показать, как каждая СУБД решает задачу в своей «родной» модели исполнения.