| 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. |