Commit | Line | Data |
---|---|---|
5e0cbfb0 PP |
1 | --- |
2 | id: channel-overwrite-mode-vs-discard-mode | |
3 | --- | |
4 | ||
5 | As previously mentioned, a channel's ring buffer is divided into many | |
6 | equally sized sub-buffers. | |
7 | ||
8 | As events occur, they are serialized as trace data into a specific | |
9 | sub-buffer (yellow arc in the following animation) until it is full: | |
10 | when this happens, the sub-buffer is marked as consumable (red) and | |
11 | another, _empty_ (white) sub-buffer starts receiving the following | |
12 | events. The marked sub-buffer will be consumed eventually by a consumer | |
13 | daemon (returns to white). | |
14 | ||
15 | <script type="text/javascript"> | |
16 | document.write('<div class="img img-50" id="docsvg-channel-subbuf-anim"></div>'); | |
17 | ||
18 | $(document).ready(function() { | |
19 | var doc = SVG('docsvg-channel-subbuf-anim'); | |
20 | ||
21 | doc.viewbox(0, 0, 2, 2); | |
22 | ||
23 | var rb = rbBuildStdAnimated(doc, { | |
24 | div: 5, | |
25 | oR: 0.97, | |
26 | evDur: 300, | |
27 | evPerSubBuf: 6, | |
28 | consumerAfter: 10 | |
29 | }); | |
30 | ||
31 | rb.getGroup().move(1, 1); | |
32 | }); | |
33 | </script> | |
34 | ||
35 | <noscript> | |
36 | <div class="err"> | |
37 | <p> | |
38 | <span class="t">Oops!</span>JavaScript must be enabled in | |
39 | order to view animations. | |
40 | </p> | |
41 | </div> | |
42 | </noscript> | |
43 | ||
44 | In an ideal world, sub-buffers are consumed faster than filled, like it | |
45 | is the case above. In the real world, however, all sub-buffers could be | |
46 | full at some point, leaving no space to record the following events. By | |
47 | design, LTTng is a _non-blocking_ tracer: when no empty sub-buffer | |
48 | exists, losing events is acceptable when the alternative would be to | |
49 | cause substantial delays in the instrumented application's execution. | |
50 | LTTng privileges performance over integrity, aiming at perturbing the | |
51 | traced system as little as possible in order to make tracing of subtle | |
52 | race conditions and rare interrupt cascades possible. | |
53 | ||
54 | When it comes to losing events because no empty sub-buffer is available, | |
55 | the channel's _event loss mode_ determines what to do amongst: | |
56 | ||
57 | * **Discard**: drop the newest events until a sub-buffer is released. | |
58 | * **Overwrite**: clear the sub-buffer containing the oldest recorded | |
59 | events and start recording the newest events there. This mode is | |
60 | sometimes called _flight recorder mode_ because it behaves like a | |
61 | flight recorder: always keep a fixed amount of the latest data. | |
62 | ||
63 | Which mechanism you should choose depends on your context: prioritize | |
64 | the newest or the oldest events in the ring buffer? | |
65 | ||
66 | Beware that, in overwrite mode, a whole sub-buffer is abandoned as soon | |
67 | as a new event doesn't find an empty sub-buffer, whereas in discard | |
68 | mode, only the event that doesn't fit is discarded. | |
69 | ||
70 | Also note that a count of lost events will be incremented and saved in | |
71 | the trace itself when an event is lost in discard mode, whereas no | |
72 | information is kept when a sub-buffer gets overwritten before being | |
73 | committed. | |
74 | ||
75 | There are known ways to decrease your probability of losing events. The | |
76 | next section shows how tuning the sub-buffers count and size can be | |
77 | used to virtually stop losing events. |