差分/時間、差分 について

ちょっと細かいところが気になるので教えてください。
一応 Zabbix 3.0 ですが、たぶんバージョンには関係のない話だと思います。

アイテムの保存時の計算で 差分/時間(または 差分)を選んだときは、最初に値を取得したときにはそれをどこかに覚えるだけで、ヒストリ(history テーブル)には何も記録しない、そして、次に値を取得したときに、前回との差分を時間で割ったもの(または前回との差分)をヒストリに記録する、という認識です。

この、前回取得した(生の)値というのは、どこに記憶しているんでしょうか?
メモリ上ですか?データベースのどこかのテーブルですか?

ソースを探してみると、テーブルを読んでいる気配がないんですよね(※1)。
どうもキャッシュ(つまりメモリ上)に覚えているような気がするのです。

そこで気になるのが、メモリ上だと Zabbix サーバー再起動時には忘れるので「再起動後二回目の値取得まではヒストリが更新されない」ということなのか?ということです。
再起動直前に取得した値は忘れてしまうんでしょうか?

もう一つ。
差分/時間 のときは、前回より値が小さくなると一旦捨てるような記述がありますが、これは例えば5分(=300秒)おきに取得する値があって 差分/時間 としていたときに、
  時間   取得した値  ヒストリに保存する値
  10:00  1000      なし (これが初回)
  10:05  1300      1
  10:10  1600      1
  10:15  0         なし
  10:20  300       1
こうなって、ヒストリを見ると、10:05、10:10、10:20 にだけデータがある状態になっているということでしょうか?

※1 3.0.9 のソースを読みました。
--- libs/zbxdbcache/dbcache.c ---
DCadd_update_item_sql()
  まず deltaitem = DCget_deltaitem(delta_history, item, h); で前回の値を取得し、
  浮動小数か整数かに応じて
  DCcalculate_item_delta_float(item, h, deltaitem); または
  DCcalculate_item_delta_uint64(item, h, deltaitem); を使って
  差分/時間(または 差分)の値を h に入れる。

DCget_deltaitem(delta_history, item, h)
  保存時の計算が必要なら
  zbx_hashset_search(delta_history, &item->itemid)
  を実行してその結果を返す。
  delta_history は差分/時間 や 差分 の計算に使うためのハッシュテーブル。

--- src/libs/zbxalgo/hashset.c ---
zbx_hashset_search(hs, data)
  ハッシュテーブル hs から data に対応する値を探して返す。

余談ですが、マニュアルを読むと、差分/時間 のときは、前回より値が小さくなると一旦捨てるような記述(※2)がありますが、差分 のときはそういう記述がありません。
2.2 のマニュアル
 注意:現在の値が前の値より小さい場合、その差は破棄され(何も保存されません)、別の値を待ちます。
3.0 のマニュアル
 If current value is smaller than the previous value,
 Zabbix discards that difference (stores nothing) and waits for another value.

でも、 DCcalculate_item_delta_float() や DCcalculate_item_delta_uint64() 内では、
case ITEM_STORE_SIMPLE_CHANGE: の中でも処理する条件として
 deltaitem->value.xxx <= h->value_orig.xxx
というのがあって、こっちも値が小さくなったら捨てられるみたいなんですよね。
マニュアルが不十分なだけなんだとは思いますが・・・。

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー minayan の写真

投稿されてだいぶ過ぎていまさらですが、
3.0.9のソースコードでDCcalculate_item_delta_*を見てみました。

> というのがあって、こっちも値が小さくなったら捨てられるみたいなんですよね。
> マニュアルが不十分なだけなんだとは思いますが・・・。

差分についても前回より値が小さいと、何もしない(=今回取得した値は捨てられる=無処理)処理となっています。
フラグにZBX_DC_FLAG_UNDEF(未定義)をセットしているので間違いないですね。
マニュアルの説明が足りないというか抜けています。

興味ついで3.4.6も見ていますが、
3.0.9と比べると跡形も無いほどにdbcache.cの内容が変わっています。
DCcalculate_item_delta_*は存在すらなくなりました。
valuecash.cも然り、リファクタリングの真っ最中という感じを受けます。
あとはnextchecks.cが無くなって、dbconfig_dump.cとdbsync.cが追加になっています。

ユーザー minayan の写真

肝心なことに答えていませんでした。

> この、前回取得した(生の)値というのは、どこに記憶しているんでしょうか?
>メモリ上ですか?データベースのどこかのテーブルですか?

メモリ上ですね

> こうなって、ヒストリを見ると、10:05、10:10、10:20 にだけデータがある状態になっているということでしょうか?

いまソースを追っている最中で途中ですが、
差分/時間 OR 差分で前回より値が小さい場合は、intやfloatのオーバーフローを考えれば値0(ゼロ)でinsertではと踏んでいます。

ユーザー minayan の写真

> 差分/時間 OR 差分で前回より値が小さい場合は、intやfloatのオーバーフローを考えれば値0(ゼロ)でinsertではと踏んでいます。

この辺りは、私自身も常々疑問に感じていましたので、実際の動作で確認しようかと思います。
zabbix_senderで値を入れ込んで、オーバーフロー(値を0)させてDBテーブルへのinsertがどうなっているのか確認します。