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

Front ported support for fallocate() call on Linux.

Front ported improvement CORE-4443 : Use fast file grow on those Linux systems which supports it
This commit is contained in:
hvlad 2014-06-10 09:00:58 +00:00
parent 6a2016235a
commit 02e898741a
5 changed files with 73 additions and 7 deletions

View File

@ -690,6 +690,7 @@ AC_CHECK_HEADERS(poll.h)
AC_CHECK_HEADERS(langinfo.h)
AC_CHECK_HEADERS(iconv.h)
AC_CHECK_HEADERS(libio.h)
AC_CHECK_HEADERS(linux/falloc.h)
dnl check for ICU presence
AC_CHECK_HEADER(unicode/ucnv.h,,AC_MSG_ERROR(ICU support not found - please install development ICU package))

View File

@ -94,6 +94,7 @@ const USHORT FIL_force_write = 1;
const USHORT FIL_no_fs_cache = 2; // not using file system cache
const USHORT FIL_readonly = 4; // file opened in readonly mode
const USHORT FIL_sh_write = 8; // file opened in shared write mode
const USHORT FIL_no_fast_extend = 16; // file not supports fast extending
// Physical IO trace events

View File

@ -45,6 +45,9 @@
#ifdef HAVE_AIO_H
#include <aio.h>
#endif
#ifdef HAVE_LINUX_FALLOC_H
#include <linux/falloc.h>
#endif
#include "../jrd/jrd.h"
#include "../jrd/os/pio.h"
@ -291,7 +294,7 @@ bool PIO_expand(const TEXT* file_name, USHORT file_length, TEXT* expanded_name,
}
void PIO_extend(Database* dbb, jrd_file* /*main_file*/, const ULONG /*extPages*/, const USHORT /*pageSize*/)
void PIO_extend(Database* dbb, jrd_file* main_file, const ULONG extPages, const USHORT pageSize)
{
/**************************************
*
@ -303,6 +306,56 @@ void PIO_extend(Database* dbb, jrd_file* /*main_file*/, const ULONG /*extPages*/
* Extend file by extPages pages of pageSize size.
*
**************************************/
#ifdef HAVE_LINUX_FALLOC_H
ULONG leftPages = extPages;
for (jrd_file* file = main_file; file && leftPages; file = file->fil_next)
{
const ULONG filePages = PIO_get_number_of_pages(file, pageSize);
const ULONG fileMaxPages = (file->fil_max_page == MAX_ULONG) ?
MAX_ULONG : file->fil_max_page - file->fil_min_page + 1;
if (filePages < fileMaxPages)
{
if (file->fil_flags & FIL_no_fast_extend)
return;
const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages);
int r;
for (r = 0; r < IO_RETRY; r++)
{
int err = fallocate(file->fil_desc, 0, filePages * pageSize, extendBy * pageSize);
if (err == 0)
break;
err = errno;
if (SYSCALL_INTERRUPTED(err))
continue;
if (err == EOPNOTSUPP || err == ENOSYS)
file->fil_flags |= FIL_no_fast_extend;
else
unix_error("fallocate", file, isc_io_write_err);
return;
}
if (r == IO_RETRY)
{
#ifdef DEV_BUILD
fprintf(stderr, "PIO_extend: retry count exceeded\n");
fflush(stderr);
#endif
unix_error("fallocate_retry", file, isc_io_write_err);
return;
}
leftPages -= extendBy;
}
}
#else
main_file->fil_flags |= FIL_no_fast_extend;
#endif // HAVE_LINUX_FALLOC_H
// not implemented
return;
}

View File

@ -640,7 +640,7 @@ PAG PAG_allocate(thread_db* tdbb, WIN* window)
// At this point we ensure database has at least "initialized" pages
// allocated. To avoid file growth by few pages when all this space
// will be used, extend file up to initialized + next_init_pages now
pageSpace->extend(tdbb, initialized + next_init_pages);
pageSpace->extend(tdbb, initialized + next_init_pages, false);
}
break; // Found a page and successfully fake-ed it
@ -2039,7 +2039,7 @@ ULONG PageSpace::lastUsedPage(const Database* dbb)
return pgSpace->lastUsedPage();
}
bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum, const bool forceSize)
{
/**************************************
*
@ -2051,12 +2051,16 @@ bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
* If "DatabaseGrowthIncrement" is less than MIN_EXTEND_BYTES then don't
* extend file(s)
*
* If forceSize is true, extend file up to pageNum pages (despite of value
* of "DatabaseGrowthIncrement") and don't make attempts to extend by less
* pages.
*
**************************************/
fb_assert(dbb == tdbb->getDatabase());
const int MAX_EXTEND_BYTES = dbb->dbb_config->getDatabaseGrowthIncrement();
if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES)
if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES && !forceSize)
return true;
if (pageNum >= maxAlloc())
@ -2071,6 +2075,7 @@ bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
while (true)
{
const ULONG oldMaxPageNumber = maxPageNumber;
try
{
PIO_extend(dbb, file, extPages, dbb->dbb_page_size);
@ -2078,10 +2083,16 @@ bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
}
catch (const status_exception&)
{
if (extPages > reqPages)
if (extPages > reqPages && !forceSize)
{
extPages = MAX(reqPages, extPages / 2);
fb_utils::init_status(tdbb->tdbb_status_vector);
// if file was extended, return, else try to extend by less pages
if (oldMaxPageNumber < maxAlloc())
return true;
extPages = MAX(reqPages, extPages / 2);
}
else
{

View File

@ -120,7 +120,7 @@ public:
static ULONG lastUsedPage(const Database* dbb);
// extend page space
bool extend(thread_db*, const ULONG);
bool extend(thread_db*, const ULONG, const bool);
// get SCN's page number
ULONG getSCNPageNum(ULONG sequence);