Use mmap if possible during startup for journal replay (#13660)
Try to mmap the journal files during replay. If the mmap fails, fallback to the old way
Stelios Fragkakis committed
Sep 14, 2022 at 13:00 UTC
3b4fc558e1b5a9e7a898934197570862ad720d00
2 files changed
+27
-17
database/engine/journalfile.c
+26
-16
@@ -442,27 +442,30 @@ static uint64_t iterate_transactions(struct rrdengine_instance *ctx, struct rrde
442
//data_file_size = journalfile->datafile->pos; TODO: utilize this?
443
444
max_id = 1;
445
- ret = posix_memalign((void *)&buf, RRDFILE_ALIGNMENT, READAHEAD_BYTES);
446
- if (unlikely(ret)) {
447
- fatal("posix_memalign:%s", strerror(ret));
445
+ bool journal_is_mmapped = journalfile->data;
446
+ if (unlikely(!journal_is_mmapped)) {
447
+ ret = posix_memalign((void *)&buf, RRDFILE_ALIGNMENT, READAHEAD_BYTES);
448
+ if (unlikely(ret))
449
+ fatal("posix_memalign:%s", strerror(ret));
450
}
449
-
451
+ else
452
+ buf = journalfile->data + sizeof(struct rrdeng_jf_sb);
453
for (pos = sizeof(struct rrdeng_jf_sb) ; pos < file_size ; pos += READAHEAD_BYTES) {
454
size_bytes = MIN(READAHEAD_BYTES, file_size - pos);
452
- iov = uv_buf_init(buf, size_bytes);
453
- ret = uv_fs_read(NULL, &req, file, &iov, 1, pos, NULL);
454
- if (ret < 0) {
455
- error("uv_fs_read: pos=%"PRIu64", %s", pos, uv_strerror(ret));
455
+ if (unlikely(!journal_is_mmapped)) {
456
+ iov = uv_buf_init(buf, size_bytes);
457
+ ret = uv_fs_read(NULL, &req, file, &iov, 1, pos, NULL);
458
+ if (ret < 0) {
459
+ error("uv_fs_read: pos=%" PRIu64 ", %s", pos, uv_strerror(ret));
460
+ uv_fs_req_cleanup(&req);
461
+ goto skip_file;
462
+ }
463
+ fatal_assert(req.result >= 0);
464
uv_fs_req_cleanup(&req);
457
- goto skip_file;
465
+ ++ctx->stats.io_read_requests;
466
+ ctx->stats.io_read_bytes += size_bytes;
467
}
459
- fatal_assert(req.result >= 0);
460
- uv_fs_req_cleanup(&req);
461
- ctx->stats.io_read_bytes += size_bytes;
462
- ++ctx->stats.io_read_requests;
468
464
- //pos_i = pos;
465
- //while (pos_i < pos + size_bytes) {
469
for (pos_i = 0 ; pos_i < size_bytes ; ) {
470
unsigned max_size;
471
@@ -475,9 +478,12 @@ static uint64_t iterate_transactions(struct rrdengine_instance *ctx, struct rrde
478
pos_i += ret;
479
max_id = MAX(max_id, id);
480
}
481
+ if (likely(journal_is_mmapped))
482
+ buf = journalfile->data + size_bytes;
483
}
484
skip_file:
480
- free(buf);
485
+ if (unlikely(!journal_is_mmapped))
486
+ free(buf);
487
return max_id;
488
}
489
@@ -512,12 +518,16 @@ int load_journal_file(struct rrdengine_instance *ctx, struct rrdengine_journalfi
518
519
journalfile->file = file;
520
journalfile->pos = file_size;
521
+ journalfile->data = netdata_mmap(path, file_size, MAP_SHARED, 0);
522
+ info("Loading journal file \"%s\" using %s.", path, journalfile->data?"using MMAP":"using uv_fs_read");
523
524
max_id = iterate_transactions(ctx, journalfile);
525
526
ctx->commit_log.transaction_id = MAX(ctx->commit_log.transaction_id, max_id + 1);
527
528
info("Journal file \"%s\" loaded (size:%"PRIu64").", path, file_size);
529
+ if (likely(journalfile->data))
530
+ munmap(journalfile->data, file_size);
531
return 0;
532
533
error:
database/engine/journalfile.h
+1
-1
@@ -19,7 +19,7 @@ struct rrdengine_journalfile;
19
struct rrdengine_journalfile {
20
uv_file file;
21
uint64_t pos;
22
-
22
+ void *data;
23
struct rrdengine_datafile *datafile;
24
};
25