SRA Win32 sync() code - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | SRA Win32 sync() code |
Date | |
Msg-id | 200311160500.hAG50u701539@candle.pha.pa.us Whole thread Raw |
Responses |
Re: SRA Win32 sync() code
|
List | pgsql-patches |
Here is the SRA sync() code for Win32. As you might know, fsync on Win32 is _commit, and sync() is _flushall. However, _flushall only flushes only _open_ kernel buffers, not dirty buffers that have been closed. Therefore, on Win32, during checkpoint, you have to open, fsync(_commit), close all file that have been modified since the previous checkpoint. Not sure how we are going to do this in Win32, but somehow we will have to record all open files between checkpoints in an area that the checkpoint process can read during a checkpoint. Here is the SRA code that records the dirty file and the code that cycles through the list and fsync's each one. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 #ifdef POWERGRES static Dllist *rnodes = NULL; static volatile slock_t mylock = 0; typedef struct { RelFileNode rnode; BlockNumber blkno; } RelSegInfo; #undef calloc #undef malloc #undef free #undef realloc #undef strdup /* * Add segment file names to the internal table */ static void add_file(RelFileNode rnode, BlockNumber blkno) { Dlelem *elm; RelSegInfo *info; #ifndef LET_OS_MANAGE_FILESIZE BlockNumber segno, isegno; #endif SpinLockAcquire_NoHoldoff(&mylock); if (rnodes == NULL) { rnodes = DLNewList(); } elm = DLGetHead(rnodes); while (elm) { RelSegInfo *ip = (RelSegInfo *)DLE_VAL(elm); #ifndef LET_OS_MANAGE_FILESIZE segno = blkno / ((BlockNumber) RELSEG_SIZE); isegno = ip->blkno / ((BlockNumber) RELSEG_SIZE); #endif if (((ip->rnode.tblNode == (Oid)0 && rnode.tblNode == (Oid)0 && ip->rnode.relNode == rnode.relNode) || (ip->rnode.tblNode == rnode.tblNode && ip->rnode.relNode == rnode.relNode)) #ifndef LET_OS_MANAGE_FILESIZE && segno == isegno #endif ) { /* already there */ SpinLockRelease_NoHoldoff(&mylock); return; } elm = DLGetSucc(elm); } info = malloc(sizeof(*info)); if (info == NULL) { elog(ERROR, "add_file: malloc failed"); } else { info->rnode = rnode; info->blkno = blkno; DLAddHead(rnodes, DLNewElem(info)); } SpinLockRelease_NoHoldoff(&mylock); } /* * fsync all file segments registered in the table */ #include <fcntl.h> static void checkpoint_buffer_sync(void) { Dllist *segs; Dlelem *elm; File fd; char segname[MAXPGPATH]; #ifndef LET_OS_MANAGE_FILESIZE BlockNumber segno; #endif if (rnodes == NULL) return; SpinLockAcquire_NoHoldoff(&mylock); segs = DLNewList(); elm = DLGetHead(rnodes); while (elm) { Dlelem *next; next = DLGetSucc(elm); DLAddHead(segs, DLNewElem(DLE_VAL(elm))); DLRemove(elm); DLFreeElem(elm); elm = next; } SpinLockRelease_NoHoldoff(&mylock); elm = DLGetHead(segs); while (elm) { RelSegInfo *ip = (RelSegInfo *)DLE_VAL(elm); if (ip->rnode.tblNode == (Oid) 0) /* "global tablespace" */ { /* Shared system relations live in {datadir}/global */ snprintf(segname, MAXPGPATH, "%s/global/%u", DataDir, ip->rnode.relNode); } else { snprintf(segname, MAXPGPATH, "%s/base/%u/%u", DataDir, ip->rnode.tblNode, ip->rnode.relNode); } #ifndef LET_OS_MANAGE_FILESIZE /* append the '.segno', if needed */ segno = ip->blkno / ((BlockNumber) RELSEG_SIZE); if (segno > 0) { snprintf(segname, MAXPGPATH, "%s.%u", segname, segno); } #endif fd = FileNameOpenFile(segname, O_RDWR | PG_BINARY, 0600); if (fd >= 0) { elog(DEBUG1,"flushing %s", segname); FileSync(fd); FileClose(fd); } elm = DLGetSucc(elm); } DLFreeList(segs); } #endif /* POWERGRES */
pgsql-patches by date: