mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:40:38 +01:00
Remove FileSystemCacheSize setting (#7984)
This commit is contained in:
parent
55fd220006
commit
fe82a29d13
@ -287,34 +287,6 @@
|
|||||||
#UseFileSystemCache = true
|
#UseFileSystemCache = true
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# File system cache size
|
|
||||||
#
|
|
||||||
# This setting controls the maximum amount of RAM used by Windows file system
|
|
||||||
# cache on a 64-bit Windows host. It has no effect for Unix hosts in this release yet.
|
|
||||||
#
|
|
||||||
# Note that the lowest number presently supported is 10%, and the highest number
|
|
||||||
# is 95%; numbers outside these limits will apply a default value of 30%.
|
|
||||||
#
|
|
||||||
# If the cache size has already been selected when the engine starts, the host
|
|
||||||
# setting will not be changed. Thus you may need to reboot the host for the
|
|
||||||
# change of this setting to have effect.
|
|
||||||
#
|
|
||||||
# To leave host caching settings unchanged, set this parameter to 0. This is
|
|
||||||
# the default parameter value.
|
|
||||||
#
|
|
||||||
# Security note
|
|
||||||
# To adjust the setting, the engine needs the SeIncreaseQuotaPrivilege right.
|
|
||||||
# Built-in service accounts and administrators have it by default. The installer
|
|
||||||
# grants this right to the Firebird service account. If the engine fails to adjust
|
|
||||||
# the cache size setting, it will log a warning message to the firebird.log and
|
|
||||||
# continue.
|
|
||||||
#
|
|
||||||
# Type: integer, measured in % of total physical RAM
|
|
||||||
#
|
|
||||||
#FileSystemCacheSize = 0
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Remove protection against opening databases on NFS mounted volumes on
|
# Remove protection against opening databases on NFS mounted volumes on
|
||||||
# Linux/Unix and SMB/CIFS volumes on Windows.
|
# Linux/Unix and SMB/CIFS volumes on Windows.
|
||||||
|
@ -154,7 +154,6 @@ enum ConfigKey
|
|||||||
KEY_DATABASE_GROWTH_INCREMENT,
|
KEY_DATABASE_GROWTH_INCREMENT,
|
||||||
KEY_TRACE_CONFIG,
|
KEY_TRACE_CONFIG,
|
||||||
KEY_MAX_TRACELOG_SIZE,
|
KEY_MAX_TRACELOG_SIZE,
|
||||||
KEY_FILESYSTEM_CACHE_SIZE,
|
|
||||||
KEY_PLUG_PROVIDERS,
|
KEY_PLUG_PROVIDERS,
|
||||||
KEY_PLUG_AUTH_SERVER,
|
KEY_PLUG_AUTH_SERVER,
|
||||||
KEY_PLUG_AUTH_CLIENT,
|
KEY_PLUG_AUTH_CLIENT,
|
||||||
@ -257,7 +256,6 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
|||||||
{TYPE_INTEGER, "DatabaseGrowthIncrement", false, 128 * 1048576}, // bytes
|
{TYPE_INTEGER, "DatabaseGrowthIncrement", false, 128 * 1048576}, // bytes
|
||||||
{TYPE_STRING, "AuditTraceConfigFile", true, ""}, // location of audit trace configuration file
|
{TYPE_STRING, "AuditTraceConfigFile", true, ""}, // location of audit trace configuration file
|
||||||
{TYPE_INTEGER, "MaxUserTraceLogSize", true, 10}, // maximum size of user session trace log
|
{TYPE_INTEGER, "MaxUserTraceLogSize", true, 10}, // maximum size of user session trace log
|
||||||
{TYPE_INTEGER, "FileSystemCacheSize", true, 0}, // percent
|
|
||||||
{TYPE_STRING, "Providers", false, "Remote, " CURRENT_ENGINE ", Loopback"},
|
{TYPE_STRING, "Providers", false, "Remote, " CURRENT_ENGINE ", Loopback"},
|
||||||
{TYPE_STRING, "AuthServer", false, "Srp256"},
|
{TYPE_STRING, "AuthServer", false, "Srp256"},
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
@ -570,8 +568,6 @@ public:
|
|||||||
|
|
||||||
CONFIG_GET_PER_DB_INT(getDatabaseGrowthIncrement, KEY_DATABASE_GROWTH_INCREMENT);
|
CONFIG_GET_PER_DB_INT(getDatabaseGrowthIncrement, KEY_DATABASE_GROWTH_INCREMENT);
|
||||||
|
|
||||||
CONFIG_GET_GLOBAL_KEY(FB_UINT64, getFileSystemCacheSize, KEY_FILESYSTEM_CACHE_SIZE, getInt);
|
|
||||||
|
|
||||||
CONFIG_GET_GLOBAL_STR(getAuditTraceConfigFile, KEY_TRACE_CONFIG);
|
CONFIG_GET_GLOBAL_STR(getAuditTraceConfigFile, KEY_TRACE_CONFIG);
|
||||||
|
|
||||||
CONFIG_GET_GLOBAL_KEY(FB_UINT64, getMaxUserTraceLogSize, KEY_MAX_TRACELOG_SIZE, getInt);
|
CONFIG_GET_GLOBAL_KEY(FB_UINT64, getMaxUserTraceLogSize, KEY_MAX_TRACELOG_SIZE, getInt);
|
||||||
|
@ -109,14 +109,6 @@ static bool maybeCloseFile(HANDLE&);
|
|||||||
static jrd_file* seek_file(jrd_file*, BufferDesc*, OVERLAPPED*);
|
static jrd_file* seek_file(jrd_file*, BufferDesc*, OVERLAPPED*);
|
||||||
static jrd_file* setup_file(Database*, const Firebird::PathName&, HANDLE, bool, bool);
|
static jrd_file* setup_file(Database*, const Firebird::PathName&, HANDLE, bool, bool);
|
||||||
static bool nt_error(const TEXT*, const jrd_file*, ISC_STATUS, FbStatusVector* const);
|
static bool nt_error(const TEXT*, const jrd_file*, ISC_STATUS, FbStatusVector* const);
|
||||||
static void adjustFileSystemCacheSize();
|
|
||||||
|
|
||||||
struct AdjustFsCache
|
|
||||||
{
|
|
||||||
static void init() { adjustFileSystemCacheSize(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static InitMutex<AdjustFsCache> adjustFsCacheOnce("AdjustFsCacheOnce");
|
|
||||||
|
|
||||||
inline static DWORD getShareFlags(const bool shared_access, bool temporary = false)
|
inline static DWORD getShareFlags(const bool shared_access, bool temporary = false)
|
||||||
{
|
{
|
||||||
@ -192,8 +184,6 @@ jrd_file* PIO_create(thread_db* tdbb, const Firebird::PathName& string,
|
|||||||
* Create a new database file.
|
* Create a new database file.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
adjustFsCacheOnce.init();
|
|
||||||
|
|
||||||
Database* const dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
const TEXT* file_name = string.c_str();
|
const TEXT* file_name = string.c_str();
|
||||||
@ -515,8 +505,6 @@ jrd_file* PIO_open(thread_db* tdbb,
|
|||||||
bool readOnly = false;
|
bool readOnly = false;
|
||||||
const bool shareMode = dbb->dbb_config->getServerMode() != MODE_SUPER;
|
const bool shareMode = dbb->dbb_config->getServerMode() != MODE_SUPER;
|
||||||
|
|
||||||
adjustFsCacheOnce.init();
|
|
||||||
|
|
||||||
HANDLE desc = CreateFile(ptr,
|
HANDLE desc = CreateFile(ptr,
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
getShareFlags(shareMode),
|
getShareFlags(shareMode),
|
||||||
@ -954,159 +942,3 @@ static bool nt_error(const TEXT* string,
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are defined in Windows Server 2008 SDK
|
|
||||||
#ifndef FILE_CACHE_FLAGS_DEFINED
|
|
||||||
#define FILE_CACHE_MAX_HARD_ENABLE 0x00000001
|
|
||||||
#define FILE_CACHE_MAX_HARD_DISABLE 0x00000002
|
|
||||||
#define FILE_CACHE_MIN_HARD_ENABLE 0x00000004
|
|
||||||
#define FILE_CACHE_MIN_HARD_DISABLE 0x00000008
|
|
||||||
#endif // FILE_CACHE_FLAGS_DEFINED
|
|
||||||
|
|
||||||
BOOL SetPrivilege(
|
|
||||||
HANDLE hToken, // access token handle
|
|
||||||
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
|
|
||||||
BOOL bEnablePrivilege) // to enable or disable privilege
|
|
||||||
{
|
|
||||||
TOKEN_PRIVILEGES tp;
|
|
||||||
LUID luid;
|
|
||||||
|
|
||||||
if (!LookupPrivilegeValue(
|
|
||||||
NULL, // lookup privilege on local system
|
|
||||||
lpszPrivilege, // privilege to lookup
|
|
||||||
&luid)) // receives LUID of privilege
|
|
||||||
{
|
|
||||||
// gds__log("LookupPrivilegeValue error: %u", GetLastError() );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp.PrivilegeCount = 1;
|
|
||||||
tp.Privileges[0].Luid = luid;
|
|
||||||
if (bEnablePrivilege)
|
|
||||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
||||||
else
|
|
||||||
tp.Privileges[0].Attributes = 0;
|
|
||||||
|
|
||||||
// Enable or disable the privilege
|
|
||||||
|
|
||||||
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
|
|
||||||
(PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
|
|
||||||
{
|
|
||||||
//gds__log("AdjustTokenPrivileges error: %u", GetLastError() );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
|
|
||||||
{
|
|
||||||
//gds__log("The token does not have the specified privilege");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void adjustFileSystemCacheSize()
|
|
||||||
{
|
|
||||||
int percent = Config::getFileSystemCacheSize();
|
|
||||||
|
|
||||||
// firebird.conf asks to do nothing
|
|
||||||
if (percent == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Ensure that the setting has a sensible value
|
|
||||||
if (percent > 95 || percent < 10)
|
|
||||||
{
|
|
||||||
gds__log("Incorrect FileSystemCacheSize setting %d. Using default (30 percent).", percent);
|
|
||||||
percent = 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMODULE hmodKernel32 = GetModuleHandle("kernel32.dll");
|
|
||||||
|
|
||||||
// This one requires 64-bit XP or Windows Server 2003 SP1
|
|
||||||
typedef BOOL (WINAPI *PFnSetSystemFileCacheSize)(SIZE_T, SIZE_T, DWORD);
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *PFnGetSystemFileCacheSize)(PSIZE_T, PSIZE_T, PDWORD);
|
|
||||||
|
|
||||||
// This one needs any NT, but load it dynamically anyways just in case
|
|
||||||
typedef BOOL (WINAPI *PFnGlobalMemoryStatusEx)(LPMEMORYSTATUSEX);
|
|
||||||
|
|
||||||
PFnSetSystemFileCacheSize pfnSetSystemFileCacheSize =
|
|
||||||
(PFnSetSystemFileCacheSize) GetProcAddress(hmodKernel32, "SetSystemFileCacheSize");
|
|
||||||
PFnGetSystemFileCacheSize pfnGetSystemFileCacheSize =
|
|
||||||
(PFnGetSystemFileCacheSize) GetProcAddress(hmodKernel32, "GetSystemFileCacheSize");
|
|
||||||
PFnGlobalMemoryStatusEx pfnGlobalMemoryStatusEx =
|
|
||||||
(PFnGlobalMemoryStatusEx) GetProcAddress(hmodKernel32, "GlobalMemoryStatusEx");
|
|
||||||
|
|
||||||
// If we got too old OS and functions are not there - do not bother
|
|
||||||
if (!pfnGetSystemFileCacheSize || !pfnSetSystemFileCacheSize || !pfnGlobalMemoryStatusEx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MEMORYSTATUSEX msex;
|
|
||||||
msex.dwLength = sizeof(msex);
|
|
||||||
|
|
||||||
// This should work
|
|
||||||
if (!pfnGlobalMemoryStatusEx(&msex))
|
|
||||||
system_call_failed::raise("GlobalMemoryStatusEx", GetLastError());
|
|
||||||
|
|
||||||
SIZE_T origMinimumFileCacheSize, origMaximumFileCacheSize;
|
|
||||||
DWORD origFlags;
|
|
||||||
|
|
||||||
BOOL result = pfnGetSystemFileCacheSize(&origMinimumFileCacheSize,
|
|
||||||
&origMaximumFileCacheSize, &origFlags);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
const DWORD error = GetLastError();
|
|
||||||
#ifndef _WIN64
|
|
||||||
// This error is returned on 64-bit Windows when the file cache size
|
|
||||||
// overflows the ULONG limit restricted by the 32-bit Windows API.
|
|
||||||
// Let's avoid writing it into the log as it's not a critical failure.
|
|
||||||
if (error != ERROR_ARITHMETIC_OVERFLOW)
|
|
||||||
#endif
|
|
||||||
gds__log("GetSystemFileCacheSize error %d", error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Somebody has already configured maximum cache size limit
|
|
||||||
// Hope it is a sensible one - do not bother to adjust it
|
|
||||||
if ((origFlags & FILE_CACHE_MAX_HARD_ENABLE) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DWORDLONG maxMem = (msex.ullTotalPhys / 100) * percent;
|
|
||||||
|
|
||||||
#ifndef _WIN64
|
|
||||||
// If we are trying to set the limit so high that it doesn't fit
|
|
||||||
// in 32-bit API - leave settings alone and write a message to log file
|
|
||||||
if (maxMem > (SIZE_T)(-2))
|
|
||||||
{
|
|
||||||
gds__log("Could not use 32-bit SetSystemFileCacheSize API to set cache size limit to %I64d."
|
|
||||||
" Please use 64-bit engine or configure cache size limit externally", maxMem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HANDLE hToken;
|
|
||||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
|
||||||
{
|
|
||||||
gds__log("OpenProcessToken error %d", GetLastError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SetPrivilege(hToken, "SeIncreaseQuotaPrivilege", TRUE))
|
|
||||||
{
|
|
||||||
result = pfnSetSystemFileCacheSize(0, maxMem, FILE_CACHE_MAX_HARD_ENABLE);
|
|
||||||
const DWORD error = GetLastError();
|
|
||||||
SetPrivilege(hToken, "SeIncreaseQuotaPrivilege", FALSE);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
// If we do not have enough permissions - silently ignore the error
|
|
||||||
gds__log("SetSystemFileCacheSize error %d. "
|
|
||||||
"The engine will continue to operate, but the system "
|
|
||||||
"performance may degrade significantly when working with "
|
|
||||||
"large databases", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hToken);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user