diff --git a/src/context/pool_process_context.c b/src/context/pool_process_context.c index 6e6402c..51b08be 100644 --- a/src/context/pool_process_context.c +++ b/src/context/pool_process_context.c @@ -292,6 +292,7 @@ pool_coninfo_set_frontend_connected(int proc_id, int pool_index) return; } con->connected = true; + con->client_connection_time = time(NULL); } } @@ -317,6 +318,7 @@ pool_coninfo_unset_frontend_connected(int proc_id, int pool_index) return; } con->connected = false; + con->client_disconnection_time = time(NULL); } } diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h index b62c3b2..237d894 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -118,6 +118,14 @@ typedef struct BackendInfo backend_info[MAX_NUM_BACKENDS]; } BackendDesc; +typedef enum +{ + WAIT_FOR_CONNECT, + COMMAND_EXECUTE, + IDLE, + IDLE_IN_TRANS +} ProcessStatus; + /* * Connection pool information. Placed on shared memory area. */ @@ -132,6 +140,9 @@ typedef struct int key; /* cancel key */ int counter; /* used counter */ time_t create_time; /* connection creation time */ + time_t client_connection_time; /* client connection time */ + time_t client_disconnection_time; /* client last disconnection time */ + int client_idle_duration; /* client idle duration time(s) */ int load_balancing_node; /* load balancing node */ char connected; /* True if frontend connected. Please note * that we use "char" instead of "bool". Since @@ -160,6 +171,8 @@ typedef struct time_t start_time; /* fork() time */ ConnectionInfo *connection_info; /* head of the connection info for * this process */ + int client_connection_count; /* how many times clients used this process */ + ProcessStatus status; char need_to_restart; /* If non 0, exit this child process as * soon as current session ends. Typical * case this flag being set is failback a @@ -181,7 +194,7 @@ typedef struct #define POOLCONFIG_MAXDATELEN 128 #define POOLCONFIG_MAXCOUNTLEN 16 #define POOLCONFIG_MAXLONGCOUNTLEN 20 - +#define POOLCONFIG_MAXPROCESSSTATUSLEN 20 /* config report struct*/ typedef struct { @@ -213,28 +226,35 @@ typedef struct typedef struct { char pool_pid[POOLCONFIG_MAXCOUNTLEN + 1]; - char start_time[POOLCONFIG_MAXDATELEN + 1]; + char process_start_time[POOLCONFIG_MAXDATELEN + 1]; + char client_connection_count[POOLCONFIG_MAXCOUNTLEN + 1]; char database[POOLCONFIG_MAXIDENTLEN + 1]; char username[POOLCONFIG_MAXIDENTLEN + 1]; - char create_time[POOLCONFIG_MAXDATELEN + 1]; + char backend_connection_time[POOLCONFIG_MAXDATELEN + 1]; char pool_counter[POOLCONFIG_MAXCOUNTLEN + 1]; + char status[POOLCONFIG_MAXPROCESSSTATUSLEN + 1]; } POOL_REPORT_PROCESSES; /* pools reporting struct */ typedef struct { char pool_pid[POOLCONFIG_MAXCOUNTLEN + 1]; - char start_time[POOLCONFIG_MAXDATELEN + 1]; + char process_start_time[POOLCONFIG_MAXDATELEN + 1]; + char client_connection_count[POOLCONFIG_MAXCOUNTLEN + 1]; char pool_id[POOLCONFIG_MAXCOUNTLEN + 1]; char backend_id[POOLCONFIG_MAXCOUNTLEN + 1]; char database[POOLCONFIG_MAXIDENTLEN + 1]; char username[POOLCONFIG_MAXIDENTLEN + 1]; - char create_time[POOLCONFIG_MAXDATELEN + 1]; + char backend_connection_time[POOLCONFIG_MAXDATELEN + 1]; + char client_connection_time[POOLCONFIG_MAXDATELEN + 1]; + char client_disconnection_time[POOLCONFIG_MAXDATELEN + 1]; + char client_idle_duration[POOLCONFIG_MAXCOUNTLEN + 1]; char pool_majorversion[POOLCONFIG_MAXCOUNTLEN + 1]; char pool_minorversion[POOLCONFIG_MAXCOUNTLEN + 1]; char pool_counter[POOLCONFIG_MAXCOUNTLEN + 1]; char pool_backendpid[POOLCONFIG_MAXCOUNTLEN + 1]; char pool_connected[POOLCONFIG_MAXCOUNTLEN + 1]; + char status[POOLCONFIG_MAXPROCESSSTATUSLEN + 1]; } POOL_REPORT_POOLS; /* version struct */ diff --git a/src/include/pool.h b/src/include/pool.h index d15a0a1..940ba39 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -619,7 +619,7 @@ extern int send_to_pg_frontend(char *data, int len, bool flush); extern int pg_frontend_exists(void); extern int set_pg_frontend_blocking(bool blocking); extern int get_frontend_protocol_version(void); - +extern void set_process_status(ProcessStatus status); /*pool_shmem.c*/ extern void *pool_shared_memory_create(size_t size); diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index c4453a7..45039c3 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -409,6 +409,8 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) { process_info[i].pid = fork_a_child(fds, i); process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; } /* create pipe for delivering event */ @@ -2022,6 +2024,8 @@ failover(void) process_info[i].pid = fork_a_child(fds, i); process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; } } else @@ -2489,6 +2493,8 @@ reaper(void) process_info[i].pid = fork_a_child(fds, i); process_info[i].start_time = time(NULL); new_pid = process_info[i].pid; + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; } else process_info[i].pid = 0; @@ -4242,6 +4248,8 @@ sync_backend_from_watchdog(void) process_info[i].pid = fork_a_child(fds, i); process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; } } else diff --git a/src/protocol/child.c b/src/protocol/child.c index 4fb6f77..427c809 100644 --- a/src/protocol/child.c +++ b/src/protocol/child.c @@ -162,6 +162,8 @@ do_child(int *fds) ereport(DEBUG2, (errmsg("I am Pgpool Child process with pid: %d", getpid()))); + ProcessInfo* proc_info = pool_get_process_info(getpid()); + /* Identify myself via ps */ init_ps_display("", "", "", ""); @@ -284,6 +286,8 @@ do_child(int *fds) if (pool_config->child_max_connections > 0) connections_count++; + proc_info->client_connection_count++; + /* check if maximum connections count for this child reached */ if ((pool_config->child_max_connections > 0) && (connections_count >= pool_config->child_max_connections)) @@ -410,6 +414,7 @@ do_child(int *fds) snprintf(psbuf, sizeof(psbuf), "%s %s %s idle", sp->user, sp->database, remote_ps_data); set_ps_display(psbuf, false); + set_process_status(IDLE); /* * Initialize per session context @@ -468,6 +473,8 @@ do_child(int *fds) if (pool_config->child_max_connections > 0) connections_count++; + proc_info->client_connection_count++; + /* check if maximum connections count for this child reached */ if ((pool_config->child_max_connections > 0) && (connections_count >= pool_config->child_max_connections)) @@ -1481,6 +1488,8 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) else set_ps_display("wait for connection request", false); + set_process_status(WAIT_FOR_CONNECT); + memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set)); if (timeout->tv_sec == 0 && timeout->tv_usec == 0) @@ -1551,6 +1560,7 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) } set_ps_display("wait for connection request", false); + set_process_status(WAIT_FOR_CONNECT); ereport(DEBUG1, (errmsg("LOCKING select()"))); } @@ -2124,3 +2134,10 @@ static int opt_sort(const void *a, const void *b) { return strcmp( *(char **)a, *(char **)b); } + +void +set_process_status(ProcessStatus status) +{ + ProcessInfo* proc_info = pool_get_process_info(getpid()); + proc_info->status = status; +} \ No newline at end of file diff --git a/src/protocol/pool_connection_pool.c b/src/protocol/pool_connection_pool.c index e84822e..ed28d87 100644 --- a/src/protocol/pool_connection_pool.c +++ b/src/protocol/pool_connection_pool.c @@ -968,6 +968,7 @@ static POOL_CONNECTION_POOL * new_connection(POOL_CONNECTION_POOL * p) else { p->info[i].create_time = time(NULL); + p->info[i].client_idle_duration = 0; p->slots[i] = s; pool_init_params(&s->con->params); diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index 898c558..13670e1 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -238,6 +238,7 @@ pool_process_query(POOL_CONNECTION * frontend, bool cont = true; status = read_packets_and_process(frontend, backend, reset_request, &state, &num_fields, &cont); + backend->info->client_idle_duration = 0; if (status != POOL_CONTINUE) return status; else if (!cont) /* Detected admin shutdown */ @@ -289,6 +290,7 @@ pool_process_query(POOL_CONNECTION * frontend, bool cont = true; status = read_packets_and_process(frontend, backend, reset_request, &state, &num_fields, &cont); + backend->info->client_idle_duration = 0; if (status != POOL_CONTINUE) return status; else if (!cont) /* Detected admin shutdown */ @@ -3862,6 +3864,7 @@ query_ps_status(char *query, POOL_CONNECTION_POOL * backend) psbuf[i] = '\0'; set_ps_display(psbuf, false); + set_process_status(COMMAND_EXECUTE); } /* compare function for bsearch() */ @@ -4754,7 +4757,7 @@ SELECT_RETRY: if (*InRecovery == RECOVERY_INIT && pool_config->client_idle_limit > 0) { idle_count++; - + backend->info->client_idle_duration++; if (idle_count > pool_config->client_idle_limit) { ereport(FRONTEND_ERROR, diff --git a/src/tools/pcp/pcp_frontend_client.c b/src/tools/pcp/pcp_frontend_client.c index af1c08b..235fcf6 100644 --- a/src/tools/pcp/pcp_frontend_client.c +++ b/src/tools/pcp/pcp_frontend_client.c @@ -701,14 +701,16 @@ output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose) int array_size = pcp_result_slot_count(pcpResInfo); const char *titles[] = { - "Database", "Username", "Start time", "Creation time", - "Major", "Minor", "Counter", "Backend PID", - "Connected", "PID", "Backend ID" + "Database", "Username", "Start time", "Client connection count", + "Major", "Minor", "Backend connection time", "Client connection time", + "Client idle duration", "Client disconnection time", "Pool Counter", "Backend PID", + "Connected", "PID", "Backend ID", "Status" }; const char *types[] = { "s", "s", "s", "s", "s", "s", "s", "s", - "s", "s", "s" + "s", "s", "s", "s", + "s", "s", "s", "s" }; @@ -716,7 +718,7 @@ output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose) format = format_titles(titles, types, sizeof(titles)/sizeof(char *)); else { - format = "%s %s %s %s %s %s %s %s %s %s %s\n"; + format = "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n"; } for (i = 0; i < array_size; i++) @@ -732,15 +734,20 @@ output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose) printf(format, pools->database, pools->username, - pools->start_time, - pools->create_time, + pools->process_start_time, + pools->client_connection_count, pools->pool_majorversion, pools->pool_minorversion, + pools->backend_connection_time, + pools->client_connection_time, + pools->client_idle_duration, + pools->client_disconnection_time, pools->pool_counter, pools->pool_backendpid, pools->pool_connected, pools->pool_pid, - pools->backend_id); + pools->backend_id, + pools->status); } if (printed == false) printf("No process information available\n\n"); diff --git a/src/utils/pool_health_check_stats.c b/src/utils/pool_health_check_stats.c index b90fd5c..b062ed2 100644 --- a/src/utils/pool_health_check_stats.c +++ b/src/utils/pool_health_check_stats.c @@ -69,17 +69,22 @@ int * pool_report_pools_offsets(int *n) static int offsettbl[] = { offsetof(POOL_REPORT_POOLS, pool_pid), - offsetof(POOL_REPORT_POOLS, start_time), + offsetof(POOL_REPORT_POOLS, process_start_time), + offsetof(POOL_REPORT_POOLS, client_connection_count), offsetof(POOL_REPORT_POOLS, pool_id), offsetof(POOL_REPORT_POOLS, backend_id), offsetof(POOL_REPORT_POOLS, database), offsetof(POOL_REPORT_POOLS, username), - offsetof(POOL_REPORT_POOLS, create_time), + offsetof(POOL_REPORT_POOLS, backend_connection_time), + offsetof(POOL_REPORT_POOLS, client_connection_time), + offsetof(POOL_REPORT_POOLS, client_disconnection_time), + offsetof(POOL_REPORT_POOLS, client_idle_duration), offsetof(POOL_REPORT_POOLS, pool_majorversion), offsetof(POOL_REPORT_POOLS, pool_minorversion), offsetof(POOL_REPORT_POOLS, pool_counter), offsetof(POOL_REPORT_POOLS, pool_backendpid), - offsetof(POOL_REPORT_POOLS, pool_connected) + offsetof(POOL_REPORT_POOLS, pool_connected), + offsetof(POOL_REPORT_POOLS, status) }; *n = sizeof(offsettbl)/sizeof(int); diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c index 78a2927..01726f5 100644 --- a/src/utils/pool_process_reporting.c +++ b/src/utils/pool_process_reporting.c @@ -1427,20 +1427,60 @@ get_pools(int *nrows) snprintf(pools[lines].pool_pid, sizeof(pools[lines].pool_pid), "%d", proc_id); if (pi->start_time) - strftime(pools[lines].start_time, sizeof(pools[lines].start_time), "%Y-%m-%d %H:%M:%S", - localtime(&pi->start_time)); + { + if (pool_config->child_life_time) + { + char proc_start_time[POOLCONFIG_MAXDATELEN + 1]; + time_t current = time(NULL); + strftime(proc_start_time, sizeof(proc_start_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); + snprintf(pools[lines].process_start_time, sizeof(pools[lines].process_start_time), + "%s (remaining: %d:%02d)", proc_start_time, + (int)difftime(current, pi->start_time) / 60, + (int)difftime(current, pi->start_time) % 60); + } + else + { + strftime(pools[lines].process_start_time, sizeof(pools[lines].process_start_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); + } + } else - *(pools[lines].start_time) = '\0'; + *(pools[lines].process_start_time) = '\0'; snprintf(pools[lines].pool_id, sizeof(pools[lines].pool_id), "%d", pool); snprintf(pools[lines].backend_id, sizeof(pools[lines].backend_id), "%d", backend_id); + snprintf(pools[lines].client_connection_count, sizeof(pools[lines].client_connection_count), + "%d", pi->client_connection_count); + + if (pi->connection_info[poolBE].client_connection_time == 0){ + *(pools[lines].client_connection_time) = '\0'; + } + else + { + strftime(pools[lines].client_connection_time, sizeof(pools[lines].client_connection_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].client_connection_time)); + } + + if (pi->connection_info[poolBE].client_disconnection_time == 0){ + *(pools[lines].client_disconnection_time) = '\0'; + } + else + { + strftime(pools[lines].client_disconnection_time, sizeof(pools[lines].client_disconnection_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].client_disconnection_time)); + } + + snprintf(pools[lines].client_idle_duration, sizeof(pools[lines].client_idle_duration), "%d", + pi->connection_info[poolBE].client_idle_duration); + if (strlen(pi->connection_info[poolBE].database) == 0) { StrNCpy(pools[lines].database, "", POOLCONFIG_MAXIDENTLEN); StrNCpy(pools[lines].username, "", POOLCONFIG_MAXIDENTLEN); - *(pools[lines].create_time) = '\0'; + *(pools[lines].backend_connection_time) = '\0'; snprintf(pools[lines].pool_majorversion, sizeof(pools[lines].pool_majorversion), "%d", 0); snprintf(pools[lines].pool_minorversion, sizeof(pools[lines].pool_minorversion), "%d", 0); } @@ -1448,8 +1488,8 @@ get_pools(int *nrows) { StrNCpy(pools[lines].database, pi->connection_info[poolBE].database, POOLCONFIG_MAXIDENTLEN); StrNCpy(pools[lines].username, pi->connection_info[poolBE].user, POOLCONFIG_MAXIDENTLEN); - strftime(pools[lines].create_time, sizeof(pools[lines].create_time), "%Y-%m-%d %H:%M:%S", - localtime(&pi->connection_info[poolBE].create_time)); + strftime(pools[lines].backend_connection_time, sizeof(pools[lines].backend_connection_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].create_time)); snprintf(pools[lines].pool_majorversion, sizeof(pools[lines].pool_majorversion), "%d", pi->connection_info[poolBE].major); snprintf(pools[lines].pool_minorversion, sizeof(pools[lines].pool_minorversion), "%d", @@ -1462,6 +1502,24 @@ get_pools(int *nrows) snprintf(pools[lines].pool_connected, sizeof(pools[lines].pool_connected), "%d", pi->connection_info[poolBE].connected); + switch(pi->status) + { + case WAIT_FOR_CONNECT: + StrNCpy(pools[lines].status, "Wait for connection", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + case COMMAND_EXECUTE: + StrNCpy(pools[lines].status, "Execute command", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + case IDLE: + StrNCpy(pools[lines].status, "Idle", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + case IDLE_IN_TRANS: + StrNCpy(pools[lines].status, "Idle in transaction", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + default: + *(pools[lines].status) = '\0'; + } + lines++; } } @@ -1478,8 +1536,10 @@ void pools_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { short num_fields; - static char *field_names[] = {"pool_pid", "start_time", "pool_id", "backend_id", "database", "username", "create_time", - "majorversion", "minorversion", "pool_counter", "pool_backendpid", "pool_connected"}; + static char *field_names[] = {"pool_pid", "start_time", "client_connection_count", "pool_id", + "backend_id", "database", "username", "backend_connection_time", + "client_connection_time", "client_disconnection_time", "client_idle_duration", + "majorversion", "minorversion", "pool_counter", "pool_backendpid", "pool_connected", "status"}; int n; int *offsettbl; int nrows; @@ -1512,10 +1572,27 @@ get_processes(int *nrows) pi = pool_get_process_info(proc_id); snprintf(processes[child].pool_pid, POOLCONFIG_MAXCOUNTLEN, "%d", proc_id); - strftime(processes[child].start_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); + if (pool_config->child_life_time) + { + char proc_start_time[POOLCONFIG_MAXDATELEN + 1]; + time_t current = time(NULL); + strftime(proc_start_time, sizeof(proc_start_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); + snprintf(processes[child].process_start_time, sizeof(processes[child].process_start_time), + "%s (remaining: %d:%02d)", proc_start_time, + (int)difftime(current, pi->start_time) / 60, + (int)difftime(current, pi->start_time) % 60); + } + else + { + strftime(processes[child].process_start_time, sizeof(processes[child].process_start_time), + "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); + } + snprintf(processes[child].client_connection_count, sizeof(processes[child].client_connection_count), + "%d", pi->client_connection_count); StrNCpy(processes[child].database, "", POOLCONFIG_MAXIDENTLEN); StrNCpy(processes[child].username, "", POOLCONFIG_MAXIDENTLEN); - StrNCpy(processes[child].create_time, "", POOLCONFIG_MAXDATELEN); + StrNCpy(processes[child].backend_connection_time, "", POOLCONFIG_MAXDATELEN); StrNCpy(processes[child].pool_counter, "", POOLCONFIG_MAXCOUNTLEN); for (pool = 0; pool < pool_config->max_pool; pool++) @@ -1525,10 +1602,27 @@ get_processes(int *nrows) { StrNCpy(processes[child].database, pi->connection_info[poolBE].database, POOLCONFIG_MAXIDENTLEN); StrNCpy(processes[child].username, pi->connection_info[poolBE].user, POOLCONFIG_MAXIDENTLEN); - strftime(processes[child].create_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].create_time)); + strftime(processes[child].backend_connection_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].create_time)); snprintf(processes[child].pool_counter, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[poolBE].counter); } } + switch(pi->status) + { + case WAIT_FOR_CONNECT: + StrNCpy(processes[child].status, "Wait for connection", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + case COMMAND_EXECUTE: + StrNCpy(processes[child].status, "Execute command", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + case IDLE: + StrNCpy(processes[child].status, "Idle", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + case IDLE_IN_TRANS: + StrNCpy(processes[child].status, "Idle in transaction", POOLCONFIG_MAXPROCESSSTATUSLEN); + break; + default: + *(processes[child].status) = '\0'; + } } *nrows = child; @@ -1542,15 +1636,18 @@ get_processes(int *nrows) void processes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - static char *field_names[] = {"pool_pid", "start_time", "database", "username", "create_time", "pool_counter"}; + static char *field_names[] = {"pool_pid", "start_time", "client_connection_count", + "database", "username", "backend_connection_time", "pool_counter", "status"}; static int offsettbl[] = { offsetof(POOL_REPORT_PROCESSES, pool_pid), - offsetof(POOL_REPORT_PROCESSES, start_time), + offsetof(POOL_REPORT_PROCESSES, process_start_time), + offsetof(POOL_REPORT_PROCESSES, client_connection_count), offsetof(POOL_REPORT_PROCESSES, database), offsetof(POOL_REPORT_PROCESSES, username), - offsetof(POOL_REPORT_PROCESSES, create_time), - offsetof(POOL_REPORT_PROCESSES, pool_counter) + offsetof(POOL_REPORT_PROCESSES, backend_connection_time), + offsetof(POOL_REPORT_PROCESSES, pool_counter), + offsetof(POOL_REPORT_PROCESSES, status), }; int nrows; diff --git a/src/utils/ps_status.c b/src/utils/ps_status.c index 6d7d9ee..bedcfc6 100644 --- a/src/utils/ps_status.c +++ b/src/utils/ps_status.c @@ -399,10 +399,16 @@ pool_ps_idle_display(POOL_CONNECTION_POOL * backend) sp = MAIN_CONNECTION(backend)->sp; if (MAIN(backend)->tstate == 'T') + { snprintf(psbuf, sizeof(psbuf), "%s %s %s idle in transaction", sp->user, sp->database, remote_ps_data); + set_process_status(IDLE_IN_TRANS); + } else + { snprintf(psbuf, sizeof(psbuf), "%s %s %s idle", sp->user, sp->database, remote_ps_data); + set_process_status(IDLE); + } set_ps_display(psbuf, false); }