Я работаю над ядром базы данных для Linux, и у меня есть вопрос о согласованности в отношении записи множества блоков одним системным вызовом в ядро.Я открываю устройство с помощью O_DIRECT.
Устройство записывает данные в блоках, в зависимости от аппаратного обеспечения это может быть 512, 2048 или 4096. Допустим, я буду записывать 2 блока по 512 байт за один системный вызов.Что произойдет, если система выключится ровно после того, как диск записал 1 блок?Во время нормальной работы системный вызов write () будет возвращать размер записанных данных, поэтому я мог бы сравнить и сгенерировать ошибку, когда 2 значения (по сравнению с возвращенными) не совпадают, но при отключении питания это усложняется.Это еще сложнее, поскольку ядро может отправлять запросы на запись на устройство не в том порядке, в котором вы его указали, поэтому хвост запроса может быть записан перед заголовком, и тогда у вас будет отключено питание.
Учтите, что ядро базы данных записывает журнал транзакций.Допустим, транзакция составляет около 4096 байт, движку потребуется записать 8 блоков по 512 байт.Внезапно у нас отключение питания, и только половина запроса была написана.Как базы данных справляются с этими проблемами?Я полагаю, чтобы обойти это, вам сначала нужно записать количество блоков, которые вы собираетесь записать, в другое место на диске.Как только вы получили правильное возвращаемое значение, вы можете записать свои данные.Затем, после получения подтверждения, вы должны отправить еще одну запись на диск, обновив информацию о том, что все блоки, которые вы хотели записать, были успешно записаны.Таким образом, для этого потребуется 3 операции записи, и если ядро выполняет запись на диск из других процессов, это, скорее всего, приведет к 3 поискам.Слишком неэффективно.
Я ищу способ добиться согласованной записи множества блоков с помощью только одной операции записи на диск.(одна запись () syscall) Возможно ли это?