Search code examples
rrdtool

rrdtool update multiple datasources in two commands


RRD does not update the second datasource correctly, see:

First, I create the RRD file with two datasources (c1 and c2):

rdtool create test.rrd  --start N  --step 60 DS:c1:GAUGE:120:0:100 DS:c2:GAUGE:120:0:100 RRA:AVERAGE:0.5:1:1440

Then I do update the two datasources in two commands:

rrdtool update test.rrd -t c1 N:10 && rrdtool update test.rrd -t c2 N:10

Wait for 60 seconds.... Do again an update :

rdtool update test.rrd -t c1 N:20 && rrdtool update test.rrd -t c2 N:20

Then lets see what we have:

rrdtool fetch test.rrd AVERAGE | tail -5
1468409580: -nan -nan
1468409640: -nan -nan
1468409700: -nan -nan
1468409760: 1,5988575517e+01 1,9266620475e-01
1468409820: -nan -nan

The first datacource c1 works as expected, but the second c2 shows a value lower than 1 and I expect also a value close to 15.

Yes, I know I can also update both datasources in ONE update command, but in my case a have a lot of datasources in one rrd file and its better to read and follow the mass of values.

Used rrd version : 1.6.0


Solution

  • This is, of course, Data Normalisation. It is also caused by your updating the two datasources in two separate calls.

    If you instead use: rrdtool update test.rrd -t c1:c2 N:10:10 rrdtool update test.rrd -t c1:c2 N:20:20 then you will be updating both DSs at the same time. You see, when you do it in separate updates, what you're actually doing is implicitly updating the other DS with 'unknown' and then relying on the automatic interpolation to fill things in. RRDTool is not a relational database, and you cannot update values in a timewindow independently without affecting the other values.

    The other issue is Data Normalisation, where values are adjusted temporally to fit into the exact time boundaries and in doing so, the values are adjusted to be linearly equivalent... the practical upshot when using network traffic (big numbers) is pretty much the same, and the overall totals and averages are consistent, but smaller point-in-time values end up as decimals like this.

    So, two things:

    1. Update your DS all together, not in separate calls
    2. Try to update exactly on the time boundary.(Instead of using 'N' use an exact time, rounded to the nearest minute)