/*!
\page oess_1__trace_file_struct	oess_1: Физическая структура trace-файла oess_1::db 

\section oess_1__trace_file_struct__intro Назначение trace-файла

oess_1::db использует trace-файлы в качестве журнала транзакции
(т.н. write-ahead-log). При фиксации транзакции все измененные страницы
хранилища сначала записываются в trace-файл и только затем в основной
файл данных. Т.о., если произойдет сбой при фиксации транзации, то
могут быть две ситуации:
- транзакция не была полностью зафиксирована в trace-файле. В этом случае
транзакция просто игнорируется и БД остается в состоянии, предшествовавшем
началу транзакции;
- транзакция была полностью зафиксирована в trace-файле но не была
зафиксирована в основном файле данных. В этом случае транзакция из
trace-файла еще раз записывается в основной файл данных.

Главным требованием к trace-файлу является обеспечение целостности информации.
Нужно иметь возможность определить, сохранена ли в trace-файле транзакция
полность и ее можно использовать для восстановления БД, или же сбой произошел
во время записи в trace-файл и описание транзакции некорректно. Так же нужно
учитывать вероятность поврежения информации уже после того, как она была
полностью сохранена в trace-файле. Например, из-за жесткого сбоя носителя
в какой-то части trace-файла может оказаться случайный "мусор".

Для выполнения этого требования вся информация в trace-файле защищается
с помощью контрольных сумм, вычисляемых по алгоритму alder32. Если после
извлечения информации из trace-файла вычисленная заново контрольная
сумма не совпадает с извлеченной из файла контрольной суммой, то описание
транзакции объявляется некорректным.

\section oess_1__trace_file_struct__struct	Структура trace-файла

Информация в trace-файл записывается разбитой на страницы одинакового размера.
Размер страницы trace-файла задается в конфигурации при создании БД. Каждая
страница имеет заголовок следующего вида:
\code
struct	trace_file_page_header_t
	{
		// Значение контрольной суммы всей страницы.
		oess_1::uint_t	m_checksum;
		// Порядковый номер этой страницы в образе всей транзакции.
		oess_1::uint_t	m_chain_ordinal;
		// Общее количество страниц в образе транзакции.
		oess_1::uint_t m_chain_size;
		// Длина исходного образа транзакции в байтах.
		oess_1::uint_t m_image_len;
		// Контрольная сумма исходного образа.
		oess_1::uint_t m_image_checksum;
		oess_1::uint_t m_reserved[ 3 ];
	};
\endcode

В поле m_checksum хранится контрольная сумма всей страницы без самого поля
m_checksum (т.е., начиная с m_chain_ordinal). В m_image_checksum находится
контрольная сумма всего образа транзакции. Такая организация позволяет
диагностировать нарушение целостности данных данных на двух стадиях:
- при извлечении страницы из trace-файла. Если оказывается, что одна из
страниц с описанием транзакции некорректна, то вся транзакция объявляется
некорректной;
- после извлечения всех страниц с описанием транзакции, после того, как
будет сформирован полный образ транзакции. Эта проверка выглядит избыточной.
Но она предназначена для защиты от случаев, когда в результате сбоя
в описание транзакции попала страница из описания другой транзакции.

Для восстановления хранилища применяется обратный просмотр trace-файлов.
Он позволяет игнорировать те страницы хранилища, которые уже были изменены
более поздними транзакциями. Для поддержки обратного просмотра trace-файла
важную роль играет то, что информация записывается в trace-файл
страницами одного размера. При восстановлении БД по trace-файлу сначала
определяется, кратен ли размер trace-файла размеру страницы. Если не кратен
(в результате сбоя последняя страница не была записана полностью, либо в
конец файла был записан мусор), то та часть, которая не является полной
страницей просто игнорируется. Далее из файла считываются страницы и
проверяется их контрольная сумма, корректные страницы обрабатываются и т.д.

\section oess_1__trace_file_struct__page_chains	Цепочки страниц в описании транзакций

Образ транзакции записывается в trace-файл в виде цепочки страниц (если не
помещается на одну страницу trace-файла целиком). При возникновении сбоя
цепочка может быть оборвана или нарушена (например, вместо какой-то из
страниц цепочки будет записан мусор). Для того, чтобы диагностировать эти
ситуации, в заголовке страницы trace-файла сохраняется информация для
идентификации цепочки:
- поле m_chain_size указывает общий размер образа транзакции в страницах;
- поле m_chain_ordinal указывает порядковый номер страницы в цепочке;
- поле m_image_len содержит размер всего образа транзакции;
- поле m_image_checksum содержит контрольную сумму всего образа транзакции.

Т.о. для корректно сформированной цепочки транзакции все последовательно
идущие страницы должны содержать одинаковые значения полей
m_chain_size, m_image_len, m_image_checksum. Так же для них значение
поля m_chain_ordinal должно последовательно увеличиваться от нуля до
(m_chain_size - 1).

Это правило определяет алгоритм обработки цепочки страниц при обратном
просмотре trace-файла:
- если обнаружена страница, у которой m_chain_ordinal равен
(m_chain_size - 1), то эта страница является хвостом цепочки. Сохраняются
значения m_chain_size, m_image_len, m_image_checksum;
- этой странице должны предшествовать (m_chain_size - 1) страниц с
последовательно уменьшающемся до нуля m_chain_ordinal и с такими же
значениями m_chain_size, m_image_len, m_image_checksum. Если обнаруживается
страница, которая не удовлетворяет этим условиям, то вся транзакция
объявляется поврежденной и поиск транзакции происходит заново.

Если транзакция извлекается полностью, то для ее образа подсчитывается
контрольная сумма. Если полученная контрольная сумма не совпадает с
сохраненным значением m_image_checksum, то транзакция так же объявляется
некорректной.

*/

