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