NanoDB 用户使用手册

NanoDB 是一款基于 Rust 构建的嵌入式时序数据库,采用 TSM(Time‑Structured Merge)存储引擎,以 SQL 为核心交互语言,兼容 InfluxDB 行协议写入,适用于 IoT、监控指标、链路追踪等时序数据场景。

目录

核心概念

Table(表)

NanoDB 的数据组织在中,对应一类时序数据(等同于 InfluxDB 中的 Measurement)。表结构通过 CREATE TABLE 预定义,包含列名、数据类型和主键。

列类型

SQL 类型 存储类型 说明
INT / INTEGER / BIGINT Int64 64 位有符号整数
FLOAT / DOUBLE / REAL Float64 64 位浮点数
VARCHAR / TEXT / STRING Utf8 字符串
BOOLEAN / BOOL Boolean 布尔值
TIMESTAMP Timestamp 时间戳(纳秒)

time 列

每张表必须包含 time 列(BIGINT 类型),存储纳秒级 Unix 时间戳,是时序数据的时间轴。

Tags 与 Fields

Database(数据库)

数据库是表和保留策略的命名空间,一个实例可管理多个数据库。

Retention Policy(保留策略)

定义数据保留时长和分片周期。每个数据库创建时自动生成名为 autogen 的默认策略(分片周期 7 天)。

快速开始

1. 启动服务

./nanodb

2. 连接数据库

nanocli -host localhost -port 3000 -username admin -password yourpassword
Connected to http://localhost:3000 version 1.8
InfluxDB shell version: 0.1.0
>

3. 创建数据库

> CREATE DATABASE mydb

4. 切换数据库

> use mydb
Using database mydb

5. 创建表

> CREATE TABLE cpu (
time         BIGINT NOT NULL,
host         VARCHAR,
region       VARCHAR,
usage_user   DOUBLE,
usage_system DOUBLE,
PRIMARY KEY (host)
)

6. 写入数据

写入通过行协议完成,详见写入数据章节。

7. 查询数据

> SELECT * FROM cpu WHERE host = 'server01' and time>$start and time<$end
time                host      region   usage_user  usage_system
----                ----      ------   ----------  ------------
1748000000000000000 server01  us-east  64.2        10.5

配置参考

NanoDB 使用 config/config.toml 作为主配置文件:

[meta]
dir = "/path/to/meta"        # 元数据存储目录(meta.db 所在位置)
[data]
dir = "/path/to/dbdata"      # TSM 数据文件目录
wal-dir = "/path/to/waldata" # WAL 预写日志目录
[http]
bind-address = "0.0.0.0:3000"  # HTTP 监听地址
auth-enabled = true             # 是否开启认证
配置项 类型 说明
meta.dir string 元数据(数据库、保留策略、用户)持久化目录
data.dir string TSM 数据文件目录,建议使用高速磁盘
data.wal‑dir string WAL 日志目录,建议与 data.dir 分开放置
http.bind‑address string 服务监听地址,默认 0.0.0.0:3000
http.auth‑enabled bool 启用后所有请求需认证,默认 false

日志通过 config/log4rs.yaml 配置,支持文件滚动和日志级别调整。

连接数据库

使用 nanocli 客户端连接 NanoDB:

# 基本连接
nanocli -host localhost -port 3000
# 带认证连接
nanocli -host localhost -port 3000 -username admin -password yourpassword
# 连接后直接切换到指定数据库
nanocli -host localhost -port 3000 -username admin -password yourpassword -database mydb

连接成功后进入交互式 Shell:

Connected to http://localhost:3000 version 1.8
InfluxDB shell version: 0.1.0
>

客户端设置

命令 说明
use <database> 切换当前数据库
format <json|csv|column> 设置输出格式(默认 column
precision <ns|u|ms|s|m|h|rfc3339> 设置时间戳精度(默认 ns
settings 查看当前连接配置
help 查看帮助
exit / quit / Ctrl+D 退出客户端

数据库管理

创建数据库

> CREATE DATABASE mydb
> CREATE DATABASE IF NOT EXISTS mydb

创建成功后,系统自动生成名为 autogen 的默认保留策略(保留 7 天,分片周期 7 天)。

删除数据库

> DROP DATABASE mydb
> DROP DATABASE IF EXISTS mydb
警告: 删除数据库会永久移除其所有元数据,操作不可逆。

查看所有数据库

> SHOW DATABASES
name: databases
name
----
mydb
metrics
iot

切换数据库

> use mydb
Using database mydb

切换后,后续所有 SQL 默认在 mydb 数据库中执行。

表管理

创建表

写入数据前须先定义表结构。time 列(纳秒时间戳)是必须的,PRIMARY KEY 必须且只能指定一个。

语法:

CREATE TABLE [database.]table_name (
time      BIGINT NOT NULL,   -- 必须:纳秒时间戳
tag_col   VARCHAR,           -- 标签列:字符串类型,用于分类过滤
field_col DOUBLE,            -- 指标列:数值类型,存储实际测量值
...
PRIMARY KEY (tag_col)        -- 必须,只能有一个
)

字段类型与行协议写入对应关系:

列类型 行协议写入示例
BIGINT count=100i
DOUBLE / FLOAT value=3.14
VARCHAR / TEXT msg="hello"
BOOLEAN active=true

示例:

> CREATE TABLE cpu (
time         BIGINT NOT NULL,
host         VARCHAR,
region       VARCHAR,
usage_user   DOUBLE,
usage_system DOUBLE,
usage_idle   DOUBLE,
PRIMARY KEY (host)
)
> CREATE TABLE disk (
time        BIGINT NOT NULL,
host        VARCHAR,
path        VARCHAR,
bytes_used  BIGINT,
bytes_free  BIGINT,
PRIMARY KEY (host)
)

查看表列表

> SHOW TABLES
Tables_in_mydb
--------------
cpu
disk
memory

查看表结构

> SHOW COLUMNS FROM cpu

或使用 DESCRIBE / DESC

> DESCRIBE cpu
> DESC cpu
Field         Type     Null
-----         ----     ----
time          Int64    NO
host          Utf8     YES
region        Utf8     YES
usage_user    Float64  YES
usage_system  Float64  YES
usage_idle    Float64  YES

写入数据

数据写入使用 InfluxDB 行协议(Line Protocol)。行协议格式如下:

<table>[,<tag>=<val>,...] <field>=<val>[,...] <timestamp_ns>
部分 说明
table 表名,对应 CREATE TABLE 中的表名
tag=val 标签键值对,逗号分隔,对应 VARCHAR
field=val 指标键值对,空格后跟随,对应数值/布尔列
timestamp_ns 纳秒 Unix 时间戳,对应 time

字段值格式

类型 写法 示例
Float64 纯数字(无后缀) 3.14
Int64 数字 + i 100i
UInt64 数字 + u 200u
String 双引号包裹 "hello world"
Boolean true / false true

特殊字符转义

位置 需转义字符
表名 , 和空格
Tag Key / Value , = 和空格
Field Key , = 和空格
Field Value(字符串) "\

行协议示例

# CPU 监控数据(浮点指标)
cpu,host=server01,region=us-east usage_user=64.2,usage_system=10.5,usage_idle=25.3 1748000000000000000
# 网络请求计数(整数指标)
http_requests,host=web01,method=GET,status=200 count=1024i 1748000000000000000
# 磁盘使用量(无符号整数)
disk,host=server01,path=/data bytes_used=107374182400u,bytes_free=53687091200u 1748000000000000000
# 日志事件(字符串指标)
logs,host=server01,level=ERROR message="connection timeout after 30s" 1748000000000000000
# IoT 传感器(混合类型)
sensor,device_id=temp_001,location=room_a temperature=23.5,humidity=65.2,online=true 1748000000000000000

批量写入

多条数据以换行符分隔,一次请求写入:

cpu,host=server01 usage_user=64.2,usage_system=10.5 1748000000000000000
cpu,host=server02 usage_user=32.1,usage_system=5.3  1748000000000000000
cpu,host=server03 usage_user=71.8,usage_system=15.2 1748000000000000000

提示: 写入使用 InfluxDB 兼容的 /write 端点,请求体大小限制为 20 MB(解压后)。大批量写入建议启用 gzip 压缩。

查询数据

所有查询在客户端 Shell 中直接输入 SQL 执行。NanoDB 使用 DataFusion 引擎,支持标准 SQL SELECT 语法。

基础查询

> SELECT * FROM cpu
time                 host      region   usage_user  usage_system  usage_idle
----                 ----      ------   ----------  ------------  ----------
1748000000000000000  server01  us-east  64.2        10.5          25.3
1748000000000000000  server02  us-west  32.1        5.3           62.6
> SELECT time, host, usage_user FROM cpu
> SELECT * FROM cpu WHERE host = 'server01'
> SELECT * FROM cpu WHERE host = 'server01' AND region = 'us-east'

时间范围查询

time 列支持纳秒整数和时间字符串两种写法,时间字符串自动转换为 UTC 纳秒。

支持的时间字符串格式:

格式 示例
RFC 3339 '2024-05-23T10:00:00Z'
RFC 3339 带时区 '2024-05-23T18:00:00+08:00'
日期时间(UTC) '2024-05-23 10:00:00'
仅日期(UTC 零点) '2024-05-23'
> SELECT * FROM cpu WHERE time > '2024-05-23T00:00:00Z'
> SELECT * FROM cpu
WHERE time >= '2024-05-23 00:00:00'
AND time <  '2024-05-24 00:00:00'
> SELECT * FROM cpu WHERE time BETWEEN '2024-05-23' AND '2024-05-24'

聚合与分组

> SELECT host, AVG(usage_user) AS avg_cpu FROM cpu GROUP BY host
host      avg_cpu
----      -------
server01  64.2
server02  32.1
server03  71.8
> SELECT host, MAX(usage_user) AS peak_cpu, MIN(usage_user) AS min_cpu
FROM cpu
WHERE time > '2024-05-23'
GROUP BY host
> SELECT COUNT(*) FROM cpu WHERE host = 'server01'

排序与分页

> SELECT * FROM cpu ORDER BY time DESC
> SELECT * FROM cpu ORDER BY time DESC LIMIT 10
> SELECT * FROM cpu ORDER BY time LIMIT 100 OFFSET 200

完整查询示例

> use mydb
Using database mydb
> SELECT time, host, usage_user, usage_system
FROM cpu
WHERE host = 'server01'
AND time > '2024-05-23 00:00:00'
ORDER BY time DESC
LIMIT 50
time                 host      usage_user  usage_system
----                 ----      ----------  ------------
1748086300000000000  server01  67.4        11.2
1748086200000000000  server01  65.8        10.9
1748086100000000000  server01  64.2        10.5
...
> SELECT host, AVG(usage_user) AS avg_cpu
FROM cpu
WHERE time > '2024-05-23'
GROUP BY host
ORDER BY avg_cpu DESC
host      avg_cpu
----      -------
server03  71.8
server01  64.2
server02  32.1

查询约束

保留策略管理

查看保留策略

> SHOW RETENTION POLICIES
> SHOW RETENTION POLICIES ON mydb
name        duration   shardGroupDuration  replicaN  default
----        --------   ------------------  --------  -------
autogen     168h0m0s   168h0m0s            1         true
thirty_days 720h0m0s   24h0m0s             1         false
字段 说明
name 保留策略名称
duration 数据保留时长(人类可读)
shardGroupDuration 分片周期
replicaN 副本数(当前固定为 1)
default 是否为该数据库的默认策略

创建保留策略

语法:

CREATE RETENTION POLICY <name> ON <db>
DURATION <duration>
REPLICATION <n>
[SHARD DURATION <shard_duration>]
[DEFAULT]

Duration 支持的时间单位: s(秒)、m(分钟)、h(小时)、d(天)、w(周)

> CREATE RETENTION POLICY thirty_days ON mydb
DURATION 30d
REPLICATION 1
SHARD DURATION 1d
DEFAULT
> CREATE RETENTION POLICY one_year ON mydb
DURATION 365d
REPLICATION 1
SHARD DURATION 7d

修改保留策略

语法:

ALTER RETENTION POLICY <name> ON <db>
DURATION <duration>
REPLICATION <n>
[SHARD DURATION <shard_duration>]
[DEFAULT]
> ALTER RETENTION POLICY autogen ON mydb
DURATION 90d
REPLICATION 1
SHARD DURATION 1d
DEFAULT

分片管理

分片(Shard)是存储引擎按时间范围自动划分的最小存储单元,通常由系统自动管理。

查看分片

> SHOW SHARDS
> SHOW SHARDS ON mydb
id    database  retention_policy  start_time            end_time              expiry_time
--    --------  ----------------  ----------            --------              -----------
1001  mydb      autogen           2024-05-16 00:00 UTC  2024-05-23 00:00 UTC  2024-05-23 00:00 UTC
1002  mydb      autogen           2024-05-23 00:00 UTC  2024-05-30 00:00 UTC  2024-05-30 00:00 UTC
字段 说明
id 分片唯一 ID
database 所属数据库
retention_policy 所属保留策略
start_time 分片时间范围起始
end_time 分片时间范围结束
expiry_time 数据过期时间

说明: 删除和压缩分片的操作通过管理接口执行,详见运维与监控

用户与权限管理

创建用户

> CREATE USER alice WITH PASSWORD 'secure_pass'
> CREATE USER admin WITH PASSWORD 'admin_pass' WITH ALL PRIVILEGES

授予权限

语法:

GRANT <READ | WRITE | ALL [PRIVILEGES]> ON <database> TO <user>
> GRANT READ ON mydb TO alice
> GRANT WRITE ON mydb TO bob
> GRANT ALL PRIVILEGES ON mydb TO charlie

撤销权限

语法:

REVOKE <READ | WRITE | ALL [PRIVILEGES]> ON <database> FROM <user>
> REVOKE READ ON mydb FROM alice
> REVOKE ALL PRIVILEGES ON mydb FROM bob

权限说明

权限 SQL 操作 写入操作
READ SELECT、SHOW 类查询
WRITE CREATE / DROP / ALTER 类 DDL 行协议写入
ALL 全部读写操作 全部

认证缓存: NanoDB 对认证结果缓存 5 分钟(bcrypt 验证结果),密码修改后缓存自动失效。

运维与监控

健康检查

curl http://localhost:3000/health
# 返回:health

适用于负载均衡器探活和容器健康检查。

内存使用查询

curl http://localhost:3000/memory
# 返回当前已分配的堆内存字节数,如:52428800

NanoDB 使用 mimalloc 分配器并通过 TrackedAlloc 实时追踪堆内存。

Prometheus 指标

curl http://localhost:3000/metrics

以 Prometheus 文本格式暴露运行时指标,可直接接入 Prometheus + Grafana:

指标名 类型 标签 说明
http_requests_total Counter method, path, status HTTP 请求总数
http_requests_duration_seconds Histogram method, path, status 请求延迟分布

延迟桶边界(秒):0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 3, 5, 10

手动压缩分片

对指定分片触发 TSM 文件合并压缩,减少文件碎片、释放磁盘空间:

curl "http://localhost:3000/compact?shard_id=1001"

NanoDB 后台每 10 秒自动执行定期压缩,通常无需手动触发。

删除分片

警告: 删除分片会永久删除该时间范围内的所有数据,操作不可逆。
curl "http://localhost:3000/drop/shard?db=mydb&shard_id=1001"

优雅关闭

curl http://localhost:3000/shutdown
# 返回:OK

触发后,服务完成当前请求后安全停止,存储引擎和 WAL 正常关闭。

客户端命令参考

nanocli 交互式 Shell 中支持以下客户端命令:

命令 说明
use <database> 切换当前数据库
help 查看帮助
exit / quit / Ctrl+D 退出客户端

所有非以上命令的输入均作为 SQL 语句发送执行。

错误处理

常见错误及解决方案

错误信息 原因 解决方案
authentication required 未提供认证信息 连接时添加 -username-password
access denied 用户权限不足 使用管理员账号执行 GRANT 授权
数据库 'xx' 已存在 CREATE DATABASE 重复 改用 CREATE DATABASE IF NOT EXISTS
数据库 'xx' 不存在 目标数据库不存在 SHOW DATABASES 确认名称
PRIMARY KEY 只能有 1 个 建表指定了多个主键 只保留一个 PRIMARY KEY 定义
CREATE TABLE 必须指定 PRIMARY KEY 建表未指定主键 在列定义或表约束中加入 PRIMARY KEY
不允许使用 JOIN 操作 查询包含 JOIN 当前不支持多表连接
创建用户失败: user already exists 用户名重复 换用不同用户名
retention policy already exists 策略名重复 改用 ALTER RETENTION POLICY 修改

时间字符串说明

WHERE 子句中 time 列支持字符串写法,引擎自动转为 UTC 纳秒:

-- 以下三种写法等价
WHERE time > 1716422400000000000
WHERE time > '2024-05-23T00:00:00Z'
WHERE time > '2024-05-23'

行协议格式检查清单

附录:典型使用场景

场景一:IoT 传感器数据采集

> CREATE DATABASE iot
> use iot
Using database iot
> CREATE RETENTION POLICY iot_30d ON iot
DURATION 30d REPLICATION 1 SHARD DURATION 1d DEFAULT
> CREATE TABLE sensor_data (
time        BIGINT NOT NULL,
device_id   VARCHAR,
location    VARCHAR,
temperature DOUBLE,
humidity    DOUBLE,
online      BOOLEAN,
PRIMARY KEY (device_id)
)
> SELECT time, device_id, temperature, humidity
FROM sensor_data
WHERE location = 'room_a' AND time > '2024-05-23'
ORDER BY time DESC LIMIT 100

场景二:应用性能监控

> CREATE DATABASE monitor
> use monitor
Using database monitor
> CREATE TABLE http_requests (
time        BIGINT NOT NULL,
service     VARCHAR,
endpoint    VARCHAR,
status_code BIGINT,
duration_ms DOUBLE,
PRIMARY KEY (service)
)
> SELECT service, endpoint, MAX(duration_ms) AS p99_ms
FROM http_requests
WHERE time > '2024-05-23T09:00:00Z'
GROUP BY service, endpoint
ORDER BY p99_ms DESC
service  endpoint       p99_ms
-------  --------       ------
api      /v1/orders     523.4
api      /v1/users      312.1
web      /dashboard     198.7
> SELECT service, COUNT(*) AS error_count
FROM http_requests
WHERE status_code >= 500 AND time > '2024-05-23'
GROUP BY service
ORDER BY error_count DESC

时间单位换算参考

时间 纳秒值
1 秒 1,000,000,000
1 分钟 60,000,000,000
1 小时 3,600,000,000,000
1 天 86,400,000,000,000
7 天(autogen 默认) 604,800,000,000,000
30 天 2,592,000,000,000,000