blob: 1727b617deec73263c1536f9252bf6dc2f0022e6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#ifndef GPMON_H
#define GPMON_H
#ifdef POSTGRES_H
void gpmon_init(void);
typedef int64 apr_int64_t;
typedef int32 apr_int32_t;
typedef int16 apr_int16_t;
typedef uint8 apr_byte_t;
typedef uint16 apr_uint16_t;
typedef uint32 apr_uint32_t;
typedef uint64 apr_uint64_t;
#endif
extern apr_int64_t gpmon_tick;
typedef struct gpmon_packet_t gpmon_packet_t;
typedef struct gpmon_qlogkey_t gpmon_qlogkey_t;
typedef struct gpmon_qlog_t gpmon_qlog_t;
typedef struct gpmon_qexec_t gpmon_qexec_t;
typedef struct gpmon_hello_t gpmon_hello_t;
typedef struct gpmon_metrics_t gpmon_metrics_t;
typedef struct gpmon_seginfo_t gpmon_seginfo_t;
typedef struct gpmon_filerepinfo_t gpmon_filerepinfo_t;
typedef struct gpmon_fsinfokey_t gpmon_fsinfokey_t;
typedef struct gpmon_fsinfo_t gpmon_fsinfo_t;
/*
* this dir sits in $MASTER_DATA_DIRECTORY. always include the
* suffix /
*/
#define GPMON_DIR "./gpperfmon/data/"
#define GPMON_DIR_MAX_PATH 100
#define GPMON_DB "gpperfmon"
#define GPMON_FSINFO_MAX_PATH 255
#define GPMON_UNKNOWN "Unknown"
/*
this is enough space for 2 names plus a . between the names plus a null char at the end of the string
for example SCHEMA.RELATION\0
*/
#define SCAN_REL_NAME_BUF_SIZE (NAMEDATALEN*2)
/* ------------------------------------------------------------------
INTERFACE
------------------------------------------------------------------ */
extern void gpmon_qlog_packet_init(gpmon_packet_t *gpmonPacket);
extern void gpmon_qlog_query_submit(gpmon_packet_t *gpmonPacket);
extern void gpmon_qlog_query_text(const gpmon_packet_t *gpmonPacket,
const char *queryText,
const char *appName,
const char *resqName,
const char *resqPriority);
extern void gpmon_qlog_query_start(gpmon_packet_t *gpmonPacket);
extern void gpmon_qlog_query_end(gpmon_packet_t *gpmonPacket);
extern void gpmon_qlog_query_error(gpmon_packet_t *gpmonPacket);
extern void gpmon_qlog_query_canceling(gpmon_packet_t *gpmonPacket);
extern void gpmon_send(gpmon_packet_t*);
extern void gpmon_gettmid(apr_int32_t*);
/* ------------------------------------------------------------------
FSINFO
------------------------------------------------------------------ */
struct gpmon_fsinfokey_t
{
char fsname [GPMON_FSINFO_MAX_PATH];
char hostname[NAMEDATALEN];
};
struct gpmon_fsinfo_t
{
gpmon_fsinfokey_t key;
apr_int64_t bytes_used;
apr_int64_t bytes_available;
apr_int64_t bytes_total;
};
/* ------------------------------------------------------------------
METRICS
------------------------------------------------------------------ */
struct gpmon_metrics_t
{
/* if you modify this, do not forget to edit gpperfmon/src/gpmon/gpmonlib.c:gpmon_ntohpkt() */
char hname[NAMEDATALEN];
struct
{
apr_uint64_t total, used, actual_used, actual_free;
} mem;
struct
{
apr_uint64_t total, used, page_in, page_out;
} swap;
struct
{
float user_pct, sys_pct, idle_pct;
} cpu;
struct
{
float value[3];
} load_avg;
struct
{
apr_uint64_t ro_rate, wo_rate, rb_rate, wb_rate;
} disk;
struct
{
apr_uint64_t rp_rate, wp_rate, rb_rate, wb_rate;
} net;
};
/* ------------------------------------------------------------------
QLOG
------------------------------------------------------------------ */
struct gpmon_qlogkey_t {
/* if you modify this, do not forget to edit gpperfmon/src/gpmon/gpmonlib.c:gpmon_ntohpkt() */
apr_int32_t tmid; /* transaction time */
apr_int32_t ssid; /* session id */
apr_int32_t ccnt; /* command count */
};
/* process metrics ... filled in by gpsmon */
typedef struct gpmon_proc_metrics_t gpmon_proc_metrics_t;
struct gpmon_proc_metrics_t {
apr_uint32_t fd_cnt; /* # opened files / sockets etc */
float cpu_pct; /* cpu usage % */
struct {
apr_uint64_t size, resident, share;
} mem;
};
#define GPMON_QLOG_STATUS_INVALID -1
#define GPMON_QLOG_STATUS_SILENT 0
#define GPMON_QLOG_STATUS_SUBMIT 1
#define GPMON_QLOG_STATUS_START 2
#define GPMON_QLOG_STATUS_DONE 3
#define GPMON_QLOG_STATUS_ERROR 4
#define GPMON_QLOG_STATUS_CANCELING 5
#define GPMON_NUM_SEG_CPU 10
struct gpmon_qlog_t
{
gpmon_qlogkey_t key;
char user[NAMEDATALEN];
char db[NAMEDATALEN];
apr_int32_t tsubmit, tstart, tfin;
apr_int32_t status; /* GPMON_QLOG_STATUS_XXXXXX */
apr_int32_t cost;
apr_int64_t cpu_elapsed; /* CPU elapsed for query */
gpmon_proc_metrics_t p_metrics;
};
/* ------------------------------------------------------------------
QEXEC
------------------------------------------------------------------ */
typedef struct gpmon_qexec_hash_key_t {
apr_int16_t segid; /* segment id */
apr_int32_t pid; /* process id */
apr_int16_t nid; /* plan node id */
}gpmon_qexec_hash_key_t;
/* XXX According to CK.
* QE will NOT need to touch anything begin with _
*/
typedef struct gpmon_qexeckey_t {
/* if you modify this, do not forget to edit gpperfmon/src/gpmon/gpmonlib.c:gpmon_ntohpkt() */
apr_int32_t tmid; /* transaction time */
apr_int32_t ssid; /* session id */
apr_int16_t ccnt; /* command count */
gpmon_qexec_hash_key_t hash_key;
}gpmon_qexeckey_t;
enum {
GPMON_QEXEC_M_ROWSIN = 0,
#if 0
GPMON_QEXEC_M_BYTESIN,
GPMON_QEXEC_M_BYTESOUT,
#endif
GPMON_QEXEC_M_NODE_START,
GPMON_QEXEC_M_COUNT = 10,
GPMON_QEXEC_M_DBCOUNT = 16
};
/* there is an array of 10 measurements in the array inside a gpmon packet
however the gpperfmon DB will contain 16 measurements.
long term we need a more extensible solution. short term we limit size of packets
to what is actually used to conserve resources
*/
struct gpmon_qexec_t {
/* if you modify this, do not forget to edit gpperfmon/src/gpmon/gpmonlib.c:gpmon_ntohpkt() */
gpmon_qexeckey_t key;
apr_int32_t pnid; /* plan parent node id */
char _hname[NAMEDATALEN];
apr_uint16_t nodeType; /* using enum PerfmonNodeType */
apr_byte_t status; /* node status using PerfmonNodeStatus */
apr_int32_t tstart, tduration; /* start (wall clock) time and duration. XXX Leave as 0 for now. */
apr_uint64_t p_mem, p_memmax; /* XXX Aset instrumentation. Leave as 0 for now. */
apr_uint64_t _cpu_elapsed; /* CPU elapsed for iter */
gpmon_proc_metrics_t _p_metrics;
apr_uint64_t rowsout, rowsout_est;
apr_uint64_t measures[GPMON_QEXEC_M_COUNT];
char relation_name[SCAN_REL_NAME_BUF_SIZE];
};
/*
* Segment-related statistics
*/
struct gpmon_seginfo_t {
apr_int32_t dbid; // dbid as in gp_segment_configuration
char hostname[NAMEDATALEN]; // hostname without NIC extension
apr_uint64_t dynamic_memory_used; // allocated memory in bytes
apr_uint64_t dynamic_memory_available; // available memory in bytes,
};
/*
//we could clean up the primary and mirror stats using this basicStat struct
typedef struct gpmon_filerep_basicStat_s
{
apr_uint32_t count;
apr_uint32_t time_avg;
apr_uint32_t time_max;
apr_uint32_t size_avg;
apr_uint32_t size_max;
} gpmon_filerep_basicStat_s;
*/
/*
* Filerep related statistics
*/
typedef struct gpmon_filerep_primarystats_s
{
//NOTE: 32 bits can store over an hour of microseconds - we will not worry about this
// EVENT: write systemcall on primary
apr_uint32_t write_syscall_size_avg;
apr_uint32_t write_syscall_size_max;
apr_uint32_t write_syscall_time_avg; // microseconds;
apr_uint32_t write_syscall_time_max; // microseconds;
apr_uint32_t write_syscall_count;
// EVENT: fsync systemcall on primary
apr_uint32_t fsync_syscall_time_avg; // microseconds;
apr_uint32_t fsync_syscall_time_max; // microseconds;
apr_uint32_t fsync_syscall_count;
// EVENT: putting write message into shared memory
apr_uint32_t write_shmem_size_avg;
apr_uint32_t write_shmem_size_max;
apr_uint32_t write_shmem_time_avg; // microseconds;
apr_uint32_t write_shmem_time_max; // microseconds;
apr_uint32_t write_shmem_count;
// EVENT: putting fsync message into shared memory
apr_uint32_t fsync_shmem_time_avg; // microseconds;
apr_uint32_t fsync_shmem_time_max; // microseconds;
apr_uint32_t fsync_shmem_count;
// EVENT: Roundtrip from sending fsync message to mirror to get ack back on primary
apr_uint32_t roundtrip_fsync_msg_time_avg; // microseconds;
apr_uint32_t roundtrip_fsync_msg_time_max; // microseconds;
apr_uint32_t roundtrip_fsync_msg_count;
// EVENT: Roundtrip from sending test message to mirror to getting back on primary
apr_uint32_t roundtrip_test_msg_time_avg; // microseconds;
apr_uint32_t roundtrip_test_msg_time_max; // microseconds;
apr_uint32_t roundtrip_test_msg_count;
} gpmon_filerep_primarystats_s;
typedef struct gpmon_filerep_mirrorstats_s
{
// EVENT: write systemcall on mirror
apr_uint32_t write_syscall_size_avg;
apr_uint32_t write_syscall_size_max;
apr_uint32_t write_syscall_time_avg; // microseconds;
apr_uint32_t write_syscall_time_max; // microseconds;
apr_uint32_t write_syscall_count;
// EVENT: fsync systemcall on mirror
apr_uint32_t fsync_syscall_time_avg; // microseconds;
apr_uint32_t fsync_syscall_time_max; // microseconds;
apr_uint32_t fsync_syscall_count;
} gpmon_filerep_mirrorstats_s;
typedef union gpmon_filerep_stats_u {
gpmon_filerep_primarystats_s primary;
gpmon_filerep_mirrorstats_s mirror;
} gpmon_filerep_stats_u;
typedef struct gpmmon_filerep_key_t
{
char primary_hostname[NAMEDATALEN];
apr_uint16_t primary_port;
char mirror_hostname[NAMEDATALEN];
apr_uint16_t mirror_port;
} gpmmon_filerep_key_t;
typedef struct gpsmon_filerep_key_t
{
gpmmon_filerep_key_t dkey;
bool isPrimary;
} gpsmon_filerep_key_t;
struct gpmon_filerepinfo_t
{
gpsmon_filerep_key_t key;
float elapsedTime_secs;
gpmon_filerep_stats_u stats;
};
/* ------------------------------------------------------------------
HELLO
------------------------------------------------------------------ */
struct gpmon_hello_t {
apr_int64_t signature;
};
#define GPMON_MAGIC 0x78ab928d
/*
* When updating the format of the packets update these variables
* in order to make sure that the communication between the GPDB
* and perfmon is compatible
*/
#define GPMON_PACKET_VERSION 5
#define GPMMON_PACKET_VERSION_STRING "gpmmon packet version 5\n"
enum gpmon_pkttype_t {
GPMON_PKTTYPE_NONE = 0,
GPMON_PKTTYPE_HELLO = 1,
GPMON_PKTTYPE_METRICS = 2,
GPMON_PKTTYPE_QLOG = 3,
GPMON_PKTTYPE_QEXEC = 4,
GPMON_PKTTYPE_SEGINFO = 5,
GPMON_PKTTYPE_FILEREP = 6,
GPMON_PKTTYPE_QUERY_HOST_METRICS = 7, // query metrics update from a segment such as CPU per query
GPMON_PKTTYPE_FSINFO = 8,
GPMON_PKTTYPE_MAX
};
struct gpmon_packet_t {
/* if you modify this, do not forget to edit gpperfmon/src/gpmon/gpmonlib.c:gpmon_ntohpkt() */
apr_int32_t magic;
apr_int16_t version;
apr_int16_t pkttype;
union {
gpmon_hello_t hello;
gpmon_metrics_t metrics;
gpmon_qlog_t qlog;
gpmon_qexec_t qexec;
gpmon_seginfo_t seginfo;
gpmon_filerepinfo_t filerepinfo;
gpmon_fsinfo_t fsinfo;
} u;
};
extern const char* gpmon_qlog_status_string(int gpmon_qlog_status);
/* when adding a node type for perfmon display be sure to also update the corresponding structures in
in gpperfmon/src/gpmon/gpmonlib.c */
typedef enum PerfmonNodeType
{
PMNT_Invalid = 0,
PMNT_Append,
PMNT_AppendOnlyScan,
PMNT_AssertOp,
PMNT_Aggregate,
PMNT_GroupAggregate,
PMNT_HashAggregate,
PMNT_AppendOnlyColumnarScan,
PMNT_BitmapAnd,
PMNT_BitmapOr,
PMNT_BitmapAppendOnlyScan,
PMNT_BitmapHeapScan,
PMNT_BitmapTableScan,
PMNT_BitmapIndexScan,
PMNT_DML,
PMNT_DynamicIndexScan,
PMNT_DynamicTableScan,
PMNT_ExternalScan,
PMNT_FunctionScan,
PMNT_Group,
PMNT_Hash,
PMNT_HashJoin,
PMNT_HashLeftJoin,
PMNT_HashLeftAntiSemiJoin,
PMNT_HashFullJoin,
PMNT_HashRightJoin,
PMNT_HashExistsJoin,
PMNT_HashReverseInJoin,
PMNT_HashUniqueOuterJoin,
PMNT_HashUniqueInnerJoin,
PMNT_IndexScan,
PMNT_Limit,
PMNT_Materialize,
PMNT_MergeJoin,
PMNT_MergeLeftJoin,
PMNT_MergeLeftAntiSemiJoin,
PMNT_MergeFullJoin,
PMNT_MergeRightJoin,
PMNT_MergeExistsJoin,
PMNT_MergeReverseInJoin,
PMNT_MergeUniqueOuterJoin,
PMNT_MergeUniqueInnerJoin,
PMNT_RedistributeMotion,
PMNT_BroadcastMotion,
PMNT_GatherMotion,
PMNT_ExplicitRedistributeMotion,
PMNT_NestedLoop,
PMNT_NestedLoopLeftJoin,
PMNT_NestedLoopLeftAntiSemiJoin,
PMNT_NestedLoopFullJoin,
PMNT_NestedLoopRightJoin,
PMNT_NestedLoopExistsJoin,
PMNT_NestedLoopReverseInJoin,
PMNT_NestedLoopUniqueOuterJoin,
PMNT_NestedLoopUniqueInnerJoin,
PMNT_PartitionSelector,
PMNT_Result,
PMNT_Repeat,
PMNT_RowTrigger,
PMNT_SeqScan,
PMNT_Sequence,
PMNT_SetOp,
PMNT_SetOpIntersect,
PMNT_SetOpIntersectAll,
PMNT_SetOpExcept,
PMNT_SetOpExceptAll,
PMNT_SharedScan,
PMNT_Sort,
PMNT_SplitUpdate,
PMNT_SubqueryScan,
PMNT_TableFunctionScan,
PMNT_TableScan,
PMNT_TidScan,
PMNT_Unique,
PMNT_ValuesScan,
PMNT_Window,
PMNT_MAXIMUM_ENUM
} PerfmonNodeType;
typedef enum PerfmonNodeStatus
{
PMNS_Initialize = 0,
PMNS_Executing,
PMNS_Finished
} PerfmonNodeStatus;
#endif