fix pg_clog issue where read page beyond the file size (less than one segment size)

This commit is contained in:
peibaoyi
2022-12-12 20:42:10 +08:00
parent d8f3e9955a
commit 8dca586a5a
2 changed files with 63 additions and 63 deletions

View File

@ -258,12 +258,8 @@ static Page _bt_blnewpage(uint32 level)
}
ADIO_ELSE()
{
if (ENABLE_DSS) {
page = (Page)mem_align_alloc(SYS_LOGICAL_BLOCK_SIZE, BLCKSZ);
} else {
page = (Page)palloc(BLCKSZ);
}
}
ADIO_END();
/* Zero the page and set up standard page header info */
@ -312,11 +308,7 @@ static void _bt_segment_blwritepage(BTWriteState *wstate, Page page, BlockNumber
PageSetLSN(BufferGetPage(buf), xlog_ptr);
MarkBufferDirty(buf);
UnlockReleaseBuffer(buf);
if (ENABLE_DSS) {
mem_align_free(page);
} else {
pfree(page);
}
page = NULL;
}
@ -433,11 +425,7 @@ static void _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
}
wstate->btws_zeropage = NULL;
}
if (ENABLE_DSS) {
mem_align_free(page);
} else {
pfree(page);
}
page = NULL;
}
ADIO_END();
@ -828,12 +816,8 @@ void _bt_uppershutdown(BTWriteState *wstate, BTPageState *state)
}
ADIO_ELSE()
{
if (ENABLE_DSS) {
metapage = (Page)mem_align_alloc(SYS_LOGICAL_BLOCK_SIZE, BLCKSZ);
} else {
metapage = (Page)palloc(BLCKSZ);
}
}
ADIO_END();
_bt_initmetapage(metapage, rootblkno, rootlevel);
_bt_blwritepage(wstate, metapage, BTREE_METAPAGE);

View File

@ -422,8 +422,10 @@ int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xi
/* Acquire per-buffer lock (cannot deadlock, see notes at top) */
(void)LWLockAcquire(shared->buffer_locks[slotno], LW_EXCLUSIVE);
if (!ENABLE_DSS) {
/* Release control lock while doing I/O */
LWLockRelease(shared->control_lock);
}
/* Do the read */
ok = SlruPhysicalReadPage(ctl, pageno, slotno);
@ -431,8 +433,10 @@ int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xi
/* Set the LSNs for this newly read-in page to zero */
SimpleLruZeroLSNs(ctl, slotno);
if (!ENABLE_DSS) {
/* Re-acquire control lock and update page state */
(void)LWLockAcquire(shared->control_lock, LW_EXCLUSIVE);
}
if (!(shared->page_number[slotno] == pageno && shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS &&
!shared->page_dirty[slotno]))
@ -583,6 +587,41 @@ void SimpleLruWritePage(SlruCtl ctl, int slotno)
SlruInternalWritePage(ctl, slotno, NULL);
}
static bool SSPreAllocSegment(int fd, SlruFlush fdata)
{
struct stat s;
if (fstat(fd, &s) < 0) {
t_thrd.xact_cxt.slru_errcause = SLRU_OPEN_FAILED;
t_thrd.xact_cxt.slru_errno = errno;
if (fdata == NULL) {
(void)close(fd);
}
return false;
}
int64 trunc_size = (int64)(SLRU_PAGES_PER_SEGMENT * BLCKSZ);
if (s.st_size < trunc_size) {
/* extend file at once to avoid dss cross-border write issue */
pgstat_report_waitevent(WAIT_EVENT_SLRU_WRITE);
errno = 0;
if (fallocate(fd, 0, s.st_size, trunc_size) != 0) {
pgstat_report_waitevent(WAIT_EVENT_END);
if (errno == 0) {
errno = ENOSPC;
}
t_thrd.xact_cxt.slru_errcause = SLRU_WRITE_FAILED;
t_thrd.xact_cxt.slru_errno = errno;
if (fdata == NULL) {
(void)close(fd);
}
return false;
}
pgstat_report_waitevent(WAIT_EVENT_END);
}
return true;
}
/*
* Physical read of a (previously existing) page into a buffer slot
*
@ -629,11 +668,23 @@ static bool SlruPhysicalReadPage(SlruCtl ctl, int64 pageno, int slotno)
}
if (lseek(fd, (off_t)offset, SEEK_SET) < 0) {
bool failed = true;
if (ENABLE_DSS && errno == ERR_DSS_FILE_SEEK) {
if (!SSPreAllocSegment(fd, NULL)) {
return false;
}
if (lseek(fd, (off_t)offset, SEEK_SET) >= 0) {
failed = false;
}
}
if (failed) {
t_thrd.xact_cxt.slru_errcause = SLRU_SEEK_FAILED;
t_thrd.xact_cxt.slru_errno = errno;
(void)close(fd);
return false;
}
}
errno = 0;
pgstat_report_waitevent(WAIT_EVENT_SLRU_READ);
@ -663,41 +714,6 @@ static bool SlruPhysicalReadPage(SlruCtl ctl, int64 pageno, int slotno)
return true;
}
static bool SSPreAllocSegment(int fd, SlruFlush fdata)
{
struct stat s;
if (fstat(fd, &s) < 0) {
t_thrd.xact_cxt.slru_errcause = SLRU_OPEN_FAILED;
t_thrd.xact_cxt.slru_errno = errno;
if (fdata == NULL) {
(void)close(fd);
}
return false;
}
int64 trunc_size = (int64)(SLRU_PAGES_PER_SEGMENT * BLCKSZ);
if (s.st_size < trunc_size) {
/* extend file at once to avoid dss cross-border write issue */
pgstat_report_waitevent(WAIT_EVENT_SLRU_WRITE);
errno = 0;
if (fallocate(fd, 0, s.st_size, trunc_size) != 0) {
pgstat_report_waitevent(WAIT_EVENT_END);
if (errno == 0) {
errno = ENOSPC;
}
t_thrd.xact_cxt.slru_errcause = SLRU_WRITE_FAILED;
t_thrd.xact_cxt.slru_errno = errno;
if (fdata == NULL) {
(void)close(fd);
}
return false;
}
pgstat_report_waitevent(WAIT_EVENT_END);
}
return true;
}
/*
* Physical write of a page from a buffer slot
*