On Wed, Dec 9, 2009 at 10:51 AM, Fujii Masao <masao.fu...@gmail.com> wrote:
> On Wed, Dec 9, 2009 at 10:12 AM, Tom Lane <t...@sss.pgh.pa.us> wrote:
>> Fujii Masao <masao.fu...@gmail.com> writes:
>>> Thought? Am I missing something?
>>
>> This seems terribly overdesigned.  Just emit a warning when you see
>> the "unlogged op" record and have done.
>
> Sounds quite simple. OK, I'll do so.

Here is the patch:

- Write an XLOG UNLOGGED record in WAL if WAL-logging is skipped for only
  the reason that WAL archiving is not enabled and such record has not been
  written yet.

- Cause archive recovery to end if an XLOG UNLOGGED record is found during
  it.


I add this patch to the CommitFest 2010-01.

Regards,

-- 
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center
*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 1972,1977 **** heap_insert(Relation relation, HeapTuple tup, CommandId cid,
--- 1972,1984 ----
  		PageSetTLI(page, ThisTimeLineID);
  	}
  
+ 	/*
+ 	 * Write an XLOG UNLOGGED record if WAL-logging is skipped for the reason
+ 	 * that WAL archiving is not enabled.
+ 	 */
+ 	if (options & HEAP_INSERT_SKIP_WAL && !relation->rd_istemp)
+ 		XLogSkipLogging();
+ 
  	END_CRIT_SECTION();
  
  	UnlockReleaseBuffer(buffer);
*** a/src/backend/access/nbtree/nbtsort.c
--- b/src/backend/access/nbtree/nbtsort.c
***************
*** 215,220 **** _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
--- 215,227 ----
  	 */
  	wstate.btws_use_wal = XLogArchivingActive() && !wstate.index->rd_istemp;
  
+ 	/*
+ 	 * Write an XLOG UNLOGGED record if WAL-logging is skipped for the reason
+ 	 * that WAL archiving is not enabled.
+ 	 */
+ 	if (!XLogArchivingActive() && !wstate.index->rd_istemp)
+ 		XLogSkipLogging();
+ 
  	/* reserve the metapage */
  	wstate.btws_pages_alloced = BTREE_METAPAGE + 1;
  	wstate.btws_pages_written = 0;
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 550,555 **** XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
--- 550,556 ----
  	bool		updrqst;
  	bool		doPageWrites;
  	bool		isLogSwitch = (rmid == RM_XLOG_ID && info == XLOG_SWITCH);
+ 	bool		isLogUnlogged = (rmid == RM_XLOG_ID && info == XLOG_UNLOGGED);
  
  	/* cross-check on whether we should be here or not */
  	if (!XLogInsertAllowed())
***************
*** 699,707 **** begin:;
  	 * error checking in ReadRecord.  This means that all callers of
  	 * XLogInsert must supply at least some not-in-a-buffer data.  However, we
  	 * make an exception for XLOG SWITCH records because we don't want them to
! 	 * ever cross a segment boundary.
  	 */
! 	if (len == 0 && !isLogSwitch)
  		elog(PANIC, "invalid xlog record length %u", len);
  
  	START_CRIT_SECTION();
--- 700,708 ----
  	 * error checking in ReadRecord.  This means that all callers of
  	 * XLogInsert must supply at least some not-in-a-buffer data.  However, we
  	 * make an exception for XLOG SWITCH records because we don't want them to
! 	 * ever cross a segment boundary. Also XLOG UNLOGGED records are exception.
  	 */
! 	if (len == 0 && !isLogSwitch && !isLogUnlogged)
  		elog(PANIC, "invalid xlog record length %u", len);
  
  	START_CRIT_SECTION();
***************
*** 3551,3558 **** ReadRecord(XLogRecPtr *RecPtr, int emode)
  got_record:;
  
  	/*
! 	 * xl_len == 0 is bad data for everything except XLOG SWITCH, where it is
! 	 * required.
  	 */
  	if (record->xl_rmid == RM_XLOG_ID && record->xl_info == XLOG_SWITCH)
  	{
--- 3552,3559 ----
  got_record:;
  
  	/*
! 	 * xl_len == 0 is bad data for everything except XLOG SWITCH and XLOG UNLOGGED,
! 	 * where it is required.
  	 */
  	if (record->xl_rmid == RM_XLOG_ID && record->xl_info == XLOG_SWITCH)
  	{
***************
*** 3564,3569 **** got_record:;
--- 3565,3580 ----
  			goto next_record_is_invalid;
  		}
  	}
+ 	else if (record->xl_rmid == RM_XLOG_ID && record->xl_info == XLOG_UNLOGGED)
+ 	{
+ 		if (record->xl_len != 0)
+ 		{
+ 			ereport(emode,
+ 					(errmsg("invalid xlog unlogged operation record at %X/%X",
+ 							RecPtr->xlogid, RecPtr->xrecoff)));
+ 			goto next_record_is_invalid;
+ 		}
+ 	}
  	else if (record->xl_len == 0)
  	{
  		ereport(emode,
***************
*** 3759,3764 **** got_record:;
--- 3770,3788 ----
  		 */
  		readOff = XLogSegSize - XLOG_BLCKSZ;
  	}
+ 
+ 	/*
+ 	 * Special processing if it's an XLOG UNLOGGED record and we are doing
+ 	 * an archive recovery.
+ 	 */
+ 	if (record->xl_rmid == RM_XLOG_ID && record->xl_info == XLOG_UNLOGGED &&
+ 		InArchiveRecovery)
+ 	{
+ 		ereport(emode,
+ 				(errmsg("unlogged operation record is found at %X/%X",
+ 						RecPtr->xlogid, RecPtr->xrecoff)));
+ 		goto next_record_is_invalid;
+ 	}
  	return (XLogRecord *) buffer;
  
  next_record_is_invalid:;
***************
*** 6998,7003 **** RequestXLogSwitch(void)
--- 7022,7057 ----
  }
  
  /*
+  * Write an XLOG UNLOGGED record.
+  */
+ void
+ XLogSkipLogging(void)
+ {
+ 	XLogRecData rdata;
+ 	static bool skipped = false;
+ 
+ 	/*
+ 	 * If an XLOG UNLOGGED record has already been written since
+ 	 * postmaster has started, we need to do nothing here.
+ 	 *
+ 	 * We can reduce the number of an XLOG UNLOGGED records written
+ 	 * by sharing the flag 'skipped' between backends. But this is
+ 	 * not worthwhile.
+ 	 */
+ 	if (skipped)
+ 		return;
+ 	skipped = true;
+ 
+ 	/* XLOG UNLOGGED, alone among xlog record types, has no data */
+ 	rdata.buffer = InvalidBuffer;
+ 	rdata.data = NULL;
+ 	rdata.len = 0;
+ 	rdata.next = NULL;
+ 
+ 	XLogInsert(RM_XLOG_ID, XLOG_UNLOGGED, &rdata);
+ }
+ 
+ /*
   * XLOG resource manager's routines
   *
   * Definitions of info values are in include/catalog/pg_control.h, though
***************
*** 7100,7105 **** xlog_redo(XLogRecPtr lsn, XLogRecord *record)
--- 7154,7163 ----
  	{
  		/* nothing to do here */
  	}
+ 	else if (info == XLOG_UNLOGGED)
+ 	{
+ 		/* nothing to do here */
+ 	}
  }
  
  void
***************
*** 7140,7145 **** xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
--- 7198,7207 ----
  	{
  		appendStringInfo(buf, "xlog switch");
  	}
+ 	else if (info == XLOG_UNLOGGED)
+ 	{
+ 		appendStringInfo(buf, "xlog unlogged");
+ 	}
  	else
  		appendStringInfo(buf, "UNKNOWN");
  }
*** a/src/backend/commands/cluster.c
--- b/src/backend/commands/cluster.c
***************
*** 801,806 **** copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
--- 801,813 ----
  	 */
  	use_wal = XLogArchivingActive() && !NewHeap->rd_istemp;
  
+ 	/*
+ 	 * Write an XLOG UNLOGGED record if WAL-logging is skipped for the reason
+ 	 * that WAL archiving is not enabled.
+ 	 */
+ 	if (!XLogArchivingActive() && !NewHeap->rd_istemp)
+ 		XLogSkipLogging();
+ 
  	/* use_wal off requires rd_targblock be initially invalid */
  	Assert(NewHeap->rd_targblock == InvalidBlockNumber);
  
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 7109,7114 **** copy_relation_data(SMgrRelation src, SMgrRelation dst,
--- 7109,7121 ----
  	 */
  	use_wal = XLogArchivingActive() && !istemp;
  
+ 	/*
+ 	 * Write an XLOG UNLOGGED record if WAL-logging is skipped for the reason
+ 	 * that WAL archiving is not enabled.
+ 	 */
+ 	if (!XLogArchivingActive() && !istemp)
+ 		XLogSkipLogging();
+ 
  	nblocks = smgrnblocks(src, forkNum);
  
  	for (blkno = 0; blkno < nblocks; blkno++)
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
***************
*** 218,223 **** extern XLogRecPtr GetRedoRecPtr(void);
--- 218,225 ----
  extern XLogRecPtr GetInsertRecPtr(void);
  extern void GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch);
  
+ extern void XLogSkipLogging(void);
+ 
  extern void StartupProcessMain(void);
  
  #endif   /* XLOG_H */
*** a/src/include/catalog/pg_control.h
--- b/src/include/catalog/pg_control.h
***************
*** 48,53 **** typedef struct CheckPoint
--- 48,54 ----
  #define XLOG_NOOP						0x20
  #define XLOG_NEXTOID					0x30
  #define XLOG_SWITCH						0x40
+ #define XLOG_UNLOGGED					0x50
  
  
  /* System status indicator */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to