文档文档

InfluxDB 常见问题解答

此页面记录了早期版本的 InfluxDB OSS。InfluxDB OSS v2 是最新的稳定版本。请参阅 InfluxDB v2 文档

此页面解决了常见的困惑来源以及 InfluxDB 相对于其他数据库系统表现出意外行为的地方。在适用的情况下,它链接到 GitHub 上的未解决问题。

管理

命令行界面 (CLI)

数据类型

InfluxQL 函数

查询数据

序列和序列基数

写入数据

如何在密码中包含单引号?

在创建密码和发送身份验证请求时,都使用反斜杠 (\) 转义单引号。

如何识别我的 InfluxDB 版本?

有很多方法可以识别您正在使用的 InfluxDB 版本

在终端中运行 influxd version

$ influxd version

InfluxDB v1.11.8 (git: master b7bb7e8359642b6e071735b50ae41f5eb343fd42)

curl /ping 端点

$ curl -i 'https://127.0.0.1:8086/ping'

HTTP/1.1 204 No Content
Content-Type: application/json
Request-Id: 1e08aeb6-fec0-11e6-8486-000000000000
X-Influxdb-Version: 1.11.8
Date: Wed, 01 Mar 2017 20:46:17 GMT

启动 InfluxDB 命令行界面

$ influx

Connected to https://127.0.0.1:8086version 1.11.8
InfluxDB shell version: 1.11.8

检查日志中的 HTTP 响应

$ journalctl -u influxdb.service

Mar 01 20:49:45 rk-api influxd[29560]: [httpd] 127.0.0.1 - - [01/Mar/2017:20:49:45 +0000] "POST /query?db=&epoch=ns&q=SHOW+DATABASES HTTP/1.1" 200 151 "-" "InfluxDBShell/1.11.8" 9a4371a1-fec0-11e6-84b6-000000000000 1709

在哪里可以找到 InfluxDB 日志?

在 System V 操作系统上,日志存储在 /var/log/influxdb/ 下。

在 systemd 操作系统上,您可以使用 journalctl 访问日志。使用 journalctl -u influxdb 在日志中查看日志,或使用 journalctl -u influxdb > influxd.log 将日志打印到文本文件。使用 systemd,日志保留取决于系统的 journald 设置。

分片组持续时间和保留策略之间的关系是什么?

InfluxDB 将数据存储在分片组中。单个分片组覆盖特定的时间间隔;InfluxDB 通过查看相关保留策略 (RP) 的 DURATION 来确定该时间间隔。下表概述了 RP 的 DURATION 与分片组的时间间隔之间的默认关系

RP 持续时间分片组间隔
< 2 天1 小时
>= 2 天且 <= 6 个月1 天
> 6 个月7 天

用户还可以使用 CREATE RETENTION POLICYALTER RETENTION POLICY 语句配置分片组持续时间。使用 SHOW RETENTION POLICIES 语句检查保留策略的分片组持续时间。

为什么在我更改保留策略后数据没有被删除?

有几个因素可以解释为什么在保留策略 (RP) 更改后数据可能不会立即删除。

第一个也是最可能的原因是,默认情况下,InfluxDB 每 30 分钟检查一次以强制执行 RP。您可能需要等待下一次 RP 检查,InfluxDB 才能删除超出 RP 新 DURATION 设置的数据。30 分钟间隔是可配置的

其次,更改 RP 的 DURATIONSHARD DURATION 都可能导致意外的数据保留。InfluxDB 将数据存储在分片组中,这些分片组覆盖特定的 RP 和时间间隔。当 InfluxDB 强制执行 RP 时,它会删除整个分片组,而不是单个数据点。InfluxDB 无法分割分片组。

如果 RP 的新 DURATION 小于旧的 SHARD DURATION,并且 InfluxDB 当前正在将数据写入旧的、更长的分片组之一,则系统被迫保留该分片组中的所有数据。即使该分片组中的某些数据超出新的 DURATION,也会发生这种情况。一旦分片组的所有数据都超出新的 DURATION,InfluxDB 将删除该分片组。然后,系统将开始将数据写入具有新的、更短的 SHARD DURATION 的分片组,从而防止任何进一步的意外数据保留。

为什么 InfluxDB 无法解析配置文件中的微秒单位?

指定微秒持续时间单位的语法在 配置 设置、写入、查询以及在 InfluxDB 命令行界面 (CLI) 中设置精度时有所不同。下表显示了每个类别的支持语法

配置文件InfluxDB API 写入所有查询CLI 精度命令
u👍👍👍
us👍
µ👍
µs👍

如果配置选项指定了 uµ 语法,InfluxDB 将无法启动,并在日志中报告以下错误

run: parse config: time: unknown unit [µ|u] in duration [<integer>µ|<integer>u]

InfluxDB 是否有文件系统大小限制?

InfluxDB 在 Linux 和 Windows POSIX 的文件系统大小限制内工作。一些存储提供商和发行版具有大小限制;例如

  • Amazon EBS 卷将大小限制为约 16TB
  • Linux ext3 文件系统将大小限制为约 16TB
  • Linux ext4 文件系统将大小限制为约 1EB(文件大小限制约为 16TB)

如果您预计每个卷/文件系统增长超过 16TB,我们建议您寻找支持您存储需求的提供商和发行版。

如何使用 InfluxDB CLI 返回人类可读的时间戳?

首次连接到 CLI 时,请指定 rfc3339 精度

influx -precision rfc3339

或者,在您已连接到 CLI 后指定精度

$ influx
Connected to https://127.0.0.1:8086 version 0.xx.x
InfluxDB shell 0.xx.x
> precision rfc3339
>

查看 CLI/Shell 以获取更多有用的 CLI 选项。

非管理员用户如何在 InfluxDB CLI 中 USE 数据库?

在 v1.3 之前的版本中,非管理员用户 即使对该数据库具有 READ 和/或 WRITE 权限,也无法在 CLI 中执行 USE <database_name> 查询。

从版本 1.3 开始,非管理员用户可以对其具有 READ 和/或 WRITE 权限的数据库执行 USE <database_name> 查询。如果非管理员用户尝试 USE 用户没有 READ 和/或 WRITE 权限的数据库,系统将返回错误

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

请注意SHOW DATABASES 查询 仅返回非管理员用户具有 READ 和/或 WRITE 权限的那些数据库。

如何使用 InfluxDB CLI 写入非 DEFAULT 保留策略?

使用语法 INSERT INTO [<database>.]<retention_policy> <line_protocol> 以使用 CLI 将数据写入非 DEFAULT 保留策略。(仅 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

请注意,您需要完全限定测量值才能在非 DEFAULT 保留策略中查询数据。使用以下语法完全限定测量值

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

如何取消长时间运行的查询?

您可以使用 Ctrl+C 从 CLI 取消长时间运行的交互式查询。要停止在使用 SHOW QUERIES 命令时看到的其他长时间运行的查询,您可以使用 KILL QUERY 命令停止它。

为什么我无法查询布尔字段值?

可接受的布尔语法对于数据写入和数据查询有所不同。

布尔语法写入查询
t,f👍
T,F👍
true,false👍👍
True,False👍👍
TRUE,FALSE👍👍

例如,SELECT * FROM "hamlet" WHERE "bool"=True 返回所有 bool 设置为 TRUE 的点,但 SELECT * FROM "hamlet" WHERE "bool"=T 不返回任何内容。

InfluxDB 如何处理跨分片的字段类型差异?

字段值可以是浮点数、整数、字符串或布尔值。字段值类型在 分片 中不能不同,但它们可以在跨分片中不同

SELECT 语句

SELECT 语句如果所有值都具有相同的类型,则返回所有字段值。如果字段值类型在跨分片中不同,InfluxDB 首先执行任何适用的 强制转换 操作,然后返回类型在以下列表中首先出现的所有值:浮点数、整数、字符串、布尔值。

如果您的数据存在字段值类型差异,请使用语法 <field_key>::<type> 查询不同的数据类型。

示例

测量值 just_my_type 具有一个名为 my_field 的字段。my_field 在四个不同的分片中具有四个字段值,并且每个值都具有不同的数据类型(浮点数、整数、字符串和布尔值)。

SELECT * 仅返回浮点数和整数字段值。请注意,InfluxDB 在响应中将整数值强制转换为浮点数。

SELECT * FROM just_my_type

name: just_my_type
------------------
time		                	my_field
2016-06-03T15:45:00Z	  9.87034
2016-06-03T16:45:00Z	  7

SELECT <field_key>::<type> [...] 返回所有值类型。InfluxDB 在其自己的列中输出每种值类型,并带有递增的列名。在可能的情况下,InfluxDB 将字段值强制转换为另一种类型;它将第一个列中的整数 7 强制转换为浮点数,并将第二个列中的浮点数 9.879034 强制转换为整数。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:00Z	 9.87034	  9
2016-06-03T16:45:00Z	 7	        7
2016-06-03T17:45:00Z			                     a string
2016-06-03T18:45:00Z					                                true

SHOW FIELD KEYS 查询

SHOW FIELD KEYS 返回与字段键关联的每个数据类型(跨每个分片)。

示例

测量值 just_my_type 具有一个名为 my_field 的字段。my_field 在四个不同的分片中具有四个字段值,并且每个值都具有不同的数据类型(浮点数、整数、字符串和布尔值)。SHOW FIELD KEYS 返回所有四种数据类型

> SHOW FIELD KEYS

name: just_my_type
fieldKey   fieldType
--------   ---------
my_field   float
my_field   string
my_field   integer
my_field   boolean

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

InfluxDB 将所有整数存储为有符号 int64 数据类型。int64 的最小和最大有效值分别为 -92233720368547758089223372036854775807。有关更多信息,请参阅 Go builtins

接近但未超过这些限制的值可能会导致意外结果;某些函数和运算符在计算期间将 int64 数据类型转换为 float64,这可能会导致溢出问题。

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

最小时间戳为 -92233720368547758061677-09-21T00:12:43.145224194Z。最大时间戳为 92233720368547758062262-04-11T23:47:16.854775806Z

超出该范围的时间戳返回 解析错误

如何判断字段中存储的数据类型?

SHOW FIELD KEYS 查询也返回字段的类型。

示例

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

我可以更改字段的数据类型吗?

目前,InfluxDB 对更改字段的数据类型的支持非常有限。

<field_key>::<type> 语法支持将字段值从整数强制转换为浮点数或从浮点数强制转换为整数。有关示例,请参阅 强制转换操作。无法将浮点数或整数强制转换为字符串或布尔值(反之亦然)。

我们在下面列出了更改字段数据类型的可能解决方法。请注意,这些解决方法不会更新已写入数据库的数据。

将数据写入不同的字段

最简单的解决方法是开始将新的数据类型写入同一序列中的不同字段。

处理分片系统

字段值类型在分片中不能不同,但它们可以在跨分片中不同。

希望更改字段数据类型的用户可以使用 SHOW SHARDS 查询来识别当前分片的 end_time。如果点的时间戳发生在 end_time 之后,InfluxDB 将接受使用不同数据类型写入现有字段。

请注意,这不会更改先前分片上的字段数据类型。有关这如何影响您的查询,请参阅 InfluxDB 如何处理跨分片的字段类型差异

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

目前,InfluxDB 不支持在函数中进行数学运算。我们建议使用 InfluxQL 的 子查询 作为解决方法。

示例

InfluxQL 不支持以下语法

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

而是使用子查询来获得相同的结果

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

有关更多信息,请参阅数据浏览页面。

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

在 InfluxDB 中,epoch 0 (1970-01-01T00:00:00Z) 通常用作空时间戳等效项。如果您请求没有时间戳返回的查询,例如具有无界时间范围的聚合函数,则 InfluxDB 返回 epoch 0 作为时间戳。

哪些 InfluxQL 函数支持嵌套?

以下 InfluxQL 函数支持嵌套

有关如何使用子查询代替嵌套函数的信息,请参阅数据浏览

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

GROUP BY time() 查询返回的时间间隔符合 InfluxDB 数据库的预设时间桶或用户指定的 偏移间隔

示例

预设时间桶

以下查询计算了下午 6:15 到下午 7:45 之间 sunflowers 的平均值,并将这些平均值分组为一小时间隔

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

以下结果显示了 InfluxDB 如何维护其预设时间桶。

在此示例中,下午 6 点小时是一个预设桶,下午 7 点小时是一个预设桶。由于 WHERE 时间子句,下午 6 点时间桶的平均值不包括下午 6:15 之前的数据,但下午 6 点时间桶的平均值中包含的任何数据都必须在下午 6 点小时内发生。下午 7 点时间桶的情况相同;下午 7 点时间桶的平均值中包含的任何数据都必须在下午 7 点小时内发生。虚线显示了构成每个平均值的点。

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

原始数据:                                                                                

结果

name: flower_orders                                name: flower_orders
—————————                                          -------------------
time                    sunflowers                 time                  mean
2016-08-29T18:00:00Z    34                         2016-08-29T18:00:00Z  22.332
                       |--|                        2016-08-29T19:00:00Z  62.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:00Z    70
偏移间隔

以下查询计算了下午 6:15 到下午 7:45 之间 sunflowers 的平均值,并将这些平均值分组为一小时间隔。它还将 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

在此示例中,用户指定的 偏移间隔 将 InfluxDB 数据库的预设时间桶向前移动了 15 分钟。下午 6 点时间桶的平均值现在包括下午 6:15 到下午 7 点之间的数据,下午 7 点时间桶的平均值包括下午 7:15 到下午 8 点之间的数据。虚线显示了构成每个平均值的点。

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

原始数据:                                                                                

结果

name: flower_orders                                name: flower_orders
—————————                                          -------------------
time                    sunflowers                 time                  mean
2016-08-29T18:00:00Z    34                         2016-08-29T18:15:00Z  30.75
                       |--|                        2016-08-29T19:15:00Z  65
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|
                       |--|

为什么我的查询返回无数据或部分数据?

您的查询返回无数据或部分数据的最常见原因

查询错误的保留策略

InfluxDB 自动查询数据库默认保留策略 (RP) 中的数据。如果您的数据存储在另一个 RP 中,则必须在查询中指定 RP 才能获得结果。

SELECT 子句中没有字段键

查询需要在 SELECT 子句中至少包含一个字段键。如果 SELECT 子句仅包含标签键,则查询返回空响应。有关更多信息,请参阅数据浏览

SELECT 查询包含 GROUP BY time()

如果您的 SELECT 查询包含 GROUP BY time() 子句,则仅返回 1677-09-21 00:12:43.145224194now() 之间的数据点。因此,如果您的任何数据点发生在 now() 之后,请在时间间隔中指定替代上限

(默认情况下,大多数 SELECT 查询 查询时间戳在 1677-09-21 00:12:43.1452241942262-04-11T23:47:16.854775806Z UTC 之间的数据。)

具有相同名称的标签键和字段键

避免为标签键和字段键使用相同的名称。如果您不小心为标签键和字段键添加了相同的名称,然后一起查询这两个键,则查询结果会显示附加了 _1 的第二个查询键(标签或字段)(在 Chronograf 中也可见为列标题)。要查询附加了 _1 的标签键或字段键,您必须删除附加的 _1并包含语法 ::tag::field

示例

  1. 启动 influx.

  2. 写入以下点以创建具有相同名称 leaves 的字段键和标签键

    # create the `leaves` tag key
    INSERT grape,leaves=species leaves=6
    
    #create the `leaves` field key
    INSERT grape leaves=5
    
  3. 如果您查看这两个键,您会注意到这两个键都不包含 _1

    # show the `leaves` tag key
    SHOW TAG KEYS
    
    name: grape
    tagKey
    ------
    leaves
    
    # create the `leaves` field key
    SHOW FIELD KEYS
    
    name: grape
    fieldKey   fieldType
    ------     ---------
    leaves     float
    
  4. 如果您查询 grape 测量值,您会看到 leaves 标签键已附加 _1

    # query the `grape` measurement
    SELECT * FROM <database_name>.<retention_policy>."grape"
    
    name: grape
    time                leaves      leaves_1
    ----                --------    ----------
    1574128162128468000 6.00        species
    1574128238044155000 5.00
    
  5. 要查询重复的键名,您必须删除 _1并在键后包含 ::tag::field

    # query duplicate keys using the correct syntax
    SELECT "leaves"::tag, "leaves"::field FROM <database_name>.<retention_policy>."grape"
    
    name: grape
    time                leaves     leaves_1
    ----                --------   ----------
    1574128162128468000 species    6.00
    1574128238044155000            5.00
    

    因此,引用 leaves_1 的查询不返回值。

警告:如果您不小心添加了重复的键名,请按照以下步骤删除重复的键。由于内存要求,如果您有大量数据,我们建议您按指定的时间间隔(例如,日期范围)对数据进行分块(在选择数据时)以适应分配的内存。

删除重复的键

  1. 启动 influx.

  2. 使用以下查询删除重复的键。

    
    /* select each field key to keep in the original measurement and send to a temporary
       measurement; then, group by the tag keys to keep (leave out the duplicate key) */
    
    SELECT "field_key","field_key2","field_key3"
    INTO <temporary_measurement> FROM <original_measurement>
    WHERE <date range> GROUP BY "tag_key","tag_key2","tag_key3"
    
    /* verify the field keys and tags keys were successfully moved to the temporary
    measurement */
    SELECT * FROM "temporary_measurement"
    
    /* drop original measurement (with the duplicate key) */
    DROP MEASUREMENT "original_measurement"
    
    /* move data from temporary measurement back to original measurement you just dropped */
    SELECT * INTO "original_measurement" FROM "temporary_measurement" GROUP BY *
    
    /* verify the field keys and tags keys were successfully moved back to the original
     measurement */
    SELECT * FROM "original_measurement"
    
    /* drop temporary measurement */
    DROP MEASUREMENT "temporary_measurement"
    

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

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

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

在以下示例中,第一个查询涵盖时间戳在 2015-09-18T21:30:00Znow() 之间的数据。第二个查询涵盖时间戳在 2015-09-18T21:30:00Z 和从 now() 起 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)
>

有关查询中时间语法的更多信息,请参阅数据浏览

我可以对时间戳执行数学运算吗?

目前,无法对 InfluxDB 中的时间戳值执行数学运算符。大多数时间计算必须由接收查询结果的客户端执行。

对针对时间戳值使用 InfluxQL 函数的支持有限。ELAPSED() 函数返回单个字段中后续时间戳之间的差异。

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

InfluxDB 将所有时间戳存储为纳秒值,而与提供的写入精度无关。请务必注意,当返回查询结果时,数据库会静默地删除时间戳末尾的零,这会掩盖初始写入精度。

在下面的示例中,标签 precision_suppliedtimestamp_supplied 显示了用户在写入时提供的时间精度和时间戳。由于 InfluxDB 会静默地删除返回时间戳的末尾零,因此在返回的时间戳中无法识别写入精度。

name: trails
-------------
time                  value	 precision_supplied  timestamp_supplied
1970-01-01T01:00:00Z  3      n                   3600000000000
1970-01-01T01:00:00Z  5      h                   1
1970-01-01T02:00:00Z  4      n                   7200000000000
1970-01-01T02:00:00Z  6      h                   2

何时应该在查询中使用单引号,何时应该使用双引号?

单引号字符串值(例如,标签值),但不要单引号标识符(数据库名称、保留策略名称、用户名、测量名称、标签键和字段键)。

如果标识符以数字开头、包含 [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'

单引号日期时间字符串。如果您双引号日期时间字符串,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 保留策略后,我的数据会丢失?

当您在数据库上创建新的 DEFAULT 保留策略 (RP) 时,写入旧 DEFAULT RP 的数据仍保留在旧 RP 中。不指定 RP 的查询会自动查询新的 DEFAULT RP,因此旧数据可能看起来像是丢失了。要查询旧数据,您必须在查询中完全限定相关数据。

示例

测量 fleeting 中的所有数据都属于名为 one_hourDEFAULT RP

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

我们创建一个新的 DEFAULT RP (two_hour) 并执行相同的查询

> SELECT count(flounders) FROM fleeting
>

要查询旧数据,我们必须通过完全限定 fleeting 来指定旧的 DEFAULT RP

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

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

目前,InfluxDB 不支持在 WHERE 子句中使用 OR 来指定多个时间范围。如果查询的 WHERE 子句将 OR 与时间间隔一起使用,InfluxDB 将返回空响应。

示例

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

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

如果先前的值在查询的时间范围之外,则 fill(previous) 不会填充时间桶的结果。

在以下示例中,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:00Z   3
2016-07-12T16:50:10Z   2
2016-07-12T16:50:40Z   12
2016-07-12T16:50:50Z   11

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:40Z   12
2016-07-12T16:51:00Z   12

虽然这是 fill(previous) 的预期行为,但 GitHub 上的一个开放功能请求建议即使先前的值落在查询的时间范围之外,fill(previous) 也应该填充结果。

为什么我的 INTO 查询缺少数据?

默认情况下,INTO 查询会将初始数据中的任何标签转换为新写入数据中的字段。这可能会导致 InfluxDB 覆盖先前通过标签区分的 。在所有 INTO 查询中包含 GROUP BY * 以在新写入的数据中保留标签。

请注意,此行为不适用于使用 TOP()BOTTOM() 函数的查询。有关更多信息,请参阅 TOP()BOTTOM() 文档。

示例

初始数据

french_bulldogs 测量包括 color 标签和 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 查询会将 color 标签转换为新写入数据中的字段。在初始数据中,nugget 点和 rumple 点仅通过 color 标签来区分。一旦 color 变成一个字段,InfluxDB 就会假定 nugget 点和 rumple 点是重复点,并使用 rumple 点覆盖 nugget 点。

> SELECT * INTO "all_dogs" FROM "french_bulldogs"
name: result
------------
time                  written
1970-01-01T00:00:00Z  3

> 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 查询将 color 保留为新写入数据中的标签。在这种情况下,nugget 点和 rumple 点仍然是唯一点,InfluxDB 不会覆盖任何数据。

> SELECT "name" INTO "all_dogs" FROM "french_bulldogs" GROUP BY *
name: result
------------
time                  written
1970-01-01T00:00:00Z  3

> 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

如何查询具有相同标签键和字段键的数据?

使用 :: 语法来指定键是字段键还是标签键。

示例

示例数据
> INSERT candied,almonds=true almonds=50,half_almonds=51 1465317610000000000
> INSERT candied,almonds=true almonds=55,half_almonds=56 1465317620000000000

> SELECT * FROM "candied"
name: candied
-------------
time                   almonds  almonds_1  half_almonds
2016-06-07T16:40:10Z   50       true       51
2016-06-07T16:40:20Z   55       true       56
指定键是字段
> SELECT * FROM "candied" WHERE "almonds"::field > 51
name: candied
-------------
time                   almonds  almonds_1  half_almonds
2016-06-07T16:40:20Z   55       true       56
指定键是标签
> SELECT * FROM "candied" WHERE "almonds"::tag='true'
name: candied
-------------
time                   almonds  almonds_1  half_almonds
2016-06-07T16:40:10Z   50       true       51
2016-06-07T16:40:20Z   55       true       56

如何跨测量查询数据?

目前,没有办法执行跨测量数学或分组。所有数据必须在单个测量下才能一起查询。InfluxDB 不是关系数据库,跨测量映射数据目前不是推荐的 模式。有关在 InfluxDB 中实现 JOIN 的讨论,请参阅 GitHub Issue #3552

时间戳的顺序重要吗?

否。我们的测试表明,InfluxDB 完成以下查询所需的时间只有微不足道的差异

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

如何使用没有值的标签 SELECT 数据?

使用 '' 指定空标签值。例如

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

为什么序列基数很重要?

InfluxDB 维护系统中每个 序列 的内存索引。随着唯一序列数量的增长,RAM 使用量也会随之增长。高 序列基数 可能导致操作系统使用内存不足 (OOM) 异常终止 InfluxDB 进程。请参阅 SHOW CARDINALITY 以了解有关序列基数的 InfluxSQL 命令。

如何从索引中删除序列?

要减少序列基数,必须从索引中删除序列。DROP DATABASEDROP MEASUREMENTDROP SERIES 都将从索引中删除序列并降低总体序列基数。

注意: DROP 命令通常是 CPU 密集型的,因为它们经常触发 TSM 压缩。以高频率发出 DROP 查询可能会显着影响写入和其他查询吞吐量。

如何写入整数字段值?

写入整数时,在字段值的末尾添加尾随 i。如果您不提供 i,InfluxDB 会将字段值视为浮点数。

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

InfluxDB 如何处理重复点?

一个点由测量名称、标签集 和时间戳唯一标识。如果您提交一个新点,其测量名称、标签集和时间戳与现有点相同,则字段集将成为旧字段集和新字段集的并集,其中任何冲突都归于新字段集。这是预期的行为。

例如

旧点: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

提交新点后,InfluxDB 将使用新的字段值覆盖 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.24    7

要存储两个点

  • 引入任意新标签以强制唯一性。

    旧点: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

    将新点写入 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   1      24.5    7
1970-01-15T06:56:07.89Z   us_west   server02   2      5.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

    将新点写入 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.5    7
1970-01-15T06:56:07.890000001Z   us_west   server02   5.24

InfluxDB API 需要什么换行符?

InfluxDB 行协议依赖于换行符 (\n,即 ASCII 0x0A) 来指示行的结尾和新行的开始。使用除 \n 以外的换行符的文件或数据将导致以下错误:bad timestampunable to parse

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

在向 InfluxDB 写入数据时,应避免哪些单词和字符?

InfluxQL 关键字

如果您使用 InfluxQL 关键字 作为标识符,则需要在每个查询中双引号该标识符。这可能会导致 不直观的错误。标识符是连续查询名称、数据库名称、字段键、测量名称、保留策略名称、订阅名称、标签键和用户名。

time

关键字 time 是一种特殊情况。time 可以是 连续查询 名称、数据库名称、测量 名称、保留策略 名称、订阅 名称和 用户 名称。在这些情况下,time 在查询中不需要双引号。time 不能是 字段键标签键;InfluxDB 拒绝将 time 作为字段键或标签键的写入,并返回错误。

示例

time 写入为测量并查询它
> INSERT time value=1

> SELECT * FROM time

name: time
time                            value
----                            -----
2017-02-07T18:28:27.349785384Z  1

time 是 InfluxDB 中有效的测量名称。

time 写入为字段键并尝试查询它
> INSERT mymeas time=1
ERR: {"error":"partial write: invalid field name: input field \"time\" on measurement \"mymeas\" is invalid dropped=1"}

time 不是 InfluxDB 中有效的字段键。系统不写入点并返回 400

time 写入为标签键并尝试查询它
> INSERT mymeas,time=1 value=1
ERR: {"error":"partial write: invalid tag key: input tag \"time\" on measurement \"mymeas\" is invalid dropped=1"}

time 不是 InfluxDB 中有效的标签键。系统不写入点并返回 400

字符

为了保持正则表达式和引用简单,请避免在标识符中使用以下字符

\ 反斜杠 ^ 抑扬符 $ 美元符号 ' 单引号 " 双引号 = 等号 , 逗号

写入数据时,何时应该使用单引号,何时应该使用双引号?

  • 通过行协议写入数据时,避免单引号和双引号标识符;请参阅下面的示例,了解如何使用引号写入标识符会使查询复杂化。标识符是数据库名称、保留策略名称、用户名、测量名称、标签键和字段键。

    使用双引号测量写入:INSERT "bikes" bikes_available=3 适用查询:SELECT * FROM "\"bikes\""

    使用单引号测量写入:INSERT 'bikes' bikes_available=3 适用查询:SELECT * FROM "\'bikes\'"

    使用未加引号的测量写入:INSERT bikes bikes_available=3 适用查询:SELECT * FROM "bikes"

  • 双引号字符串值的字段值。

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

  • 特殊字符应使用反斜杠转义,而不是放在引号中。

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

有关更多信息,请参阅 行协议

时间戳的精度重要吗?

是的。为了最大限度地提高性能,在将数据写入 InfluxDB 时,请使用尽可能粗糙的时间戳精度。

在以下两个示例中,第一个请求使用纳秒的默认精度,而第二个示例将精度设置为秒

curl -i -XPOST "https://127.0.0.1:8086/write?db=weather" --data-binary 'temperature,location=1 value=90 1472666050000000000'

curl -i -XPOST "https://127.0.0.1:8086/write?db=weather&precision=s" --data-binary 'temperature,location=1 value=90 1472666050'

权衡是,具有重复时间戳的相同点(随着精度变得粗糙,这种情况更有可能发生)可能会覆盖其他点。

写入稀疏历史数据的配置建议和模式指南是什么?

对于希望将稀疏的历史数据写入 InfluxDB 的用户,InfluxData 建议

首先,延长您的 保留策略分片组 持续时间,以覆盖数年。默认分片组持续时间为一周,如果您的数据覆盖数百年 – 嗯,那将是很多分片!拥有极高数量的分片对于 InfluxDB 来说效率低下。使用 ALTER RETENTION POLICY 查询 增加数据的保留策略的分片组持续时间。

其次,暂时降低 cache-snapshot-write-cold-duration 配置设置。如果您要写入大量历史数据,则默认设置 (10m) 可能会导致系统为每个分片将所有数据保存在缓存中。在您写入历史数据时,暂时将 cache-snapshot-write-cold-duration 设置降低到 10s 会使该过程更有效率。


此页是否对您有所帮助?

感谢您的反馈!


Flux 的未来

Flux 即将进入维护模式。您可以继续像现在这样使用它,而无需对您的代码进行任何更改。

阅读更多

InfluxDB 3 开源版本现已公开发布 Alpha 版

InfluxDB 3 开源版本现已可用于 alpha 测试,根据 MIT 或 Apache 2 许可获得许可。

我们正在发布两个产品作为 alpha 版的一部分。

InfluxDB 3 Core 是我们新的开源产品。它是用于时间序列和事件数据的最新数据引擎。InfluxDB 3 Enterprise 是一个商业版本,它建立在 Core 的基础上,增加了历史查询功能、读取副本、高可用性、可扩展性和细粒度的安全性。

有关如何入门的更多信息,请查看