@@ -107,6 +107,7 @@ PG_FUNCTION_INFO_V1(mtm_recover_node);
107107PG_FUNCTION_INFO_V1 (mtm_get_snapshot );
108108PG_FUNCTION_INFO_V1 (mtm_get_nodes_state );
109109PG_FUNCTION_INFO_V1 (mtm_get_cluster_state );
110+ PG_FUNCTION_INFO_V1 (mtm_get_cluster_info );
110111PG_FUNCTION_INFO_V1 (mtm_make_table_local );
111112PG_FUNCTION_INFO_V1 (mtm_dump_lock_graph );
112113
@@ -1608,7 +1609,7 @@ _PG_init(void)
16081609"Minamal amount of time (milliseconds) to wait 2PC confirmation from all nodes" ,
16091610"Timeout for 2PC is calculated as MAX(prepare_time*2pc_prepare_ratio/100,2pc_min_timeout)" ,
16101611& Mtm2PCMinTimeout ,
1611- 10000 ,
1612+ 100000 , /* 100 seconds */
161216130 ,
16131614INT_MAX ,
16141615PGC_BACKEND ,
@@ -1623,7 +1624,7 @@ _PG_init(void)
16231624"Percent of prepare time for maximal time of second phase of two-pahse commit" ,
16241625"Timeout for 2PC is calculated as MAX(prepare_time*2pc_prepare_ratio/100,2pc_min_timeout)" ,
16251626& Mtm2PCPrepareRatio ,
1626- 100 ,
1627+ 1000 , /* 10 times */
162716280 ,
16281629INT_MAX ,
16291630PGC_BACKEND ,
@@ -2177,10 +2178,9 @@ mtm_get_snapshot(PG_FUNCTION_ARGS)
21772178typedef struct
21782179{
21792180int nodeId ;
2180- char * connStrPtr ;
21812181TupleDesc desc ;
2182- Datum values [8 ];
2183- bool nulls [8 ];
2182+ Datum values [Natts_mtm_nodes_state ];
2183+ bool nulls [Natts_mtm_nodes_state ];
21842184}MtmGetNodeStateCtx ;
21852185
21862186Datum
@@ -2189,7 +2189,6 @@ mtm_get_nodes_state(PG_FUNCTION_ARGS)
21892189FuncCallContext * funcctx ;
21902190MtmGetNodeStateCtx * usrfctx ;
21912191MemoryContext oldcontext ;
2192- char * p ;
21932192int64 lag ;
21942193bool is_first_call = SRF_IS_FIRSTCALL ();
21952194
@@ -2199,7 +2198,6 @@ mtm_get_nodes_state(PG_FUNCTION_ARGS)
21992198usrfctx = (MtmGetNodeStateCtx * )palloc (sizeof (MtmGetNodeStateCtx ));
22002199get_call_result_type (fcinfo ,NULL ,& usrfctx -> desc );
22012200usrfctx -> nodeId = 1 ;
2202- usrfctx -> connStrPtr = pstrdup (MtmConnStrs );
22032201memset (usrfctx -> nulls , false,sizeof (usrfctx -> nulls ));
22042202funcctx -> user_fctx = usrfctx ;
22052203MemoryContextSwitchTo (oldcontext );
@@ -2218,23 +2216,19 @@ mtm_get_nodes_state(PG_FUNCTION_ARGS)
22182216usrfctx -> nulls [4 ]= lag < 0 ;
22192217usrfctx -> values [5 ]= Int64GetDatum (Mtm -> transCount ?Mtm -> nodes [usrfctx -> nodeId - 1 ].transDelay /Mtm -> transCount :0 );
22202218usrfctx -> values [6 ]= TimestampTzGetDatum (time_t_to_timestamptz (Mtm -> nodes [usrfctx -> nodeId - 1 ].lastStatusChangeTime ));
2221- p = strchr (usrfctx -> connStrPtr ,',' );
2222- if (p != NULL ) {
2223- * p ++ = '\0' ;
2224- }
2225- usrfctx -> values [7 ]= CStringGetTextDatum (usrfctx -> connStrPtr );
2226- usrfctx -> connStrPtr = p ;
2219+ usrfctx -> values [7 ]= CStringGetTextDatum (Mtm -> nodes [usrfctx -> nodeId - 1 ].con .connStr );
22272220usrfctx -> nodeId += 1 ;
22282221
22292222SRF_RETURN_NEXT (funcctx ,HeapTupleGetDatum (heap_form_tuple (usrfctx -> desc ,usrfctx -> values ,usrfctx -> nulls )));
22302223}
22312224
2225+
22322226Datum
22332227mtm_get_cluster_state (PG_FUNCTION_ARGS )
22342228{
22352229TupleDesc desc ;
2236- Datum values [10 ];
2237- bool nulls [10 ]= {false};
2230+ Datum values [Natts_mtm_cluster_state ];
2231+ bool nulls [Natts_mtm_cluster_state ]= {false};
22382232get_call_result_type (fcinfo ,NULL ,& desc );
22392233
22402234values [0 ]= CStringGetTextDatum (MtmNodeStatusMnem [Mtm -> status ]);
@@ -2243,16 +2237,73 @@ mtm_get_cluster_state(PG_FUNCTION_ARGS)
22432237values [3 ]= Int64GetDatum (Mtm -> nodeLockerMask );
22442238values [4 ]= Int32GetDatum (Mtm -> nNodes );
22452239values [5 ]= Int32GetDatum ((int )Mtm -> pool .active );
2246- values [6 ]= Int64GetDatum ( BgwPoolGetQueueSize ( & Mtm -> pool ) );
2247- values [7 ]= Int64GetDatum (Mtm -> transCount );
2248- values [8 ]= Int64GetDatum (Mtm -> timeShift );
2249- values [9 ]= Int32GetDatum (Mtm -> recoverySlot );
2250- nulls [ 9 ]= Mtm -> recoverySlot == 0 ;
2240+ values [6 ]= Int32GetDatum (( int ) Mtm -> pool . pending );
2241+ values [7 ]= Int64GetDatum (BgwPoolGetQueueSize ( & Mtm -> pool ) );
2242+ values [8 ]= Int64GetDatum (Mtm -> transCount );
2243+ values [9 ]= Int64GetDatum (Mtm -> timeShift );
2244+ values [ 10 ]= Int32GetDatum ( Mtm -> recoverySlot ) ;
22512245
22522246PG_RETURN_DATUM (HeapTupleGetDatum (heap_form_tuple (desc ,values ,nulls )));
22532247}
22542248
22552249
2250+ typedef struct
2251+ {
2252+ int nodeId ;
2253+ }MtmGetClusterInfoCtx ;
2254+
2255+
2256+ Datum
2257+ mtm_get_cluster_info (PG_FUNCTION_ARGS )
2258+ {
2259+
2260+ FuncCallContext * funcctx ;
2261+ MtmGetClusterInfoCtx * usrfctx ;
2262+ MemoryContext oldcontext ;
2263+ TupleDesc desc ;
2264+ bool is_first_call = SRF_IS_FIRSTCALL ();
2265+ int i ;
2266+ PGconn * conn ;
2267+ PGresult * result ;
2268+ char * values [Natts_mtm_cluster_state ];
2269+ HeapTuple tuple ;
2270+
2271+ if (is_first_call ) {
2272+ funcctx = SRF_FIRSTCALL_INIT ();
2273+ oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
2274+ usrfctx = (MtmGetClusterInfoCtx * )palloc (sizeof (MtmGetNodeStateCtx ));
2275+ get_call_result_type (fcinfo ,NULL ,& desc );
2276+ funcctx -> attinmeta = TupleDescGetAttInMetadata (desc );
2277+ usrfctx -> nodeId = 1 ;
2278+ funcctx -> user_fctx = usrfctx ;
2279+ MemoryContextSwitchTo (oldcontext );
2280+ }
2281+ funcctx = SRF_PERCALL_SETUP ();
2282+ usrfctx = (MtmGetClusterInfoCtx * )funcctx -> user_fctx ;
2283+ if (usrfctx -> nodeId > MtmNodes ) {
2284+ SRF_RETURN_DONE (funcctx );
2285+ }
2286+ conn = PQconnectdb (Mtm -> nodes [usrfctx -> nodeId - 1 ].con .connStr );
2287+ if (PQstatus (conn )!= CONNECTION_OK ) {
2288+ elog (ERROR ,"Failed to establish connection '%s' to node %d" ,Mtm -> nodes [usrfctx -> nodeId - 1 ].con .connStr ,usrfctx -> nodeId );
2289+ }
2290+ result = PQexec (conn ,"select * from mtm.get_cluster_state()" );
2291+
2292+ if (PQresultStatus (result )!= PGRES_TUPLES_OK || PQntuples (result )!= 1 ) {
2293+ elog (ERROR ,"Failed to receive data from %d" ,usrfctx -> nodeId );
2294+ }
2295+
2296+ for (i = 0 ;i < Natts_mtm_cluster_state ;i ++ ) {
2297+ values [i ]= PQgetvalue (result ,0 ,i );
2298+ }
2299+ tuple = BuildTupleFromCStrings (funcctx -> attinmeta ,values );
2300+ PQclear (result );
2301+ PQfinish (conn );
2302+ usrfctx -> nodeId += 1 ;
2303+ SRF_RETURN_NEXT (funcctx ,HeapTupleGetDatum (tuple ));
2304+ }
2305+
2306+
22562307Datum mtm_make_table_local (PG_FUNCTION_ARGS )
22572308{
22582309Oid reloid = PG_GETARG_OID (1 );