static int
get_remote_relstat(char *nspname, char *relname, bool istemp, bool replicated,
int32 *pages, int32 *allvisiblepages,
- float4 *tuples, TransactionId *frozenXid)
+ float4 *tuples,
+ TransactionId *frozenXid,
+ MultiXactId *multiXid)
{
StringInfoData query;
EState *estate;
int validpages,
validtuples,
validfrozenxids,
- validallvisiblepages;
+ validallvisiblepages,
+ validminmxids;
/* Make up query string */
initStringInfo(&query);
appendStringInfo(&query, "SELECT c.relpages, "
"c.reltuples, "
"c.relallvisible, "
- "c.relfrozenxid "
+ "c.relfrozenxid, "
+ "c.relminmxid "
"FROM pg_class c "
"WHERE c.relnamespace = pg_my_temp_schema() "
"AND c.relname = '%s'",
appendStringInfo(&query, "SELECT c.relpages, "
"c.reltuples, "
"c.relallvisible, "
- "c.relfrozenxid "
+ "c.relfrozenxid, "
+ "c.relminmxid "
"FROM pg_class c JOIN pg_namespace n "
"ON c.relnamespace = n.oid "
"WHERE n.nspname = '%s' "
make_relation_tle(RelationRelationId,
"pg_class",
"relfrozenxid"));
+ step->scan.plan.targetlist = lappend(step->scan.plan.targetlist,
+ make_relation_tle(RelationRelationId,
+ "pg_class",
+ "relminmxid"));
/* Execute query on the data nodes */
estate = CreateExecutorState();
*allvisiblepages = 0;
*tuples = 0.0;
*frozenXid = InvalidTransactionId;
+ *multiXid = InvalidMultiXactId;
validpages = 0;
validallvisiblepages = 0;
validtuples = 0;
validfrozenxids = 0;
+ validminmxids = 0;
result = ExecRemoteQuery((PlanState *) node);
while (result != NULL && !TupIsNull(result))
{
if (TransactionIdIsValid(xid))
{
validfrozenxids++;
- if (!TransactionIdIsValid(*frozenXid) ||
- TransactionIdPrecedes(xid, *frozenXid))
- {
+ if (!TransactionIdIsValid(*frozenXid) || TransactionIdPrecedes(xid, *frozenXid))
*frozenXid = xid;
- }
}
}
+ value = slot_getattr(result, 5, &isnull); /* relminmxid */
+ if (!isnull)
+ {
+ /*
+ * relminmxid on coordinator should be the lowest one from the
+ * datanodes.
+ */
+ MultiXactId mxid = DatumGetTransactionId(value);
+ if (MultiXactIdIsValid(mxid))
+ {
+ validminmxids++;
+ if (!MultiXactIdIsValid(*multiXid) || MultiXactIdPrecedes(mxid, *multiXid))
+ *multiXid = mxid;
+ }
+ }
+
/* fetch next */
result = ExecRemoteQuery((PlanState *) node);
}
*allvisiblepages /= validallvisiblepages;
}
+ /*
+ * If some node returned invalid value for frozenxid we can not set
+ * it on coordinator. There are other cases when returned value of
+ * frozenXid should be ignored, these cases are checked by caller.
+ * Basically, to be sure, there should be one value from each node,
+ * where the table is partitioned.
+ */
if (validfrozenxids < validpages || validfrozenxids < validtuples)
- {
- /*
- * If some node returned invalid value for frozenxid we can not set
- * it on coordinator. There are other cases when returned value of
- * frozenXid should be ignored, these cases are checked by caller.
- * Basically, to be sure, there should be one value from each node,
- * where the table is partitioned.
- */
*frozenXid = InvalidTransactionId;
- return Max(validpages, validtuples);
- }
- else
- {
- return validfrozenxids;
- }
+
+ if (validminmxids < validpages || validminmxids < validtuples)
+ *multiXid = InvalidMultiXactId;
+
+ return Max(validpages, validtuples);
}
int32 num_allvisible_pages;
float4 num_tuples;
TransactionId min_frozenxid;
+ MultiXactId min_mxid;
bool hasindex;
bool replicated;
int rel_nodes;
*/
rel_nodes = get_remote_relstat(nspname, relname, istemp, replicated,
&num_pages, &num_allvisible_pages,
- &num_tuples, &min_frozenxid);
+ &num_tuples,
+ &min_frozenxid,
+ &min_mxid);
if (rel_nodes > 0)
{
int nindexes;
{
int32 idx_pages, idx_allvisible_pages;
float4 idx_tuples;
- TransactionId idx_frozenxid;
+ TransactionId idx_frozenxid;
+ MultiXactId idx_mxid;
int idx_nodes;
/* Get the index identifier */
idx_nodes = get_remote_relstat(nspname, relname, istemp,
replicated,
&idx_pages, &idx_allvisible_pages,
- &idx_tuples, &idx_frozenxid);
+ &idx_tuples, &idx_frozenxid,
+ &idx_mxid);
if (idx_nodes > 0)
{
/*
0,
false,
idx_frozenxid,
- InvalidMultiXactId,
+ idx_mxid,
is_outer);
}
}
if (rel_nodes < nodes)
{
min_frozenxid = InvalidTransactionId;
+ min_mxid = InvalidMultiXactId;
}
/* save changes */
num_allvisible_pages,
hasindex,
min_frozenxid,
- InvalidMultiXactId,
+ min_mxid,
is_outer);
}
}