Force page alignment per dimension of chart. (#6240)
Markos Fountoulakis committed
Jun 7, 2019 at 13:06 UTC
f3edd43b4fd5ab98aa15b50f50d04751b3303bae
3 files changed
+45
-6
database/engine/rrdengineapi.c
+38
-5
@@ -41,6 +41,7 @@ void rrdeng_store_metric_init(RRDDIM *rd)
41
42
handle->descr = NULL;
43
handle->prev_descr = NULL;
44
+ handle->unaligned_page = 0;
45
46
uv_rwlock_rdlock(&pg_cache->metrics_index.lock);
47
PValue = JudyHSGet(pg_cache->metrics_index.JudyHS_array, &temp_id, sizeof(uuid_t));
@@ -102,7 +103,7 @@ void rrdeng_store_metric_flush_current_page(RRDDIM *rd)
103
page_is_empty = page_has_only_empty_metrics(descr);
104
if (page_is_empty) {
105
debug(D_RRDENGINE, "Page has empty metrics only, deleting:");
105
- if(unlikely(debug_flags & D_RRDENGINE))
106
+ if (unlikely(debug_flags & D_RRDENGINE))
107
print_page_cache_descr(descr);
108
pg_cache_put(ctx, descr);
109
pg_cache_punch_hole(ctx, descr, 1);
@@ -115,8 +116,8 @@ void rrdeng_store_metric_flush_current_page(RRDDIM *rd)
116
assert (1 == ret);
117
118
rrdeng_commit_page(ctx, descr, handle->page_correlation_id);
119
+ handle->prev_descr = descr;
120
}
119
- handle->prev_descr = descr;
121
} else {
122
free(descr->pg_cache_descr->page);
123
rrdeng_destroy_pg_cache_descr(ctx, descr->pg_cache_descr);
@@ -132,12 +133,38 @@ void rrdeng_store_metric_next(RRDDIM *rd, usec_t point_in_time, storage_number n
133
struct page_cache *pg_cache;
134
struct rrdeng_page_descr *descr;
135
storage_number *page;
136
+ uint8_t must_flush_unaligned_page = 0, perfect_page_alignment = 0;
137
138
handle = &rd->state->handle.rrdeng;
139
ctx = handle->ctx;
140
pg_cache = &ctx->pg_cache;
141
descr = handle->descr;
140
- if (unlikely(NULL == descr || descr->page_length + sizeof(number) > RRDENG_BLOCK_SIZE)) {
142
+
143
+ if (descr) {
144
+ /* Make alignment decisions */
145
+
146
+ if (descr->page_length == rd->rrdset->rrddim_page_alignment) {
147
+ /* this is the leading dimension that defines chart alignment */
148
+ perfect_page_alignment = 1;
149
+ }
150
+ /* is the metric far enough out of alignment with the others? */
151
+ if (unlikely(descr->page_length + sizeof(number) < rd->rrdset->rrddim_page_alignment)) {
152
+ handle->unaligned_page = 1;
153
+ debug(D_RRDENGINE, "Metric page is not aligned with chart:");
154
+ if (unlikely(debug_flags & D_RRDENGINE))
155
+ print_page_cache_descr(descr);
156
+ }
157
+ if (unlikely(handle->unaligned_page &&
158
+ /* did the other metrics change page? */
159
+ rd->rrdset->rrddim_page_alignment <= sizeof(number))) {
160
+ debug(D_RRDENGINE, "Flushing unaligned metric page.");
161
+ must_flush_unaligned_page = 1;
162
+ handle->unaligned_page = 0;
163
+ }
164
+ }
165
+ if (unlikely(NULL == descr ||
166
+ descr->page_length + sizeof(number) > RRDENG_BLOCK_SIZE ||
167
+ must_flush_unaligned_page)) {
168
rrdeng_store_metric_flush_current_page(rd);
169
170
page = rrdeng_create_page(ctx, &handle->page_index->id, &descr);
@@ -148,12 +175,18 @@ void rrdeng_store_metric_next(RRDDIM *rd, usec_t point_in_time, storage_number n
175
uv_rwlock_wrlock(&pg_cache->commited_page_index.lock);
176
handle->page_correlation_id = pg_cache->commited_page_index.latest_corr_id++;
177
uv_rwlock_wrunlock(&pg_cache->commited_page_index.lock);
178
+
179
+ if (0 == rd->rrdset->rrddim_page_alignment) {
180
+ /* this is the leading dimension that defines chart alignment */
181
+ perfect_page_alignment = 1;
182
+ }
183
}
184
page = descr->pg_cache_descr->page;
153
-
185
page[descr->page_length / sizeof(number)] = number;
186
descr->end_time = point_in_time;
187
descr->page_length += sizeof(number);
188
+ if (perfect_page_alignment)
189
+ rd->rrdset->rrddim_page_alignment = descr->page_length;
190
if (unlikely(INVALID_TIME == descr->start_time)) {
191
descr->start_time = point_in_time;
192
@@ -334,7 +367,7 @@ void *rrdeng_create_page(struct rrdengine_instance *ctx, uuid_t *id, struct rrde
367
pg_cache_descr->refcnt = 1;
368
369
debug(D_RRDENGINE, "Created new page:");
337
- if(unlikely(debug_flags & D_RRDENGINE))
370
+ if (unlikely(debug_flags & D_RRDENGINE))
371
print_page_cache_descr(descr);
372
rrdeng_page_descr_mutex_unlock(ctx, descr);
373
*ret_descr = descr;
database/rrd.h
+5
-1
@@ -250,6 +250,8 @@ union rrddim_collect_handle {
250
unsigned long page_correlation_id;
251
struct rrdengine_instance *ctx;
252
struct pg_cache_page_index *page_index;
253
+ // set to 1 when this dimension is not page aligned with the other dimensions in the chart
254
+ uint8_t unaligned_page;
255
} rrdeng; // state the database engine uses
256
#endif
257
};
@@ -431,7 +433,9 @@ struct rrdset {
433
char *plugin_name; // the name of the plugin that generated this
434
char *module_name; // the name of the plugin module that generated this
435
434
- size_t unused[6];
436
+ size_t unused[5];
437
+
438
+ size_t rrddim_page_alignment; // keeps metric pages in alignment when using dbengine
439
440
uint32_t hash; // a simple hash on the id, to speed up searching
441
// we first compare hashes, and only if the hashes are equal we do string comparisons
database/rrdset.c
+2
@@ -251,6 +251,7 @@ void rrdset_reset(RRDSET *st) {
251
st->current_entry = 0;
252
st->counter = 0;
253
st->counter_done = 0;
254
+ st->rrddim_page_alignment = 0;
255
256
RRDDIM *rd;
257
rrddim_foreach_read(rd, st) {
@@ -707,6 +708,7 @@ RRDSET *rrdset_create_custom(
708
st->last_collected_time.tv_sec = 0;
709
st->last_collected_time.tv_usec = 0;
710
st->counter_done = 0;
711
+ st->rrddim_page_alignment = 0;
712
713
st->gap_when_lost_iterations_above = (int) (gap_when_lost_iterations_above + 2);
714