All streams
Search
Write a publication
Pull to refresh
35
0
Simonov Denis @sim_84

User

Send message

Прочитайте мой комментарий. Всё устроено не совсем так как вы думаете. Сборка мусора нужна и для UNDO в InnoDB. В Oracle не нужна, но и там если пожадничать можно попасть на "ORA-01555: Snapshot too old"

Если схема хранения в Firebird в сравнении с изначальной, из Interbase, существенно не менялась, то объеединятт в общую категорию реализации MVCC в Firebird и в Oracle с MS SQL некорректно: в изначальной реализации MVCC (котрая появилась в первой половине 00-х - до этого там MVCC вообще не было, а для обеспецения согласованности доступа к записям использовались блокировки) в Oracle и MS SQL AFAIK разницы старых копий записей с текущей хранились отдельно: в Oracle - в журнале транзакций, в MS SQL - в tempdb (сейчас, там, может, что-то ещё поменялось - я с тех пор за этой темой не следил).

Реализация MVCC везде разная. Уcловно её можно поделить по следующим критериям:

  • версии чего хранятся?

  • где хранятся версии?

Oracle единственная СУБД, которая хранит версии блоков, а не записей.

Где хранятся версии?

  • Firebird, Postgres - data files;

  • MSSQL - tempdb;

  • InnoDB, Oracle - Undo log.

Так вот автор написал не про эти особенности. Он всего лишь отметил, что реализация MVCC в большинстве СУБД расcчитана на успешный commit. В том числе и в Firebird. В Postgres это не совсем так, ибо старая и новая запись в принципе выглядят одинаково, занимают примерно одинаковое место на диске. Так что в этом он прав.

Теперь о хранении в data files и о том насколько это мешает. В реальности в Firebird не сильно мешает. Объясню почему. И так Firebird всегда хранит самую последнюю версию записи. Предыдущая версия записи во-первых в большинстве случае хранится в виде diff от главной (то есть она обычно намного компактней). Во-вторых она может хранится либо на той же странице, что и основная версия, либо на отдельной странице. Обычно Firebird оставляет примерно 20% свободного пространства на страницах данных под версии и фрагменты. Это позволяет в ряде случаев хранить старую версию на той же странице, на которой находится главная, что в свою очередь очень ускоряет реконструкцию старой версии записи и откат. Но если места недостаточно, то версия уходит на другую страницу. Такая страница называется вторичной, и она пропускается при Full Scan, если возможно. Таким образом хранение версий прямо в data files не сильно мешает эффективному чтению. Отмечу, что даже если версии записей всегда размещать на secondary page, то место на основной странице данных всё равно надо резервировать под фрагменты записей, так что это не такое уж сильное зло.

Другое дело сборка мусора... Но именно это не сильно отличается в Firebird и Postgres.

Видимо автор вернулся в C++ недавно, поэтому и офигел, когда увидел, что сделано в С++11. В общем-то я тоже не трогал С++ довольно долго (с 2008 года), и тоже немного прифигел года 4 назад, когда увидел сколько всего с тех пор изменилось. Сейчас тоже с удовольствием использую C++17, планирую перейти на C++20

Файерберд похож тут на постгресс , только вакуум делается не отдельным процессом, а его делает select когда сканит таблицу, по пути чистя старые версии

Это не совсем так. В Firebird существует фоновая и кооперативная сборка мусора. Фоновая делает сборку мусора в отдельном потоке, а кооперативная как раз таки при чтении данных запросами. И это настраивается в конфигурации. По умолчанию для SuperServer установлен комбинированный режим сборки мусора. Так что если не делать массовых удалений/обновлений, то фоновая сборка мусора уберёт весь мусор до того как вы начнёте читать данные select.

Ибо версии в оракле оптимизированны под успешный commit. (если комит прошел, то ничего делать не надо, старая версия сама умрет в undo log-е просто со временем, а вот если ролбек - надо возвращать старую версию из undo log)

Почему-то все рассуждают про commit/rollback и забывают, что старые версии могут потребоваться не только при rollback, но и долгоживущим транзакциям/курсорам в зависимости от изолированности транзакции. Так что накладные расходы могут быть не только для rollback. Я бы сказал что оракл лучше оптимизирован под короткие снимки (курсор в RC) или короткие транзакции.

Каждая запись хранит номер формата (1 байт). Формат записи содержит все необходимые сведения для декодирования записи в том числе типы и смещения. Но когда для таблицы делаешь alter более 255 раз будет больно (либо бекап рестор, либо пересоздание таблицы с полной перезаливкой данных). Впрочем не любой alter меняет формат. Это одна из особенностей фб, которая с одной стороны позволяет делать быстрый alter таблицы без ее блокировки, но с другой ограничивает полет фантазий разработчика.

Во-первых сжимаются не отдельные varchar, а запись целиком. То есть потенциально могут быть сжаты и другие типы данных если там null.

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

И в-третьих, firebird 5.0 не вводит новую мажорную ods. RLE использовался еще со времен interbase, просто сейчас его усовершенствовали. Таким образом 5 ка может работать с базами данных 4 ки.

В будущих версиях сжатие/ кодирование записи может изменится.

Microsoft SQL Server в некоторых случаях далек от SQL стандарта. В прочем ни один он, все так или иначе отклоняются от стандарта, ибо стандарт обычно формируется постфактум, когда коммерческие субд уже реализовали некоторую фичу и пропихивают ее в стандарт.

Из курсора читается обычно не одна запись. Предположим в первой записи один символ, а во второй 200, в третьей 50. Предлагаешь на каждом фетче буфер переаллоцировать? Сейчас переаллокаций не происходит вообще. Выделяется буфер фиксированного размера и в нем просто перезаписываются байтики.

Не знаю где вы этот "классический" вариант нашли. Его в Firebird с роду не было. Направление всегда указывалось для всего индекса, а не отдельного столбца.

А дополнился синтаксис предложением where, которое фильтрует ключи записей по некоторому условию. Те что не соответствуют предикату просто не будут попадать в индекс.

Это нестандартно и не переносимо, поэтому такого точно не будет, а вот поддержка хинтов Аля оракул не помешала бы.

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

Что касается смены тип с varchar(100) на varchar(200), то это происходит быстро потому что в реальности записи на диске вообще не изменяются. Просто записывается новый формат таблицы, а при извлечении данных записи со старым форматом преобразуются к новому на лету.

Я не знаю что там за PHP драйвер использован, наверное PDO. Но выполняю простейший запрос:

select 
  current_timestamp
from rdb$database

и видим:

|------------------------------------------|
| select                                   |
|   current_timestamp                      |
| from rdb$database                        |
|------------------------------------------|
| Incorrect values within SQLDA structure  |

Что обозначает, что там либо fbclient не от 4.0, либо что pdo_firebird тупо до сих пор не знает типа TIMESTAMP WITH TIME ZONE. Эхх... опять что ли придётся Pull Request пилить (((

Если уж делать, то не только для insert, а нормальный Table Value Constructor, чтобы можно было и для insert, update, delete, merge, select использовать

MERGE INTO SalesReason AS Target  
USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion'))  
       AS Source (NewName, NewReasonType)  
ON Target.Name = Source.NewName  
WHEN MATCHED THEN  
UPDATE SET ReasonType = Source.NewReasonType  
WHEN NOT MATCHED BY TARGET THEN  
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType) 
Материализованные представления вещь безусловно полезная, но их функциональность можно обеспечить существующими средствами (обычная таблица + ХП), пусть и с большими затратами и менее красиво. Поэтому у них не очень большой приоритет. А вот поддержку геоданных, например, нормально без поддержке в ядре не сделать.
Его ещё в 3.0 увеличили. Он сейчас внутри 48 битный, наружу номер выдаётся как 64 битный
Можно. Тут описан переход в том числе и с 2.5
Насчёт Pacemaker не уверен. Статья про настройку обычной синхронной/асинхронной репликации будет
Вот только не надо сравнивать внешние инструмент репликации, которые основаны на триггерах, и встроенную в ядро репликацию. Это две большие разницы.
Увы нету. На самом деле и тема UDR плохо документирована. Статья родилась на основе моих собственных исследованиях в этой области.

Information

Rating
Does not participate
Location
Рязань, Рязанская обл., Россия
Date of birth
Registered
Activity