-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrace_planning.c
136 lines (109 loc) · 4.14 KB
/
trace_planning.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "postgres.h"
#include <time.h>
#include "utils/plancache.h"
#include "trace_lock_on_buffers.h"
#include "trace_session.h"
#include "trace_file.h"
#include "trace_planning.h"
typedef struct PlannerTrace
{
uint64 startTime;
} PlannerTrace;
typedef struct GetCachedPlanTrace
{
CachedPlanSource *plansource;
ParamListInfo boundParams;
int64 prevNumCustomPlans;
int64 prevNumGenericPlans;
} GetCachedPlanTrace;
static PlannerTrace plannerTrace = { .startTime = 0};
static GetCachedPlanTrace getCachedPlanTrace = {.plansource = NULL,
.prevNumCustomPlans = 0,
.prevNumGenericPlans = 0};
static void PlannerTraceInFunc(void* data);
static void PlannerTraceRetFunc(void* data);
static void PlannerTraceCleanFunc(UprobeAttachInterface* uprobe);
static void GetCachedPlanInFunc(void* data, CachedPlanSource *plansource, ParamListInfo boundParams);
static void GetCachedPlanRetFunc(void* data);
static void GetCachedPlanCleanFunc(UprobeAttachInterface* uprobe);
static void
PlannerTraceInFunc(void* data)
{
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
plannerTrace.startTime = time.tv_sec * 1000000000L + time.tv_nsec;
LockOnBuffersTraceStatPush();
}
static void
PlannerTraceRetFunc(void* data)
{
struct timespec time;
uint64 timeDiff;
clock_gettime(CLOCK_MONOTONIC, &time);
timeDiff = time.tv_sec * 1000000000L + time.tv_nsec - plannerTrace.startTime;
if (writeMode == TEXT_WRITE_MODE)
TracePrintf("TRACE PLAN. planningTime %lu nanosec\n", timeDiff);
else
TracePrintf("\"planningTime\": \"%lu nanosec\",\n", timeDiff);
LockOnBuffersTraceDumpCurrentStatWithPrefix("Buffer locks usage for planning", "LWLockPlanning");
LockOnBuffersTraceStatPop();
}
static void
PlannerTraceCleanFunc(UprobeAttachInterface* uprobe)
{
pfree(uprobe);
}
static void
GetCachedPlanInFunc(void* data, CachedPlanSource *plansource, ParamListInfo boundParams)
{
getCachedPlanTrace.plansource = plansource;
getCachedPlanTrace.prevNumCustomPlans = plansource->num_custom_plans;
getCachedPlanTrace.prevNumGenericPlans = plansource->num_generic_plans;
getCachedPlanTrace.boundParams = boundParams;
}
static void
GetCachedPlanRetFunc(void* data)
{
char* boundParamsLogStr;
if (getCachedPlanTrace.boundParams)
boundParamsLogStr = BuildParamLogString(getCachedPlanTrace.boundParams, NULL, -1);
else
boundParamsLogStr = "";
if (getCachedPlanTrace.plansource->num_custom_plans != getCachedPlanTrace.prevNumCustomPlans)
{
if (writeMode == TEXT_WRITE_MODE)
TracePrintf("TRACE GET_CACHED_PLAN. Custom plan was chosen for boundParams: %s", boundParamsLogStr);
else
TracePrintf(" \"planType\": \"custom\",\n \"params\": \"%s\",\n", boundParamsLogStr);
}
else if (getCachedPlanTrace.plansource->num_generic_plans != getCachedPlanTrace.prevNumGenericPlans)
{
if (writeMode == TEXT_WRITE_MODE)
TracePrintf("TRACE GET_CACHED_PLAN. Generic plan was chosen for boundParams: %s", boundParamsLogStr);
else
TracePrintf(" \"planType\": \"generic\",\n \"params\": \"%s\",\n", boundParamsLogStr);
}
if (boundParamsLogStr[0] != '\0') //check on emty params str
pfree(boundParamsLogStr);
}
static void
GetCachedPlanCleanFunc(UprobeAttachInterface* uprobe)
{
pfree(uprobe);
}
//return 2 Uprobes to attach in resUrpobes array
void
PlanningUprobesGet(UprobeAttachInterface** resUprobes)
{
resUprobes[0] = (UprobeAttachInterface*) palloc0(sizeof(UprobeAttachInterface));
resUprobes[0]->cleanFunc = PlannerTraceCleanFunc;
resUprobes[0]->inFunc = PlannerTraceInFunc;
resUprobes[0]->retFunc = PlannerTraceRetFunc;
resUprobes[0]->targetSymbol = "planner";
resUprobes[1] = (UprobeAttachInterface*) palloc0(sizeof(UprobeAttachInterface));
resUprobes[1]->cleanFunc = GetCachedPlanCleanFunc;
resUprobes[1]->inFunc = GetCachedPlanInFunc;
resUprobes[1]->retFunc = GetCachedPlanRetFunc;
resUprobes[1]->numArgs = 2;
resUprobes[1]->targetSymbol = "GetCachedPlan";
}