From a008b0b16f6060c3adb25f183e1148ed2442bfb0 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Fri, 9 Aug 2019 21:36:02 +0300 Subject: [PATCH] mdbx: description of lck-implementation for Linux. Change-Id: I8fe5f49a19e5cc61198ecd96dfe479d0e17c10a5 --- src/lck-linux.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/lck-linux.c b/src/lck-linux.c index 5eeaccc6..750d42ca 100644 --- a/src/lck-linux.c +++ b/src/lck-linux.c @@ -72,6 +72,41 @@ static __cold __attribute__((destructor)) void mdbx_global_destructor(void) { /*----------------------------------------------------------------------------*/ /* lck */ +/* Описание реализации блокировок для Linux: + * + * lck-файл отображается в память, в нём организуется таблица читателей и + * размещаются совместно используемые posix-мьютексы (futex). Посредством + * этих мьютексов (см struct MDBX_lockinfo) реализуются: + * - Блокировка таблицы читателей для регистрации, + * т.е. функции mdbx_rdt_lock() и mdbx_rdt_unlock(). + * - Блокировка БД для пишущих транзакций, + * т.е. функции mdbx_txn_lock() и mdbx_txn_unlock(). + * + * Остальной функционал реализуется отдельно посредством файловых блокировок: + * - Первоначальный захват БД в режиме exclusive/shared и последующий перевод + * в операционный режим, функции mdbx_lck_seize() и mdbx_lck_downgrade(). + * - Проверка присутствие процессов-читателей, + * т.е. функции mdbx_rpid_set(), mdbx_rpid_clear() и mdbx_rpid_check(). + * + * Используется два вида файловых блокировок flock() и fcntl(F_SETLK), + * как для lck-файла, так и для основного файла БД: + * - Для контроля процессов-читателей используются однобайтовые + * range-блокировки lck-файла посредством fcntl(F_SETLK). При этом + * в качестве позиции используется pid процесса-читателя. + * - Для первоначального захвата и shared/exlcusive блокировок используется + * комбинация flock() и fcntl(F_SETLK) блокировки одного байта lck-файла + * в нулевой позиции (нулевая позиция не используется механизмом контроля + * процессов-читателей, так как pid пользовательского процесса в Linux + * всегда больше 0). + * - Кроме этого, flock() блокировка основного файла БД используется при работе + * в режимах без lck-файла, как в в read-only, так и в эксклюзивном. + * - Блокировки flock() и fcntl(F_SETLK) в Linux работают независимо. Поэтому + * их комбинирование позволяет предотвратить совместное использование БД + * через NFS, что позволяет fcntl(F_SETLK), одновременно защитившись + * от проблем не-аторманости flock() при переходе между эксклюзивным + * и атомарным режимами блокировок. + */ + #ifndef OFF_T_MAX #define OFF_T_MAX \ ((sizeof(off_t) > 4 ? INT64_MAX : INT32_MAX) & ~(size_t)0xffff)