1. Согласованное чтение
2. Восстановление данных
3. Принцип кэширования блоков в память при чтении
4. Парсинг запросов
5. RAC - кластер экземпляров oracle
6. Блокировки и защелки
1. согласованное чтение
общий принцип:
a. транзакция 1 изменяет данные:
* в буферный кэш скидывается грязный блок
** в блоке данных записывается список недавних транзакий ITL (включая сейчас выполняющуюся)
** если транзакция сейчас выполняется, то также проставляется признак блокировки строки в блоке
* процесс lgwr пишет:
** в redo журнал повтора - новое значение, новый scn, список ITL
** в undo журнал отката - старое значение и старый scn
* процесс dbwr пишет:
** асинхронно с задержкой записывает данные в блок базы
*** сразу после commit записывается не более 30% данных
*** остальная часть записывается отложенно при следующем select из строк этой таблицы.
Детектировать можно через события "db block change, consisten gets - examination"
Т.е. не стоит удивляться, что первый select после большого update будет выполняться очень долго.
b. транзакция 2 читает данные:
* считываются данные из буферного кэша или напрямую с диска
* просматривается список ITL на наличие незавершенных транзакций
* в любом случае (не зависимо от ITL) сверяется SCN транзакции и SCN блока (ITL незавершенной транзакции)
** если SCN блока/ITL оказывается больше запрашиваемого, то данные берутся из сегментов отката UNDO через ссылку из ITL
*** поиск по ITL может продолжиться и дальше рекурсивно, если SCN запроса опять меньше SCN из undo
*** если данные в undo не находятся, то это является причиной ошибки "snapshot too old"
* в случае недавнего обновления блока, строка может оказаться помеченной как сейчас обновляемая и со старым SCN в списке ITL выполняется операция отложенная очистка:
** берутся данные из UNDO сегмента, смотрится, что транзакция подтверждена
** сбрасывается флаг блокировки в строке блока и ITL (что повторно генерирует redo логи при select таблицы)
** в случае отсутствия блока в буферном кэше и чтения с диска дополнительно изменяется номер SCN на максимальный (т.к. отсутствие блока в кэше говорит об однозначно последней версии на диске)
Примечание: как многоверсионность сделана в Postgree:
Устаревшие строки (после delete/update) хранятся в том же месте, где основная таблица. Определение версии используются дополнительные идентификаторы в самой строке. При update выполняются действия: * Создается строка с новыми данными * От старой строки создается указатель на новую * У старой строки проставляется: ** xmin - идентификатор транзакции от старой версии строки ** xmax - идентификатор транзакции от новой версии строки Т.е. при select читаются строки у которых нет новой версии (xmax), т.е. актуальные сейчас строки. Если в этот момент идет модификация, то старые строки будут существовать до полного окончания, а после будут очищены фоновым vacuum. + быстрое чтение, без обращения к стороннему логу - любое изменение генерирует новую строку, из-за чего нужно перестраивать все индексы на таблице, даже если изменялось поле не из индексов - большой поток изменений в репликации