Exemplo n.º 1
0
/*
 * Returns true iff the given segment file should be compacted.
 */
bool
AppendOnlyCompaction_ShouldCompact(
	Relation aoRelation,
	AppendOnlyEntry *aoEntry,
	int segno,
	int64 segmentTotalTupcount,
	bool isFull)
{
	bool result;
	AppendOnlyVisimap visiMap;
	int64 hiddenTupcount;
	int hideRatio;

	Assert(RelationIsAoRows(aoRelation) || RelationIsAoCols(aoRelation));

	if (!gp_appendonly_compaction)
	{
		ereport(LOG,
			(errmsg("Append-only compaction skipped on relation %s, segment file num %d",
				RelationGetRelationName(aoRelation),
				segno),
			 errdetail("Compaction is disabled")));
		/* Disable compaction by global guc. */
		return false;
	}

	AppendOnlyVisimap_Init(&visiMap,
			aoEntry->visimaprelid,
			aoEntry->visimapidxid,
			ShareLock,
			SnapshotNow);
	hiddenTupcount = AppendOnlyVisimap_GetSegmentFileHiddenTupleCount(
			&visiMap, segno);

	result = true;
	if (isFull && hiddenTupcount > 0)
	{
		/* 
		 * if it is a full vacuum and there is any obsolete data, do a compaction
		 */
		result = true;
	}
	else
	{
	hideRatio = AppendOnlyCompaction_GetHideRatio(hiddenTupcount, segmentTotalTupcount);
	if (hideRatio <= gp_appendonly_compaction_threshold || gp_appendonly_compaction_threshold == 0)
	{
			if (hiddenTupcount > 0)
			{
				ereportif(Debug_appendonly_print_compaction, LOG, 
					(errmsg("Append-only compaction skipped on relation %s, segment file num %d, "
					"hidden tupcount " INT64_FORMAT ", total tupcount " INT64_FORMAT ", " 
					"hide ratio %d%%, threshold %d%%",
					RelationGetRelationName(aoRelation),
					segno,
					hiddenTupcount, segmentTotalTupcount, 
					hideRatio, gp_appendonly_compaction_threshold)));
				ereport(LOG,
					(errmsg("Append-only compaction skipped on relation %s, segment file num %d",
					RelationGetRelationName(aoRelation),
					segno),
					errdetail("Ratio of obsolete tuples below threshold (%d%% vs %d%%)",
						hideRatio, gp_appendonly_compaction_threshold)));
			}
			else
			{
				ereportif(Debug_appendonly_print_compaction, LOG, 
					(errmsg("Append-only compaction skipped on relation %s, segment file num %d, "
					"hidden tupcount " INT64_FORMAT ", total tupcount " INT64_FORMAT ", " 
					"hide ratio %d%%, threshold %d%%",
					RelationGetRelationName(aoRelation),
					segno,
					hiddenTupcount, segmentTotalTupcount, 
					hideRatio, gp_appendonly_compaction_threshold)));
			}
			result = false;
		}
		elogif(Debug_appendonly_print_compaction, LOG, 
			"Schedule compaction: "
			"segno %d, "
			"hidden tupcount " INT64_FORMAT ", total tupcount " INT64_FORMAT ", " 
			"hide ratio %d%%, threshold %d%%",
			segno,
			hiddenTupcount, segmentTotalTupcount, 
			hideRatio, gp_appendonly_compaction_threshold);
	}
	AppendOnlyVisimap_Finish(&visiMap, ShareLock);
	return result;
}
Exemplo n.º 2
0
static Datum
gp_aovisimap_hidden_info_internal(PG_FUNCTION_ARGS, Oid aoRelOid)
{
	Datum		values[3];
	bool		nulls[3];
	HeapTuple tuple;
	Datum result;

	typedef struct Context
	{
		AppendOnlyVisimap visiMap;

		Relation parentRelation;

		FileSegInfo **appendonlySegfileInfo;
		AOCSFileSegInfo **aocsSegfileInfo;
		int segfile_info_total;

		int i;
	} Context;
	
	FuncCallContext *funcctx;
	Context *context;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		MemoryContext oldcontext;

		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		 * switch to memory context appropriate for multiple function
		 * calls
		 */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* build tupdesc for result tuples */
		tupdesc = CreateTemplateTupleDesc(3, false);
		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "segno",
						   INT4OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "hidden_tupcount",
						   INT8OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "total_tupcount",
						   INT8OID, -1, 0);

		funcctx->tuple_desc = BlessTupleDesc(tupdesc);

		/*
		 * Collect all the locking information that we will format and send
		 * out as a result set.
		 */
		context = (Context *) palloc0(sizeof(Context));

		context->parentRelation = heap_open(aoRelOid, AccessShareLock);
		if (!(RelationIsAoRows(context->parentRelation) || RelationIsAoCols(context->parentRelation)))
		{
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("Function not supported on relation")));
		}

		if (RelationIsAoRows(context->parentRelation))
		{
			context->appendonlySegfileInfo = GetAllFileSegInfo(
				context->parentRelation,
				SnapshotNow,
				&context->segfile_info_total);
		}
		else
		{
			Assert(RelationIsAoCols(context->parentRelation));
			context->aocsSegfileInfo = GetAllAOCSFileSegInfo(context->parentRelation,
					SnapshotNow, &context->segfile_info_total);
		}
		context->i = 0;

		AppendOnlyVisimap_Init(&context->visiMap,
				context->parentRelation->rd_appendonly->visimaprelid,
				context->parentRelation->rd_appendonly->visimapidxid,
				AccessShareLock,
				SnapshotNow);

		funcctx->user_fctx = (void *) context;

		MemoryContextSwitchTo(oldcontext);
	}

	funcctx = SRF_PERCALL_SETUP();
	context = (Context *) funcctx->user_fctx;

	while (context->i < context->segfile_info_total)
	{
		int64 tupcount;
		int segno;
		if (context->appendonlySegfileInfo)
		{
			FileSegInfo *fsinfo = context->appendonlySegfileInfo[context->i];
			tupcount = fsinfo->total_tupcount;
			segno = fsinfo->segno;
		}
		else if (context->aocsSegfileInfo)
		{
			AOCSFileSegInfo *fsinfo = context->aocsSegfileInfo[context->i];
			tupcount = fsinfo->total_tupcount;
			segno = fsinfo->segno;
		}
		else
		{
			Insist(false);
		}

		MemSet(values, 0, sizeof(values));
		MemSet(nulls, false, sizeof(nulls));
		values[0] = Int32GetDatum(segno);
		values[1] = Int64GetDatum(AppendOnlyVisimap_GetSegmentFileHiddenTupleCount(
					&context->visiMap, segno));
		values[2] = Int64GetDatum(tupcount);

		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
		result = HeapTupleGetDatum(tuple);

		context->i++;
		SRF_RETURN_NEXT(funcctx, result);
	}
	
	AppendOnlyVisimap_Finish(&context->visiMap, AccessShareLock);
	if (context->appendonlySegfileInfo)
	{
		FreeAllSegFileInfo(context->appendonlySegfileInfo, context->segfile_info_total);
		pfree(context->appendonlySegfileInfo);
		context->appendonlySegfileInfo = NULL;
	}
	if (context->aocsSegfileInfo)
	{
		FreeAllAOCSSegFileInfo(context->aocsSegfileInfo, context->segfile_info_total);
		pfree(context->aocsSegfileInfo);
		context->aocsSegfileInfo = NULL;

	}
	heap_close(context->parentRelation, AccessShareLock);
	pfree(context);
	funcctx->user_fctx = NULL;

	SRF_RETURN_DONE(funcctx);
}