1 /*
2 * This file and its contents are licensed under the Apache License 2.0.
3 * Please see the included NOTICE for copyright information and
4 * LICENSE-APACHE for a copy of the license.
5 */
6 #include <postgres.h>
7 #include <utils/guc.h>
8 #include <miscadmin.h>
9
10 #include "guc.h"
11 #include "license_guc.h"
12 #include "config.h"
13 #include "hypertable_cache.h"
14 #include "telemetry/telemetry.h"
15
16 typedef enum TelemetryLevel
17 {
18 TELEMETRY_OFF,
19 TELEMETRY_BASIC,
20 } TelemetryLevel;
21
22 /* Define which level means on. We use this object to have at least one object
23 * of type TelemetryLevel in the code, otherwise pgindent won't work for the
24 * type */
25 static const TelemetryLevel on_level = TELEMETRY_BASIC;
26
27 bool
ts_telemetry_on()28 ts_telemetry_on()
29 {
30 return ts_guc_telemetry_level == on_level;
31 }
32
33 static const struct config_enum_entry telemetry_level_options[] = {
34 { "off", TELEMETRY_OFF, false }, { "basic", TELEMETRY_BASIC, false }, { NULL, 0, false }
35 };
36
37 static const struct config_enum_entry remote_data_fetchers[] = {
38 { "rowbyrow", RowByRowFetcherType, false },
39 { "cursor", CursorFetcherType, false },
40 { NULL, 0, false }
41 };
42
43 bool ts_guc_enable_optimizations = true;
44 bool ts_guc_restoring = false;
45 bool ts_guc_enable_constraint_aware_append = true;
46 bool ts_guc_enable_ordered_append = true;
47 bool ts_guc_enable_chunk_append = true;
48 bool ts_guc_enable_parallel_chunk_append = true;
49 bool ts_guc_enable_runtime_exclusion = true;
50 bool ts_guc_enable_constraint_exclusion = true;
51 bool ts_guc_enable_qual_propagation = true;
52 bool ts_guc_enable_cagg_reorder_groupby = true;
53 TSDLLEXPORT bool ts_guc_enable_transparent_decompression = true;
54 bool ts_guc_enable_per_data_node_queries = true;
55 bool ts_guc_enable_async_append = true;
56 TSDLLEXPORT bool ts_guc_enable_skip_scan = true;
57 int ts_guc_max_open_chunks_per_insert = 10;
58 int ts_guc_max_cached_chunks_per_hypertable = 10;
59 int ts_guc_telemetry_level = TELEMETRY_DEFAULT;
60
61 TSDLLEXPORT char *ts_guc_license = TS_LICENSE_DEFAULT;
62 char *ts_last_tune_time = NULL;
63 char *ts_last_tune_version = NULL;
64 char *ts_telemetry_cloud = NULL;
65 TSDLLEXPORT bool ts_guc_enable_2pc;
66 TSDLLEXPORT int ts_guc_max_insert_batch_size = 1000;
67 TSDLLEXPORT bool ts_guc_enable_connection_binary_data;
68 TSDLLEXPORT bool ts_guc_enable_client_ddl_on_data_nodes = false;
69 TSDLLEXPORT char *ts_guc_ssl_dir = NULL;
70 TSDLLEXPORT char *ts_guc_passfile = NULL;
71 TSDLLEXPORT bool ts_guc_enable_remote_explain = false;
72 TSDLLEXPORT DataFetcherType ts_guc_remote_data_fetcher = RowByRowFetcherType;
73
74 #ifdef TS_DEBUG
75 bool ts_shutdown_bgw = false;
76 char *ts_current_timestamp_mock = "";
77 #endif
78
79 static void
assign_max_cached_chunks_per_hypertable_hook(int newval,void * extra)80 assign_max_cached_chunks_per_hypertable_hook(int newval, void *extra)
81 {
82 /* invalidate the hypertable cache to reset */
83 ts_hypertable_cache_invalidate_callback();
84 }
85
86 void
_guc_init(void)87 _guc_init(void)
88 {
89 /* Main database to connect to. */
90 DefineCustomBoolVariable("timescaledb.enable_optimizations",
91 "Enable TimescaleDB query optimizations",
92 NULL,
93 &ts_guc_enable_optimizations,
94 true,
95 PGC_USERSET,
96 0,
97 NULL,
98 NULL,
99 NULL);
100
101 DefineCustomBoolVariable("timescaledb.restoring",
102 "Install timescale in restoring mode",
103 "Used for running pg_restore",
104 &ts_guc_restoring,
105 false,
106 PGC_SUSET,
107 0,
108 NULL,
109 NULL,
110 NULL);
111
112 DefineCustomBoolVariable("timescaledb.enable_constraint_aware_append",
113 "Enable constraint-aware append scans",
114 "Enable constraint exclusion at execution time",
115 &ts_guc_enable_constraint_aware_append,
116 true,
117 PGC_USERSET,
118 0,
119 NULL,
120 NULL,
121 NULL);
122
123 DefineCustomBoolVariable("timescaledb.enable_ordered_append",
124 "Enable ordered append scans",
125 "Enable ordered append optimization for queries that are ordered by "
126 "the time dimension",
127 &ts_guc_enable_ordered_append,
128 true,
129 PGC_USERSET,
130 0,
131 NULL,
132 NULL,
133 NULL);
134
135 DefineCustomBoolVariable("timescaledb.enable_chunk_append",
136 "Enable chunk append node",
137 "Enable using chunk append node",
138 &ts_guc_enable_chunk_append,
139 true,
140 PGC_USERSET,
141 0,
142 NULL,
143 NULL,
144 NULL);
145
146 DefineCustomBoolVariable("timescaledb.enable_parallel_chunk_append",
147 "Enable parallel chunk append node",
148 "Enable using parallel aware chunk append node",
149 &ts_guc_enable_parallel_chunk_append,
150 true,
151 PGC_USERSET,
152 0,
153 NULL,
154 NULL,
155 NULL);
156
157 DefineCustomBoolVariable("timescaledb.enable_runtime_exclusion",
158 "Enable runtime chunk exclusion",
159 "Enable runtime chunk exclusion in ChunkAppend node",
160 &ts_guc_enable_runtime_exclusion,
161 true,
162 PGC_USERSET,
163 0,
164 NULL,
165 NULL,
166 NULL);
167
168 DefineCustomBoolVariable("timescaledb.enable_constraint_exclusion",
169 "Enable constraint exclusion",
170 "Enable planner constraint exclusion",
171 &ts_guc_enable_constraint_exclusion,
172 true,
173 PGC_USERSET,
174 0,
175 NULL,
176 NULL,
177 NULL);
178
179 DefineCustomBoolVariable("timescaledb.enable_qual_propagation",
180 "Enable qualifier propagation",
181 "Enable propagation of qualifiers in JOINs",
182 &ts_guc_enable_qual_propagation,
183 true,
184 PGC_USERSET,
185 0,
186 NULL,
187 NULL,
188 NULL);
189
190 DefineCustomBoolVariable("timescaledb.enable_transparent_decompression",
191 "Enable transparent decompression",
192 "Enable transparent decompression when querying hypertable",
193 &ts_guc_enable_transparent_decompression,
194 true,
195 PGC_USERSET,
196 0,
197 NULL,
198 NULL,
199 NULL);
200
201 DefineCustomBoolVariable("timescaledb.enable_skipscan",
202 "Enable SkipScan",
203 "Enable SkipScan for DISTINCT queries",
204 &ts_guc_enable_skip_scan,
205 true,
206 PGC_USERSET,
207 0,
208 NULL,
209 NULL,
210 NULL);
211
212 DefineCustomBoolVariable("timescaledb.enable_cagg_reorder_groupby",
213 "Enable group by reordering",
214 "Enable group by clause reordering for continuous aggregates",
215 &ts_guc_enable_cagg_reorder_groupby,
216 true,
217 PGC_USERSET,
218 0,
219 NULL,
220 NULL,
221 NULL);
222
223 DefineCustomBoolVariable("timescaledb.enable_2pc",
224 "Enable two-phase commit",
225 "Enable two-phase commit on distributed hypertables",
226 &ts_guc_enable_2pc,
227 true,
228 PGC_USERSET,
229 0,
230 NULL,
231 NULL,
232 NULL);
233
234 DefineCustomBoolVariable("timescaledb.enable_per_data_node_queries",
235 "Enable the per data node query optimization for hypertables",
236 "Enable the optimization that combines different chunks belonging to "
237 "the same hypertable into a single query per data_node",
238 &ts_guc_enable_per_data_node_queries,
239 true,
240 PGC_USERSET,
241 0,
242 NULL,
243 NULL,
244 NULL);
245
246 DefineCustomIntVariable("timescaledb.max_insert_batch_size",
247 "The max number of tuples to batch before sending to a data node",
248 "When acting as a access node, TimescaleDB splits batches of "
249 "inserted tuples across multiple data nodes. It will batch up to the "
250 "configured batch size tuples per data node before flushing. "
251 "Setting this to 0 disables batching, reverting to tuple-by-tuple "
252 "inserts",
253 &ts_guc_max_insert_batch_size,
254 1000,
255 0,
256 65536,
257 PGC_USERSET,
258 0,
259 NULL,
260 NULL,
261 NULL);
262
263 DefineCustomBoolVariable("timescaledb.enable_connection_binary_data",
264 "Enable binary format for connection",
265 "Enable binary format for data exchanged between nodes in the cluster",
266 &ts_guc_enable_connection_binary_data,
267 true,
268 PGC_USERSET,
269 0,
270 NULL,
271 NULL,
272 NULL);
273
274 DefineCustomBoolVariable("timescaledb.enable_client_ddl_on_data_nodes",
275 "Enable DDL operations on data nodes by a client",
276 "Do not restrict execution of DDL operations only by access node",
277 &ts_guc_enable_client_ddl_on_data_nodes,
278 false,
279 PGC_USERSET,
280 0,
281 NULL,
282 NULL,
283 NULL);
284
285 DefineCustomBoolVariable("timescaledb.enable_async_append",
286 "Enable async query execution on data nodes",
287 "Enable optimization that runs remote queries asynchronously"
288 "across data nodes",
289 &ts_guc_enable_async_append,
290 true,
291 PGC_USERSET,
292 0,
293 NULL,
294 NULL,
295 NULL);
296
297 DefineCustomBoolVariable("timescaledb.enable_remote_explain",
298 "Show explain from remote nodes when using VERBOSE flag",
299 "Enable getting and showing EXPLAIN output from remote nodes",
300 &ts_guc_enable_remote_explain,
301 false,
302 PGC_USERSET,
303 0,
304 NULL,
305 NULL,
306 NULL);
307
308 DefineCustomEnumVariable("timescaledb.remote_data_fetcher",
309 "Set remote data fetcher type",
310 "Pick data fetcher type based on type of queries you plan to run "
311 "(rowbyrow or cursor)",
312 (int *) &ts_guc_remote_data_fetcher,
313 CursorFetcherType,
314 remote_data_fetchers,
315 PGC_USERSET,
316 0,
317 NULL,
318 NULL,
319 NULL);
320
321 DefineCustomStringVariable("timescaledb.ssl_dir",
322 "TimescaleDB user certificate directory",
323 "Determines a path which is used to search user certificates and "
324 "private keys",
325 &ts_guc_ssl_dir,
326 NULL,
327 PGC_SIGHUP,
328 0,
329 NULL,
330 NULL,
331 NULL);
332
333 DefineCustomStringVariable("timescaledb.passfile",
334 "TimescaleDB password file path",
335 "Specifies the name of the file used to store passwords used for "
336 "data node connections",
337 &ts_guc_passfile,
338 NULL,
339 PGC_SIGHUP,
340 0,
341 NULL,
342 NULL,
343 NULL);
344
345 DefineCustomIntVariable("timescaledb.max_open_chunks_per_insert",
346 "Maximum open chunks per insert",
347 "Maximum number of open chunk tables per insert",
348 &ts_guc_max_open_chunks_per_insert,
349 Min(work_mem * INT64CONST(1024) / INT64CONST(25000),
350 PG_INT16_MAX), /* Measurements via
351 * `MemoryContextStats(TopMemoryContext)`
352 * show chunk insert
353 * state memory context
354 * takes up ~25K bytes
355 * (work_mem is in
356 * kbytes) */
357 0,
358 PG_INT16_MAX,
359 PGC_USERSET,
360 0,
361 NULL,
362 NULL,
363 NULL);
364
365 DefineCustomIntVariable("timescaledb.max_cached_chunks_per_hypertable",
366 "Maximum cached chunks",
367 "Maximum number of chunks stored in the cache",
368 &ts_guc_max_cached_chunks_per_hypertable,
369 100,
370 0,
371 65536,
372 PGC_USERSET,
373 0,
374 NULL,
375 assign_max_cached_chunks_per_hypertable_hook,
376 NULL);
377 DefineCustomEnumVariable("timescaledb.telemetry_level",
378 "Telemetry settings level",
379 "Level used to determine which telemetry to send",
380 &ts_guc_telemetry_level,
381 TELEMETRY_DEFAULT,
382 telemetry_level_options,
383 PGC_USERSET,
384 0,
385 NULL,
386 NULL,
387 NULL);
388
389 DefineCustomStringVariable(/* name= */ "timescaledb.license",
390 /* short_dec= */ "TimescaleDB license type",
391 /* long_dec= */ "Determines which features are enabled",
392 /* valueAddr= */ &ts_guc_license,
393 /* bootValue= */ TS_LICENSE_DEFAULT,
394 /* context= */ PGC_SUSET,
395 /* flags= */ 0,
396 /* check_hook= */ ts_license_guc_check_hook,
397 /* assign_hook= */ ts_license_guc_assign_hook,
398 /* show_hook= */ NULL);
399
400 DefineCustomStringVariable(/* name= */ "timescaledb.last_tuned",
401 /* short_dec= */ "last tune run",
402 /* long_dec= */ "records last time timescaledb-tune ran",
403 /* valueAddr= */ &ts_last_tune_time,
404 /* bootValue= */ NULL,
405 /* context= */ PGC_SIGHUP,
406 /* flags= */ 0,
407 /* check_hook= */ NULL,
408 /* assign_hook= */ NULL,
409 /* show_hook= */ NULL);
410
411 DefineCustomStringVariable(/* name= */ "timescaledb.last_tuned_version",
412 /* short_dec= */ "version of timescaledb-tune",
413 /* long_dec= */ "version of timescaledb-tune used to tune",
414 /* valueAddr= */ &ts_last_tune_version,
415 /* bootValue= */ NULL,
416 /* context= */ PGC_SIGHUP,
417 /* flags= */ 0,
418 /* check_hook= */ NULL,
419 /* assign_hook= */ NULL,
420 /* show_hook= */ NULL);
421
422 DefineCustomStringVariable(/* name= */ "timescaledb_telemetry.cloud",
423 /* short_dec= */ "cloud provider",
424 /* long_dec= */ "cloud provider used for this instance",
425 /* valueAddr= */ &ts_telemetry_cloud,
426 /* bootValue= */ NULL,
427 /* context= */ PGC_SIGHUP,
428 /* flags= */ 0,
429 /* check_hook= */ NULL,
430 /* assign_hook= */ NULL,
431 /* show_hook= */ NULL);
432
433 #ifdef TS_DEBUG
434 DefineCustomBoolVariable(/* name= */ "timescaledb.shutdown_bgw_scheduler",
435 /* short_dec= */ "immediately shutdown the bgw scheduler",
436 /* long_dec= */ "this is for debugging purposes",
437 /* valueAddr= */ &ts_shutdown_bgw,
438 /* bootValue= */ false,
439 /* context= */ PGC_SIGHUP,
440 /* flags= */ 0,
441 /* check_hook= */ NULL,
442 /* assign_hook= */ NULL,
443 /* show_hook= */ NULL);
444
445 DefineCustomStringVariable(/* name= */ "timescaledb.current_timestamp_mock",
446 /* short_dec= */ "set the current timestamp",
447 /* long_dec= */ "this is for debugging purposes",
448 /* valueAddr= */ &ts_current_timestamp_mock,
449 /* bootValue= */ NULL,
450 /* context= */ PGC_USERSET,
451 /* flags= */ 0,
452 /* check_hook= */ NULL,
453 /* assign_hook= */ NULL,
454 /* show_hook= */ NULL);
455 #endif
456 }
457
458 void
_guc_fini(void)459 _guc_fini(void)
460 {
461 }
462