Example #1
0
void PersistentEndXactRec_Print(
	char 							*procName,

	PersistentEndXactRecObjects		*objects)
{
	int i;

	elog(Persistent_DebugPrintLevel(), 
		 "%s: file-system action count %d, Append-Only mirror resync EOFs count %d",
		 procName,
		 objects->typed.fileSysActionInfosCount,
		 objects->typed.appendOnlyMirrorResyncEofsCount);

	for (i = 0; i < objects->typed.fileSysActionInfosCount; i++)
	{
		PersistentEndXactFileSysActionInfo	*fileSysActionInfos =
										&objects->typed.fileSysActionInfos[i];

		elog(Persistent_DebugPrintLevel(), 
			 "%s: [%d] action '%s' %s, relation storage manager '%s', persistent serial num " INT64_FORMAT ", TID %s",
			 procName,
			 i,
			 PersistentEndXactFileSysAction_Name(fileSysActionInfos->action),
			 PersistentFileSysObjName_TypeAndObjectName(&fileSysActionInfos->fsObjName),
			 PersistentFileSysRelStorageMgr_Name(fileSysActionInfos->relStorageMgr),
			 fileSysActionInfos->persistentSerialNum,
			 ItemPointerToString(&fileSysActionInfos->persistentTid));
		
	}

	for (i = 0; i < objects->typed.appendOnlyMirrorResyncEofsCount; i++)
	{
		PersistentEndXactAppendOnlyMirrorResyncEofs *eofs = 
					&objects->typed.appendOnlyMirrorResyncEofs[i];

		elog(Persistent_DebugPrintLevel(), 
			 "%s: [%d] Append-Only Mirror Resync EOFs %u/%u/%u, segment file #%d -- persistent serial num " INT64_FORMAT ", TID %s, mirror loss EOF " INT64_FORMAT ", mirror new EOF " INT64_FORMAT,
			 procName,
			 i,
			 eofs->relFileNode.spcNode,
			 eofs->relFileNode.dbNode,
			 eofs->relFileNode.relNode,
			 eofs->segmentFileNum,
			 eofs->persistentSerialNum,
			 ItemPointerToString(&eofs->persistentTid),
			 eofs->mirrorLossEof,
			 eofs->mirrorNewEof);
	}
}
PersistentFileSysObjStateChangeResult PersistentRelation_MarkAbortingCreate(
		PersistentFileSysObjName *fsObjName,
		ItemPointer persistentTid,
		int64 persistentSerialNum,
		bool retryPossible)
{
	WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

	RelFileNode *relFileNode = &fsObjName->variant.rel.relFileNode;

	RelationDirEntry relationDirEntry;

	PersistentFileSysObjStateChangeResult stateChangeResult;

	if (RelFileNode_IsEmpty(relFileNode))
	{
		elog(ERROR, "Invalid RelFileNode (0,0,0)");
	}

	if (Persistent_BeforePersistenceWork())
	{
		if (Debug_persistent_print)
		{
			elog(Persistent_DebugPrintLevel(),
				"Skipping persistent relation '%s' because we are before persistence work",
				relpath(*relFileNode));

			/*
			 * The initdb process will load the persistent table once we out of bootstrap mode.
			 */
			return PersistentFileSysObjStateChangeResult_None;
		}
	}

	PersistentRelation_VerifyInitScan();

	/*
	 * Do this check after skipping out if in bootstrap mode.
	 */
	if (PersistentStore_IsZeroTid(persistentTid))
	{
		elog(ERROR, "TID for persistent '%s' tuple for mark DROP pending is invalid (0,0)",
			PersistentFileSysObjName_TypeAndObjectName(fsObjName));
	}

	if (persistentSerialNum == 0)
	{
		elog(ERROR, "Persistent '%s' serial number for mark DROP pending is invalid (0)",
			PersistentFileSysObjName_TypeAndObjectName(fsObjName));
	}

	WRITE_PERSISTENT_STATE_ORDERED_LOCK;

	relationDirEntry = PersistentRelation_FindEntryUnderLock(relFileNode);

	if (relationDirEntry == NULL)
	{
		elog(ERROR, "Did not find persistent relation entry %u/%u/%u",
			relFileNode->spcNode,
			relFileNode->dbNode,
			relFileNode->relNode);
	}

	if (relationDirEntry->state != PersistentFileSysState_CreatePending)
	{
		elog(ERROR, "Persistent relation entry %u/%u/%u expected to be in 'Create Pending' (actual state '%s')",
			relFileNode->spcNode,
			relFileNode->dbNode,
			relFileNode->relNode,
			PersistentFileSysObjState_Name(relationDirEntry->state));
	}

	stateChangeResult = PersistentFileSysObj_StateChange(
											fsObjName,
											persistentTid,
											persistentSerialNum,
											PersistentFileSysState_AbortingCreate,
											retryPossible,
											/* flushToXLog */ false,
											/* oldState */ NULL,
											/* verifiedActionCallback */ NULL);

	relationDirEntry->state = PersistentFileSysState_AbortingCreate;

	WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

	if (Debug_persistent_print)
	{
		elog(Persistent_DebugPrintLevel(),
			"Persistent relation: '%s' changed state from 'Create Pending' to 'Aborting Create', serial number " INT64_FORMAT " at TID %s (State-Change result '%s')",
			PersistentFileSysObjName_ObjectName(fsObjName),
			persistentSerialNum,
			ItemPointerToString(persistentTid),
			PersistentFileSysObjStateChangeResult_Name(stateChangeResult));
	}

	return stateChangeResult;
}
Example #3
0
static void
PersistentEndXactRec_VerifyFileSysActionInfos(
	EndXactRecKind						endXactRecKind,

	PersistentEndXactFileSysActionInfo	*fileSysActionInfos,

	int 								count)
{
	int i;

	ItemPointerData maxTid;

	if (InRecovery || Persistent_BeforePersistenceWork())
		return;

	for (i = 0; i < count; i++)
	{
		PersistentTidIsKnownResult persistentTidIsKnownResult;

		if (!PersistentEndXactFileSysAction_IsValid(fileSysActionInfos[i].action))
			elog(ERROR, "Persistent file-system action is invalid (%d) (index %d, transaction kind '%s')",
				 fileSysActionInfos[i].action,
				 i,
				 EndXactRecKind_Name(endXactRecKind));
			
		if (!PersistentFsObjType_IsValid(fileSysActionInfos[i].fsObjName.type))
			elog(ERROR, "Persistent file-system object type is invalid (%d) (index %d, transaction kind '%s')",
				 fileSysActionInfos[i].fsObjName.type,
				 i,
				 EndXactRecKind_Name(endXactRecKind));
			
		if (PersistentStore_IsZeroTid(&fileSysActionInfos[i].persistentTid))
			elog(ERROR, "TID for persistent '%s' tuple is invalid (0,0) (index %d, transaction kind '%s')",
				 PersistentFileSysObjName_TypeAndObjectName(&fileSysActionInfos[i].fsObjName),
				 i,
				 EndXactRecKind_Name(endXactRecKind));

		persistentTidIsKnownResult = PersistentFileSysObj_TidIsKnown(
													fileSysActionInfos[i].fsObjName.type,
													&fileSysActionInfos[i].persistentTid,
													&maxTid);
		switch (persistentTidIsKnownResult)
		{
		case PersistentTidIsKnownResult_BeforePersistenceWork:
			elog(ERROR, "Shouldn't being trying to verify persistent TID before persistence work");
			break;

		case PersistentTidIsKnownResult_ScanNotPerformedYet:
			// UNDONE: For now, just debug log this.
			if (Debug_persistent_print)
				elog(Persistent_DebugPrintLevel(), 
				     "Can't verify persistent TID if we haven't done the persistent scan yet");
			break;

		case PersistentTidIsKnownResult_MaxTidIsZero:
			// UNDONE: For now, just debug log this.
			if (Debug_persistent_print)
				elog(Persistent_DebugPrintLevel(), 
					 "TID for persistent '%s' tuple TID %s and the last known TID zero (0,0) (index %d, transaction kind '%s')",
					 PersistentFileSysObjName_TypeAndObjectName(&fileSysActionInfos[i].fsObjName),
					 ItemPointerToString(&fileSysActionInfos[i].persistentTid),
					 i,
					 EndXactRecKind_Name(endXactRecKind));
			break;

		case PersistentTidIsKnownResult_NotKnown:
			// UNDONE: For now, just debug log this.
			if (Debug_persistent_print)
				elog(Persistent_DebugPrintLevel(), 
					 "TID for persistent '%s' tuple TID %s is beyond the last known TID %s (index %d, transaction kind '%s')",
					 PersistentFileSysObjName_TypeAndObjectName(&fileSysActionInfos[i].fsObjName),
					 ItemPointerToString(&fileSysActionInfos[i].persistentTid),
					 ItemPointerToString2(&maxTid),
					 i,
					 EndXactRecKind_Name(endXactRecKind));
			break;

		case PersistentTidIsKnownResult_Known:
			/* OK */
			break;
			
		default:
			elog(ERROR, "Unexpected persistent file-system TID is known result: %d",
				 persistentTidIsKnownResult);
		}

		if (fileSysActionInfos[i].persistentSerialNum == 0)
			elog(ERROR, "Persistent '%s' serial number is invalid (0) (index %d, transaction kind '%s')",
				 PersistentFileSysObjName_TypeAndObjectName(&fileSysActionInfos[i].fsObjName),
				 i,
				 EndXactRecKind_Name(endXactRecKind));

		if (fileSysActionInfos[i].fsObjName.type == PersistentFsObjType_RelationFile &&
			!PersistentFileSysRelStorageMgr_IsValid(fileSysActionInfos[i].relStorageMgr))
			elog(ERROR, "Persistent '%s' relation storage manager has invalid value (%d) (index %d, transaction kind '%s')",
				 PersistentFileSysObjName_TypeAndObjectName(&fileSysActionInfos[i].fsObjName),
				 fileSysActionInfos[i].relStorageMgr,
				 i,
				 EndXactRecKind_Name(endXactRecKind));
	}
}
Example #4
0
/*
 * Indicate we are aborting the create of a relation file.
 *
 * This state will make sure the relation gets dropped after a system crash.
 */
PersistentFileSysObjStateChangeResult PersistentRelation_MarkAbortingCreate(
    RelFileNode 		*relFileNode,
    /* The tablespace, database, and relation OIDs for the aborting create. */
    int32				segmentFileNum,
    ItemPointer			persistentTid,
    /* TID of the gp_persistent_rel_files tuple for the relation. */
    int64				persistentSerialNum,
    /* Serial number for the relation.  Distinquishes the uses of the tuple. */
    bool				retryPossible)
{
    WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

    PersistentFileSysObjName fsObjName;

    PersistentFileSysObjStateChangeResult stateChangeResult;

    if(RelFileNode_IsEmpty(relFileNode))
        elog(ERROR, "Invalid RelFileNode (0,0,0)");

    if (Persistent_BeforePersistenceWork())
    {
        if (Debug_persistent_print)
            elog(Persistent_DebugPrintLevel(),
                 "Skipping persistent relation '%s' because we are before persistence work",
                 relpath(*relFileNode));

        return false;	// The initdb process will load the persistent table once we out of bootstrap mode.
    }

    /* MPP-16543: When inserting tuples into AO table, row numbers will be
     * generated from gp_fastsequence catalog table, as part of the design,
     * these sequence numbers are not reusable, even if the AO insert
     * transaction is aborted. The entry in gp_fastsequence was inserted
     * using frozen_heap_insert, which means it's always visible.

     * Aborted AO insert transaction will cause inconsistency between
     * gp_fastsequence and pg_class, the solution is to introduce "frozen
     * delete" - inplace update tuple's MVCC header to make it invisible.
     */

    Relation gp_fastsequence_rel = heap_open(FastSequenceRelationId, RowExclusiveLock);
    HeapTuple   tup;
    SysScanDesc scan;
    ScanKeyData skey;
    ScanKeyInit(&skey,
                Anum_gp_fastsequence_objid,
                BTEqualStrategyNumber,
                F_OIDEQ,
                relFileNode->relNode);

    scan = systable_beginscan(gp_fastsequence_rel,
                              InvalidOid,
                              false,
                              SnapshotNow,
                              1,
                              &skey);
    while (HeapTupleIsValid(tup = systable_getnext(scan)))
    {
        Form_gp_fastsequence found = (Form_gp_fastsequence) GETSTRUCT(tup);
        if (found->objid == relFileNode->relNode)
        {
            if (Debug_persistent_print)
            {
                elog(LOG, "frozen deleting gp_fastsequence entry for aborted AO insert transaction on relation %s", relpath(*relFileNode));
            }

            frozen_heap_inplace_delete(gp_fastsequence_rel, tup);
        }
    }
    systable_endscan(scan);
    heap_close(gp_fastsequence_rel, RowExclusiveLock);




    PersistentRelation_VerifyInitScan();

    PersistentFileSysObjName_SetRelationFile(
        &fsObjName,
        relFileNode,
        segmentFileNum);

    // Do this check after skipping out if in bootstrap mode.
    if (PersistentStore_IsZeroTid(persistentTid))
        elog(ERROR, "TID for persistent '%s' tuple for mark DROP pending is invalid (0,0)",
             PersistentFileSysObjName_TypeAndObjectName(&fsObjName));

    if (persistentSerialNum == 0)
        elog(ERROR, "Persistent '%s' serial number for mark DROP pending is invalid (0)",
             PersistentFileSysObjName_TypeAndObjectName(&fsObjName));

    WRITE_PERSISTENT_STATE_ORDERED_LOCK;

    stateChangeResult =
        PersistentFileSysObj_StateChange(
            &fsObjName,
            persistentTid,
            persistentSerialNum,
            PersistentFileSysState_AbortingCreate,
            retryPossible,
            /* flushToXlog */ false,
            /* oldState */ NULL,
            /* verifiedActionCallback */ NULL);

    WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

    if (Debug_persistent_print)
        elog(Persistent_DebugPrintLevel(),
             "Persistent relation: '%s' changed state from 'Create Pending' to 'Aborting Create', serial number " INT64_FORMAT " at TID %s (State-Change result '%s')",
             PersistentFileSysObjName_ObjectName(&fsObjName),
             persistentSerialNum,
             ItemPointerToString(persistentTid),
             PersistentFileSysObjStateChangeResult_Name(stateChangeResult));

    return stateChangeResult;
}
Example #5
0
/*
 * Indicate we intend to drop a relation file as part of the current transaction.
 *
 * This relation file to drop will be listed inside a commit, distributed commit, a distributed
 * prepared, and distributed commit prepared XOG records.
 *
 * For any of the commit type records, once that XLOG record is flushed then the actual
 * file-system delete will occur.  The flush guarantees the action will be retried after system
 * crash.
 */
PersistentFileSysObjStateChangeResult PersistentRelation_MarkDropPending(
    RelFileNode 		*relFileNode,
    /* The tablespace, database, and relation OIDs for the drop. */
    int32				segmentFileNum,
    ItemPointer			persistentTid,
    /* TID of the gp_persistent_rel_files tuple for the relation. */
    int64				persistentSerialNum,
    /* Serial number for the relation.  Distinquishes the uses of the tuple. */
    bool				retryPossible)
{
    WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE;

    PersistentFileSysObjName fsObjName;

    PersistentFileSysState oldState;

    PersistentFileSysObjStateChangeResult stateChangeResult;

    if(RelFileNode_IsEmpty(relFileNode))
        elog(ERROR, "Invalid RelFileNode (0,0,0)");

    if (Persistent_BeforePersistenceWork())
    {
        if (Debug_persistent_print)
            elog(Persistent_DebugPrintLevel(),
                 "Skipping persistent relation '%s' because we are before persistence work",
                 relpath(*relFileNode));

        return false;	// The initdb process will load the persistent table once we out of bootstrap mode.
    }

    PersistentRelation_VerifyInitScan();

    PersistentFileSysObjName_SetRelationFile(
        &fsObjName,
        relFileNode,
        segmentFileNum);

    // Do this check after skipping out if in bootstrap mode.
    if (PersistentStore_IsZeroTid(persistentTid))
        elog(ERROR, "TID for persistent '%s' tuple for mark DROP pending is invalid (0,0)",
             PersistentFileSysObjName_TypeAndObjectName(&fsObjName));

    if (persistentSerialNum == 0)
        elog(ERROR, "Persistent '%s' serial number for mark DROP pending is invalid (0)",
             PersistentFileSysObjName_TypeAndObjectName(&fsObjName));

    WRITE_PERSISTENT_STATE_ORDERED_LOCK;

    stateChangeResult =
        PersistentFileSysObj_StateChange(
            &fsObjName,
            persistentTid,
            persistentSerialNum,
            PersistentFileSysState_DropPending,
            retryPossible,
            /* flushToXlog */ false,
            &oldState,
            /* verifiedActionCallback */ NULL);

    WRITE_PERSISTENT_STATE_ORDERED_UNLOCK;

    if (Debug_persistent_print)
        elog(Persistent_DebugPrintLevel(),
             "Persistent relation: '%s' changed state from '%s' to 'Drop Pending', serial number " INT64_FORMAT " TID %s (State-Change result '%s')",
             PersistentFileSysObjName_ObjectName(&fsObjName),
             PersistentFileSysObjState_Name(oldState),
             persistentSerialNum,
             ItemPointerToString(persistentTid),
             PersistentFileSysObjStateChangeResult_Name(stateChangeResult));

    return stateChangeResult;
}
Example #6
0
void PersistentRelation_MarkBufPoolRelationForScanIncrementalResync(
    RelFileNode 		*relFileNode,
    /* The tablespace, database, and relation OIDs for the created relation. */
    ItemPointer			persistentTid,
    /* TID of the gp_persistent_rel_files tuple for the relation. */
    int64				persistentSerialNum)
/* Serial number for the relation.  Distinquishes the uses of the tuple. */
{
    PersistentFileSysObjName fsObjName;

    if(RelFileNode_IsEmpty(relFileNode))
        elog(ERROR, "Invalid RelFileNode (0,0,0)");

    if (GpPersistent_SkipXLogInfo(relFileNode->relNode))
    {
        if (Debug_persistent_print)
            elog(Persistent_DebugPrintLevel(),
                 "Skipping persistent relation '%s' because it is special",
                 relpath(*relFileNode));

        return; // Resynchronize will always handle these relations as 'Scan Incremental'..
    }

    if (IsBootstrapProcessingMode())
    {
        if (Debug_persistent_print)
            elog(Persistent_DebugPrintLevel(),
                 "Skipping persistent relation '%s' because we are in bootstrap mode",
                 relpath(*relFileNode));

        return;	// The initdb process will load the persistent table once we out of bootstrap mode.
    }

    if (Persistent_BeforePersistenceWork())
    {
        if (Debug_persistent_print)
            elog(Persistent_DebugPrintLevel(),
                 "Skipping persistent relation '%s' because we are before persistence work",
                 relpath(*relFileNode));

        return;	// The initdb process will load the persistent table once we out of bootstrap mode.
    }

    PersistentRelation_VerifyInitScan();

    PersistentFileSysObjName_SetRelationFile(
        &fsObjName,
        relFileNode,
        /* segmentFileNum */ 0);

    // Do this check after skipping out if in bootstrap mode.
    if (PersistentStore_IsZeroTid(persistentTid))
        elog(ERROR, "TID for persistent '%s' tuple for mark physically truncated is invalid (0,0)",
             PersistentFileSysObjName_TypeAndObjectName(&fsObjName));

    if (persistentSerialNum == 0)
        elog(ERROR, "Persistent '%s' serial number for mark physcially truncated is invalid (0)",
             PersistentFileSysObjName_TypeAndObjectName(&fsObjName));

    PersistentFileSysObj_MarkBufPoolRelationForScanIncrementalResync(
        &fsObjName,
        persistentTid,
        persistentSerialNum,
        /* flushToXlog */ true);

    if (Debug_persistent_print)
        elog(Persistent_DebugPrintLevel(),
             "Persistent relation: '%s' marked physically truncated, serial number " INT64_FORMAT " at TID %s",
             PersistentFileSysObjName_ObjectName(&fsObjName),
             persistentSerialNum,
             ItemPointerToString(persistentTid));
}