Improve agent shutdown time (#13649)
* Remove dbengine statistics on shutdown since this is now provided by the /api/v1/dbengine_stats endpoint Skip the memory cleanup if the agent is shutting down and not compiled with NETDATA_INTERNAL_CHECKS * Report database tier as the event loop is shutting down * Remove not-useful pointer report in the logfile
Stelios Fragkakis committed
Sep 8, 2022 at 23:45 UTC
e6870f0e8f24486b89396fe4f0985e69e1914c24
4 files changed
+12
-160
database/engine/datafile.c
-27
@@ -444,44 +444,17 @@ void finalize_data_files(struct rrdengine_instance *ctx)
444
struct rrdengine_journalfile *journalfile;
445
struct extent_info *extent, *next_extent;
446
447
- size_t extents_number = 0;
448
- size_t extents_bytes = 0;
449
- size_t page_compressed_sizes = 0;
450
-
451
- size_t files_number = 0;
452
- size_t files_bytes = 0;
453
-
447
for (datafile = ctx->datafiles.first ; datafile != NULL ; datafile = next_datafile) {
448
journalfile = datafile->journalfile;
449
next_datafile = datafile->next;
450
451
for (extent = datafile->extents.first ; extent != NULL ; extent = next_extent) {
459
- extents_number++;
460
- extents_bytes += sizeof(*extent) + sizeof(struct rrdeng_page_descr *) * extent->number_of_pages;
461
- page_compressed_sizes += extent->size;
462
-
452
next_extent = extent->next;
453
freez(extent);
454
}
455
close_journal_file(journalfile, datafile);
456
close_data_file(datafile);
468
-
469
- files_number++;
470
- files_bytes += sizeof(*journalfile) + sizeof(*datafile);
471
-
457
freez(journalfile);
458
freez(datafile);
459
}
475
-
476
- if(!files_number) files_number = 1;
477
- if(!extents_number) extents_number = 1;
478
-
479
- info("DBENGINE STATISTICS ON DATAFILES:"
480
- " Files %zu, structures %zu bytes, %0.2f bytes per file."
481
- " Extents %zu, structures %zu bytes, %0.2f bytes per extent."
482
- " Compressed size of all pages: %zu bytes."
483
- , files_number, files_bytes, (double)files_bytes/files_number
484
- , extents_number, extents_bytes, (double)extents_bytes/extents_number
485
- , page_compressed_sizes
486
- );
460
}
database/engine/pagecache.c
+10
-129
@@ -1238,24 +1238,6 @@ void init_page_cache(struct rrdengine_instance *ctx)
1238
init_committed_page_index(ctx);
1239
}
1240
1241
-
1242
-
1243
-/*
1244
- * METRIC # number
1245
- * 1. INDEX: JudyHS # bytes
1246
- * 2. DATA: page_index # bytes
1247
- *
1248
- * PAGE (1 page of 1 metric) # number
1249
- * 1. INDEX AT METRIC: page_index->JudyL_array # bytes
1250
- * 2. DATA: descr # bytes
1251
- *
1252
- * PAGE CACHE (1 page of 1 metric at the cache) # number
1253
- * 1. pg_cache_descr (if PG_CACHE_DESCR_ALLOCATED) # bytes
1254
- * 2. data (if RRD_PAGE_POPULATED) # bytes
1255
- *
1256
- */
1257
-
1258
-
1241
void free_page_cache(struct rrdengine_instance *ctx)
1242
{
1243
struct page_cache *pg_cache = &ctx->pg_cache;
@@ -1265,30 +1247,15 @@ void free_page_cache(struct rrdengine_instance *ctx)
1247
struct rrdeng_page_descr *descr;
1248
struct page_cache_descr *pg_cache_descr;
1249
1268
- Word_t metrics_number = 0,
1269
- metrics_bytes = 0,
1270
- metrics_index_bytes = 0,
1271
- metrics_duration = 0;
1272
-
1273
- Word_t pages_number = 0,
1274
- pages_bytes = 0,
1275
- pages_index_bytes = 0;
1276
-
1277
- Word_t pages_size_per_type[256] = { 0 },
1278
- pages_count_per_type[256] = { 0 };
1279
-
1280
- Word_t cache_pages_number = 0,
1281
- cache_pages_bytes = 0,
1282
- cache_pages_data_bytes = 0;
1283
-
1284
- size_t points_in_db = 0,
1285
- uncompressed_points_size = 0,
1286
- seconds_in_db = 0,
1287
- single_point_pages = 0;
1288
-
1289
- Word_t pages_dirty_index_bytes = 0;
1290
-
1291
- usec_t oldest_time_ut = LONG_MAX, latest_time_ut = 0;
1250
+ // if we are exiting, the OS will recover all memory so do not slow down the shutdown process
1251
+ // Do the cleanup if we are compiling with NETDATA_INTERNAL_CHECKS
1252
+ // This affects the reporting of dbengine statistics which are available in real time
1253
+ // via the /api/v1/dbengine_stats endpoint
1254
+#ifndef NETDATA_INTERNAL_CHECKS
1255
+ if (netdata_exit)
1256
+ return;
1257
+#endif
1258
+ Word_t metrics_index_bytes = 0, pages_index_bytes = 0, pages_dirty_index_bytes = 0;
1259
1260
/* Free committed page index */
1261
pages_dirty_index_bytes = JudyLFreeArray(&pg_cache->committed_page_index.JudyL_array, PJE0);
@@ -1305,116 +1272,30 @@ void free_page_cache(struct rrdengine_instance *ctx)
1272
PValue = JudyLFirst(page_index->JudyL_array, &Index, PJE0);
1273
descr = unlikely(NULL == PValue) ? NULL : *PValue;
1274
1308
- size_t metric_duration = 0;
1309
- size_t metric_update_every = 0;
1310
- size_t metric_single_point_pages = 0;
1311
-
1275
while (descr != NULL) {
1276
/* Iterate all page descriptors of this metric */
1277
1278
if (descr->pg_cache_descr_state & PG_CACHE_DESCR_ALLOCATED) {
1316
- cache_pages_number++;
1317
-
1279
/* Check rrdenglocking.c */
1280
pg_cache_descr = descr->pg_cache_descr;
1281
if (pg_cache_descr->flags & RRD_PAGE_POPULATED) {
1282
dbengine_page_free(pg_cache_descr->page);
1322
- cache_pages_data_bytes += RRDENG_BLOCK_SIZE;
1283
}
1284
rrdeng_destroy_pg_cache_descr(ctx, pg_cache_descr);
1325
- cache_pages_bytes += sizeof(*pg_cache_descr);
1285
}
1327
-
1328
- if(descr->start_time < oldest_time_ut)
1329
- oldest_time_ut = descr->start_time;
1330
-
1331
- if(descr->end_time > latest_time_ut)
1332
- latest_time_ut = descr->end_time;
1333
-
1334
- pages_size_per_type[descr->type] += descr->page_length;
1335
- pages_count_per_type[descr->type]++;
1336
-
1337
- size_t points_in_page = (descr->page_length / PAGE_POINT_SIZE_BYTES(descr));
1338
- size_t page_duration = ((descr->end_time - descr->start_time) / USEC_PER_SEC);
1339
- size_t update_every = (page_duration == 0) ? 1 : page_duration / (points_in_page - 1);
1340
-
1341
- if (!page_duration && metric_update_every) {
1342
- page_duration = metric_update_every;
1343
- update_every = metric_update_every;
1344
- }
1345
- else if(page_duration)
1346
- metric_update_every = update_every;
1347
-
1348
- uncompressed_points_size += descr->page_length;
1349
-
1350
- if(page_duration > 0) {
1351
- page_duration = update_every * points_in_page;
1352
- metric_duration += page_duration;
1353
- seconds_in_db += page_duration;
1354
- points_in_db += descr->page_length / PAGE_POINT_SIZE_BYTES(descr);
1355
- }
1356
- else
1357
- metric_single_point_pages++;
1358
-
1286
rrdeng_page_descr_freez(descr);
1360
- pages_bytes += sizeof(*descr);
1361
- pages_number++;
1287
1288
PValue = JudyLNext(page_index->JudyL_array, &Index, PJE0);
1289
descr = unlikely(NULL == PValue) ? NULL : *PValue;
1290
}
1291
1367
- if(metric_single_point_pages && metric_update_every) {
1368
- points_in_db += metric_single_point_pages;
1369
- seconds_in_db += metric_update_every * metric_single_point_pages;
1370
- metric_duration += metric_update_every * metric_single_point_pages;
1371
- }
1372
- else
1373
- single_point_pages += metric_single_point_pages;
1374
-
1292
/* Free page index */
1293
pages_index_bytes += JudyLFreeArray(&page_index->JudyL_array, PJE0);
1294
fatal_assert(NULL == page_index->JudyL_array);
1295
freez(page_index);
1379
-
1380
- metrics_number++;
1381
- metrics_bytes += sizeof(*page_index);
1382
- metrics_duration += metric_duration;
1296
}
1297
/* Free metrics index */
1298
metrics_index_bytes = JudyHSFreeArray(&pg_cache->metrics_index.JudyHS_array, PJE0);
1299
fatal_assert(NULL == pg_cache->metrics_index.JudyHS_array);
1387
-
1388
- if(!metrics_number) metrics_number = 1;
1389
- if(!pages_number) pages_number = 1;
1390
- if(!cache_pages_number) cache_pages_number = 1;
1391
- if(!points_in_db) points_in_db = 1;
1392
- if(latest_time_ut == oldest_time_ut) oldest_time_ut -= USEC_PER_SEC;
1393
-
1394
- if(single_point_pages) {
1395
- long double avg_duration = (long double)seconds_in_db / points_in_db;
1396
- points_in_db += single_point_pages;
1397
- seconds_in_db += (size_t)(avg_duration * single_point_pages);
1398
- }
1399
-
1400
- info("DBENGINE STATISTICS ON METRICS:"
1401
- " Metrics: %lu (structures %lu bytes - per metric %0.2f, index (HS) %lu bytes - per metric %0.2f bytes - duration %zu secs) |"
1402
- " Page descriptors: %lu (structures %lu bytes - per page %0.2f bytes, index (L) %lu bytes - per page %0.2f, dirty index %lu bytes). |"
1403
- " Page cache: %lu pages (structures %lu bytes - per page %0.2f bytes, data %lu bytes). |"
1404
- " Points in db %zu, uncompressed size of points database %zu bytes. |"
1405
- " Duration of all points %zu seconds, average point duration %0.2f seconds."
1406
- " Duration of the database %llu seconds, average metric duration %0.2f seconds, average metric lifetime %0.2f%%."
1407
- , metrics_number, metrics_bytes, (double)metrics_bytes/metrics_number, metrics_index_bytes, (double)metrics_index_bytes/metrics_number, metrics_duration
1408
- , pages_number, pages_bytes, (double)pages_bytes/pages_number, pages_index_bytes, (double)pages_index_bytes/pages_number, pages_dirty_index_bytes
1409
- , cache_pages_number, cache_pages_bytes, (double)cache_pages_bytes/cache_pages_number, cache_pages_data_bytes
1410
- , points_in_db, uncompressed_points_size
1411
- , seconds_in_db, (double)seconds_in_db/points_in_db
1412
- , (latest_time_ut - oldest_time_ut) / USEC_PER_SEC, (double)metrics_duration/metrics_number
1413
- , (double)metrics_duration/metrics_number * 100.0 / ((latest_time_ut - oldest_time_ut) / USEC_PER_SEC)
1414
- );
1415
-
1416
- for(int i = 0; i < 256 ;i++) {
1417
- if(pages_count_per_type[i])
1418
- info("DBENGINE STATISTICS ON PAGE TYPES: page type %d total pages %lu, average page size %0.2f bytes", i, pages_count_per_type[i], (double)pages_size_per_type[i]/pages_count_per_type[i]);
1419
- }
1300
+ info("Freed %lu bytes of memory from page cache.", pages_dirty_index_bytes + pages_index_bytes + metrics_index_bytes);
1301
}
database/engine/rrdengine.c
+2
-2
@@ -1329,7 +1329,7 @@ void rrdeng_worker(void* arg)
1329
}
1330
1331
/* cleanup operations of the event loop */
1332
- info("Shutting down RRD engine event loop.");
1332
+ info("Shutting down RRD engine event loop for tier %d", ctx->tier);
1333
1334
/*
1335
* uv_async_send after uv_close does not seem to crash in linux at the moment,
@@ -1344,7 +1344,7 @@ void rrdeng_worker(void* arg)
1344
wal_flush_transaction_buffer(wc);
1345
uv_run(loop, UV_RUN_DEFAULT);
1346
1347
- info("Shutting down RRD engine event loop complete.");
1347
+ info("Shutting down RRD engine event loop for tier %d complete", ctx->tier);
1348
/* TODO: don't let the API block by waiting to enqueue commands */
1349
uv_cond_destroy(&wc->cmd_cond);
1350
/* uv_mutex_destroy(&wc->cmd_mutex); */
database/rrdhost.c
-2
@@ -1007,8 +1007,6 @@ void __rrd_check_wrlock(const char *file, const char *function, const unsigned l
1007
// RRDHOST - free
1008
1009
void rrdhost_system_info_free(struct rrdhost_system_info *system_info) {
1010
- info("SYSTEM_INFO: free %p", system_info);
1011
-
1010
if(likely(system_info)) {
1011
freez(system_info->cloud_provider_type);
1012
freez(system_info->cloud_instance_type);