InfluxDB 数据迁移方案测试以及风险性评估

1. 背景描述

上周,我们完成了 influx-proxy 的代码审计,部署测试以及正式部署的工作,经过我们的测试,influx-proxy 基本满足我们目前针对 InfluxDB 的集群需求。目前我们依托于influx-proxy,提供了 双环双实例使用,考虑到目前旧InfluxDB实例中已存在的MSP监控数据不丢失,我们需要对旧实例和新实例进行数据备份与迁移。

2. 前期准备工作

2.1 迁移方案

  1. 迁移方案的确定与测试,通过测试验证整理出迁移方案的详细的步骤;
  2. 在迁移测试验证的过程中,记录评估迁移的影响范围和风险,建立应对措施与回退方案
  3. 迁移完成后,数据源接入 influx-proxy,执行数据同步操作

2.2 InfluxDB实例测试准备

镜像ID 镜像 端口 实例名
2639ea8f8338 harbor.oneitfarm.com/cidata/influxdb:1.8.3-alpine 8086/8088 influx-1
0af90b775404 harbor.oneitfarm.com/cidata/influxdb:1.8.3-alpine 8076/8078 influx-2
6969da63f9dd harbor.oneitfarm.com/cidata/influxdb:1.8.3-alpine 8066/8068 influx-3

3. 迁移方案

3.1 几种迁移方案参考

目前,考虑到的迁移方案分为三种:

  1. 通过 InfluxDB的数据备份方式,直接针对备份数据进行在新的实例上进行恢复;
  2. 通过InfluxDB的数据导出方式,将指定的数据库进行导出,在新的机器实例上在进行导入操作;
  3. 准备三环三实例机器,直接使用 influx-proxy 进行数据同步,influx-proxy 会将目前已存在的实例数据同步到其他环中的实例;
  4. 使用第三方数据同步工具进行数据迁移,如:DataX

3.2 方案存在的风险性评估

3.2.1 数据备份方式

  1. 需要进入到 旧 InfluxDB实例,修改InfluxDB配置文件,并重启 InfluxDB服务。在这个过程中,会导致部分的数据的丢失,会影响到前端的展示。

3.2.2 数据同步方式

  1. 执行的操作时 influx cql , 在执行写入的操作的时候,会带来比较高的负载;
  2. 在执行的同时,会受到网络等机器本身的影响,且由于是因为执行了 influx 的写入操作,若出现中途意外导致写入终止,将重新执行;

3.2.3 三环三实例方式

  1. 本身并无什么很大的风险,但是在数据量大的情况下,会导致数据迁移(数据同步)过程效率低下;
  2. 若遇到旧InfluxDB在进行持续的写入,会导致数据迁移(数据同步)工作始终无法终止,将会持续的进行。

3.2.4 第三方工具

暂不考虑该方案的执行。目前公司暂不支持 DataX 等数据迁移工具。

3.3 数据迁移步骤

首先,我们需要准备待迁移的 InfluxDB 实例,并在 实例中 配置好 我们需要用到的待迁移的数据库等信息。

3.3.1 数据备份方式

目前数据备份可以根据数据保留策略进行备份,若不设置数据保留策略,将默认备份所有的数据保留策略下的数据。

数据备份:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Usage: influxd backup [options] PATH

-portable
Required to generate backup files in a portable format that can be restored to InfluxDB OSS or InfluxDB
Enterprise. Use unless the legacy backup is required.
-host <host:port>
InfluxDB OSS host to back up from. Optional. Defaults to 127.0.0.1:8088.
-db <name>
InfluxDB OSS database name to back up. Optional. If not specified, all databases are backed up when
using '-portable'.
-rp <name>
Retention policy to use for the backup. Optional. If not specified, all retention policies are used by
default.
-shard <id>
The identifier of the shard to back up. Optional. If specified, '-rp <rp_name>' is required.
-start <2015-12-24T08:12:23Z>
Include all points starting with specified timestamp (RFC3339 format).
Not compatible with '-since <timestamp>'.
-end <2015-12-24T08:12:23Z>
Exclude all points after timestamp (RFC3339 format).
Not compatible with '-since <timestamp>'.
-since <2015-12-24T08:12:23Z>
Create an incremental backup of all points after the timestamp (RFC3339 format). Optional.
Recommend using '-start <timestamp>' instead.
-skip-errors
Optional flag to continue backing up the remaining shards when the current shard fails to backup.

数据恢复:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Options:
-portable
Required to activate the portable restore mode. If not specified, the legacy restore mode is used.
-host <host:port>
InfluxDB OSS host to connect to where the data will be restored. Defaults to '127.0.0.1:8088'.
-db <name>
Name of database to be restored from the backup (InfluxDB OSS or InfluxDB Enterprise)
-newdb <name>
Name of the InfluxDB OSS database into which the archived data will be imported on the target system.
Optional. If not given, then the value of '-db <db_name>' is used. The new database name must be unique
to the target system.
-rp <name>
Name of retention policy from the backup that will be restored. Optional.
Requires that '-db <db_name>' is specified.
-newrp <name>
Name of the retention policy to be created on the target system. Optional. Requires that '-rp <rp_name>'
is set. If not given, the '-rp <rp_name>' value is used.
-shard <id>
Identifier of the shard to be restored. Optional. If specified, then '-db <db_name>' and '-rp <rp_name>' are
required.
PATH
Path to directory containing the backup files.
3.3.1.1 数据备份
  1. 备份当前的InfluxDB数据库,目前官方提供的数据备份中提供了本地备份和远程备份。

我们首先备份元数据:

1
influxd backup -host influx-1:8088 ./influx_db_backup
1
2
3
4
2020/12/09 03:30:56 backing up metastore to influx_db_backup/meta.00
2020/12/09 03:30:56 No database, retention policy or shard ID given. Full meta store backed up.
2020/12/09 03:30:56 backup complete:
2020/12/09 03:30:56 influx_db_backup/influx_db_backup/meta.00

备份好元数据后,我们在备份数据库,这里我们需要制定数据库:

1
influxd backup -database msp -host influx-1:8088 ./influx_db_backup
1
2
3
4
5
6
2020/12/09 03:33:48 backing up metastore to influx_db_backup/meta.01
2020/12/09 03:33:48 backing up db=msp
2020/12/09 03:33:48 backing up db=msp rp=autogen shard=2 to influx_db_backup/msp.autogen.00002.00 since 0001-01-01T00:00:00Z
2020/12/09 03:33:48 backup complete:
2020/12/09 03:33:48 influx_db_backup/influx_db_backup/meta.01
2020/12/09 03:33:48 influx_db_backup/influx_db_backup/msp.autogen.00002.00

我们备份好之后,查看./influx_db_backup

1
2
3
-rw-r--r--    1 root     root           270 Dec  9 03:30 meta.00
-rw-r--r-- 1 root root 270 Dec 9 03:33 meta.01
-rw-r--r-- 1 root root 172032 Dec 9 03:33 msp.autogen.00002.00
3.3.1.2 备份恢复

首先针对InfluxDB实例进行初始化操作,这里我们暂时不创建数据库,验证一下,数据本非过程中,数据库是否会正常创建,这里我们暂时先创建一个管理员用户,我们先测试在拥有管理员用户的情况下的数据恢复情形:

1
2
3
4
5
6
7
8
9
10
> CREATE USER root WITH PASSWORD '123456' WITH ALL PRIVILEGES;
> auth
username: root
password:
> show databases;
name: databases
name
----
monitor
>

开始进行数据备份:

先进行元数据备份:

1
influxd restore -metadir /var/lib/influxdb/meta/ ./influx_db_backup
1
2
bash-5.0# influxd restore -metadir /var/lib/influxdb/meta/ ./influx_db_backup
Using metastore snapshot: influx_db_backup/meta.01

再进行数据库的备份:

1
influxd restore -database msp -datadir /var/lib/influxdb/data ./influx_db_backup
1
2
3
Using metastore snapshot: influx_db_backup/meta.01
bash-5.0# influxd restore -database msp -datadir /var/lib/influxdb/data ./influx_db_backup
2020/12/09 03:46:48 Restoring offline from backup influx_db_backup/msp.*

这也不知道是否备份成功,我们比较下两个数据库里面的数据:

针对influx-1

1
2
3
4
5
6
7
8
9
10
11
> show measurements;
name: measurements
name
----
test_udp_proxy
> select sum(count) from test_udp_proxy;
name: test_udp_proxy
time sum
---- ---
0 96100
>

针对influx-2

1
2
3
4
5
6
> show databases;
name: databases
name
----
monitor
>

首先,是没有msp这个数据库的,说明我们备份恢复的时候,这个数据库必须要存在。

现在我们创建这个数据库后,在执行数据恢复,显示结果如下:

1
Restoring offline from backup influx_db_backup/msp.*

这个说明了,我们的恢复失败了。为什么失败了呢?我们重新根据官网的操作来执行。

备份数据:

1
influxd backup -portable -database msp -host influx-1:8088 ./influx_db_backup/

换原数据:

1
influxd restore -portable -db msp ./influx_db_backup/

这里又会出现错误:

1
2
2020/12/09 05:27:15 error updating meta: DB metadata not changed. database may already exist
restore: DB metadata not changed. database may already exist

这里说明,备份的数据库已存在了,DB的元数据说明不需要备份,而导致了数据备份失败了。但是目前我们的数据库中,的确是存在MSP 的数据库的,因此我们需要操作:

1
influxd restore -portable -db msp -newdb msp_bak ./influx_db_backup/

将数据备份到msp_bak,在使用 msp_bak执行:

1
SELECT * INTO msp..:MEASUREMENT FROM /.*/ GROUP BY *

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> SELECT * INTO msp..:MEASUREMENT FROM /.*/ GROUP BY *
name: result
time written
---- -------
0 96100
> select sum(count) from test_udp_proxy;
name: test_udp_proxy
time sum
---- ---
0 96100
> use msp;
Using database msp
> select sum(count) from test_udp_proxy;
name: test_udp_proxy
time sum
---- ---
0 96100
>

至此,我们的数据备份结束,恢复成功。

3.3.1.3 其他的备份

刚刚我们在前面有提到的,现在考虑,备份的目标实例,为空的实例,没有权限,没有目标数据库,我们的这种备份方式该如何:

InfluxDB 实例为docker 部署的,我们在influx-3上进行测试:

1
2
3
4
5
6
7
> auth
username: root
password:
> use msp
WARN: error authorizing query: create admin user first or disable authentication
Using database msp
>

这是一个很新的数据库,我们现在来直接对influx-1进行备份,恢复

1
2
3
4
5
6
7
8
9
10
bash-5.0# influxd backup -portable -database msp -host influx-1:8088 ./influx_db_backup/
2020/12/09 05:52:18 backing up metastore to influx_db_backup/meta.00
2020/12/09 05:52:18 backing up db=msp
2020/12/09 05:52:18 backing up db=msp rp=autogen shard=2 to influx_db_backup/msp.autogen.00002.00 since 0001-01-01T00:00:00Z
2020/12/09 05:52:18 backup complete:
2020/12/09 05:52:18 influx_db_backup/20201209T055218Z.meta
2020/12/09 05:52:18 influx_db_backup/20201209T055218Z.s2.tar.gz
2020/12/09 05:52:18 influx_db_backup/20201209T055218Z.manifest
bash-5.0# influxd restore -portable -db msp ./influx_db_backup/
2020/12/09 05:52:35 Restoring shard 2 live from backup 20201209T055218Z.s2.tar.gz

我们再次进入客户端,进行测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
> auth
username: root
password:
> use msp;
WARN: error authorizing query: create admin user first or disable authentication
Using database msp
> CREATE USER root WITH PASSWORD '123456' WITH ALL PRIVILEGES
> auth
username: root
password:
> use msp;
Using database msp
> show measurements;
name: measurements
name
----
test_udp_proxy
> select sum(count) from test_udp_proxy;
name: test_udp_proxy
time sum
---- ---
0 96100
>

结果显示:

  1. 数据备份恢复后,并不能帮我创建当前InfluxDB实例的管理员账户;
  2. 数据备份恢复后,数据库可以自动创建恢复,数据不会丢失

3.3.2 数据导出方式

在数据导出的时候,我们需要先删除原来的数据库中的数据,以免影响到我们的测试。

使用官方 influx_inspect export -out 导出所有的数据,在使用 influx -import -path , 导入到 influx-proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bash-5.0# influx_inspect  export -help
Exports TSM files into InfluxDB line protocol format.

Usage: influx_inspect export [flags]

-compress
Compress the output
-database string
Optional: the database to export
-datadir string
Data storage path (default "/root/.influxdb/data")
-end string
Optional: the end time to export (RFC3339 format)
-lponly
Only export line protocol
-out string
Destination file to export to (default "/root/.influxdb/export")
-retention string
Optional: the retention policy to export (requires -database)
-start string
Optional: the start time to export (RFC3339 format)
-waldir string
WAL storage path (default "/root/.influxdb/wal")

我们可以看到,我们这里不支持进行远程的数据导出

首先第一步是要导出我们数据库的数据:

1
2
3
4
bash-5.0# influx_inspect  export -database msp -out "msp" -datadir "/var/lib/influxdb/data" -waldir "/var/lib/influxdb/wal"

writing out tsm file data for msp/autogen...complete.
writing out wal file data for msp/autogen...complete.

我们执行导出之后,在当前的目录中会有msp的文件,现在,我们需要将这个文件进行写入到我们新的InfluxDB实例中。

执行:

1
influx -import -path=msp -precision=ns

我们可以猜测到,写入肯定是失败的,因为没有权限。但是我认为,如果写入失败,是否会在第一时间暴露?测试结果如下:

1
ERROR: 1057100 points were not inserted

我们再次执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bash-5.0# influx -import -host influx-2 -port 8086 -username root -password 123456 -path=msp -precision=ns -database msp
2020/12/09 07:36:40 Processed 100000 lines. Time elapsed: 991.6736ms. Points per second (PPS): 100839
2020/12/09 07:36:41 Processed 200000 lines. Time elapsed: 1.936923s. Points per second (PPS): 103256
2020/12/09 07:36:42 Processed 300000 lines. Time elapsed: 2.9666234s. Points per second (PPS): 101125
2020/12/09 07:36:43 Processed 400000 lines. Time elapsed: 3.9109787s. Points per second (PPS): 102276
2020/12/09 07:36:44 Processed 500000 lines. Time elapsed: 4.8662251s. Points per second (PPS): 102749
2020/12/09 07:36:45 Processed 600000 lines. Time elapsed: 5.9503395s. Points per second (PPS): 100834
2020/12/09 07:36:46 Processed 700000 lines. Time elapsed: 6.9116939s. Points per second (PPS): 101277
2020/12/09 07:36:47 Processed 800000 lines. Time elapsed: 7.9081228s. Points per second (PPS): 101161
2020/12/09 07:36:48 Processed 900000 lines. Time elapsed: 8.945495s. Points per second (PPS): 100609
2020/12/09 07:36:49 Processed 1000000 lines. Time elapsed: 9.9123997s. Points per second (PPS): 100883
2020/12/09 07:36:49 Processed 1 commands
2020/12/09 07:36:49 Processed 1057100 inserts
2020/12/09 07:36:49 Failed 0 inserts

现在查看influx-2的数据库是否正常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bash-5.0# influx
Connected to http://localhost:8086 version 1.8.3
InfluxDB shell version: 1.8.3
> auth
username: root
password:
> use msp
Using database msp
> show measurements;
name: measurements
name
----
test_udp_proxy
> select sum(count) from test_udp_proxy;
name: test_udp_proxy
time sum
---- ---
0 96100
>

如此,我们的数据导出导入正常。

同样,我们可以将我们的输入源修改为我们的influx-proxy的地址,这样,就可以实现多环多实例写入。试验一下:

我们确保influx-2 , influx-3 的数据库为空的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bash-5.0# influx -import -host 192.168.123.190 -port 7076 -username root -password 123456 -path=msp -precision=ns -database msp
2020/12/09 08:00:31 Processed 100000 lines. Time elapsed: 2.6889542s. Points per second (PPS): 37189
2020/12/09 08:00:33 Processed 200000 lines. Time elapsed: 5.4363249s. Points per second (PPS): 36789
2020/12/09 08:00:36 Processed 300000 lines. Time elapsed: 8.2739573s. Points per second (PPS): 36258
2020/12/09 08:00:39 Processed 400000 lines. Time elapsed: 11.3514986s. Points per second (PPS): 35237
2020/12/09 08:00:42 Processed 500000 lines. Time elapsed: 14.3055308s. Points per second (PPS): 34951
2020/12/09 08:00:45 Processed 600000 lines. Time elapsed: 17.3569801s. Points per second (PPS): 34568
2020/12/09 08:00:48 Processed 700000 lines. Time elapsed: 20.2428159s. Points per second (PPS): 34580
2020/12/09 08:00:51 Processed 800000 lines. Time elapsed: 23.5036841s. Points per second (PPS): 34037
2020/12/09 08:00:55 Processed 900000 lines. Time elapsed: 26.7930924s. Points per second (PPS): 33590
2020/12/09 08:00:58 Processed 1000000 lines. Time elapsed: 30.2915705s. Points per second (PPS): 33012
2020/12/09 08:01:00 Processed 1 commands
2020/12/09 08:01:00 Processed 1057100 inserts
2020/12/09 08:01:00 Failed 0 inserts

随后我们在 influx-2 , influx-3 找到的数据 条数为:96100 , 96100 , 在 influx-1 中,我们的测试表的数据为:``96100 , 说明我们的数据在均正常写入了。

但是做这个测试的时候,对于influx-proxy暴露了一个问题:

1
2
3
2020/12/09 16:05:33.811073 D:/Projects/GoProjects/src/ci123_workspace/influx-proxy/backend/file.go:193: truncate error: truncate data\influxdb-1-1.dat: Access is denied.
2020/12/09 16:05:33.811073 D:/Projects/GoProjects/src/ci123_workspace/influx-proxy/backend/file.go:157: cleanup error: influxdb-1-1 truncate data\influxdb-1-1.dat: Access is denied.
2020/12/09 16:05:33.811073 D:/Projects/GoProjects/src/ci123_workspace/influx-proxy/backend/backend.go:264: update meta error: truncate data\influxdb-1-1.dat: Access is denied.

这个问题目前暂时未知。

3.3.3 三环三实例方式

测试之前,我们需要删除上次测试中产生的 data/

三环三实例方式便是纯的influx-proxy方式。我们测试下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- name: circle-1
backends:
- name: influxdb-1-1
url: 'http://127.0.0.1:8076'
username: root
password: '123456'
auth_secure: false
- name: circle-2
backends:
- name: influxdb-2-1
url: 'http://127.0.0.1:8066'
username: root
password: '123456'
auth_secure: false
- name: circle-3
backends:
- name: influxdb-3-1
url: 'http://127.0.0.1:8086'
username: root
password: '123456'
auth_secure: false

我们调用 /resync 接口

测试后,在 influx-2 , influx-3 找到的数据 条数为:96100 , 96100 ,在当前的数据量下,我们的测试是有效的。

4.迁移总结

4.1 备份方式

  1. 需要重启数据库操作,因为在原来的数据库的配置中,我们并没有绑定8088 端口在当前机器IP , 而是直接指向的:127.0.0.1
  2. 备份方式,数据不易丢失,且直接对持久化文件操作,效率高

4.1.1 备份命令

1
influxd backup -portable -database msp -host influx-1:8088 ./influx_db_backup/
1
influxd restore -portable -db msp ./influx_db_backup/
1
influxd restore -portable -db msp -newdb msp_bak ./influx_db_backup/
1
SELECT * INTO msp..:MEASUREMENT FROM /.*/ GROUP BY *

4.2 数据导入方式

  1. 不需要进行数据库的重启操作
  2. 直接使用influx_inspect export -out 操作,可以将当前的数据库导出成文件,再将改文件进行远程写入到新的数据库中即可,操作也比较简单;
  3. 必须当所有数据全部执行导入操作,才知道导入时候成功;
  4. 可以设置导入源为:influx-proxy

4.2.1 数据导入导出命令

1
influx_inspect  export -database msp -out "msp" -datadir "/var/lib/influxdb/data" -waldir "/var/lib/influxdb/wal"
1
influx -import -host 192.168.123.190 -port 7076 -username root -password 123456 -path=msp -precision=ns -database msp

4.3 三环三实例方式

在数据量小的情况下使用该种方式比较方便合理。

4.3.1 influx-proxy 接口

调用/resync 接口