@cryptotaxi247 / netdata-1 / commits / e6870f0e8

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);