资讯详情

资讯详情

ThingsBoard 多租户备份:凌晨自动跑,数据坏了也能按租户找回

ThingsBoard 多租户备份:凌晨自动跑,数据坏了也能按租户找回【免费下载链接】thingsboardOpen-source IoT Platform - Device management, data collection, processing and visualization.项目地址: https://gitcode.com/GitHub_Trending/th/thingsboard如果你在用 ThingsBoard 给多个客户跑设备平台,最怕的就是手动备份做到一半断掉,第二天发现某个租户的历史遥测数据没了着落。这套流程把按租户备份变成每天半夜自己跑的任务。不做自动备份,坑长什么样手动 pg_dump 导到一半网络断了,留下的文件是半份表,你根本不知道它缺了哪几张;客户要求只回滚我们租户最近一周,可你手里只有全库快照,没有能单独拿出来恢复的租户级文件;磁盘坏掉时花两小时灌完备份,最后发现 .sql 打不开——平时压根没验证过。这三件事的共同点:备份存在不等于备份可用。整体思路先把链路想清楚,数据从哪来、存到哪、怎么确认没丢:数据源是容器里的 PostgreSQL(设备、租户、ts_kv 时序表都在里面)→ 用 pg_dump 按 tenant_id 切片导出成 .dump 文件 → 落到主机上的 backups 目录 → 定期恢复到空库再数行数验证 → 失败就写错误日志,让你知道哪份备份不可信。tenant_id 说白了就是每个租户在平台上的唯一编号,几乎所有业务表都带这一列,这正是我们能按租户切片的根本原因。落地步骤先从数据库里把租户ID清单捞出来做完这一步,你会拿到一行一个租户ID的清单,后面脚本直接拿它循环。# 查 tenant 表,输出纯文本,每行一个 UUID docker compose exec -T postgres psql -U postgres -d thingsboard -Atc \ select id::text from tenant-Atc关掉表头只出裸数据;id::text是因为 UUID 直接打印会带括号,转成字符串方便 shell 循环。tenant 表就是租户数据的入口,它的增删改查逻辑可以参考 租户 DAO 模块。清单拿到手,接下来把它交给备份脚本。写一个按租户切片的备份脚本做完这一步,每个租户对应一个独立 .dump,单租户坏了不影响别人,恢复时也只灌自己的那份。#!/usr/bin/env bash # 按租户切片备份:靠 tenant_id 过滤,产物可单独恢复 set -euo pipefail STAMP$(date %F_%H%M) OUT_DIR./backups/${STAMP} mkdir -p $OUT_DIR # 从 tenant 表拿全部租户ID docker compose exec -T postgres psql -U postgres -d thingsboard -Atc \ select id::text from tenant | while read -r tid; do # -Fc:自定义压缩格式,恢复时可挑表、可并行 # --where:给列出的每张表都加租户过滤,只导这一个租户的行 docker compose exec -T postgres pg_dump -U postgres -d thingsboard \ -t ts_kv -t ts_kv_latest -t device -t device_credentials \ --where tenant_id in (${tid}) \ -f /tmp/tb_${tid}.dump docker compose cp postgres:/tmp/tb_${tid}.dump ${OUT_DIR}/ done echo 备份完成: ${OUT_DIR}两个关键参数值得留意:-Fc产出自定义格式,恢复时能挑表、能并行;--where只对-t显式列出的表生效,所以想按租户切的表都要列全。如果你的 compose 里 postgres 服务名不叫 postgres,改脚本里那一处就行。脚本手动跑通之后,剩下就是让它别依赖人记得。让 crontab 每天半夜自己跑做完这一步,每天 02:30 备份自动执行,stdout 和报错全进独立日志,你只需要偶尔翻一眼。# crontab -e 加这一行:02:30 跑备份,日志单独落盘 30 2 * * * /opt/tb-backup/run_backup_all.sh /var/log/tb_backup.log 21时点选在设备上报的低峰期。pg_dump 走的是 MVCC 一致性快照,不需要停写,但半夜跑对线上查询的压力最小。验证与兜底备份这件事,本质是给自己买个保险:不验证过的备份,等于没备份。恢复测试怎么做才靠谱:把某份 .dump 灌进一个全新的空库,再和源库当时的行数对比,一致才算数。#!/usr/bin/env bash # 恢复演练:空库 行数比对 DUMP$1 # 待验证的 .dump TID$2 # 对应的租户ID createdb tb_restore_check pg_restore -d tb_restore_check $DUMP NEW$(psql -d tb_restore_check -Atc select count(*) from ts_kv) OLD$(docker compose exec -T postgres psql -U postgres -d thingsboard \ -Atc select count(*) from ts_kv where tenant_id in ($TID)) [ $NEW $OLD ] echo 验证通过 || \ { echo $(date) 行数不一致: ${TID} /var/log/tb_backup_error.log; exit 1; }每周挑一两个租户跑一遍就够,不用天天来。备份失败怎么第一时间知道:脚本里的set -e保证任何一步挂掉就整体退出,再在退出路径上把租户ID和时间戳追加进/var/log/tb_backup_error.log。然后配个最简单的巡检:每天早上用 cron 检查这个错误日志有没有新增行,有就发邮件或丢到 IM 群。如果你已经上了监控栈(docker 目录里有 prometheus-grafana 的 compose 文件),把这个错误日志接成告警规则更省事。生产环境注意事项保留策略:每日备份留 30 天,月度备份留 12 个月,过期直接删,别让 backups 目录撑爆磁盘。每周加一次全量:按表切片只保数据,库结构变更、没列进-t的表,靠每周一次-Fc全库 dump 兜底。本地状态文件不走 pg_dump:队列和 EDQS 用的 RocksDB 状态是文件,靠拷贝目录备份,路径在 thingsboard.yml 里用TB_QUEUE_CF_ROCKS_DB_PATH、TB_EDQS_ROCKSDB_PATH两个环境变量配置。留一份异地:本地盘和数据库同机,盘坏了备份跟着没,压缩包定期 rsync 或上传到对象存储。跑通这套之后,你对某租户数据坏了的焦虑会小很多——凌晨自动导出、每周恢复演练、失败有日志可查。想确认哪些表和租户相关,直接翻 dao 模块里的 ModelConstants,表名和列名都定义在那里。【免费下载链接】thingsboardOpen-source IoT Platform - Device management, data collection, processing and visualization.项目地址: https://gitcode.com/GitHub_Trending/th/thingsboard创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →