FAQ

更新时间:

本页面讨论了经常容易混淆的内容,以及跟其它数据库系统相比TSDB For InfluxDB®以意想不到的方式运行的地方。

问题导览

管理(Administration)

序列和序列基数

数据查询

数据写入

命令行界面(Influx CLI)

数据类型

InfluxQL函数

管理(Administration)

如何高效安全地删除数据?

InfluxDBdrop measurement 、drop series、delete采用逻辑删除,该删除方式有以下几点缺陷:

  • InfluxDB 1.X在代码实现层面存在死锁的可能性。

  • 查询需要过滤被删除的时间线,严重影响查询效率。

  • 逻辑删除无法立刻释放磁盘空间,需要等待后台数据合并调度,空间释放慢。

建议通过修改数据保留策略来删除老数据,或使用drop sharddrop database进行物理删除。

为什么修改保留策略后不生效?

v1.8.13及以后版本,修改保留策略后立即生效,若没有生效请检查以下两点:

  • 版本是否为v1.8.12或更老的版本,老版本中修改保留策略需要等待后台调度,请耐心等待30~60分钟。

  • Shard覆盖的时间范围较大,可以通过show shards查看,只有当前时间超过Shard的结束时间时,该Shard才可以被删除。

为什么服务经常中断?

检查内存水位是否比较高,一般内存水位超过80%以上,可能会出现内存上涨导致的进程OOM,建议对实例进行升配。

内存占用为什么很高?

内存占用高主要有以下几点原因:

  • 时间线数量多。索引合并时会占用大量内存,请排查schema设计是否合理,不建议存储超过100W的时间线。海量时间线场景详情,请参见Lindorm 时序引擎简介

  • 数据量大。数据量越大,空间占用越多,数据文件合并也会占用大量内存,而且重启花费的时间也会比较长。大量数据存储场景详情,请参见Lindorm 时序引擎简介

  • 存在大查询。避免使用大查询,建议查询时候带上 tag 和时间过滤,减少数据扫描的范围。

  • 如果有使用Grafana查询,Grafana在配置图表时可能会下发show tag keys的查询,此类查询会瞬间占用过多的内存导致进程OOM。推荐升级到v1.8.13后,可以配置禁用show tag keys的查询。

当内存水位超过80%以上时,建议对实例进行升配。升配操作详情,请参见升配或降配

云盘扩容是否会重启?

InfluxDB云盘扩容时进程会重启。如果是单机版本,重启期间可能会导致服务的不可用。如果是高可用版本,三节点会滚动重启,业务一般不会受到影响。

重启需要多长时间?

InfluxDB 重启时间和存储的数据量有关,一般存储的数据量越大,重启所需的时间越长。

是否支持InfluxDB内置的Grafana?

建议使用阿里云产品可观测可视化 Grafana 版。不建议使用InfluxDB内置的Grafana,因为InfluxDB内置的Grafana版本比较旧而且不再维护更新。

为什么访问出现ip block错误?

v1.8.12及以下版本会在错误密码重试太多时临时禁用IP,建议升级到v1.8.13及以上版本。

如何识别TSDB For InfluxDB®的版本?

有多种方法可以识别您正在使用的TSDB For InfluxDB®版本:

  • curl路径/ping

    $ curl -i 'https://<网络地址>:3242/ping?u=<账号名称>&p=<密码>'
    HTTP/1.1204NoContent
    Content-Type: application/json
    X-Influxdb-Build: OSS
    X-Influxdb-Version:1.7.x
  • 启动TSDB For InfluxDB®的命令行界面

    $ influx -ssl -username <账号名称>-password <密码>-host <网络地址>-port 3242
    
    Connected to https://<网络地址>:3242 version 1.7.x

Shard Group Duration和保留策略之间的关系是什么?

TSDB For InfluxDB®将数据存储在Shard Group。一个Shard Group覆盖一个特定的时间间隔;TSDB For InfluxDB®通过查看相关保留策略(Retention Policy)的DURATION来确定时间间隔。下表列出了RPDURATION和一个Shard Group的时间间隔之间的默认关系:

RP持续时间(duration)

Shard Group时间间隔

< 2 days

1 hour

>= 2 days and <= 6 months

1 day

> 6 months

7 days

使用SHOW RETENTION POLICIES查看保留策略的Shard Group Duration。

当更改保留策略后,为什么数据没有丢失?

有可能是以下原因,导致保留策略改变后数据没有马上丢失:

  • 第一个可能的原因(最有可能的场景):默认情况下,TSDB For InfluxDB®每30分钟检查并强制执行一次RP。您可能需要等到下一次RP检查,TSDB For InfluxDB®才能删除在RP的新DURATION之外的数据。

  • 第二个可能的原因:更改RPDURATIONSHARD DURATION会导致意外的数据保留。TSDB For InfluxDB®将数据存储在Shard Group,每个Shard Group覆盖一个特定的RP和时间间隔。当TSDB For InfluxDB®强制执行RP时,整个Shard Group的数据会被删除,而不是单个数据点。TSDB For InfluxDB®不能拆分Shard Group。如果RP的新DURATION小于旧的SHARD DURATION,并且TSDB For InfluxDB®正在将数据写入一个旧的、DURATION较长的Shard Group,那么系统将强制把所有数据存储在该Shard Group中,即使该Shard Group中有些数据已经在新的DURATION之外。一旦Shard Group中所有数据都在新的DURATION之外,TSDB For InfluxDB®将会删除整个Shard Group,然后系统开始将数据写入具有新的、更短SHARD DURATIONShard Group,避免进一步意想不到的数据保留。

为什么TSDB For InfluxDB®无法解析微秒单位?

在不同场景下写入、查询以及在TSDB For InfluxDB®命令行界面(Influx CLI)设置精度,用于指定微秒时间单位的语法也不同。下表显示了每个类别支持的语法:

使用HTTP API写入数据

所有查询

Influx CLI设置精度

u

us

µ

µs

序列和序列基数

为什么序列基数很重要?

TSDB For InfluxDB®维护系统中每个序列在内存中的索引。随着序列数量不断增加,RAM(内存)使用量也在不断增加。序列基数过大会导致操作系统终止TSDB For InfluxDB®进程,并抛出内存不足(OOM)异常。请查看文档InfluxQL参考了解关于序列基数的InfluxQL命令。

如何进行建模,有什么注意事项?

不建议存储大量时间线,建议时间线量级保持在100w以下,海量时间线场景建议使用Lindorm 时序引擎简介。其次,开始建模前请先参考InfluxDB 建模指南。虽然InfluxDB会对tag创建索引来加速查询,但是过多的tag会因时间线膨胀而导致查询/写入速度降低,因此在建模上需要注意控制时间线的数量,特别是以下几点:

  • 避免使用id、hash值和时间等极易无限膨胀的值作为tag。

  • 避免在measurementtag的命名中存储数据信息,请将相关信息保存到tagfield中。

  • 避免在一个tag中存储多个信息,可以拆解成多个tag。

  • 需要经常使用Group by字段,可以当作tag来建模。

数据查询

如何排查慢查询的原因?

慢查询一般是由于扫描了过多时间线或原始数据导致,因此,建议为每个查询都加上tag过滤条件和时间范围过滤条件。此外可以使用EXPLAIN ANALYZE命令查看自查与优化查询,execution_time主要包括原始数据读取时间和计算时间,planning_time主要包括时间线扫描时间,可以针对这两个时间优化查询过滤条件。

什么决定了GROUP BY time()查询返回的时间间隔?

GROUP BY time()查询返回的时间间隔符合TSDB For InfluxDB®的预设时间段或者符合用户指定的偏移间隔。示例如下:

  • 预设时间段

    以下查询计算sunflowers6:15pm7:45pm之间的平均值,并将这些平均值按一小时进行分组:

    SELECT mean("sunflowers")
    FROM "flower_orders"
    WHERE time >='2016-08-29T18:15:00Z' AND time <='2016-08-29T19:45:00Z' GROUP BY time(1h)

    下面的结果展示了TSDB For InfluxDB®如何维护它的预设时间段。

    在这个示例中,6pm是一个预设的时间段,7pm也是一个预设的时间段。由于WHERE子句中指定了查询的时间范围,所以在计算6pm时间段对应的平均值时不包括在6:15pm之前的数据,但是用于计算6pm时间段平均值的数据必须发生在6pm这个小时里。对于7pm时间段也是一样;用于计算7pm时间段平均值的数据必须发生在7pm这个小时里。虚线部分展示了用于计算每个平均值的数据点。

    请注意,虽然结果中第一个时间戳是2016-08-29T18:00:00Z,但是在该时间段的查询结果不包含发生在2016-08-29T18:15:00ZWHERE子句中指定的开始时间)之前的数据。

    原始数据结果:

    name: flower_orders                                name: flower_orders
    —————————-------------------
    time                    sunflowers                 time                  mean
    2016-08-29T18:00:00Z342016-08-29T18:00:00Z22.332
    |--|2016-08-29T19:00:00Z62.75
    2016-08-29T18:15:00Z|28|
    2016-08-29T18:30:00Z|19|
    2016-08-29T18:45:00Z|20|
    |--|
    |--|
    2016-08-29T19:00:00Z|56|
    2016-08-29T19:15:00Z|76|
    2016-08-29T19:30:00Z|29|
    2016-08-29T19:45:00Z|90|
    |--|
    2016-08-29T20:00:00Z70
  • 偏移间隔

    以下查询计算sunflowers6:15pm7:45pm之间的平均值,并将这些平均值按一小时进行分组,同时,该查询还将TSDB For InfluxDB®的预设时间段偏移15分钟:

    SELECT mean("sunflowers")
    FROM "flower_orders"
    WHERE time >='2016-08-29T18:15:00Z' AND time <='2016-08-29T19:45:00Z' GROUP BY time(1h,15m)
    ---
    |
                                                                                      offset interval

    在这个示例中,用户指定的偏移间隔将TSDB For InfluxDB®的预设时间段前移了15分钟。现在,6pm时间段的平均值包括在6:15pm7:15pm之间的数据,7pm时间段的平均值包括在7:15pm8:15pm之间的数据。虚线部分展示了用于计算每个平均值的数据点。

    请注意,现在结果中第一个时间戳是2016-08-29T18:15:00Z,而不是2016-08-29T18:00:00Z

    原始数据结果:

    name: flower_orders                                name: flower_orders
    —————————-------------------
    time                    sunflowers                 time                  mean
    2016-08-29T18:00:00Z342016-08-29T18:15:00Z30.75
    |--|2016-08-29T19:15:00Z65
    2016-08-29T18:15:00Z|28|
    2016-08-29T18:30:00Z|19|
    2016-08-29T18:45:00Z|20|
    2016-08-29T19:00:00Z|56|
    |--|
    |--|
    2016-08-29T19:15:00Z|76|
    2016-08-29T19:30:00Z|29|
    2016-08-29T19:45:00Z|90|
    2016-08-29T20:00:00Z|70|
    |--|

为什么查询没有返回任何数据或者只返回一部分数据?

对于为什么查询没有返回任何数据或者只返回一部分数据,有几种可能的解释。我们在下面列出了一些最常见的原因:

  • 保留策略

    第一个也是最常见的解释与保留策略(RP)有关。TSDB For InfluxDB®自动从数据库的默认(DEFAULT)RP中查询数据。如果您的数据不是存储在默认的RP,TSDB For InfluxDB®不会返回任何结果,除非您明确指定所使用的RP。

  • SELECT子句中的tag key

    SELECT子句中,至少需要包含一个field key,查询才会返回数据。如果SELECT子句只包含一个或多个tag key,查询会返回空的结果。请查看文档数据探索获得更多相关信息。

  • 查询时间范围

    另一个可能的解释与查询的时间范围有关。默认情况下,大多数SELECT查询涵盖在1677-09-21 00:12:43.145224194 UTC2262-04-11T23:47:16.854775806Z UTC之间的时间范围。SELECT查询还包括GROUP BY time()子句,但是,它涵盖的时间范围在1677-09-21 00:12:43.145224194now()之间。如果您的数据发生在now()之后,那么GROUP BY time()查询不会覆盖这些发生在now()之后的数据。如果查询语句包括GROUP BY time()子句,并且有数据发生在now()之后,您需要为时间范围提供一个上限。

  • 标识符名字

    最后一个常见的解释与Schema有关(fieldtag有相同的名字)。如果field keytag key相同,那么在所有查询中优先考虑field。在查询中,你需要使用::tag语法指定tag key。

为什么GROUP BY time()查询不返回发生在now()之后的时间戳?

大多数SELECT语句的默认时间范围在1677-09-21 00:12:43.145224194 UTC2262-04-11T23:47:16.854775806Z UTC之间。对于带GROUP BY time()子句的SELECT语句,默认的时间范围在1677-09-21 00:12:43.145224194now()之间。

如果要查询时间戳发生在now()之后的数据,带GROUP BY time()子句的SELECT语句必须在WHERE子句中提供一个时间上限。

在下面的示例中,第一个查询涵盖时间戳在2015-09-18T21:30:00Znow()之间的数据,第二个查询涵盖时间戳在2015-09-18T21:30:00Znow()之后180个星期之间的数据。

> SELECT MEAN("boards") FROM "hillvalley" WHERE time >='2015-09-18T21:30:00Z' GROUP BY time(12m) fill(none)


> SELECT MEAN("boards") FROM "hillvalley" WHERE time >='2015-09-18T21:30:00Z' AND time <= now()+180w GROUP BY time(12m) fill(none)

请注意,WHERE子句必须提供一个时间上线来覆盖默认的now()上限。下面的查询只是将now()的下限重置,使得查询的时间范围在now()now()之间:

> SELECT MEAN("boards") FROM "hillvalley" WHERE time >= now() GROUP BY time(12m) fill(none)
>

请查看数据探索获得更多关于时间语法的信息。

是否可以对时间戳执行数学运算?

目前,在TSDB For InfluxDB®中,不能对时间戳执行数学运算。更多关于时间的计算必须由接收查询结果的客户端执行。

对时间戳使用InfluxQL函数,TSDB For InfluxDB®仅提供有限的支持。ELAPSED()函数返回单个field中时间戳之间的差值。

是否可以从返回的时间戳中识别写入精度?

不管提供的写入精度是多少,TSDB For InfluxDB®将所有时间戳存储为纳秒。需要注意的一个重要事项是,当返回查询结果时,数据库会不动声色地删除时间戳后面的零,使原始的写入精度很难识别。

在下面的示例中,tag precision_suppliedtimestamp_supplied分别显示了用户在写入数据时提供的时间精度和时间戳。因为TSDB For InfluxDB®默默地将返回的时间戳后面的零删除了,所以从返回的时间戳中很难识别写入精度。

name: trails
-------------
time                  value  precision_supplied  timestamp_supplied
1970-01-01T01:00:00Z3      n                   3600000000000
1970-01-01T01:00:00Z5      h                   1
1970-01-01T02:00:00Z4      n                   7200000000000
1970-01-01T02:00:00Z6      h                   2

当查询数据时,什么时候应该使用单引号,什么时候应该使用双引号?

用单引号将字符串类型的值括起来(例如:tag value),但是不要用单引号将标识符(数据库名字、保留策略名字、用户名、measurement的名字、tag keyfield key)括起来。

如果标识符以数字开头,或包含除[A-z,0-9,_]外的字符,或者标识符是InfluxQL关键字,那么需要使用双引号将标识符括起来。如果标识符不属于这些类别之一,可以不需要使用双引号将它们括起来,但是我们还是建议用双引号将它们括起来。

示例:

合法的查询:SELECT bikes_available FROM bikes WHERE station_id='9'

合法的查询:SELECT "bikes_available" FROM "bikes" WHERE "station_id"='9'

合法的查询:SELECT MIN("avgrq-sz") AS "min_avgrq-sz" FROM telegraf

合法的查询:SELECT * from "cr@zy" where "p^e"='2'

非法的查询:SELECT 'bikes_available' FROM 'bikes' WHERE 'station_id'="9"

非法的查询:SELECT * from cr@zy where p^e='2'

用单引号将日期时间字符串括起来。如果您使用双引号将日期时间字符串括起来,TSDB For InfluxDB®会返回错误(ERR: invalid operation: time and *influxql.VarRef are not compatible)。

示例:

合法的查询:SELECT "water_level" FROM "h2o_feet" WHERE time > '2015-08-18T23:00:01.232000000Z' AND time < '2015-09-19'

非法的查询:SELECT "water_level" FROM "h2o_feet" WHERE time > "2015-08-18T23:00:01.232000000Z" AND time < "2015-09-19"

请查看数据探索获得更多关于时间语法的信息。

为什么在创建一个新的默认(DEFAULT)保留策略后会丢失数据?

当您在数据库中创建一个新的默认保留策略(RP)后,在旧的默认RP中的数据依旧保存在旧的RP中。对于不指定RP的查询,将会自动查询新默认RP中的数据,所有旧数据可能会丢失。为了查询旧数据,必须完全限定查询中的数据。示例如下:

measurement fleeting中的所有数据属于默认的RP,该RP的名字为one_hour

> SELECT count(flounders) FROM fleeting
name: fleeting
--------------
time                     count
1970-01-01T00:00:00Z8

现在我们创建一个新的默认RP(two_hour),并执行相同的查询:

> SELECT count(flounders) FROM fleeting
>

为了查询旧数据,我们必须通过完全限定fleeting来指定旧的默认RP:

> SELECT count(flounders) FROM fish.one_hour.fleeting
name: fleeting
--------------
time                     count
1970-01-01T00:00:00Z8

为什么带有WHERE OR时间子句的查询返回空结果?

目前,TSDB For InfluxDB®不支持在WHERE子句中使用OR来指定多个时间范围。如果查询中的WHERE子句使用OR来指定多个时间范围,那么TSDB For InfluxDB®不会返回任何结果。

示例:

> SELECT * FROM "absolutismus" WHERE time ='2016-07-31T20:07:00Z' OR time ='2016-07-31T23:07:17Z'
>

为什么fill(previous)返回空结果?

如果前一个值在查询的时间范围之外,那么fill(previous)不会填充该时间段的值。

在下面的示例中,TSDB For InfluxDB®不会使用时间段2016-07-12T16:50:00Z-2016-07-12T16:50:10Z的值填充时间段2016-07-12T16:50:20Z-2016-07-12T16:50:30Z,因为该查询的时间范围并不包含较早的时间段。

示例数据:

> SELECT * FROM "cupcakes"
name: cupcakes
--------------
time                   chocolate
2016-07-12T16:50:00Z3
2016-07-12T16:50:10Z2
2016-07-12T16:50:40Z12
2016-07-12T16:50:50Z11

GROUP BY time()查询:

> SELECT max("chocolate") FROM "cupcakes" WHERE time >='2016-07-12T16:50:20Z' AND time <='2016-07-12T16:51:10Z' GROUP BY time(20s) fill(previous)
name: cupcakes
--------------
time                   max
2016-07-12T16:50:20Z
2016-07-12T16:50:40Z12
2016-07-12T16:51:00Z12

为什么INTO查询会丢失数据?

默认情况下,INTO查询将原始数据中的tag转换成新写入数据的field。这会导致TSDB For InfluxDB®覆盖之前由tag区分的数据点。在所有INTO查询中加上GROUP BY *,可以将tag保留在新写入的数据中。

说明

这种方式不适用于使用TOP()BOTTOM()函数的查询。请查看文档InfluxDB函数获得更多关于TOP()BOTTOM()的信息。

示例数据

measurement french_bulldogs包含一个tag color和一个field name

> SELECT * FROM "french_bulldogs"
name: french_bulldogs
---------------------
time                  color  name
2016-05-25T00:05:00Z  peach  nugget
2016-05-25T00:05:00Z  grey   rumple
2016-05-25T00:10:00Z  black  prince
  • 不使用GROUP BY *的INTO查询

    不使用GROUP BY *子句的INTO查询将tag color转换成新写入数据中的field。在原始数据中,数据点nuggetrumple仅由tag color区分。一旦color变成field,TSDB For InfluxDB®会认为数据点nuggetrumple是重复的,它会用数据点rumple将数据点nugget覆盖。

    > SELECT * INTO "all_dogs" FROM "french_bulldogs"
    name: result
    ------------
    time                  written
    1970-01-01T00:00:00Z3
    
    > SELECT * FROM "all_dogs"
    name: all_dogs
    --------------
    time                  color  name
    2016-05-25T00:05:00Z  grey   rumple                <---- no more nugget
    2016-05-25T00:10:00Z  black  prince
  • 使用GROUP BY *的INTO查询

    使用GROUP BY *子句的INTO查询将tag color保留在新写入的数据中。在这种情况下,数据点nuggetrumple依旧是不同的数据点,TSDB For InfluxDB®不会覆盖任何数据。

    > SELECT "name" INTO "all_dogs" FROM "french_bulldogs" GROUP BY *
    name: result
    ------------
    time                  written
    1970-01-01T00:00:00Z3
    
    > SELECT * FROM "all_dogs"
    name: all_dogs
    --------------
    time                  color  name
    2016-05-25T00:05:00Z  peach  nugget
    2016-05-25T00:05:00Z  grey   rumple
    2016-05-25T00:10:00Z  black  prince

如何查询tag keyfield key名字相同的数据?

使用语法::指定一个keyfield key还是tag key。示例数据:

> INSERT candied,almonds=true almonds=50,half_almonds=511465317610000000000
> INSERT candied,almonds=true almonds=55,half_almonds=561465317620000000000

> SELECT * FROM "candied"
name: candied
-------------
time                   almonds  almonds_1  half_almonds
2016-06-07T16:40:10Z50       true       51
2016-06-07T16:40:20Z55       true       56
  • 指定keyfield

    > SELECT * FROM "candied" WHERE "almonds"::field >51
    name: candied
    -------------
    time                   almonds  almonds_1  half_almonds
    2016-06-07T16:40:20Z55       true       56
  • 指定keytag

    > SELECT * FROM "candied" WHERE "almonds"::tag='true'
    name: candied
    -------------
    time                   almonds  almonds_1  half_almonds
    2016-06-07T16:40:10Z50       true       51
    2016-06-07T16:40:20Z55       true       56

如何跨measurement查询数据?

目前,无法跨measurement执行数学运算或分组。所有数据必须在同一个measurement下,才能一起查询这些数据。TSDB For InfluxDB®不是一个关系型数据库,跨measurement映射数据目前不是一个推荐的Schema。

时间戳的顺序是否重要?

不重要。测试结果表明TSDB For InfluxDB®完成以下查询所需的时间差别非常小:

SELECT ... FROM ... WHERE time >'timestamp1' AND time <'timestamp2'
SELECT ... FROM ... WHERE time <'timestamp2' AND time >'timestamp1'

如何SELECTtag但没有tag value的数据?

使用''指定一个空的tag value。例如:

> SELECT * FROM "vases" WHERE priceless=''
name: vases
-----------
time                   origin   priceless
2016-07-20T18:42:00Z8

数据写入

行协议写入注意事项

行协议写入存在如下注意点:

  • 在数字后面加上i来指定整数,如value=100i是整数,value=100是浮点数。

  • 只在字符串类型的field value中使用双引号,measurement、tag key、tag valuefield key中的双引号将被当做名字的一部分来处理。

  • 应该用反斜杠转义特殊字符,而不是用引号将其括起来。

为什么数据写入后,却不可见?

InfluxDB会根据保留策略丢弃过期数据,建议自查写入时间戳和保留策略中设置的TTL。

磁盘空间满导致写入失败,空间下降后写入没有恢复?

InfluxDB磁盘写满后,会导致写入失败,即使空间下降后还是会写入失败。请适当扩容或者清理数据后手动在控制台重启进程来恢复写入。

如何写入整型的field value?

当写入整数时,在field value末尾加上i。如果您不加上i,TSDB For InfluxDB®会把field value当作浮点数。

写入整数:value=100i写入浮点数:value=100

TSDB For InfluxDB®如何处理重复数据点?

measurement的名字、tag set和时间戳唯一标识一个数据点。如果您提交的数据点跟已有的数据点相比,具有相同measurement、tag set和时间戳,但具有不同field set,那么该数据点的field set会变为旧field set和新field set的并集,如果有任何冲突以新field set为准。这是预期的结果。

例如:

旧数据点:cpu_load,hostname=server02,az=us_west val_1=24.5,val_2=7 1234567890000000

新数据点:cpu_load,hostname=server02,az=us_west val_1=5.24 1234567890000000

当您提交新数据点后,TSDB For InfluxDB®使用新的field value覆盖val_1的值,val_2的值继续保留:

> SELECT * FROM "cpu_load" WHERE time =1234567890000000
name: cpu_load
--------------
time                      az        hostname   val_1   val_2
1970-01-15T06:56:07.89Z   us_west   server02   5.247

为了存储这两个数据点,可以:

  • 引入新的tag保证唯一性。

    旧数据点:cpu_load,hostname=server02,az=us_west,uniq=1 val_1=24.5,val_2=7 1234567890000000

    新数据点:cpu_load,hostname=server02,az=us_west,uniq=2 val_1=5.24 1234567890000000

    将新数据点写入TSDB For InfluxDB®后:

    > SELECT * FROM "cpu_load" WHERE time =1234567890000000
    name: cpu_load
    --------------
    time                      az        hostname   uniq   val_1   val_2
    1970-01-15T06:56:07.89Z   us_west   server02   124.57
    1970-01-15T06:56:07.89Z   us_west   server02   25.24
  • 时间戳增加一纳秒。

    旧数据点:cpu_load,hostname=server02,az=us_west val_1=24.5,val_2=7 1234567890000000

    新数据点:cpu_load,hostname=server02,az=us_west val_1=5.24 1234567890000001

    将新数据点写入TSDB For InfluxDB®后:

    > SELECT * FROM "cpu_load" WHERE time >=1234567890000000 and time <=1234567890000001
    name: cpu_load
    --------------
    time                             az        hostname   val_1   val_2
    1970-01-15T06:56:07.89Z          us_west   server02   24.57
    1970-01-15T06:56:07.890000001Z   us_west   server02   5.24

HTTP API需要怎样的换行符?

TSDB For InfluxDB®的行协议依赖换行符(\n,这是ASCII 0x0A)来表示一行的结束和新的一行的开始。文件或数据使用\n以外的换行符会导致以下错误:bad timestamp, unable to parse

请注意,Windows使用回车键和换行符(\r\n)作为换行符。

当将数据写入TSDB For InfluxDB®时,应该避免哪些文字和字符?

  • InfluxQL关键字

    如果您使用InfluxQL关键字作为标识符,您需要在每个查询中使用双引号将该标识符括起来。如果不使用双引号,会导致错误。标识符是连续查询名字、数据库名字、field key、measurement的名字、保留策略名字、tag key和用户名。

  • 时间

    关键字time是一个特例。time可以是一个连续查询名字、数据库名字、measurement的名字、保留策略名字和用户名。在这些情况下,不需要在查询中用双引号将time括起来。time不能是field keytag key;TSDB For InfluxDB®拒绝写入将time作为field keytag key的数据,对于这种数据写入,TSDB For InfluxDB®会返回错误。示例如下:

    • time作为measurement,写入数据并查询它。

      > INSERT time value=1
      
      > SELECT * FROM time
      
      name: time
      time                            value
      ---------
      2017-02-07T18:28:27.349785384Z1

      TSDB For InfluxDB®中,time是一个有效的measurement名字。

    • time作为field key,写入数据并尝试查询它

      > INSERT mymeas time=1
      ERR:{"error":"partial write: invalid field name: input field \"time\" on measurement \"mymeas\" is invalid dropped=1"}

      TSDB For InfluxDB®中,time不是一个有效的field key。系统无法写入该数据点,并且返回400错误。

    • time作为tag key,写入数据并尝试查询它。

      > INSERT mymeas,time=1 value=1
      ERR:{"error":"partial write: invalid tag key: input tag \"time\" on measurement \"mymeas\" is invalid dropped=1"}

      TSDB For InfluxDB®中,time不是一个有效的tag key。系统无法写入该数据点,并且返回400错误。

  • 字符

    为了保持简单的正则表达式和引号,避免在标识符中使用以下字符:\ 反斜杠^ 尖号$ 货币符号' 单引号" 双引号= 等号, 逗号。

当写入数据时,什么时候应该使用单引号,什么时候应该使用双引号?

  • 通过行协议写入数据时,避免使用单引号和双引号将标识符括起来;请查看下面的示例,使用引号后的标识符会使查询变得复杂。标识符是连续查询名字、数据库名字、field key、measurement的名字、保留策略名字、subscription的名字、tag key和用户名。

    • 写入带双引号的measurement:INSERT "bikes" bikes_available=3适用的查询:SELECT * FROM "\"bikes\""

    • 写入带单引号的measurement:INSERT 'bikes' bikes_available=3适用的查询:SELECT * FROM "\'bikes\'"

    • 写入不带引号的measurement:INSERT bikes bikes_available=3适用的查询:SELECT * FROM "bikes"

  • 用双引号将字符串类型的field value括起来。

    写入:INSERT bikes happiness="level 2"适用的查询:SELECT * FROM "bikes" WHERE "happiness"='level 2'

  • 应该用反斜杠转义特殊字符,而不是用引号将其括起来。

    写入:INSERT wacky va\"ue=4适用的查询:SELECT "va\"ue" FROM "wacky"

请查看文档行协议参考获得更多相关信息。

时间戳的精度是否重要?

重要。为了最大限度地提高性能,向TSDB For InfluxDB®写入数据时尽量使用最粗糙的时间精度。

在下面两个例子中,第一个请求使用默认精度(纳秒),而第二个请求将精度设置为秒:

curl -i -XPOST "https://<网络地址>:3242/write?db=weather&u=<账号名称>&p=<密码>"--data-binary 'temperature,location=1 value=90 1472666050000000000'

curl -i -XPOST "https://<网络地址>:3242/write?db=weather&precision=s&u=<账号名称>&p=<密码>"--data-binary 'temperature,location=1 value=90 1472666050'

虽然性能会提高,但是代价是精度越粗糙,越有可能出现具有相同时间戳的重复数据点,可能会覆盖其它数据点。

命令行界面(Influx CLI

如何使TSDB For InfluxDB®的Influx CLI返回用户可读的时间戳?

在您首次连接Influx CLI时,请指定rfc3339精度:

$ influx -ssl -username <账号名称>-password <密码>-host <网络地址>-port 3242-precision rfc3339

或者,在连接Influx CLI后指定精度:

$ influx -ssl -username <账号名称>-password <密码>-host <网络地址>-port 3242
Connected to https://<网络地址>:3242 version 1.7.x
> precision rfc3339

详情请参见命令行界面

admin用户如何使用USE指定一个数据库?

如果非admin用户拥有数据库的READWRITE,或仅有READ权限,那么可以执行USE <database_name>语句。如果非admin用户尝试用USE指定一个他们没有READWRITE,或没有READ权限的数据库,那么系统会返回错误:

ERR:Database<database_name> doesn't exist. Run SHOW DATABASES for a list of existing databases.
说明

SHOW DATABASES查询只返回那些非admin用户有READWRITE权限的数据库。

如何使用TSDB For InfluxDB®的Influx CLI将数据写入一个非默认的保留策略?

请使用语法INSERT INTO [<database>.]<retention_policy> <line_protocol>将数据写入一个非默认的保留策略。(只允许在Influx CLI中使用这种方式指定数据库和保留策略。如果通过HTTP写入数据,必须使用参数dbrp分别指定数据库和保留策略,指定保留策略是可选的。)示例如下。

> INSERT INTO one_day mortality bool=true
Using retention policy one_day
> SELECT * FROM "mydb"."one_day"."mortality"
name: mortality
---------------
time                             bool
2016-09-13T22:29:43.229530864Z   true

您需要完全限定measurement来查询非默认保留策略中的数据。使用以下语法完全限定measurement:

"<database>"."<retention_policy>"."<measurement>"

数据类型

为什么不能查询布尔类型的field value?

写入和查询布尔值的语法不一样。

布尔值语法

写入

查询

t,f

T,F

true,false

True,False

TRUE,FALSE

例如:SELECT * FROM "hamlet" WHERE "bool"=True返回所有bool等于TRUE的数据点,但是,SELECT * FROM "hamlet" WHERE "bool"=T不会返回任何结果。

TSDB For InfluxDB®如何处理多个Shard之间的field的类型差异?

field value可以是浮点数、整数、字符串或者布尔值。在一个Shard中,field value的数据类型需要保持统一,但是在不同的Shard,field value的数据类型可以不同。

  • SELECT语句

    SELECT语句返回默认所有相同数据类型的field value,如果在不同的Shard里面field value的数据类型不一样,那么TSDB For InfluxDB®首先会执行类型转换(如果适用的话),然后返回所有值,并且按以下数据类型的顺序返回结果:浮点数,整数,字符串,布尔值。如果在您的数据中,field value的类型不同,请使用语法<field_key>::<type>查询不同的数据类型。示例如下:

    measurement just_my_type有一个名为my_fieldfield,my_field在四个不同的Shard中有四个field value,并且每个field value的数据类型不一样(分别是浮点数、整数、字符串和布尔值)。

    SELECT只返回浮点型和整型的field value。在返回结果中TSDB For InfluxDB®强制将整数转换成浮点数。

    > SELECT * FROM just_my_type
    
    name: just_my_type
    ------------------
    time                      my_field
    2016-06-03T15:45:00Z9.87034
    2016-06-03T16:45:00Z7

    SELECT <field_key>::<type> [...]返回所有数据类型。TSDB For InfluxDB®将每种类型的数据输出到单独的列中,并且使用递增的列名表示。在可能的情况下,TSDB For InfluxDB®将field value转换成另一种数据类型;它将整数7转换成第一列中的浮点数,将浮点数9.879034转换成第二列中的整数。TSDB For InfluxDB®不能将浮点数或整数转换成字符串或布尔值。

    > SELECT "my_field"::float,"my_field"::integer,"my_field"::string,"my_field"::boolean FROM just_my_type
    
    name: just_my_type
    ------------------
    time                   my_field  my_field_1  my_field_2  my_field_3
    2016-06-03T15:45:00Z9.870349
    2016-06-03T16:45:00Z77
    2016-06-03T17:45:00Z                         a string
    2016-06-03T18:45:00Z                                     true
  • SHOW FIELD KEYS查询

    SHOW FIELD KEYS返回field key对应的每个shard中的每种数据类型。示例如下:

    measurement just_my_type有一个名为my_fieldfield,my_field在四个不同的shard中有四个field value,并且每个field value的数据类型不一样(分别是浮点数、整数、字符串和布尔值)。

    SHOW FIELD KEYS返回所有四种数据类型:

    > SHOW FIELD KEYS
    
    name: just_my_type
    fieldKey   fieldType
    -----------------
    my_field   float
    my_field   string
    my_field   integer
    my_field   boolean

TSDB For InfluxDB®可以存储的最小和最大整数是多少?

TSDB For InfluxDB®将所有整数存储为有符号的int64数据类型。int64有效的最小和最大值分别是-90233720368547758089023372036854775807。请查看Go builtins获得更多相关信息。

使用接近最小/最大整数但依旧在限制范围内的值可能会导致非预期的结果;有些函数和运算符会在计算过程中将数据类型int64转换成float64,这会引起溢出问题。

TSDB For InfluxDB®可以存储的最小和最大时间戳是多少?

最小的时间戳是-92233720368547758061677-09-21T00:12:43.145224194Z,最大的时间戳是92233720368547758062262-04-11T23:47:16.854775806Z。超出该范围的时间戳会返回解析错误。

如何知道存储在field中的数据类型?

SHOW FIELD KEYS查询还返回field的数据类型。

> SHOW FIELD KEYS FROM all_the_types
name: all_the_types
-------------------
fieldKey  fieldType
blue      string
green     boolean
orange    integer
yellow    float

是否可以改变field的数据类型?

目前,在改变field的数据类型上面,TSDB For InfluxDB®提供非常有限的支持。语法<field_key>::<type>支持将field value从整数转换为浮点数或者从浮点数转换为整数。请查看文档数据探索获得更多关于转换操作的信息。无法将浮点数或整数转换为字符串或布尔值(反之亦然)。

我们列出了可用于更改field数据类型的方法:

  • 将数据写入一个不同的field

    最简单的解决方法就是将具有新数据类型的数据写入到同一个序列中的不同field。

  • 使用shard系统

    在一个shard里面,field value的数据类型不能不一样,但是在不同的shard,field value的数据类型可以不同。

    如果要更改field的数据类型,用户可以使用SHOW SHARDS查询来识别当前shardend_time。如果数据点的时间戳发生在end_time之后,那么TSDB For InfluxDB®允许将不同数据类型的数据写入到一个现有的field中(例如,field原来接受整数,但是在end_time之后,该field可以接受浮点数)。

    请注意,这不会改变原来shard里面field的数据类型。

InfluxQL函数

如何执行函数中的数学运算?

目前,TSDB For InfluxDB®不支持函数内的数学运算。我们建议使用子查询作为解决方法。示例如下:

InfluxQL不支持以下语法:

SELECT MEAN("dogs"-"cats")from"pet_daycare"

相反,我们可以使用子查询获得相同的结果:

> SELECT MEAN("difference") FROM (SELECT "dogs"-"cat" AS "difference" FROM "pet_daycare")

请查看数据探索获得更多关于子查询的信息。

为什么查询将epoch 0作为时间戳返回?

TSDB For InfluxDB®中,epoch 0(1970-01-01T00:00:00Z)通常用作空时间戳(null timestamp),如果您请求的查询中没有时间戳返回,例如,对于没有规定时间范围的聚合函数,TSDB For InfluxDB®返回epoch 0作为时间戳。

哪些InfluxQL函数支持嵌套使用?

以下InfluxQL函数支持嵌套使用:

  • COUNT()嵌套DISTINCT()

  • CUMULATIVE_SUM()

  • DERIVATIVE()

  • DIFFERENCE()

  • ELAPSED()

  • MOVING_AVERAGE()

  • NON_NEGATIVE_DERIVATIVE()

  • HOLT_WINTERS()HOLT_WINTERS_WITH_FIT()

关于如何使用子查询代替嵌套函数,请查看文档数据探索