#mynavi()
#setlinebreak(on);

* 概要 [#jafbab15]
#html(<div class="pl10">)
オープンソースの時系列データベースである InfluxDB の簡単な使用方法等について記載する。
#html(</div>)

* 目次 [#cd6e33ac]
#contents

* インストール/起動 [#fec51e12]
#html(<div class="pl10">)

ここでは公開されているdockerイメージを使用する事とする。

作業用ディレクトリ作成
#myterm2(){{
mkdir myinfluxdb
cd myinfluxdb
}}

influxdb 及び chronograf 用のディレクトリ作成
#myterm2(){{
mkdir influxdb
mkdir etc/myinfluxdb
mkdir chronograf
}}

influxdb 用の設定ファイル作成
※デフォルト設定でよければ作らなくても良い。

./etc/influxdb/influxdb.conf
#mycode2(){{
[meta]
  dir = "/var/lib/influxdb/meta"

[data]
  dir = "/var/lib/influxdb/data"
  engine = "tsm1"
  wal-dir = "/var/lib/influxdb/wal"

[http]
  auth-enabled = true
}}

docker-compose.yml
#mycode2(){{
version: "3" 

services:
  influxdb:
    image: influxdb
    volumes:
      - ./influxdb:/var/lib/influxdb
      - ./etc/influxdb:/etc/influxdb
    ports:
      - 8086:8086

  chronograf:
    image: chronograf:alpine
    volumes:
      - ./chronograf:/var/lib/chronograf
    ports:
      - 8888:8888
    links:
      - influxdb
    depends_on:
      - influxdb
}}
#TODO(telegraf など足りない)

起動
#myterm2(){{
docker-compose up
}}

手っ取り早く必要なものが揃うサンドボックス用の docker-compose.yml が公開されているので、そちらを使用しても良い。
https://github.com/influxdata/sandbox



#html(</div>)

* コマンドを使用して操作する [#l2f4e579]
#html(<div class="pl10">)

コンテナIDを確認
#myterm2(){{
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
baeed6a9bce9        chronograf:alpine   "/entrypoint.sh chro…"   4 minutes ago       Up 3 minutes        0.0.0.0:8888->8888/tcp   influxdb_chronograf_1
e66c42c48178        influxdb            "/entrypoint.sh infl…"   4 minutes ago       Up 3 minutes        0.0.0.0:8086->8086/tcp   influxdb_influxdb_1
}}

コンテナに入る
#myterm2(){{
docker exec -it e66c42c48178 /bin/bash
}}

InfluxDB shellを起動する
#myterm2(){{
influx -precision rfc3339
Connected to http://localhost:8086 version 1.7.9
InfluxDB shell version: 1.7.9
> 
}}
※ユーザ作成後は influx -username 'user名' -password 'パスワード' -precision rfc3339 で接続可能。

以降は InfluxDB shell から InfluxQL を使用して各種操作を行う事ができる。
詳細は、以下の URL 及び 後述を参照。

| - | ドキュメントURL |h
| コマンドラインIF | https://docs.influxdata.com/influxdb/v1.7/tools/shell/ |
| データベース管理 | https://docs.influxdata.com/influxdb/v1.7/query_language/database_management/ |
| データ検索 | https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/ |

** データベースの作成 データの登録/検索まで [#j9a6aaa9]
#html(<div class="pl10">)

細かなコマンドの詳細は後述する事として、まずはデータベースを作成し、データの登録/検索を行う所までを行ってみる。

データベースの作成
#myterm2(){{
> create database mydb1
}}

データベースの一覧を確認
#myterm2(){{
> show databases
name: databases
name
----
_internal
mydb1
}}

作成したデータベースに切り替える
#myterm2(){{
> use mydb1
Using database mydb1
}}

データを登録する
#myterm2(){{
> insert sample,server=server1,ym=201912 load_average=0.5
}}

データを検索する
#myterm2(){{
> select * from sample
name: sample
time                         load_average server  ym
----                         ------------ ------  --
2019-12-08T11:00:54.1441902Z 0.5          server1 201912
}}


#html(</div>)


#html(</div>)

* 主なオブジェクトなど [#f82a4dbf]
#html(<div class="pl10">)

https://docs.influxdata.com/influxdb/v1.7/concepts/glossary/

** Retention policy [#e61d8a22]
#html(<div class="pl10">)
InfluxDB では、データを保持する期間、クラスターに保存するデータのコピーの数(レプリケーションファクター)、および シャードグループがカバーする時間範囲などを名前を付けて Retention policy として定義する事ができる。
Retention policy は各レコードの insert 時にレコード毎に指定する事ができ、省略された場合はデフォルトの Retention policy が使用される。
※ NoSQL や キーバリュー型のデータストアでいう所の TTL のような物。
#html(</div>)

** Measurement [#e17a856b]
#html(<div class="pl10">)
RDBでいう所のテーブルのようなもの。
ただし、InfluxDB ではレコード毎に列が不揃いでもよく列定義も不要な為か、事前にテーブル定義などは必要無い。
#html(</div>)

** Series [#ga075544]
#html(<div class="pl10">)
measurement と tag set を論理的にグループ化したもの。
※ show series で確認できる。
#html(</div>)

** Tag [#g58d16db]
#html(<div class="pl10">)
レコードにおけるキー項目。
insert 時に指定する事ができる。
#html(</div>)

** Field [#c17865fa]
#html(<div class="pl10">)
レコードにおけるキー以外の項目。
insert 時に指定する事ができる。
#html(</div>)

** Timestamp [#nc65740e]
#html(<div class="pl10">)
レコードに必ず付与する日時列。(省略時は現在日時が使用される)
検索時は time 列として表示される。
#html(</div>)

** データ型 [#ca6e11c8]
#html(<div class="pl10">)

https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/#data-types

| データ型 | 説明 |h
| Float | 64ビット浮動小数点数。デフォルトの数値型 。|
| Integer | 符号付き64ビット整数(-9223372036854775808から9223372036854775807)。数値の末尾にiを付けて整数を指定する。例:1i |
| String | 文字列。Measurements, tag keys, tag values, field keys, field values で使用できる。最大 64KB。 |
| Boolean | 真偽値。真は [t、T、true、True、TRUE]。 偽は [f、F、false、False、FALSE] で表現する。|
| Timestamp | Unixナノ秒タイムスタンプ。 |

#html(</div>)


#html(</div>)


* 操作方法 (管理/登録系) [#e8e1011d]
#html(<div class="pl10">)

https://docs.influxdata.com/influxdb/v1.7/administration/authentication_and_authorization/
https://docs.influxdata.com/influxdb/v1.7/query_language/database_management/
https://docs.influxdata.com/influxdb/v1.7/query_language/schema_exploration/
https://docs.influxdata.com/influxdb/v1.7/tools/shell/

** ユーザの作成 [#y90d7bef]
#html(<div class="pl10">)

#mycode2(){{
CREATE USER &lt;username&gt; WITH PASSWORD '&lt;password&gt;' WITH ALL PRIVILEGES  # 管理者ユーザの場合
}}

#html(</div>)

** データベースの作成 [#f385b608]
#html(<div class="pl10">)

コマンド
#mycode2(){{
CREATE DATABASE &lt;database_name&gt; [WITH [DURATION &lt;duration&gt;] [REPLICATION &lt;n&gt;] [SHARD DURATION &lt;duration&gt;] [NAME &lt;retention-policy-name&gt;]]
}}

使用例)
#myterm2(){{
> create database mydb1
> show databases
name: databases
name
----
_internal
mydb1
}}


#html(</div>)

** データベースの削除 [#z2363d5c]
#html(<div class="pl10">)

コマンド
#mycode2(){{
DROP DATABASE &lt;database_name&gt;
}}

使用例 )
#myterm2(){{
> drop database mydb1
> show databases
name: databases
name
----
_internal
}}

#html(</div>)

** 計測データの作成 [#f8cdc28c]
#html(<div class="pl10">)
RDBのように事前にテーブルを作成する必要はなく、データを直接投入する事ができる。
また retention policy を省略した場合は、デフォルトの retention policy が使用される。
#mycode2(){{
INSERT INTO [retention policy] &lt;measurement&gt;[,&lt;tag_key&gt;=&lt;tag_value&gt;[,&lt;tag_key&gt;=&lt;tag_value&gt;]] &lt;field_key&gt;=&lt;field_value&gt;[,&lt;field_key&gt;=&lt;field_value&gt;] [&lt;timestamp&gt;]
}}
https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/

*** 主キーは tag + timestamp [#n416d158]
#html(<div class="pl10">)

RDBでいう所の主キーは tag + timestamp となる模様。

1件データを登録
#myterm2(){{
insert sample,type=1 value=1 1576407071041296896
> select * from sample
name: sample
time                           type value
----                           ---- -----
2019-12-15T10:51:11.041296896Z 1    1
}}

同じタグ 及び timestamp でデータを insert すると既存データが update される。
#myterm2(){{
> insert sample,type=1 value=100 1576407071041296896
> select * from sample
name: sample
time                           type value
----                           ---- -----
2019-12-15T10:51:11.041296896Z 1    100
}}

同じ timestamp でもキーが違う場合は、別レコードとして登録される。
#myterm2(){{
> insert sample,type=2 value=1 1576407071041296896
> select * from sample
name: sample
time                           type value
----                           ---- -----
2019-12-15T10:51:11.041296896Z 1    100
2019-12-15T10:51:11.041296896Z 2    1
}}

#html(</div>)

#html(</div>)

** 計測データの削除 [#k557db20]
#html(<div class="pl10">)
#mycode2(){{
DROP MEASUREMENT &lt;measurement_name&gt;
もしくは
DELETE FROM &lt;measurement_name&gt; where ....
}}
#html(</div>)

** RETENTION POLICY の作成 [#dde42157]
#html(<div class="pl10">)
#mycode2(){{
CREATE RETENTION POLICY &lt;retention_policy_name&gt; ON &lt;database_name&gt; DURATION &lt;duration&gt; REPLICATION &lt;n&gt; [SHARD DURATION &lt;duration&gt;] [DEFAULT]
}}

*** 補足 [#s8c8df1e]
#html(<div class="pl10">)
SHARD DURATIONはデータ保持期間内のデータの粒度。
例えば、DURATION 10m SHARD DURATION 1m の場合は、データは1分ずつ10個のシャードに分かれて保存され、1分毎に古いシャードが削除される。
#html(</div>)


#html(</div>)

** RETENTION POLICY の削除 [#dfb68183]
#html(<div class="pl10">)
#mycode2(){{
DROP RETENTION POLICY &lt;retention_policy_name&gt; ON &lt;database_name&gt;
}}
#html(</div>)

#html(</div>)


* 操作方法 (検索系) [#de4b19f8]
#html(<div class="pl10">)

https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/

** 計測データの検索 [#d7136032]
#html(<div class="pl10">)

RDB のように select 文を from 句 や where 句 を使用して記述する事ができる。
また group by や limit, offset も使用可能。

#mycode2(){{
SELECT &lt;field_key&gt;[,&lt;field_key&gt;,&lt;tag_key&gt;] FROM &lt;measurement_name&gt;[,&lt;measurement_name&gt;]
SELECT_clause FROM_clause WHERE &lt;conditional_expression&gt; [(AND|OR) &lt;conditional_expression&gt; [...]]
}}

尚、from 句は以下の形式で指定する事が可能。

| 構文 | 説明 |h
| FROM <measurement_name> | 現在のDBの指定した measurement からデフォルトのリテンションポリシーのデータを検索。 |
| FROM <database_name>.<retention_policy_name>.<measurement_name> | 指定した DB の 指定した measurement から指定したリテンションポリシーのデータを検索 |
| FROM <database_name>..<measurement_name> | 指定した DB の指定した measurement からデフォルトのリテンションポリシーのデータを検索 |


#html(</div>)

** 計測データから別の計測データを作成する [#r6b12fbf]
#html(<div class="pl10">)
#mycode2(){{
SELECT_clause INTO &lt;measurement_name&gt; FROM_clause [WHERE_clause] [GROUP_BY_clause]
}}

尚、into 句は以下の形式で指定する事が可能。

| 構文 | 説明 |h
| INTO <measurement_name> | 指定した measurement にinsert  |
| INTO <database_name>.<retention_policy_name>.<measurement_name> | 指定した db の measurement に、指定したリテンションポリシーで insert |
| INTO <database_name>..<measurement_name> | 指定した db の measurement に、デフォルトのリテンションポリシーで insert |
| INTO <database_name>.<retention_policy_name>.:MEASUREMENT | FROM句の正規表現に一致する、ユーザー指定のデータベースと保持ポリシーのすべての測定値にデータを書き込む |

#html(</div>)


#html(</div>)


* CLI  から使用できるコマンド [#ub76ace6]
#html(<div class="pl10">)

help を入力すると使用できるコマンドが表示される。
使用頻度の高い use や show などはもちろん、表示/整形に有用な pretty や format なども覚えておきたい。

https://docs.influxdata.com/influxdb/v1.7/tools/shell/
https://docs.influxdata.com/influxdb/v1.7/query_language/schema_exploration/


#myterm2(){{
> help
Usage:
        connect <host:port>   connects to another node specified by host:port
        auth                  prompts for username and password
        pretty                toggles pretty print for the json format
        chunked               turns on chunked responses from server
        chunk size <size>     sets the size of the chunked responses.  Set to 0 to reset to the default chunked size
        use <db_name>         sets current database
        format <format>       specifies the format of the server responses: json, csv, or column
        precision <format>    specifies the format of the timestamp: rfc3339, h, m, s, ms, u or ns
        consistency <level>   sets write consistency level: any, one, quorum, or all
        history               displays command history
        settings              outputs the current settings for the shell
        clear                 clears settings such as database or retention policy.  run 'clear' for help
        exit/quit/ctrl+d      quits the influx shell

        show databases        show database names
        show series           show series information
        show measurements     show measurement information
        show tag keys         show tag key information
        show field keys       show field key information

        A full list of influxql commands can be found at:
        https://docs.influxdata.com/influxdb/latest/query_language/spec/
}}

以下、サンプルをいくつか記載する。

** データベースの一覧 [#sc0701dc]
#myterm2(){{
show databases
}}

** measurement の一覧 [#o28fc611]
#myterm2(){{
show measurements
}}

** tag の一覧 [#b3719481]
#myterm2(){{
show tag keys
show tag keys from &lt;measurement&gt;
}}

** field の一覧 [#of1bc3ef]
#myterm2(){{
show field keys
show field keys from &lt;measurement&gt;
}}

** retention policy の一覧 [#vc9dd5ea]
#myterm2(){{
show retention policies
}}

#html(</div>)

* バックアップとリストア [#wa681bfe]
#html(<div class="pl10">)

https://docs.influxdata.com/influxdb/v1.7/administration/backup_and_restore/#backup

#html(<div style="display: inline-block;">)

[バックアップ]
#myterm2(){{
influxd backup
    [ -database &lt;db_name> ]
    [ -portable ]
    [ -host &lt;host:port> ]
    [ -retention &lt;rp_name> ] | [ -shard &lt;shard_ID> -retention &lt;rp_name> ]
    [ -start &lt;timestamp> [ -end &lt;timestamp> ] | -since &lt;timestamp> ]
    &lt;path-to-backup>

}}

#html(</div>)

#html(<div style="display: inline-block;">)

[リストア]
#myterm2(){{
influxd restore [ -db &lt;db_name> ]
    -portable | -online
    [ -host &lt;host:port> ]
    [ -newdb &lt;newdb_name> ]
    [ -rp &lt;rp_name> ]
    [ -newrp &lt;newrp_name> ]
    [ -shard &lt;shard_ID> ]
    &lt;path-to-backup-files>
}}
#html(</div><br />)

確認用の measurement にデータを登録しておく。(デフォルトのリテンションポリシーと別のリテンションポリシーの2種類のデータを登録)

#html(<div id="tabs1"><ul><li><a href="#tabs1-1">データ</a></li><li><a href="#tabs1-2">DDL/DML</a></li><li><a href="#tabs1-3">生成スクリプト(Python)</a></li></ul>)
#html(<div id="tabs1-1">)

#myterm2(){{
> select * from sample
name: sample
time                           type value
----                           ---- -----
2019-12-07T10:04:30.755184896Z 9    9
2019-12-08T10:04:30.755184896Z 8    8
2019-12-09T10:04:30.755184896Z 7    7
2019-12-10T10:04:30.755184896Z 6    6
2019-12-11T10:04:30.755184896Z 5    5
2019-12-12T10:04:30.755184896Z 4    4
2019-12-13T10:04:30.755184896Z 3    3
2019-12-14T10:04:30.755184896Z 2    2
2019-12-15T10:04:30.755184896Z 1    1
> select * from one_month.sample
name: sample
time                           type value
----                           ---- -----
2019-12-07T10:04:30.755184896Z 90   90
2019-12-08T10:04:30.755184896Z 80   80
2019-12-09T10:04:30.755184896Z 70   70
2019-12-10T10:04:30.755184896Z 60   60
2019-12-11T10:04:30.755184896Z 50   50
2019-12-12T10:04:30.755184896Z 40   40
2019-12-13T10:04:30.755184896Z 30   30
2019-12-14T10:04:30.755184896Z 20   20
2019-12-15T10:04:30.755184896Z 10   10
}}
#html(</div>)
// tabs1-1

#html(<div id="tabs1-2">)
#myterm2(){{
create database mydb1
use mydb1
create retention policy one_month on mydb1 duration 31d replication 1
insert sample,type=1 value=1 1576404270755184896
insert sample,type=2 value=2 1576317870755184896
insert sample,type=3 value=3 1576231470755184896
insert sample,type=4 value=4 1576145070755184896
insert sample,type=5 value=5 1576058670755184896
insert sample,type=6 value=6 1575972270755184896
insert sample,type=7 value=7 1575885870755184896
insert sample,type=8 value=8 1575799470755184896
insert sample,type=9 value=9 1575713070755184896
insert into one_month sample,type=10 value=10 1576404270755184896
insert into one_month sample,type=20 value=20 1576317870755184896
insert into one_month sample,type=30 value=30 1576231470755184896
insert into one_month sample,type=40 value=40 1576145070755184896
insert into one_month sample,type=50 value=50 1576058670755184896
insert into one_month sample,type=60 value=60 1575972270755184896
insert into one_month sample,type=70 value=70 1575885870755184896
insert into one_month sample,type=80 value=80 1575799470755184896
insert into one_month sample,type=90 value=90 1575713070755184896
}}
#html(</div>)
// tabs1-2

#html(<div id="tabs1-3">)
#mycode2(){{
from datetime import datetime
import time

if __name__ == '__main__':

    print("create retention policy one_month on mydb1 duration 31d replication 1")

    now_ts = datetime.now()
    ts = int(now_ts.timestamp() * 1000000000)
    for i in range(1, 10):
        print(f'insert sample,type={i} value={i} {ts}')
        ts = ts - (60 * 60 * 24 * 1000000000)

    ts = int(now_ts.timestamp() * 1000000000)
    for i in range(1, 10):
        print(f'insert into one_month sample,type={i*10} value={i*10} {ts}')
        ts = ts - (60 * 60 * 24 * 1000000000)
}}
#html(</div>)
// tabs1-3


#html(</div>)
// tabs1

#html(<script>$(function() { $("#tabs1").tabs(); });</script>)

DB名だけ指定してバックアップを取ってみる。
#myterm2(){{
influxd backup -database mydb1 -portable /tmp/mydb1_all_dump
2019/12/15 10:14:18 backing up metastore to mydb1_all_dump/meta.00
2019/12/15 10:14:18 backing up db=mydb1
2019/12/15 10:14:18 backing up db=mydb1 rp=autogen shard=137 to mydb1_all_dump/mydb1.autogen.00137.00 since 0001-01-01T00:00:00Z
2019/12/15 10:14:18 backing up db=mydb1 rp=autogen shard=136 to mydb1_all_dump/mydb1.autogen.00136.00 since 0001-01-01T00:00:00Z
:
2019/12/15 10:14:18 backing up db=mydb1 rp=autogen shard=124 to mydb1_all_dump/mydb1.autogen.00124.00 since 0001-01-01T00:00:00Z
2019/12/15 10:14:18 backing up db=mydb1 rp=autogen shard=123 to mydb1_all_dump/mydb1.autogen.00123.00 since 0001-01-01T00:00:00Z
2019/12/15 10:14:18 backing up db=mydb1 rp=one_month shard=147 to mydb1_all_dump/mydb1.one_month.00147.00 since 0001-01-01T00:00:00Z
2019/12/15 10:14:18 backing up db=mydb1 rp=one_month shard=146 to mydb1_all_dump/mydb1.one_month.00146.00 since 0001-01-01T00:00:00Z
:
2019/12/15 10:14:18 backing up db=mydb1 rp=one_month shard=139 to mydb1_all_dump/mydb1.one_month.00139.00 since 0001-01-01T00:00:00Z
2019/12/15 10:14:18 backing up db=mydb1 rp=one_month shard=138 to mydb1_all_dump/mydb1.one_month.00138.00 since 0001-01-01T00:00:00Z
2019/12/15 10:14:18 backup complete:
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.meta
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.s137.tar.gz
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.s136.tar.gz
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.s135.tar.gz
:
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.s140.tar.gz
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.s139.tar.gz
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.s138.tar.gz
2019/12/15 10:14:18 	mydb1_all_dump/20191215T101418Z.manifest
}}

今回のパラメータ指定だと、内部的にはDBとリテンションポリシー毎にバックアップを取っている様子。
尚、バックアップデータは以下のフォルダ構成で作成されていた。
#myterm2(){{
.
└── mydb1_all_dump
    ├── 20191215T101418Z.manifest
    ├── 20191215T101418Z.meta
    ├── 20191215T101418Z.s123.tar.gz
    ├── 20191215T101418Z.s124.tar.gz
                              :
    ├── 20191215T101418Z.s146.tar.gz
    └── 20191215T101418Z.s147.tar.gz
}}

リテンションポリシー毎に別のDBにリストアしてみる。
#myterm2(){{
influxd restore -db mydb1 -portable -newdb mydb1_backup_autogen -rp autogen /tmp/mydb1_all_dump
influxd restore -db mydb1 -portable -newdb mydb1_backup_month -rp one_month /tmp/mydb1_all_dump
}}

リストア結果を確認してみる。

まずはデータベースを確認
#myterm2(){{
> show databases
name: databases
name
----
_internal
mydb1
mydb1_backup_autogen
mydb1_backup_month
}}

mydb1_backup_autogen のデータを確認
#myterm2(){{
> use mydb1_backup_autogen
Using database mydb1_backup_autogen
> select * from sample
name: sample
time                           type value
----                           ---- -----
2019-12-07T10:04:30.755184896Z 9    9
2019-12-08T10:04:30.755184896Z 8    8
2019-12-09T10:04:30.755184896Z 7    7
2019-12-10T10:04:30.755184896Z 6    6
2019-12-11T10:04:30.755184896Z 5    5
2019-12-12T10:04:30.755184896Z 4    4
2019-12-13T10:04:30.755184896Z 3    3
2019-12-14T10:04:30.755184896Z 2    2
2019-12-15T10:04:30.755184896Z 1    1
> select * from one_month.sample
ERR: retention policy not found: one_month       ...   リテンションポリシー(one_month)がリストアしていないので当然エラーになる。
}}

次に mydb1_backup_month 側のデータを確認
#myterm2(){{
> use mydb1_backup_month
Using database mydb1_backup_month
> select * from sample
name: sample
time                           type value
----                           ---- -----
2019-12-07T10:04:30.755184896Z 90   90
2019-12-08T10:04:30.755184896Z 80   80
2019-12-09T10:04:30.755184896Z 70   70
2019-12-10T10:04:30.755184896Z 60   60
2019-12-11T10:04:30.755184896Z 50   50
2019-12-12T10:04:30.755184896Z 40   40
2019-12-13T10:04:30.755184896Z 30   30
2019-12-14T10:04:30.755184896Z 20   20
2019-12-15T10:04:30.755184896Z 10   10
}}

なぜかデフォルトのリテンションポリシーのデータがいる?

リテンションポリシーに one_month を指定して確認してみる。
#myterm2(){{
> select * from one_month.sample
name: sample
time                           type value
----                           ---- -----
2019-12-07T10:04:30.755184896Z 90   90
2019-12-08T10:04:30.755184896Z 80   80
2019-12-09T10:04:30.755184896Z 70   70
2019-12-10T10:04:30.755184896Z 60   60
2019-12-11T10:04:30.755184896Z 50   50
2019-12-12T10:04:30.755184896Z 40   40
2019-12-13T10:04:30.755184896Z 30   30
2019-12-14T10:04:30.755184896Z 20   20
2019-12-15T10:04:30.755184896Z 10   10
}}

同じデータがいる。

リテンションポリシーの一覧を確認。
#myterm2(){{
> show retention policies
name      duration shardGroupDuration replicaN default
----      -------- ------------------ -------- -------
one_month 744h0m0s 24h0m0s            1        true
}}

リテンションポリシーを指定してリストアした為、
one_month がデフォルトのリテンションポリシーとしてリストアされた模様。


ちなみに、既に存在するDBをリストアするとエラーになる。
#myterm2(){{
influxd restore -db mydb1 -portable ./mydb1_all_dump
XXXX/XX/XX XX:XX:XX error updating meta: DB metadata not changed. database may already exist
restore: DB metadata not changed. database may already exist
}}

#html(</div>)

* ダウンサンプリング [#z03dad2b]
#html(<div class="pl10">)

以下のようなデータをが登録してある場合、

#html(<div id="tabs2"><ul><li><a href="#tabs2-1">データ</a></li><li><a href="#tabs2-2">DDL/DML</a></li></ul>)
#html(<div id="tabs2-1">)

#myterm2(){{
> select * from sample_detail
name: sample_detail
time                     key value
----                     --- -----
2019-12-08T11:21:48.345Z 1   10
2019-12-08T11:21:48.345Z 2   1
2019-12-08T11:21:58.345Z 1   20
2019-12-08T11:21:58.345Z 2   2
2019-12-08T11:22:08.345Z 1   30
2019-12-08T11:22:08.345Z 2   3
2019-12-08T11:22:18.345Z 1   40
2019-12-08T11:22:18.345Z 2   4
2019-12-08T11:22:28.345Z 1   50
2019-12-08T11:22:28.345Z 2   5
2019-12-08T11:22:38.345Z 1   60
2019-12-08T11:22:38.345Z 2   6
2019-12-08T11:22:48.345Z 1   70
2019-12-08T11:22:48.345Z 2   7
2019-12-08T11:22:58.345Z 1   80
2019-12-08T11:22:58.345Z 2   8
2019-12-08T11:23:08.345Z 1   90
2019-12-08T11:23:08.345Z 2   9
2019-12-08T11:23:18.345Z 1   100
2019-12-08T11:23:18.345Z 2   10
}}
#html(</div>)
// tabs2-1

#html(<div id="tabs2-2">)
#myterm2(){{
insert sample_detail,key=1 value=10  1575804108345000000
insert sample_detail,key=1 value=20  1575804118345000000
insert sample_detail,key=1 value=30  1575804128345000000
insert sample_detail,key=1 value=40  1575804138345000000
insert sample_detail,key=1 value=50  1575804148345000000
insert sample_detail,key=1 value=60  1575804158345000000
insert sample_detail,key=1 value=70  1575804168345000000
insert sample_detail,key=1 value=80  1575804178345000000
insert sample_detail,key=1 value=90  1575804188345000000
insert sample_detail,key=1 value=100 1575804198345000000
insert sample_detail,key=2 value=1   1575804108345000000
insert sample_detail,key=2 value=2   1575804118345000000
insert sample_detail,key=2 value=3   1575804128345000000
insert sample_detail,key=2 value=4   1575804138345000000
insert sample_detail,key=2 value=5   1575804148345000000
insert sample_detail,key=2 value=6   1575804158345000000
insert sample_detail,key=2 value=7   1575804168345000000
insert sample_detail,key=2 value=8   1575804178345000000
insert sample_detail,key=2 value=9   1575804188345000000
insert sample_detail,key=2 value=10  1575804198345000000
}}
#html(</div>)
// tabs2-2

#html(</div>)
// tabs2

#html(<script>$(function() { $("#tabs2").tabs(); });</script>)

以下の通り実行する事で、キー単位 かつ 1分毎に集約したデータを作成する事ができる。
#myterm2(){{
> select mean(value) as "平均", max(value) as "最大", min(value) as "最小" into sample_summary from sample_detail group by time(1m), "key"
name: result
time                 written
----                 -------
1970-01-01T00:00:00Z 6
}}

集約結果
#myterm2(){{
> select * from sample_summary
name: sample_summary
time                 key 平均     最大     最小
----                 --- ------ ------ ------
2019-12-08T11:21:00Z 1   15     20     10
2019-12-08T11:21:00Z 2   1.5    2      1
2019-12-08T11:22:00Z 1   55     80     30
2019-12-08T11:22:00Z 2   5.5    8      3
2019-12-08T11:23:00Z 1   95     100    90
2019-12-08T11:23:00Z 2   9.5    10     9
}}

尚、Influxdb には、CONTINUOUS QUERY という定期的に実行されるクエリを登録する事ができる為、自動的に集約データを作成する事が出来る。
#myterm2(){{
CREATE CONTINUOUS QUERY "cq_summary" ON "mydb1" 
    BEGIN 
        select mean(value) as "平均", max(value) as "最大", min(value) as "最小"
            into sample_summary
          from sample_detail
        group by time(1m), "key"
    END
}}

** 項目(Field)毎にダウンサンプリングを行う方法 [#y94efe38]
#html(<div class="pl10">)

尚、上記で1行で書いた select into は、以下のように複数に分けて実行しても同じように集約する事ができる。
#myterm2(){{
select mean(value) as "平均" into sample_summary2 from sample_detail group by time(1m), "key"
select max(value) as "最大" into sample_summary2 from sample_detail group by time(1m), "key"
select min(value) as "最小" into sample_summary2 from sample_detail group by time(1m), "key"
}}

複数に分けて実行しても 1行で書いた時と同じように集約されている事が分かる。
#myterm2(){{
> select * from sample_summary2
name: sample_summary2
time                 key 平均     最大     最小
----                 --- ------ ------ ------
2019-12-08T11:21:00Z 1   15     20     10
2019-12-08T11:21:00Z 2   1.5    2      1
2019-12-08T11:22:00Z 1   55     80     30
2019-12-08T11:22:00Z 2   5.5    8      3
2019-12-08T11:23:00Z 1   95     100    90
2019-12-08T11:23:00Z 2   9.5    10     9
}}
#html(</div>)
// 項目(Field)毎にダウンサンプリングを行う方法

#html(</div>)
// ダウンサンプリング



#html(<!--)

//* Web画面(Chronograf)から操作する [#v1b84721]
#html(<div class="pl10">)

//** ユーザ作成 [#db23580f]
#html(<div class="pl10">)
事前にユーザを作成しておく。
https://docs.influxdata.com/influxdb/v1.7/administration/authentication_and_authorization/#user-management-commands
#myterm2(){{
CREATE USER ユーザ名 WITH PASSWORD 'パスワード' WITH ALL PRIVILEGES
}}
#html(</div>)

//** ブラウザから localhost:8888 にアクセス [#v94ce5d5]
#html(<div class="pl10">)
#html(</div>)

#html(</div>)
// Web画面から操作する
#html(-->)


* 補足/注意点など [#p115d879]
#html(<div class="pl10">)

** INSERT時に文字列をクォーテーションで囲む必要はない。 [#u7d52063]
#html(<div class="pl10">)

insert時にクォーテーションで囲うとクォーテーションを込みで登録される為、特別な理由がない限りクォーテーションで囲う必要はない。

#myterm2(){{
> insert sample,server=server1,ym=201912 load_average=0.5
> insert sample,server='server1',ym=201912 load_average=1.0
>
> select * from sample
name: sample
time                         load_average server    ym
----                         ------------ ------    --
2019-12-08T11:11:48.5337018Z 0.5          server1   201912
2019-12-08T11:11:57.214271Z  1            'server1' 201912
}}

server='server1' のデータのみを検索。
#myterm2(){{
> select * from sample where server='server1'
name: sample
time                         load_average server  ym
----                         ------------ ------  --
2019-12-08T11:11:48.5337018Z 0.5          server1 201912
}}

server='\'server1\'' のデータのみを検索。(クォーテーションまで条件に含めて検索)
#myterm2(){{
> select * from sample where server='\'server1\''
name: sample
time                        load_average server    ym
----                        ------------ ------    --
2019-12-08T11:11:57.214271Z 1            'server1' 201912
}}
#html(</div>)

** field 値には数値以外は指定できない。 [#mee4c7e8]
** 同じ field に別のデータ型は登録できない [#s02d8ac4]
#html(<div class="pl10">)

#myterm2(){{
> insert sample,server=server1,ym=201912 load_average='0.5'
ERR: {"error":"unable to parse 'sample,server=server1,ym=201912 load_average='0.5'': invalid boolean"}

> insert sample,server=server1,ym=201912 load_average="0.5"
ERR: {"error":"partial write: field type conflict: input field \"load_average\" on measurement \"sample\" is type string, already exists as type float dropped=1"}
}}

#html(</div>)

** FROM句の Retention policy を省略した場合はデフォルトの Retention policy が使用される。 [#sa987efa]
#html(<div class="pl10">)

期間=1日 のリテンションポリシーを作成し、1つはデフォルトのリテンションポリシーで登録し、もう一方は作成したリテンションポリシーで登録する。

#myterm2(){{
> CREATE RETENTION POLICY one_day ON mydb1 DURATION 1d REPLICATION 1
> insert into one_day sample,ym=201912 value=0.5
> insert sample,ym=201912 value=1.0
}}

この状態でリテンションポリシーを省略して select すると、デフォルトのリテンションポリシーのデータのみが検索される。
#myterm2(){{
> select * from sample
name: sample
time                         value ym
----                         ----- --
2019-12-08T11:48:21.8258805Z 1     201912
>
> select * from mydb1..sample
name: sample
time                         value ym
----                         ----- --
2019-12-08T11:48:21.8258805Z 1     201912
}}

リテンションポリシーを指定して登録したデータは FROM句にリテンションポリシーを指定しないと検索できない。
#myterm2(){{
> select * from mydb1.one_day.sample
name: sample
time                         value ym
----                         ----- --
2019-12-08T11:47:50.9271556Z 0.5   201912
}}

両方とも検索したい場合は FROM句に measurement と リテンションポリシーの組み合わせを全て並べる。

#myterm2(){{
> select * from sample, mydb1.one_day.sample    
name: sample
time                         value ym
----                         ----- --
2019-12-08T11:47:50.9271556Z 0.5   201912
2019-12-08T11:48:21.8258805Z 1     201912
}}
※ select * from sample, one_day.sample  や select * from sample, mydb1.one_day.sample でもOK


#html(</div>)


** DELETE 時に Retention policy が指定できない [#z61794fa]
#html(<div class="pl10">)

#myterm2(){{
> delete from mydb1.one_day.sample
ERR: error parsing query: retention policy not supported at line 1, char 1
}}
※ https://github.com/influxdata/influxdb/issues/8088 のやり取りをみると・・・

#html(</div>)


** 後からデフォルトのリテンションポリシーを変更した場合 [#q28bf316]

データ登録後にデフォルトのリテンションポリシーを変更した場合、リテンションポリシーを指定していない select で検索されるデータが変わる。

#myterm2(){{
> CREATE RETENTION POLICY one_day ON mydb1 DURATION 1d REPLICATION 1
> insert into one_day sample,ym=201912 value=0.5
> insert sample,ym=201912 value=1.0
}}

リテンションポリシーを指定せずに検索するとデフォルトのリテンションポリシーのデータが検索される。
#myterm2(){{
> select * from sample
name: sample
time                         value ym
----                         ----- --
2019-12-08T11:48:21.8258805Z 1     201912
}}

デフォルトのリテンションポリシーを one_day に変更する
#myterm2(){{
> ALTER RETENTION POLICY one_day ON mydb1 DEFAULT
> show retention policies
name    duration shardGroupDuration replicaN default
----    -------- ------------------ -------- -------
autogen 0s       168h0m0s           1        false
one_day 24h0m0s  1h0m0s             1        true
}}

リテンションポリシーを指定せずに検索すると変更後のデフォルトのリテンションポリシーのデータが検索される。
#myterm2(){{
> select * from sample
name: sample
time                         value ym
----                         ----- --
2019-12-08T11:47:50.9271556Z 0.5   201912
}}

** measurement の複製を select into で行う場合は "group by *" が必要。 [#ic7b4d50]
#html(<div class="pl10">)

select into で別の measurement にデータを複製する場合は、「group by *」 を付けないと tag key がなくなってしまうので注意が必要。

コピー元となるデータを登録。
#myterm2(){{
insert sample_org,key=1 value=1
insert sample_org,key=1 value=2
insert sample_org,key=1 value=3
insert sample_org,key=1 value=4
insert sample_org,key=1 value=5
}}

series を確認
#myterm2(){{
> show series from sample_org
key
---
sample_org,key=1
}}

データを確認
#myterm2(){{
> select * from sample_org
name: sample_org
time                         key value
----                         --- -----
2019-12-11T10:42:29.0181793Z 1   1
2019-12-11T10:42:29.0630682Z 1   2
2019-12-11T10:42:29.0656965Z 1   3
2019-12-11T10:42:29.067036Z  1   4
2019-12-11T10:42:29.7491858Z 1   5
}}

データを別の measurement にコピー
#myterm2(){{
> select * into sample_copy1 from sample_org
name: result
time                 written
----                 -------
1970-01-01T00:00:00Z 5
}}

series を確認すると tag がなくなっている。
#myterm2(){{
> show series from sample_org, sample_copy1
key
---
sample_copy1
sample_org,key=1
}}

tag を無くさずにデータを移すには group by * を付ける。
#myterm2(){{
> select * into sample_copy2 from sample_org group by *
name: result
time                 written
----                 -------
1970-01-01T00:00:00Z 5
}}

series を確認すると tag も正しく複製されている事がわかる。
#myterm2(){{
> show series from sample_org, sample_copy2
key
---
sample_copy2,key=1
sample_org,key=1
}}

#html(</div>)



** 登録後すぐに retention policy に引っかかるようなデータは登録できない。 [#fa34f36c]
#html(<div class="pl10">)

以下のようなデータがある場合。
#myterm2(){{
> select * from sample1
name: sample1
time                 key value
----                 --- -----
2019-12-01T22:10:10Z 1   1
2019-12-02T22:10:10Z 1   2
2019-12-03T22:10:10Z 1   3
2019-12-04T22:10:10Z 1   4
2019-12-05T22:10:10Z 1   5
2019-12-06T22:10:10Z 1   6
2019-12-07T22:10:10Z 1   7
2019-12-08T22:10:10Z 1   8
2019-12-09T22:10:10Z 1   9
2019-12-10T22:10:10Z 1   10
}}

例えば、本日が 12月11日 22:00(UTC) だった場合に、
保持期間=7日のリテンションポリシー(※1)で select into しようとした場合は、一部のデータは登録されない。
※1 ... つまり 12/4 22:00 以前のデータはリテンションポリシーに引っかかる(削除対象)。

#myterm2(){{
> /* 保持期間7日のリテンションポリシーを作成 */
> CREATE RETENTION POLICY "one_week" ON "mydb1" DURATION 7d REPLICATION 1
>
> select * into "one_week".sample_copy from sample1
ERR: partial write: points beyond retention policy dropped=3       /* 3レコード登録されなかった */
}}

7日以上前のデータは登録されていない。
#myterm2(){{
> select * from "one_week".sample_copy
name: sample_copy
time                 key value
----                 --- -----
2019-12-04T22:10:10Z 1   4
2019-12-05T22:10:10Z 1   5
2019-12-06T22:10:10Z 1   6
2019-12-07T22:10:10Z 1   7
2019-12-08T22:10:10Z 1   8
2019-12-09T22:10:10Z 1   9
2019-12-10T22:10:10Z 1   10
}}


#html(</div>)


** リテンションポリシーを削除した場合はデータも消える [#j486285a]
#html(<div class="pl10">)

リテンションポリシーを削除した場合はデータも削除される。( でも何故かシリーズは残る )
#html(){{
<div style="border-left: 5px solid #ff8564; background: #292933; color: #fff; padding: 10px; display: inline-block;">Dropping a retention policy will permanently delete all measurements and data stored in the retention policy.</div>
<br />※ https://docs.influxdata.com/influxdb/v1.7/query_language/database_management/#delete-retention-policies-with-drop-retention-policy
}}

以下、挙動を確認してみた。

リテンションポリシーを作成し、作成したリテンションポリシーのデータと、デフォルトのリテンションポリシーのデータを登録する。
#myterm2(){{
> CREATE RETENTION POLICY rp_dummy ON mydb1 DURATION 1d REPLICATION 1
> insert m_dummy,key=1 value=1
> insert m_dummy,key=2 value=2
> insert into rp_dummy m_dummy,key=3 value=3
> insert into rp_dummy m_dummy,key=4 value=4
}}

デフォルトのリテンションポリシーのデータを確認
#myterm2(){{
> select * from m_dummy
name: m_dummy
time                key value
----                --- -----
1576154271123422400 1   1
1576154274313463800 2   2
}}

作成したリテンションポリシーのデータも確認
#myterm2(){{
> select * from rp_dummy.m_dummy
name: m_dummy
time                key value
----                --- -----
1576154289085026700 3   3
1576154293159653800 4   4
}}

リテンションポリシーを削除してみる。
#myterm2(){{
drop retention policy rp_dummy on mydb1
}}


デフォルトのリテンションポリシーのデータは当然残っている。
#myterm2(){{
> select * from m_dummy
name: m_dummy
time                key value
----                --- -----
1576154271123422400 1   1
1576154274313463800 2   2
}}

削除したリテンションポリシーのデータは検索出来ない。(削除されている)
#myterm2(){{
select * from rp_dummy.m_dummy
ERR: retention policy not found: rp_dummy
}}

でもシリーズは残っている。
※このケースの場合、タグの管理とデータは連動して行われない模様。
#myterm2(){{
> show series
key
---
m_dummy,key=1
m_dummy,key=2
m_dummy,key=3
m_dummy,key=4
}}

キレイにする為に無くなったデータのシリーズを削除する。
#myterm2(){{
> drop series from "m_dummy" where "key" = '3'
> drop series from "m_dummy" where "key" = '4'
>
> show series
key
---
dummy,key=1
m_dummy,key=1
m_dummy,key=2
}}

この管理の仕方は正しいの?怪しすぎる。

以下のケースがある場合は measurement 毎にリテンションポリシー名を分けておいた方が良さそう。
- measurement 毎にデータのバックアップやリストアをしたい場合
- measurement 毎に任意のリテンションポリシーを削除したい場合


#html(</div>)


#html(</div>)
// 補足

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS