pgpool2.git / summary / log / commit / refs

commit    aa516eeaa9fce2520d3ea2502d1428b64deea16d
Author:   Bo Peng <pengbo@sraoss.co.jp>
Date:     Tue Jun 15 02:46:57 2021 +0000

    New feature: Allow pcp_node_ino to list all backend nodes information.


doc.ja/src/sgml/ref/pcp_node_info.sgml | 85 ++++++++++------ doc/src/sgml/ref/pcp_node_info.sgml | 105 +++++++++++-------- src/libs/pcp/pcp.c | 34 +++++-- src/pcp_con/pcp_worker.c | 179 +++++++++++++++++++++------------ src/tools/pcp/pcp_frontend_client.c | 71 +++++++------ 5 files changed, 299 insertions(+), 175 deletions(-) diff --git a/doc.ja/src/sgml/ref/pcp_node_info.sgml b/doc.ja/src/sgml/ref/pcp_node_info.sgml index cf3b692c9..eca3f3899 100644 --- a/doc.ja/src/sgml/ref/pcp_node_info.sgml +++ b/doc.ja/src/sgml/ref/pcp_node_info.sgml @@ -66,6 +66,19 @@ Pgpool-II documentation </listitem> </varlistentry> + <varlistentry> + <term><option>-a</option></term> + <term><option>--all</option></term> + <listitem> + <para> + <!-- + Display all backend nodes informatio. + --> + すべてのバックエンドノードの情報を表示します。 + </para> + </listitem> + </varlistentry> + <varlistentry> <!-- <term><option>Other options </option></term> @@ -95,8 +108,8 @@ Pgpool-II documentation --> ここでは例を示します。 <programlisting> - $ pcp_node_info -w -p 11001 1 - /tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 +$ pcp_node_info -w -p 11001 -n 1 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 </programlisting> </para> <para> @@ -119,36 +132,25 @@ Pgpool-II documentation 11. sync replication state (PostgreSQL 9.2以降。pg_stat_replicationから取得) 12. last status change time --> - 1. ノードのホスト名 - 2. ノードのポート番号 - 3. ステータス - 4. ロードバランスウェイト - 5. バックエンド状態名 - 6. 実際のバックエンドの状態 (Pgpool-II 4.3以降。pg_isreadyで取得) - 7. バックエンドの役割 - 8. 実際のバックエンドの役割(Pgpool-II 4.3以降。pg_is_in_recoveryで取得) - 9. レプリケーションの遅延 - 10. レプリケーション状態 (Pgpool-II 4.1以降。pg_stat_replicationから取得) - 11. 同期レプリケーション状態 (Pgpool-II 4.1以降。pg_stat_replicationから取得) - 12. 最終ステータス変更時刻 +1. ノードのホスト名 +2. ノードのポート番号 +3. ステータス +4. ロードバランスウェイト +5. バックエンド状態名 +6. 実際のバックエンドの状態 (Pgpool-II 4.3以降。pg_isreadyで取得) +7. バックエンドの役割 +8. 実際のバックエンドの役割(Pgpool-II 4.3以降。pg_is_in_recoveryで取得) +9. レプリケーションの遅延 +10. レプリケーション状態 (Pgpool-II 4.1以降。pg_stat_replicationから取得) +11. 同期レプリケーション状態 (Pgpool-II 4.1以降。pg_stat_replicationから取得) +12. 最終ステータス変更時刻 </literallayout> </para> <para> <!-- - Status is represented by a digit from [0 to 3]. + 3 (status) is represented by a digit from [0 to 3]. --> - 9, 10, 11は、<xref linkend="guc-sr-check-period">が0以外でなければ正しく表示されません。 - また、10, 11は、<xref linkend="guc-sr-check-user">が<productname>PostgreSQL</productname>のスーパーユーザーであるか、"pg_monitor"グループに所属していなけれ正しく表示されません。 - <note> - <para> - <xref linkend="guc-sr-check-user">をpg_monitorグループに所属させるには、以下のSQLコマンドを<productname>PostgreSQL</productname>スーパーユーザーで実行してください("sr_check_user"を<xref linkend="guc-sr-check-user">の設定値で置き換えてください) - <programlisting> - GRANT pg_monitor TO sr_check_user; - </programlisting> - <productname>PostgreSQL</productname> 9.6にはpg_monitorグループがないので、<xref linkend="guc-sr-check-user">は<productname>PostgreSQL</productname>のスーパーユーザーでなければなりません。 - </para> - </note> - ステータスは [0..3] までの数字で表わされます。各数字の意味は以下のとおりです。 + 3 (ステータス)は [0..3] までの数字で表わされます。各数字の意味は以下のとおりです。 </para> <para> <itemizedlist> @@ -164,6 +166,12 @@ Pgpool-II documentation <listitem><para>3 - ノードダウン </para></listitem> </itemizedlist> </para> + <para> + <!-- + 4 (load balance weight) is displayed in normalized format. + --> + 4 (ロードバランスウェイト)は0から1に正規化されたフォーマットで出力されます。 + </para> <para> 6は実際のバックエンドの状態をリアルタイムで取得して表示します。 情報の取得は、このコマンドが実行された時に<function>PQpingParams</function>を呼び出すことによって行われます。 @@ -180,12 +188,31 @@ Pgpool-II documentation それ以外のモードでは、"main"あるいは"replica"と表示されます。 ストリーミングレプリケーションモードと違って、<function>pg_is_in_recovery</function>は呼び出されず、7と8が異なる値になることはありません。 </para> + <para> + 9, 10, 11は、<xref linkend="guc-sr-check-period">が0以外でなければ正しく表示されません。 + また、10, 11は、<xref linkend="guc-sr-check-user">が<productname>PostgreSQL</productname>のスーパーユーザーであるか、"pg_monitor"グループに所属していなけれ正しく表示されません。 + <note> + <para> + <xref linkend="guc-sr-check-user">をpg_monitorグループに所属させるには、以下のSQLコマンドを<productname>PostgreSQL</productname>スーパーユーザーで実行してください("sr_check_user"を<xref linkend="guc-sr-check-user">の設定値で置き換えてください) + <programlisting> +GRANT pg_monitor TO sr_check_user; + </programlisting> + <productname>PostgreSQL</productname> 9.6にはpg_monitorグループがないので、<xref linkend="guc-sr-check-user">は<productname>PostgreSQL</productname>のスーパーユーザーでなければなりません。 + </para> + </note> + </para> <para> <!-- - The load balance weight is displayed in normalized format. + The <option>-a</option> or <option>all</option> option lists all backend nodes information. --> - ロードバランスウェイトは0から1に正規化されたフォーマットで出力されます。 + <option>-a</option>または <option>--all</option>オプションはすべてのバックエンドノードの情報を表示します。 </para> + <programlisting> +$ pcp_node_info -w -p 11001 -a +/tmp 11002 1 0.500000 waiting up primary primary 0 none none 2021-02-27 14:51:30 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 + </programlisting> + <para> <!-- The <option>verbose</option> option can help understand the output. For example: diff --git a/doc/src/sgml/ref/pcp_node_info.sgml b/doc/src/sgml/ref/pcp_node_info.sgml index 3ad2a0021..25b2ce95b 100644 --- a/doc/src/sgml/ref/pcp_node_info.sgml +++ b/doc/src/sgml/ref/pcp_node_info.sgml @@ -51,6 +51,16 @@ Pgpool-II documentation </listitem> </varlistentry> + <varlistentry> + <term><option>-a</option></term> + <term><option>--all</option></term> + <listitem> + <para> + Display all backend nodes informatio. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>Other options </option></term> <listitem> @@ -68,56 +78,38 @@ Pgpool-II documentation <para> Here is an example output: <programlisting> - $ pcp_node_info -w -p 11001 1 - /tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 +$ pcp_node_info -w -p 11001 -n 1 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 </programlisting> </para> <para> The result is in the following order: <literallayout class="monospaced"> - 1. hostname - 2. port number - 3. status - 4. load balance weight - 5. status name - 6. actual backend status - 7. backend role - 8. actual backend role (taken from pg_is_in_recovery. Pgpool-II 4.3 or later) - 9. replication delay - 10. replication state (taken from pg_stat_replication. Pgpool-II 4.1 or later) - 11. sync replication state (taken from pg_stat_replication. Pgpool-II 4.1 or later) - 12. last status change time +1. hostname +2. port number +3. status +4. load balance weight +5. status name +6. actual backend status +7. backend role +8. actual backend role (taken from pg_is_in_recovery. Pgpool-II 4.3 or later) +9. replication delay +10. replication state (taken from pg_stat_replication. Pgpool-II 4.1 or later) +11. sync replication state (taken from pg_stat_replication. Pgpool-II 4.1 or later) +12. last status change time </literallayout> </para> <para> - Status is represented by a digit from [0 to 3]. To correctly 9, - 10, 11 are displayed, <xref linkend="guc-sr-check-period"> must not - be 0. 10, 11 will not be displayed - if <xref linkend="guc-sr-check-user"> is - not <productname>PostgreSQL</productname> super user nor it's not - in "pg_monitor" group. - <note> - <para> - To make <xref linkend="guc-sr-check-user"> in pg_monitor - group, execute following SQL command - by <productname>PostgreSQL</productname> super user (replace - "sr_check_user" with the setting - of <xref linkend="guc-sr-check-user">): - <programlisting> - GRANT pg_monitor TO sr_check_user; - </programlisting> - For <productname>PostgreSQL</productname> 9.6, there's no - pg_monitor group and <xref linkend="guc-sr-check-user"> must - be <productname>PostgreSQL</productname> super user. - </para> - </note> - - <itemizedlist> - <listitem><para>0 - This state is only used during the initialization. PCP will never display it. </para></listitem> - <listitem><para>1 - Node is up. No connections yet. </para></listitem> - <listitem><para>2 - Node is up. Connections are pooled. </para></listitem> - <listitem><para>3 - Node is down. </para></listitem> - </itemizedlist> + 3 (status) is represented by a digit from [0 to 3]. + <itemizedlist> + <listitem><para>0 - This state is only used during the initialization. PCP will never display it. </para></listitem> + <listitem><para>1 - Node is up. No connections yet. </para></listitem> + <listitem><para>2 - Node is up. Connections are pooled. </para></listitem> + <listitem><para>3 - Node is down. </para></listitem> + </itemizedlist> + </para> + <para> + 4 (load balance weight) is displayed in normalized format (0 - 1). </para> <para> 6 shows the backend status in real time. The info is obtained by @@ -147,8 +139,35 @@ Pgpool-II documentation 7 and 8 will be always the same. </para> <para> - The load balance weight is displayed in normalized format (0 - 1). + To correctly 9, 10, 11 are displayed, <xref linkend="guc-sr-check-period"> must not + be 0. 10, 11 will not be displayed + if <xref linkend="guc-sr-check-user"> is + not <productname>PostgreSQL</productname> super user nor it's not + in "pg_monitor" group. + <note> + <para> + To make <xref linkend="guc-sr-check-user"> in pg_monitor + group, execute following SQL command + by <productname>PostgreSQL</productname> super user (replace + "sr_check_user" with the setting of <xref linkend="guc-sr-check-user">): + <programlisting> +GRANT pg_monitor TO sr_check_user; + </programlisting> + For <productname>PostgreSQL</productname> 9.6, there's no + pg_monitor group and <xref linkend="guc-sr-check-user"> must + be <productname>PostgreSQL</productname> super user. + </para> + </note> + </para> + <para> + The <option>-a</option> or <option>--all</option> option lists all backend nodes information. </para> + <programlisting> +$ pcp_node_info -w -p 11001 -a +/tmp 11002 1 0.500000 waiting up primary primary 0 none none 2021-02-27 14:51:30 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 + </programlisting> + <para> The <option>--verbose</option> option can help understand the output. For example: </para> diff --git a/src/libs/pcp/pcp.c b/src/libs/pcp/pcp.c index 052ff1e41..e0c9785f4 100644 --- a/src/libs/pcp/pcp.c +++ b/src/libs/pcp/pcp.c @@ -698,12 +698,31 @@ pcp_node_count(PCPConnInfo * pcpConn) static void process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) { + char *index; BackendInfo *backend_info = NULL; - if (strcmp(buf, "CommandComplete") == 0) + if (strcmp(buf, "ArraySize") == 0) + { + int ci_size; + + index = (char *) memchr(buf, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + index += 1; + ci_size = atoi(index); + + setResultStatus(pcpConn, PCP_RES_INCOMPLETE); + setResultSlotCount(pcpConn, ci_size); + pcpConn->pcpResInfo->nextFillSlot = 0; + return; + } + else if (strcmp(buf, "NodeInfo") == 0) { char *index = NULL; + if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) + goto INVALID_RESPONSE; + backend_info = (BackendInfo *) palloc(sizeof(BackendInfo)); index = (char *) memchr(buf, '\0', len); @@ -772,7 +791,7 @@ process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) index = (char *) memchr(index, '\0', len); if (index == NULL) goto INVALID_RESPONSE; - + index++; backend_info->status_changed_time = atol(index); @@ -783,17 +802,14 @@ process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) backend_info, sizeof(BackendInfo), NULL) < 0) goto INVALID_RESPONSE; - setCommandSuccessful(pcpConn); + return; } - else + else if (strcmp(buf, "CommandComplete") == 0) { - pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"", buf); - setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + setResultStatus(pcpConn, PCP_RES_COMMAND_OK); + return; } - return; - INVALID_RESPONSE: if (backend_info) diff --git a/src/pcp_con/pcp_worker.c b/src/pcp_con/pcp_worker.c index 201f11049..f391d3177 100644 --- a/src/pcp_con/pcp_worker.c +++ b/src/pcp_con/pcp_worker.c @@ -839,86 +839,135 @@ inform_node_info(PCP_CONNECTION * frontend, char *buf) int nrows; int node_id; int wsize; - char port_str[6]; - char status[2]; - char weight_str[20]; - char role_str[10]; - char standby_delay_str[20]; - char status_changed_time_str[20]; - char code[] = "CommandComplete"; - BackendInfo *bi = NULL; - SERVER_ROLE role; + int i; - node_id = atoi(buf); - bi = pool_get_node_info(node_id); + node_id = atoi(buf); - if (bi == NULL) + if ((node_id != -1) && (pool_get_node_info(node_id) == NULL)) + { ereport(ERROR, (errmsg("informing node info failed"), - errdetail("invalid node ID"))); - - ereport(DEBUG2, - (errmsg("PCP: informing node info"), - errdetail("retrieved node information from shared memory"))); - - snprintf(port_str, sizeof(port_str), "%d", bi->backend_port); - snprintf(status, sizeof(status), "%d", bi->backend_status); - snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight); - - if (STREAM) - { - if (Req_info->primary_node_id == node_id) - role = ROLE_PRIMARY; - else - role = ROLE_STANDBY; + errdetail("invalid node ID : %s", buf))); } else { - if (Req_info->main_node_id == node_id) - role = ROLE_MAIN; + /* First, send array size of node_info */ + char arr_code[] = "ArraySize"; + char node_info_size[16]; + + /* Finally, indicate that all data is sent */ + char fin_code[] = "CommandComplete"; + + nodes = get_nodes(&nrows); + + if (node_id == -1) + { + snprintf(node_info_size, sizeof(node_info_size), "%d", NUM_BACKENDS); + } else - role = ROLE_REPLICA; - } - snprintf(role_str, sizeof(role_str), "%d", role); + { + snprintf(node_info_size, sizeof(node_info_size), "%d", 1); + } + + pcp_write(frontend, "i", 1); + wsize = htonl(sizeof(arr_code) + + strlen(node_info_size) + 1 + + sizeof(int)); + pcp_write(frontend, &wsize, sizeof(int)); + pcp_write(frontend, arr_code, sizeof(arr_code)); + pcp_write(frontend, node_info_size, strlen(node_info_size) + 1); + do_pcp_flush(frontend); + + /* Second, send process information for all connection_info */ + for (i = 0; i < NUM_BACKENDS ; i++) + { + char port_str[6]; + char status[2]; + char weight_str[20]; + char role_str[10]; + char standby_delay_str[20]; + char status_changed_time_str[20]; + char code[] = "NodeInfo"; + BackendInfo *bi = NULL; + SERVER_ROLE role; + + if (node_id != -1 && node_id != atoi(nodes[i].node_id)) + continue; - snprintf(standby_delay_str, sizeof(standby_delay_str), UINT64_FORMAT, bi->standby_delay); + bi = pool_get_node_info(i); - snprintf(status_changed_time_str, sizeof(status_changed_time_str), UINT64_FORMAT, bi->status_changed_time); + if (bi == NULL) + ereport(ERROR, + (errmsg("informing node info failed"), + errdetail("invalid node ID"))); - nodes = get_nodes(&nrows); + snprintf(port_str, sizeof(port_str), "%d", bi->backend_port); + snprintf(status, sizeof(status), "%d", bi->backend_status); + snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight); - pcp_write(frontend, "i", 1); - wsize = htonl(sizeof(code) + - strlen(bi->backend_hostname) + 1 + - strlen(port_str) + 1 + - strlen(status) + 1 + - strlen(nodes[node_id].pg_status) + 1 + - strlen(weight_str) + 1 + - strlen(role_str) + 1 + - strlen(nodes[node_id].pg_role) + 1 + - strlen(standby_delay_str) + 1 + - strlen(bi->replication_state) + 1 + - strlen(bi->replication_sync_state) + 1 + - strlen(status_changed_time_str) + 1 + - sizeof(int)); - pcp_write(frontend, &wsize, sizeof(int)); - pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname) + 1); - pcp_write(frontend, port_str, strlen(port_str) + 1); - pcp_write(frontend, status, strlen(status) + 1); - pcp_write(frontend, nodes[node_id].pg_status, strlen(nodes[node_id].pg_status) + 1); - pcp_write(frontend, weight_str, strlen(weight_str) + 1); - pcp_write(frontend, role_str, strlen(role_str) + 1); - pcp_write(frontend, nodes[node_id].pg_role, strlen(nodes[node_id].pg_role) + 1); - pcp_write(frontend, standby_delay_str, strlen(standby_delay_str) + 1); - pcp_write(frontend, bi->replication_state, strlen(bi->replication_state) + 1); - pcp_write(frontend, bi->replication_sync_state, strlen(bi->replication_sync_state) + 1); - pcp_write(frontend, status_changed_time_str, strlen(status_changed_time_str) + 1); + if (STREAM) + { + if (Req_info->primary_node_id == i) + role = ROLE_PRIMARY; + else + role = ROLE_STANDBY; + } + else + { + if (Req_info->main_node_id == i) + role = ROLE_MAIN; + else + role = ROLE_REPLICA; + } + snprintf(role_str, sizeof(role_str), "%d", role); - do_pcp_flush(frontend); + snprintf(standby_delay_str, sizeof(standby_delay_str), UINT64_FORMAT, bi->standby_delay); + + snprintf(status_changed_time_str, sizeof(status_changed_time_str), UINT64_FORMAT, bi->status_changed_time); - pfree(nodes); + pcp_write(frontend, "i", 1); + wsize = htonl(sizeof(code) + + strlen(bi->backend_hostname) + 1 + + strlen(port_str) + 1 + + strlen(status) + 1 + + strlen(nodes[i].pg_status) + 1 + + strlen(weight_str) + 1 + + strlen(role_str) + 1 + + strlen(nodes[i].pg_role) + 1 + + strlen(standby_delay_str) + 1 + + strlen(bi->replication_state) + 1 + + strlen(bi->replication_sync_state) + 1 + + strlen(status_changed_time_str) + 1 + + sizeof(int)); + pcp_write(frontend, &wsize, sizeof(int)); + pcp_write(frontend, code, sizeof(code)); + pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname) + 1); + pcp_write(frontend, port_str, strlen(port_str) + 1); + pcp_write(frontend, status, strlen(status) + 1); + pcp_write(frontend, nodes[i].pg_status, strlen(nodes[i].pg_status) + 1); + pcp_write(frontend, weight_str, strlen(weight_str) + 1); + pcp_write(frontend, role_str, strlen(role_str) + 1); + pcp_write(frontend, nodes[i].pg_role, strlen(nodes[i].pg_role) + 1); + pcp_write(frontend, standby_delay_str, strlen(standby_delay_str) + 1); + pcp_write(frontend, bi->replication_state, strlen(bi->replication_state) + 1); + pcp_write(frontend, bi->replication_sync_state, strlen(bi->replication_sync_state) + 1); + pcp_write(frontend, status_changed_time_str, strlen(status_changed_time_str) + 1); + do_pcp_flush(frontend); + } + + pcp_write(frontend, "i", 1); + wsize = htonl(sizeof(fin_code) + + sizeof(int)); + pcp_write(frontend, &wsize, sizeof(int)); + pcp_write(frontend, fin_code, sizeof(fin_code)); + do_pcp_flush(frontend); + ereport(DEBUG1, + (errmsg("PCP informing node info"), + errdetail("retrieved node information from shared memory"))); + + pfree(nodes); + } } /* diff --git a/src/tools/pcp/pcp_frontend_client.c b/src/tools/pcp/pcp_frontend_client.c index 8ace0a90b..b0712099c 100644 --- a/src/tools/pcp/pcp_frontend_client.c +++ b/src/tools/pcp/pcp_frontend_client.c @@ -48,7 +48,7 @@ static void output_watchdog_info_result(PCPResultInfo * pcpResInfo, bool verbose static void output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose); static void output_proccount_result(PCPResultInfo * pcpResInfo, bool verbose); static void output_poolstatus_result(PCPResultInfo * pcpResInfo, bool verbose); -static void output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool verbose); +static void output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose); static void output_health_check_stats_result(PCPResultInfo * pcpResInfo, bool verbose); static void output_nodecount_result(PCPResultInfo * pcpResInfo, bool verbose); static char *backend_status_to_string(BackendInfo * bi); @@ -85,7 +85,7 @@ struct AppTypes AllAppTypes[] = {"pcp_attach_node", PCP_ATTACH_NODE, "n:h:p:U:wWvd", "attach a node from pgpool-II"}, {"pcp_detach_node", PCP_DETACH_NODE, "n:h:p:U:gwWvd", "detach a node from pgpool-II"}, {"pcp_node_count", PCP_NODE_COUNT, "h:p:U:wWvd", "display the total number of nodes under pgpool-II's control"}, - {"pcp_node_info", PCP_NODE_INFO, "n:h:p:U:wWvd", "display a pgpool-II node's information"}, + {"pcp_node_info", PCP_NODE_INFO, "n:h:p:U:awWvd", "display a pgpool-II node's information"}, {"pcp_health_check_stats", PCP_HEALTH_CHECK_STATS, "n:h:p:U:wWvd", "display a pgpool-II health check stats data"}, {"pcp_pool_status", PCP_POOL_STATUS, "h:p:U:wWvd", "display pgpool configuration and status"}, {"pcp_proc_count", PCP_PROC_COUNT, "h:p:U:wWvd", "display the list of pgpool-II child process PIDs"}, @@ -324,7 +324,7 @@ main(int argc, char **argv) exit(0); } } - else if (app_require_nodeID() && nodeID < 0) + else if ((app_require_nodeID() || current_app_type->app_type == PCP_NODE_INFO) && nodeID < 0) { nodeID = atoi(argv[optind]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) @@ -348,7 +348,7 @@ main(int argc, char **argv) fprintf(stderr, "Try \"%s --help\" for more information.\n\n", progname); exit(1); } - else if (current_app_type->app_type == PCP_WATCHDOG_INFO) + else if (current_app_type->app_type == PCP_WATCHDOG_INFO || current_app_type->app_type == PCP_NODE_INFO) { nodeID = -1; } @@ -465,7 +465,7 @@ main(int argc, char **argv) output_nodecount_result(pcpResInfo, verbose); if (current_app_type->app_type == PCP_NODE_INFO) - output_nodeinfo_result(pcpResInfo, verbose); + output_nodeinfo_result(pcpResInfo, all, verbose); if (current_app_type->app_type == PCP_HEALTH_CHECK_STATS) output_health_check_stats_result(pcpResInfo, verbose); @@ -505,39 +505,42 @@ output_nodecount_result(PCPResultInfo * pcpResInfo, bool verbose) } static void -output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool verbose) +output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose) { - BackendInfo *backend_info = (BackendInfo *) pcp_get_binary_data(pcpResInfo, 0); + bool printed = false; + int i; char last_status_change[20]; struct tm tm; - - localtime_r(&backend_info->status_changed_time, &tm); - strftime(last_status_change, sizeof(last_status_change), "%F %T", &tm); + char *frmt; + int array_size = pcp_result_slot_count(pcpResInfo); if (verbose) { const char *titles[] = {"Hostname", "Port", "Status", "Weight", "Status Name", "Backend Status Name", "Role", "Backend Role", "Replication Delay", "Replication State", "Replication Sync State", "Last Status Change"}; const char *types[] = {"s", "d", "d", "f", "s", "s", "s", "s", "lu", "s", "s", "s"}; - char *format_string; - format_string = format_titles(titles, types, sizeof(titles)/sizeof(char *)); - printf(format_string, - backend_info->backend_hostname, - backend_info->backend_port, - backend_info->backend_status, - backend_info->backend_weight / RAND_MAX, - backend_status_to_string(backend_info), - backend_info->pg_backend_status, - role_to_str(backend_info->role), - backend_info->pg_role, - backend_info->standby_delay, - backend_info->replication_state, - backend_info->replication_sync_state, - last_status_change); + frmt = format_titles(titles, types, sizeof(titles)/sizeof(char *)); } else { - printf("%s %d %d %f %s %s %s %s %lu %s %s %s\n", + frmt = "%s %d %d %f %s %s %s %s %lu %s %s %s\n"; + } + + for (i = 0; i < array_size; i++) + { + + BackendInfo *backend_info = (BackendInfo *) pcp_get_binary_data(pcpResInfo, i); + + if (backend_info == NULL) + break; + if ((!all) && (backend_info->backend_hostname[0] == '\0')) + continue; + + printed = true; + localtime_r(&backend_info->status_changed_time, &tm); + strftime(last_status_change, sizeof(last_status_change), "%F %T", &tm); + + printf(frmt, backend_info->backend_hostname, backend_info->backend_port, backend_info->backend_status, @@ -547,10 +550,13 @@ output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool verbose) role_to_str(backend_info->role), backend_info->pg_role, backend_info->standby_delay, - backend_info->replication_state, - backend_info->replication_sync_state, + backend_info->replication_state[0] == '\0' ? "none" : backend_info->replication_state, + backend_info->replication_sync_state[0] == '\0' ? "none" : backend_info->replication_sync_state, last_status_change); } + + if (printed == false) + printf("No node information available\n\n"); } /* @@ -814,7 +820,6 @@ app_require_nodeID(void) { return (current_app_type->app_type == PCP_ATTACH_NODE || current_app_type->app_type == PCP_DETACH_NODE || - current_app_type->app_type == PCP_NODE_INFO || current_app_type->app_type == PCP_HEALTH_CHECK_STATS || current_app_type->app_type == PCP_PROMOTE_NODE || current_app_type->app_type == PCP_RECOVERY_NODE); @@ -855,6 +860,13 @@ usage(void) { fprintf(stderr, " -n, --node-id=NODEID ID of a backend node\n"); } + + if (current_app_type->app_type == PCP_NODE_INFO) + { + fprintf(stderr, " -n, --node-id=NODEID ID of a backend node\n"); + fprintf(stderr, " -a, --all display all backend nodes information\n"); + } + if (current_app_type->app_type == PCP_STOP_PGPOOL) { fprintf(stderr, " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n"); @@ -1003,5 +1015,6 @@ format_titles(const char **titles, const char **types, int ntitles) strncat(formatbuf, buf2, sizeof(formatbuf) - strlen(formatbuf) - 2); strcat(formatbuf, "\n"); } + strcat(formatbuf, "\n"); return formatbuf; } [parent: 5089e8ea20fd]