Send server_id for statistics reports. (#1698)

This change introduces the `pg_dist_node_metadata` which has a single jsonb value. When creating
the extension, a random server id is generated and stored in there. Everything in the metadata table
is added as a nested objected to the json payload that is sent to the reports server.
pull/1724/head
Hadi Moshayedi 2017-10-18 21:20:32 -04:00 committed by GitHub
parent 86bcd93a4a
commit 9a04b78980
7 changed files with 148 additions and 4 deletions

View File

@ -12,7 +12,7 @@ EXTVERSIONS = 5.0 5.0-1 5.0-2 \
6.1-1 6.1-2 6.1-3 6.1-4 6.1-5 6.1-6 6.1-7 6.1-8 6.1-9 6.1-10 6.1-11 6.1-12 6.1-13 6.1-14 6.1-15 6.1-16 6.1-17 \ 6.1-1 6.1-2 6.1-3 6.1-4 6.1-5 6.1-6 6.1-7 6.1-8 6.1-9 6.1-10 6.1-11 6.1-12 6.1-13 6.1-14 6.1-15 6.1-16 6.1-17 \
6.2-1 6.2-2 6.2-3 6.2-4 \ 6.2-1 6.2-2 6.2-3 6.2-4 \
7.0-1 7.0-2 7.0-3 7.0-4 7.0-5 7.0-6 7.0-7 7.0-8 7.0-9 7.0-10 7.0-11 7.0-12 7.0-13 7.0-14 7.0-15 \ 7.0-1 7.0-2 7.0-3 7.0-4 7.0-5 7.0-6 7.0-7 7.0-8 7.0-9 7.0-10 7.0-11 7.0-12 7.0-13 7.0-14 7.0-15 \
7.1-1 7.1-2 7.1-1 7.1-2 7.1-3
# All citus--*.sql files in the source directory # All citus--*.sql files in the source directory
DATA = $(patsubst $(citus_abs_srcdir)/%.sql,%.sql,$(wildcard $(citus_abs_srcdir)/$(EXTENSION)--*--*.sql)) DATA = $(patsubst $(citus_abs_srcdir)/%.sql,%.sql,$(wildcard $(citus_abs_srcdir)/$(EXTENSION)--*--*.sql))
@ -174,6 +174,8 @@ $(EXTENSION)--7.1-1.sql: $(EXTENSION)--7.0-15.sql $(EXTENSION)--7.0-15--7.1-1.sq
cat $^ > $@ cat $^ > $@
$(EXTENSION)--7.1-2.sql: $(EXTENSION)--7.1-1.sql $(EXTENSION)--7.1-1--7.1-2.sql $(EXTENSION)--7.1-2.sql: $(EXTENSION)--7.1-1.sql $(EXTENSION)--7.1-1--7.1-2.sql
cat $^ > $@ cat $^ > $@
$(EXTENSION)--7.1-3.sql: $(EXTENSION)--7.1-2.sql $(EXTENSION)--7.1-2--7.1-3.sql
cat $^ > $@
NO_PGXS = 1 NO_PGXS = 1

View File

@ -0,0 +1,17 @@
/* citus--7.1-2--7.1-3 */
CREATE TABLE citus.pg_dist_node_metadata(
metadata jsonb NOT NULL
);
ALTER TABLE citus.pg_dist_node_metadata SET SCHEMA pg_catalog;
GRANT SELECT ON pg_catalog.pg_dist_node_metadata TO public;
CREATE FUNCTION pg_catalog.citus_server_id()
RETURNS uuid
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$citus_server_id$$;
COMMENT ON FUNCTION citus_server_id()
IS 'generates a random UUID to be used as server identifier';
INSERT INTO pg_dist_node_metadata
VALUES (jsonb_build_object('server_id', citus_server_id()::text));

View File

@ -1,6 +1,6 @@
# Citus extension # Citus extension
comment = 'Citus distributed database' comment = 'Citus distributed database'
default_version = '7.1-2' default_version = '7.1-3'
module_pathname = '$libdir/citus' module_pathname = '$libdir/citus'
relocatable = false relocatable = false
schema = pg_catalog schema = pg_catalog

View File

@ -31,6 +31,7 @@
#include "distributed/metadata_cache.h" #include "distributed/metadata_cache.h"
#include "distributed/multi_logical_optimizer.h" #include "distributed/multi_logical_optimizer.h"
#include "distributed/pg_dist_local_group.h" #include "distributed/pg_dist_local_group.h"
#include "distributed/pg_dist_node_metadata.h"
#include "distributed/pg_dist_node.h" #include "distributed/pg_dist_node.h"
#include "distributed/pg_dist_partition.h" #include "distributed/pg_dist_partition.h"
#include "distributed/pg_dist_shard.h" #include "distributed/pg_dist_shard.h"
@ -3167,3 +3168,51 @@ CitusInvalidateRelcacheByShardId(int64 shardId)
/* bump command counter, to force invalidation to take effect */ /* bump command counter, to force invalidation to take effect */
CommandCounterIncrement(); CommandCounterIncrement();
} }
/*
* DistNodeMetadata returns the single metadata jsonb object stored in
* pg_dist_node_metadata.
*/
Datum
DistNodeMetadata(void)
{
Datum metadata = 0;
SysScanDesc scanDescriptor = NULL;
ScanKeyData scanKey[1];
const int scanKeyCount = 0;
HeapTuple heapTuple = NULL;
Oid metadataTableOid = InvalidOid;
Relation pgDistNodeMetadata = NULL;
TupleDesc tupleDescriptor = NULL;
metadataTableOid = get_relname_relid("pg_dist_node_metadata", PG_CATALOG_NAMESPACE);
if (metadataTableOid == InvalidOid)
{
ereport(ERROR, (errmsg("pg_dist_node_metadata was not found")));
}
pgDistNodeMetadata = heap_open(metadataTableOid, AccessShareLock);
scanDescriptor = systable_beginscan(pgDistNodeMetadata,
InvalidOid, false,
NULL, scanKeyCount, scanKey);
tupleDescriptor = RelationGetDescr(pgDistNodeMetadata);
heapTuple = systable_getnext(scanDescriptor);
if (HeapTupleIsValid(heapTuple))
{
bool isNull = false;
metadata = heap_getattr(heapTuple, Anum_pg_dist_node_metadata_metadata,
tupleDescriptor, &isNull);
Assert(!isNull);
}
else
{
ereport(ERROR, (errmsg("could not find any entries in pg_dist_metadata")));
}
systable_endscan(scanDescriptor);
heap_close(pgDistNodeMetadata, AccessShareLock);
return metadata;
}

View File

@ -11,6 +11,12 @@
#include "postgres.h" #include "postgres.h"
#include "citus_version.h" #include "citus_version.h"
#include "fmgr.h"
#include "utils/uuid.h"
#if PG_VERSION_NUM >= 100000
#include "utils/backend_random.h"
#endif
bool EnableStatisticsCollection = true; /* send basic usage statistics to Citus */ bool EnableStatisticsCollection = true; /* send basic usage statistics to Citus */
@ -25,6 +31,11 @@ bool EnableStatisticsCollection = true; /* send basic usage statistics to Citus
#include "distributed/worker_manager.h" #include "distributed/worker_manager.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "utils/json.h" #include "utils/json.h"
#include "utils/jsonb.h"
#if PG_VERSION_NUM >= 100000
#include "utils/fmgrprotos.h"
#endif
static uint64 NextPow2(uint64 n); static uint64 NextPow2(uint64 n);
static uint64 ClusterSize(List *distributedTableList); static uint64 ClusterSize(List *distributedTableList);
@ -61,6 +72,8 @@ CollectBasicUsageStatistics(void)
uint64 roundedClusterSize = 0; uint64 roundedClusterSize = 0;
uint32 workerNodeCount = 0; uint32 workerNodeCount = 0;
StringInfo fields = makeStringInfo(); StringInfo fields = makeStringInfo();
Datum metadataJsonbDatum = 0;
char *metadataJsonbStr = NULL;
struct utsname unameData; struct utsname unameData;
memset(&unameData, 0, sizeof(unameData)); memset(&unameData, 0, sizeof(unameData));
@ -80,8 +93,9 @@ CollectBasicUsageStatistics(void)
roundedDistTableCount = NextPow2(list_length(distributedTables)); roundedDistTableCount = NextPow2(list_length(distributedTables));
roundedClusterSize = NextPow2(ClusterSize(distributedTables)); roundedClusterSize = NextPow2(ClusterSize(distributedTables));
workerNodeCount = ActivePrimaryNodeCount(); workerNodeCount = ActivePrimaryNodeCount();
CommitTransactionCommand(); metadataJsonbDatum = DistNodeMetadata();
metadataJsonbStr = DatumGetCString(DirectFunctionCall1(jsonb_out,
metadataJsonbDatum));
uname(&unameData); uname(&unameData);
appendStringInfoString(fields, "{\"citus_version\": "); appendStringInfoString(fields, "{\"citus_version\": ");
@ -95,8 +109,11 @@ CollectBasicUsageStatistics(void)
escape_json(fields, unameData.release); escape_json(fields, unameData.release);
appendStringInfoString(fields, ",\"hwid\": "); appendStringInfoString(fields, ",\"hwid\": ");
escape_json(fields, unameData.machine); escape_json(fields, unameData.machine);
appendStringInfo(fields, ",\"node_metadata\": %s", metadataJsonbStr);
appendStringInfoString(fields, "}"); appendStringInfoString(fields, "}");
CommitTransactionCommand();
return SendHttpPostJsonRequest(STATS_COLLECTION_HOST "/v1/usage_reports", return SendHttpPostJsonRequest(STATS_COLLECTION_HOST "/v1/usage_reports",
fields->data, HTTP_TIMEOUT_SECONDS); fields->data, HTTP_TIMEOUT_SECONDS);
} }
@ -224,3 +241,39 @@ SendHttpPostJsonRequest(const char *url, const char *jsonObj, long timeoutSecond
#endif /* HAVE_LIBCURL */ #endif /* HAVE_LIBCURL */
PG_FUNCTION_INFO_V1(citus_server_id);
/*
* citus_server_id returns a random UUID value as server identifier. This is
* modeled after PostgreSQL's pg_random_uuid().
*/
Datum
citus_server_id(PG_FUNCTION_ARGS)
{
uint8 *buf = (uint8 *) palloc(UUID_LEN);
#if PG_VERSION_NUM >= 100000
if (!pg_backend_random((char *) buf, UUID_LEN))
{
ereport(ERROR, (errmsg("failed to generate server identifier")));
}
#else
{
int bufIdx = 0;
for (bufIdx = 0; bufIdx < UUID_LEN; bufIdx++)
{
buf[bufIdx] = (uint8) (random() & 0xFF);
}
}
#endif
/*
* Set magic numbers for a "version 4" (pseudorandom) UUID, see
* http://tools.ietf.org/html/rfc4122#section-4.4
*/
buf[6] = (buf[6] & 0x0f) | 0x40; /* "version" field */
buf[8] = (buf[8] & 0x3f) | 0x80; /* "variant" field */
PG_RETURN_UUID_P((pg_uuid_t *) buf);
}

View File

@ -87,6 +87,7 @@ extern List * ShardPlacementList(uint64 shardId);
extern void CitusInvalidateRelcacheByRelid(Oid relationId); extern void CitusInvalidateRelcacheByRelid(Oid relationId);
extern void CitusInvalidateRelcacheByShardId(int64 shardId); extern void CitusInvalidateRelcacheByShardId(int64 shardId);
extern void InvalidateMetadataSystemCache(void); extern void InvalidateMetadataSystemCache(void);
extern Datum DistNodeMetadata(void);
extern bool CitusHasBeenLoaded(void); extern bool CitusHasBeenLoaded(void);
extern bool CheckCitusVersion(int elevel); extern bool CheckCitusVersion(int elevel);

View File

@ -0,0 +1,22 @@
/*-------------------------------------------------------------------------
*
* pg_dist_node_metadata.h
* definition of the relation that holds the metadata table (pg_dist_node_metadata).
*
* Copyright (c) 2017, Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/
#ifndef PG_DIST_NODE_METADATA_H
#define PG_DIST_NODE_METADATA_H
/* ----------------
* compiler constants for pg_dist_node_metadata
* ----------------
*/
#define Natts_pg_dist_node_metadata 1
#define Anum_pg_dist_node_metadata_metadata 1
#endif /* PG_DIST_NODE_METADATA_H */