1167
1168
bool agent_shutdown = false;
1169
while (datafile) {
1170
- struct journal_v2_header *j2_header = journalfile_v2_data_acquire(datafile->journalfile, NULL, 0, 0);
1170
+ struct journal_v2_header *j2_header = journalfile_v2_data_acquire_with_hint(
1171
+ datafile->journalfile, NULL, 0, 0, JOURNALFILE_V2_ACCESS_RANDOM);
1172
if (!j2_header) {
1173
datafile = datafile_release_and_acquire_next_for_retention(ctx, datafile);
1174
continue;
1343
worker_is_busy(UV_EVENT_DBENGINE_FIND_ROTATED_METRICS);
1344
1345
struct rrdengine_journalfile *journalfile = datafile_to_delete->journalfile;
1345
- struct journal_v2_header *j2_header = journalfile_v2_data_acquire(journalfile, NULL, 0, 0);
1346
+ struct journal_v2_header *j2_header = journalfile_v2_data_acquire_with_hint(
1347
+ journalfile, NULL, 0, 0, JOURNALFILE_V2_ACCESS_SEQUENTIAL_DIRECTORY);
1348
1349
if (unlikely(!j2_header)) {
1350
if (worker)
1694
}
1695
1696
size_t total = 0;
1697
+ Word_t last_index = 0;
1698
+ bool resume_scan = false;
1699
do {
1700
struct rrdengine_datafile *datafile = NULL;
1701
1702
// find a datafile to work on
1703
netdata_rwlock_rdlock(&ctx->datafiles.rwlock);
1700
- bool first_then_next = true;
1701
- Pvoid_t *Pvalue = NULL;
1702
- Word_t Index = 0;
1704
+ Pvoid_t *Pvalue = NULL;
1705
+ Word_t Index = resume_scan ? last_index : 0;
1706
+ bool first_then_next = !resume_scan;
1707
while((Pvalue = JudyLFirstThenNext(ctx->datafiles.JudyL, &Index, &first_then_next))) {
1708
datafile = *Pvalue;
1709
if(!spinlock_trylock(&datafile->populate_mrg.spinlock)) {
1723
if(!datafile)
1724
break;
1725
1726
+ // resume next scan from current position
1727
+ last_index = Index;
1728
+ resume_scan = true;
1729
+
1730
uv_sem_wait(mlt->sem);
1731
struct mrg_load_thread *local_mlt = callocz(1, sizeof(struct mrg_load_thread));
1732
local_mlt->datafile = datafile;
1735
local_mlt->populated_datafiles = &populated_datafiles;
1736
__atomic_add_fetch(local_mlt->total, 1, __ATOMIC_RELAXED);
1737
rrdeng_enq_cmd(ctx, RRDENG_OPCODE_MRG_LOAD, local_mlt, NULL, STORAGE_PRIORITY_INTERNAL_DBENGINE, NULL, NULL);
1730
- nd_log_limit_static_thread_var(erl, 10, 0);
1731
- nd_log_limit(&erl, NDLS_DAEMON, NDLP_INFO, "DBENGINE: Tier %d MRG population completed: %.2f%% (%zu/%zu)", tier, (populated_datafiles * 100.0) / total_datafiles,
1732
- populated_datafiles, total_datafiles);
1738
+ {
1739
+ nd_log_limit_static_thread_var(erl, 10, 0);
1740
+ size_t completed = __atomic_load_n(&populated_datafiles, __ATOMIC_RELAXED);
1741
+ nd_log_limit(&erl, NDLS_DAEMON, NDLP_INFO,
1742
+ "DBENGINE: Tier %d MRG population completed: %.2f%% (%zu/%zu)",
1743
+ tier, (completed * 100.0) / total_datafiles, completed, total_datafiles);
1744
+ }
1745
} while(1);
1746
1735
- // We've processed all datafiles. Now wait for all our threads to complete
1747
+ // We've queued all datafiles. Now wait for all worker threads to complete.
1748
size_t pending;
1749
do {
1750
pending = __atomic_load_n(&total, __ATOMIC_ACQUIRE);
1751
if (pending) {
1752
nd_log_limit_static_thread_var(erl, 10, 0);
1741
- nd_log_limit(&erl, NDLS_DAEMON, NDLP_INFO, "DBENGINE: Tier %d Waiting for %zu threads", tier, total);
1753
+ size_t completed = __atomic_load_n(&populated_datafiles, __ATOMIC_RELAXED);
1754
+ nd_log_limit(&erl, NDLS_DAEMON, NDLP_INFO,
1755
+ "DBENGINE: Tier %d MRG population completed: %.2f%% (%zu/%zu), waiting for %zu workers",
1756
+ tier, (completed * 100.0) / total_datafiles, completed, total_datafiles, pending);
1757
sleep_usec(10 * USEC_PER_MS);
1758
}
1759
} while (pending > 0);