PolarDBforPostgreSQL/external/polar_monitor/polar_monitor_proxy.c

170 lines
4.9 KiB
C

/*-------------------------------------------------------------------------
*
* polar_monitor_proxy.c
* views of polardb proxy
*
* Copyright (c) 2021, Alibaba Group Holding Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IDENTIFICATION
* external/polar_monitor/polar_monitor_proxy.c
*-------------------------------------------------------------------------
*/
#include "polar_monitor.h"
/*
* POLAR: return the xact split info
*/
PG_FUNCTION_INFO_V1(polar_stat_xact_split_info);
Datum
polar_stat_xact_split_info(PG_FUNCTION_ARGS)
{
#define NUM_XACT_SPLIT_INFO_ELEM 3
TupleDesc tupdesc;
Datum values[NUM_XACT_SPLIT_INFO_ELEM];
bool nulls[NUM_XACT_SPLIT_INFO_ELEM];
HeapTuple tuple;
Datum result;
char *xids = NULL;
bool splittable = false;
int i = 0;
if (RecoveryInProgress())
elog(ERROR, "recovery is in progress, this function is only available in RW");
MemSet(nulls, 0, sizeof(nulls));
MemSet(values, 0, sizeof(values));
tupdesc = CreateTemplateTupleDesc(NUM_XACT_SPLIT_INFO_ELEM, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xids", TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "splittable", BOOLOID, -1, 0);
/* Use int8 rather than LSN, for convenience of test. Might be overflow, but still fine for our test */
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "lsn", INT8OID, -1, 0);
xids = polar_xact_split_xact_info();
splittable = polar_xact_split_splittable();
if(xids != NULL)
{
values[i++] = CStringGetTextDatum(xids);
pfree(xids);
}
else
nulls[i++] = true;
values[i++] = BoolGetDatum(splittable);
values[i++] = Int64GetDatum(GetXLogInsertRecPtr());
tuple = heap_form_tuple(BlessTupleDesc(tupdesc), values, nulls);
result = HeapTupleGetDatum(tuple);
PG_RETURN_DATUM(result);
}
static char *polar_stat_proxy_infos[] = {
"total",
"splittable",
"disablesplit",
"unsplittable",
"error",
"lock",
"combocid",
"autoxact",
"readimplicit",
"readbeforewrite",
"readafterwrite",
};
/*
* POLAR: return the proxy stat info
*/
PG_FUNCTION_INFO_V1(polar_stat_proxy_info);
Datum
polar_stat_proxy_info(PG_FUNCTION_ARGS)
{
#define POLARPROXYSTATSIZE 2
int i = 0;
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
TupleDesc tupdesc;
MemoryContext per_query_ctx;
MemoryContext oldcontext;
Tuplestorestate *tupstore;
Datum values[POLARPROXYSTATSIZE];
bool nulls[POLARPROXYSTATSIZE];
StaticAssertStmt((sizeof(polar_stat_proxy_infos) / sizeof(char *)) ==
(sizeof(PolarStat_Proxy) / sizeof(uint64)), "polar_stat_proxy_infos should match PolarStat_Proxy");
MemSet(nulls, 0, sizeof(nulls));
tupdesc = CreateTemplateTupleDesc(POLARPROXYSTATSIZE, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "reason", TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "count", INT8OID, -1, 0);
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
oldcontext = MemoryContextSwitchTo(per_query_ctx);
tupstore = tuplestore_begin_heap(true, false, work_mem);
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = tupdesc;
MemoryContextSwitchTo(oldcontext);
for (i = 0; i < sizeof(polar_stat_proxy_infos) / sizeof(char *); ++i)
{
values[0] = CStringGetTextDatum(polar_stat_proxy_infos[i]);
values[1] = UInt64GetDatum((&polar_stat_proxy->proxy_total)[i]);
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
}
/* clean up and return the tuplestore */
tuplestore_donestoring(tupstore);
return (Datum) 0;
}
/*
* POLAR: reset the proxy stat info
*/
PG_FUNCTION_INFO_V1(polar_stat_reset_proxy_info);
Datum
polar_stat_reset_proxy_info(PG_FUNCTION_ARGS)
{
MemSet(polar_stat_proxy, 0, sizeof(PolarStat_Proxy));
PG_RETURN_NULL();
}
/*
* POLAR: get real pid and virtual pid
*/
PG_FUNCTION_INFO_V1(polar_stat_get_real_pid);
Datum
polar_stat_get_real_pid(PG_FUNCTION_ARGS)
{
int pid = PG_ARGISNULL(0) ? MyProcPid : PG_GETARG_INT32(0);
if (!PG_ARGISNULL(0) && !POLAR_IS_VIRTUAL_PID(pid))
elog(ERROR, "POLAR: Invalid virtual pid: %d, should between (10^7, 2*10^7)", pid);
PG_RETURN_INT32(polar_pgstat_get_real_pid(pid, 0, false, true));
}
PG_FUNCTION_INFO_V1(polar_stat_get_virtual_pid);
Datum
polar_stat_get_virtual_pid(PG_FUNCTION_ARGS)
{
int pid = PG_ARGISNULL(0) ? MyProcPid : PG_GETARG_INT32(0);
if (!PG_ARGISNULL(0) && !POLAR_IS_REAL_PID(pid))
elog(ERROR, "POLAR: Invalid real pid: %d, should between (0, 10^7)", pid);
PG_RETURN_INT32(polar_pgstat_get_virtual_pid(pid, true));
}