8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 00:03:03 +01:00

Implement CORE-1381 : Allow Firebird to not use filesystem cache for database files

Implementation in unix.cpp is experimental and commented out (calls of posix_fadvice) until testing
Cleanup in winnt.cpp : removed fil_force_write_desc
This commit is contained in:
hvlad 2007-07-25 18:44:54 +00:00
parent 27da32ced8
commit 6cd3900a9f
7 changed files with 85 additions and 55 deletions

View File

@ -125,7 +125,8 @@ const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
{TYPE_BOOLEAN, "Redirection", (ConfigValue) false},
{TYPE_BOOLEAN, "OldColumnNaming", (ConfigValue) false}, // if true use old style concatenation
{TYPE_STRING, "Authentication", (ConfigValue) AmMixed}, // use native, trusted or mixed
{TYPE_INTEGER, "DatabaseGrowthIncrement", (ConfigValue) 128 * 1048576} // bytes
{TYPE_INTEGER, "DatabaseGrowthIncrement", (ConfigValue) 128 * 1048576}, // bytes
{TYPE_INTEGER, "MaxFileSystemCache", (ConfigValue) 65536} // page buffers
};
/******************************************************************************
@ -558,3 +559,8 @@ int Config::getDatabaseGrowthIncrement()
{
return (int) sysConfig.values[KEY_DATABASE_GROWTH_INCREMENT];
}
int Config::getMaxFileSystemCache()
{
return (int) sysConfig.values[KEY_MAX_FILESYSTEM_CACHE];
}

View File

@ -119,7 +119,8 @@ class Config
KEY_REDIRECTION, // 44
KEY_OLD_COLUMN_NAMING, // 45
KEY_AUTH_METHOD, // 46
KEY_DATABASE_GROWTH_INCREMENT // 47
KEY_DATABASE_GROWTH_INCREMENT, // 47
KEY_MAX_FILESYSTEM_CACHE // 48
};
public:
@ -375,6 +376,8 @@ public:
static const char *getAuthMethod();
static int getDatabaseGrowthIncrement();
static int getMaxFileSystemCache();
};
namespace Firebird {

View File

@ -90,8 +90,7 @@ class jrd_file : public pool_alloc_rpt<SCHAR, type_fil>
ULONG fil_max_page; /* Maximum page number in file */
USHORT fil_sequence; /* Sequence number of file */
USHORT fil_fudge; /* Fudge factor for page relocation */
SLONG fil_desc;
SLONG fil_force_write_desc; /* Handle of force write open */
HANDLE fil_desc;
//int *fil_trace; /* Trace file, if any */
Firebird::Mutex fil_mutex;
#ifdef SUPERSERVER_V2
@ -106,7 +105,8 @@ class jrd_file : public pool_alloc_rpt<SCHAR, type_fil>
const USHORT FIL_force_write = 1;
const USHORT FIL_force_write_init = 2;
const USHORT FIL_no_fs_cache = 2; // not using file system cache
const USHORT FIL_readonly = 4; // file opened in readonly mode
/* Physical IO trace events */

View File

@ -40,7 +40,7 @@ Jrd::jrd_file* PIO_create(Jrd::Database*, const Firebird::PathName&, bool, bool,
bool PIO_expand(const TEXT*, USHORT, TEXT*, size_t);
void PIO_extend(Jrd::jrd_file*, const ULONG, const USHORT);
void PIO_flush(Jrd::jrd_file*);
void PIO_force_write(Jrd::jrd_file*, bool);
void PIO_force_write(Jrd::jrd_file*, bool, bool);
ULONG PIO_get_number_of_pages(const Jrd::jrd_file*, const USHORT);
void PIO_header(Jrd::Database*, SCHAR*, int);
Jrd::jrd_file* PIO_open(Jrd::Database*, const Firebird::PathName&, bool,

View File

@ -236,6 +236,8 @@ jrd_file* PIO_create(Database* dbb, const Firebird::PathName& string, bool overw
isc_arg_gds, isc_io_create_err, isc_arg_unix, errno, 0);
}
// posix_fadvise(desc, 0, 0, POSIX_FADV_RANDOM);
/* File open succeeded. Now expand the file name. */
Firebird::PathName expanded_name(string);
@ -318,7 +320,7 @@ void PIO_flush(jrd_file* main_file)
}
void PIO_force_write(jrd_file* file, bool flag)
void PIO_force_write(jrd_file* file, bool flag, bool bNotUseFSCache)
{
/**************************************
*
@ -551,6 +553,8 @@ jrd_file* PIO_open(Database* dbb,
}
}
// posix_fadvise(desc, 0, 0, POSIX_FADV_RANDOM);
#ifdef SUPPORT_RAW_DEVICES
/* At this point the file has successfully been opened in either RW or RO
* mode. Check if it is a special file (i.e. raw block device) and if a
@ -668,6 +672,7 @@ bool PIO_read(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* statu
}
}
// posix_fadvise(file->desc, offset, size, POSIX_FADV_NOREUSE);
return true;
}
@ -743,6 +748,7 @@ bool PIO_write(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* stat
THD_IO_MUTEX_UNLOCK(file->fil_mutex);
#endif
// posix_fadvise(file->desc, offset, size, POSIX_FADV_DONTNEED);
return true;
}

View File

@ -68,7 +68,7 @@ const USHORT OS_CHICAGO = 2;
#ifdef SUPERSERVER_V2
static void release_io_event(jrd_file*, OVERLAPPED*);
#endif
static bool MaybeCloseFile(SLONG*);
static bool maybe_close_file(HANDLE&);
static jrd_file* seek_file(jrd_file*, BufferDesc*, ISC_STATUS*, OVERLAPPED*, OVERLAPPED**);
static jrd_file* setup_file(Database*, const Firebird::PathName&, HANDLE);
static bool nt_error(TEXT*, const jrd_file*, ISC_STATUS, ISC_STATUS*);
@ -142,8 +142,7 @@ void PIO_close(jrd_file* main_file)
**************************************/
for (jrd_file* file = main_file; file; file = file->fil_next)
{
if (MaybeCloseFile(&file->fil_desc) ||
MaybeCloseFile(&file->fil_force_write_desc))
if (maybe_close_file(file->fil_desc))
{
#ifdef SUPERSERVER_V2
for (int i = 0; i < MAX_FILE_IO; i++)
@ -268,8 +267,7 @@ void PIO_extend(jrd_file* main_file, const ULONG extPages, const USHORT pageSize
{
const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages);
HANDLE hFile = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE hFile = file->fil_desc;
LARGE_INTEGER newSize;
newSize.QuadPart = (ULONGLONG) (filePages + extendBy) * pageSize;
@ -306,7 +304,7 @@ void PIO_flush(jrd_file* main_file)
{
file->fil_mutex.enter();
}
FlushFileBuffers((HANDLE) file->fil_desc);
FlushFileBuffers(file->fil_desc);
if (ostype == OS_CHICAGO)
{
file->fil_mutex.leave();
@ -315,7 +313,7 @@ void PIO_flush(jrd_file* main_file)
}
void PIO_force_write(jrd_file* file, bool flag)
void PIO_force_write(jrd_file* file, bool bForceWrite, bool bNotUseFSCache)
{
/**************************************
*
@ -329,22 +327,25 @@ void PIO_force_write(jrd_file* file, bool flag)
**************************************/
const bool bOldForce = (file->fil_flags & FIL_force_write) != 0;
const bool bOldNotUseCache = (file->fil_flags & FIL_no_fs_cache) != 0;
if ((flag && !bOldForce) || (!flag && bOldForce)) {
SLONG& hOld = flag ? file->fil_desc : file->fil_force_write_desc;
HANDLE& hNew = reinterpret_cast<HANDLE&>(flag ? file->fil_force_write_desc : file->fil_desc);
const int force = flag ? FILE_FLAG_WRITE_THROUGH : 0;
if (bForceWrite != bOldForce || bNotUseFSCache != bOldNotUseCache)
{
const int force = bForceWrite ? FILE_FLAG_WRITE_THROUGH : 0;
const int fsCache = bNotUseFSCache ? FILE_FLAG_NO_BUFFERING : 0;
const int writeMode = (file->fil_flags & FIL_readonly) ? 0 : GENERIC_WRITE;
MaybeCloseFile(&hOld);
hNew = CreateFile(file->fil_string,
GENERIC_READ | GENERIC_WRITE,
HANDLE &hFile = file->fil_desc;
maybe_close_file(hFile);
hFile = CreateFile(file->fil_string,
GENERIC_READ | writeMode,
g_dwShareFlags,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | force | g_dwExtraFlags,
FILE_ATTRIBUTE_NORMAL | force | fsCache | g_dwExtraFlags,
0);
if (hNew == INVALID_HANDLE_VALUE)
if (hFile == INVALID_HANDLE_VALUE)
{
ERR_post(isc_io_error,
isc_arg_string,
@ -358,12 +359,18 @@ void PIO_force_write(jrd_file* file, bool flag)
0);
}
if (flag) {
file->fil_flags |= (FIL_force_write | FIL_force_write_init);
if (bForceWrite) {
file->fil_flags |= FIL_force_write;
}
else {
file->fil_flags &= ~FIL_force_write;
}
if (bNotUseFSCache) {
file->fil_flags |= FIL_no_fs_cache;
}
else {
file->fil_flags &= ~FIL_no_fs_cache;
}
}
}
@ -386,8 +393,7 @@ void PIO_header(Database* dbb, SCHAR * address, int length)
**************************************/
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
jrd_file* file = pageSpace->file;
HANDLE desc = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE desc = file->fil_desc;
OVERLAPPED overlapped, *overlapped_ptr;
if (ostype == OS_CHICAGO)
@ -478,6 +484,7 @@ jrd_file* PIO_open(Database* dbb,
*
**************************************/
const TEXT* ptr = (string.hasData() ? string : file_name).c_str();
bool bReadOnly = false;
if (!ISC_is_WinNT())
share_delete = false;
@ -520,6 +527,7 @@ jrd_file* PIO_open(Database* dbb,
* the Header Page flag setting to make sure that the database is set
* ReadOnly.
*/
bReadOnly = true;
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
if (!pageSpace->file)
dbb->dbb_flags |= DBB_being_opened_read_only;
@ -529,6 +537,9 @@ jrd_file* PIO_open(Database* dbb,
jrd_file *file;
try {
file = setup_file(dbb, string, desc);
if (bReadOnly)
file->fil_flags |= FIL_readonly;
}
catch (const Firebird::Exception&) {
CloseHandle(desc);
@ -557,8 +568,7 @@ bool PIO_read(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* statu
if (!(file = seek_file(file, bdb, status_vector, &overlapped, &overlapped_ptr)))
return false;
HANDLE desc = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE desc = file->fil_desc;
if (dbb->dbb_encrypt_key.hasData())
{
@ -672,8 +682,7 @@ bool PIO_read_ahead(Database* dbb,
--pages;
}
HANDLE desc = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE desc = file->fil_desc;
DWORD actual_length;
if (ReadFile( desc,
@ -779,8 +788,7 @@ bool PIO_write(jrd_file* file, BufferDesc* bdb, Ods::pag* page, ISC_STATUS* stat
return false;
}
HANDLE desc = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE desc = file->fil_desc;
if (dbb->dbb_encrypt_key.hasData()) {
SLONG spare_buffer[MAX_PAGE_SIZE / sizeof(SLONG)];
@ -845,8 +853,7 @@ ULONG PIO_get_number_of_pages(const jrd_file* file, const USHORT pagesize)
* Compute number of pages in file, based only on file size.
*
**************************************/
HANDLE hFile = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE hFile = file->fil_desc;
DWORD dwFileSizeHigh;
const DWORD dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
@ -930,8 +937,7 @@ static jrd_file* seek_file(jrd_file* file,
if (ostype == OS_CHICAGO) {
file->fil_mutex.enter();
HANDLE desc = (HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
HANDLE desc = file->fil_desc;
if (SetFilePointer(desc,
(LONG) liOffset.LowPart,
@ -993,9 +999,7 @@ static jrd_file* setup_file(Database* dbb,
/* Allocate file block and copy file name string */
jrd_file* file = FB_NEW_RPT(*dbb->dbb_permanent, file_name.length() + 1) jrd_file;
file->fil_desc = reinterpret_cast<SLONG>(desc);
file->fil_force_write_desc =
reinterpret_cast<SLONG>(INVALID_HANDLE_VALUE);
file->fil_desc = desc;
file->fil_length = file_name.length();
file->fil_max_page = (ULONG) -1;
#ifdef SUPERSERVER_V2
@ -1019,7 +1023,7 @@ static jrd_file* setup_file(Database* dbb,
/* Build unique lock string for file and construct lock block */
BY_HANDLE_FILE_INFORMATION file_info;
GetFileInformationByHandle((HANDLE) desc, &file_info);
GetFileInformationByHandle(desc, &file_info);
UCHAR lock_string[32];
UCHAR* p = lock_string;
@ -1088,7 +1092,7 @@ static jrd_file* setup_file(Database* dbb,
return file;
}
static bool MaybeCloseFile(SLONG* pFile)
static bool maybe_close_file(HANDLE& hFile)
{
/**************************************
*
@ -1101,10 +1105,10 @@ static bool MaybeCloseFile(SLONG* pFile)
*
**************************************/
if (pFile && (HANDLE)*pFile != INVALID_HANDLE_VALUE)
if (hFile != INVALID_HANDLE_VALUE)
{
CloseHandle((HANDLE)*pFile);
*pFile = (SLONG) INVALID_HANDLE_VALUE;
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return true;
}
return false;

View File

@ -498,8 +498,10 @@ USHORT PAG_add_file(const TEXT* file_name, SLONG start)
jrd_file* next = file->fil_next;
if (dbb->dbb_flags & DBB_force_write)
PIO_force_write(next, true);
if (dbb->dbb_flags & (DBB_force_write | DBB_no_fs_cache))
PIO_force_write(next,
dbb->dbb_flags & DBB_force_write,
dbb->dbb_flags & DBB_no_fs_cache);
WIN window(DB_PAGE_SPACE, next->fil_min_page);
header_page* header = (header_page*) CCH_fake(tdbb, &window, 1);
@ -1246,12 +1248,17 @@ void PAG_header(bool info)
0);
}
if (header->hdr_flags & hdr_force_write) {
dbb->dbb_flags |= DBB_force_write;
const bool bUseFSCache = dbb->dbb_bcb->bcb_count < Config::getMaxFileSystemCache();
if (header->hdr_flags & hdr_force_write || !bUseFSCache) {
dbb->dbb_flags |=
(header->hdr_flags & hdr_force_write ? DBB_force_write : 0) |
(bUseFSCache ? 0 : DBB_no_fs_cache);
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
if (!(header->hdr_flags & hdr_read_only))
PIO_force_write(pageSpace->file, true);
PIO_force_write(pageSpace->file,
(dbb->dbb_flags & DBB_force_write) && !(header->hdr_flags & hdr_read_only),
dbb->dbb_flags & DBB_no_fs_cache);
}
if (header->hdr_flags & hdr_no_reserve)
@ -1599,8 +1606,10 @@ void PAG_init2(USHORT shadow_number)
file->fil_next = PIO_open(dbb, file_name, false, file_name, false);
file->fil_max_page = last_page;
file = file->fil_next;
if (dbb->dbb_flags & DBB_force_write)
PIO_force_write(file, true);
if (dbb->dbb_flags & (DBB_force_write | DBB_no_fs_cache))
PIO_force_write(file,
dbb->dbb_flags & DBB_force_write,
dbb->dbb_flags & DBB_no_fs_cache);
file->fil_min_page = last_page + 1;
file->fil_sequence = sequence++;
}
@ -1754,12 +1763,14 @@ void PAG_set_force_write(Database* dbb, SSHORT flag)
PageSpace* pageSpace =
dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
for (jrd_file* file = pageSpace->file; file; file = file->fil_next) {
PIO_force_write(file, flag != 0);
PIO_force_write(file, flag != 0,
dbb->dbb_flags & DBB_no_fs_cache);
}
for (Shadow* shadow = dbb->dbb_shadow; shadow; shadow = shadow->sdw_next) {
for (jrd_file* file = shadow->sdw_file; file; file = file->fil_next)
PIO_force_write(file, flag != 0);
PIO_force_write(file, flag != 0,
dbb->dbb_flags & DBB_no_fs_cache);
}
}