Grafana Mimir 块复制实战:使用 mimirtool blocks copy 在对象存储之间迁移与回填 TSDB 数据块
时序数据库后端数据存储可观测性云原生【免费下载链接】mimirGrafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.项目地址https://gitcode.com/gh_mirrors/mimir/mimir点击查看免费下载Grafana Mimir 的mimirtool blocks copy命令可以在两个对象存储桶之间复制 TSDB 数据块block也可以把对象存储中的块通过 Mimir 的块上传 API 回填backfill到 Mimir 实例用于数据迁移、备份与历史数据导入。本文以仓库文档 docs/internal/tools/copyblocks.md 为核心结合 pkg/mimirtool/commands/blocks/copy/copy.go 等源码完整讲解其复制标记机制、全部命令行参数、三大对象存储后端的配置示例以及回填到 Mimir 的认证与 TLS 配置帮助读者直接上手并理解底层实现。工具定位从独立 copyblocks 到 mimirtool 子命令Grafana Mimir 仓库中存在两处入口功能与命令行参数完全一致独立工具copyblockstools/copyblocks/main.go 编译出的二进制会打印弃用提示——DEPRECATED: the standalone copyblocks tool is deprecated and will be removed in a future release. Use mimirtool blocks copy instead.其文档已迁移到 docs/internal/tools/copyblocks.mdtools/copyblocks/README.md 同样只保留迁移说明。当前推荐入口mimirtool blocks copycopy命令注册在 pkg/mimirtool/commands/blocks.go 的blocks子命令组下与blocks list、blocks mark、blocks split、blocks undelete并列核心实现位于 pkg/mimirtool/commands/blocks/copy/copy.go。因此后续所有命令均使用mimirtool blocks copy形式。核心原理复制标记copy marker与幂等复制该工具最关键的机制是复制标记每成功复制一个块到某个目标桶都会在源桶对应租户的markers/目录下上传一个空对象作为标记防止同一块被重复复制到同一目的地。标记的命名格式为见 copy.go 的CopiedToBucketMarkFilenametenant/markers/blockULID-copied-目标桶名例如tenant1/markers/01EZED0X3YZMNJ3NHGMJJKMHCR-copied-backfill。标记名中携带目标桶名因此同一个块可以同时复制到多个不同的目的地而互不冲突IsCopiedToBucketMarkFilenamecopy.go在解析时会校验 ULID 与copied关键字。复制流程copyBlockscopy.go按如下顺序处理列出源桶全部租户按--tenant-concurrency并发处理对每个租户列出块目录与markers/下的标记合并为blockMarkers{deletion, copied, noCompact}结构copy.go按--block-concurrency并发处理每个块依次跳过已带 copied 标记的块、创建时间早于--min-time的块、带删除标记的块、超出--min-time/--max-time时间范围的块、时长小于--min-block-duration的块对通过筛选的块执行复制或仅在--dry-run下打印would copy block日志复制成功、或目标已存在该块errBlockAlreadyExists、或回填时目标判定块永久无效ErrBlockInvalid三种情况都会在源桶写入 copy 标记保证下次周期运行不再重复处理。值得注意的源码细节复制前会先检查目标桶中是否已有该块的meta.jsoncopy.go已存在则直接写标记跳过--min-time有一个基于块 ULID 的优化ULID 内嵌创建时间若块创建时间早于过滤值可直接认为块内不可能存在晚于该时间的样本copy.go若块带no-compact标记且配置了--skip-no-compact-block-duration-check则跳过最小时长检查复制时全局标记文件也会一并复制copy.go复制单个块时会调整文件顺序把meta.json放到最后上传因为 Mimir 以 meta.json 作为块上传完成的信号copy.go。源码注释还指出一个边界情况copy 标记只考虑块 ID 与目标桶名若同一源租户的块被复制到同一目标内的多个租户标记可能冲突copy.go使用--user-mapping跨租户复制时需要留意。服务端复制与客户端复制默认情况下若源与目标使用同一个对象存储服务复制走服务端复制server-side copy数据不经过工具所在机器若两端属于不同对象存储服务或显式传入--client-side-copy则改为客户端复制client-side copy数据流经运行工具的主机。决策逻辑位于 pkg/util/objtools/bucket.go 的toCopyFuncif c.clientSideCopy || c.source.backend ! c.destination.backend { return source.ClientSideCopy(...) } return source.ServerSideCopy(...)各后端的实现说明S3服务端复制由目标桶发起s3.go因此目标桶的凭证需额外具备访问源桶的权限大于 5 GiB 的对象走ComposeObject多段复制源码注释提示该方式跨区域可能不可用s3.goGCS通过目标对象CopierFrom触发服务端复制gcs.goAzure跨容器复制时自动生成带 10 分钟有效期的只读 SAS URL 作为复制源并在复制后轮询 copy 状态直到成功/失败/中止abs.go。提示S3 场景下若不想为目标桶额外授权访问源桶直接传--client-side-copy即可规避。构建与获取mimirtool blocks copy是 mimirtool 的子命令。在 Mimir 仓库根目录执行go build ./cmd/mimirtool也可以直接使用 Mimir 官方 release 中预编译的mimirtool二进制。完整参数参考以下参数均在 copy.go 的registerFlags中定义并带有配置校验逻辑validatecopy.go参数默认值说明--source.backend/--destination.backend空后端类型可选s3、gcs、azure目标可为backfill--client-side-copyfalse强制使用客户端复制仅同后端时有效跨后端恒为客户端复制--min-block-duration0非零时忽略时长小于该值的块与--skip-no-compact-block-duration-check配合可定位等待压缩的块--min-time/--max-time空仅复制时间范围内的块格式为 RFC3339如--min-time 2026-01-15T00:00:00Z--tenant-concurrency5同时处理的租户数必须为正数--block-concurrency5每个租户同时复制的块数必须为正数--copy-period0周期执行间隔为 0 时执行一次即退出否则持续运行直到被终止--enabled-users空非空时仅复制这些用户的块--disabled-users空非空时跳过这些用户的块--user-mapping空逗号分隔的源用户:目标用户映射未映射的用户目标与源相同--dry-runfalse只记录将要复制的块不真正执行复制--skip-no-compact-block-duration-checkfalse对带 no-compact 标记的块跳过最小时长检查--clear-copy-markersfalse不复制而是删除源桶中的 copy 标记以允许重新复制同样尊重--enabled-users/--disabled-users--http-listen-address:8080指标 HTTP 监听地址暴露/metrics--backfill.*—回填目标相关配置见下文用户映射的解析在parseUserMappingcopy.go每个映射必须是源:目标二元组且两端均为合法租户 ID同一源用户不得重复映射。例如--user-mappinguser1:user2,user3:user4表示将user1的块复制为user2的块、user3的块复制为user4的块其余用户原样复制。各对象存储后端配置示例Google Cloud StorageGCSmimirtool blocks copy \ --source.backend gcs \ --destination.backend gcs \ --gcs.source.bucket-name source bucket name \ --gcs.destination.bucket-name destination bucket name \ --copy-period 24h \ --min-block-duration 13h \ --dry-runGCS 只需配置桶名--gcs.source|destination.bucket-name见 gcs.go认证走 Google 默认的应用默认凭据Application Default Credentialsstorage.NewClientgcs.go。Azure Blob StorageABSmimirtool blocks copy \ --source.backend azure \ --destination.backend azure \ --azure.source.container-name source container name \ --azure.source.account-name source account name \ --azure.source.account-key source account key \ --azure.destination.container-name destination container name \ --azure.destination.account-name destination account name \ --azure.destination.account-key destination account key \ --copy-period 24h \ --min-block-duration 13h \ --dry-runABS 使用 Shared Key Credential 认证container-name、account-name、account-key三者均必填校验见 abs.go。另可调--azure.source|destination.copy-status-backoff-min-duration默认 15s、--copy-status-backoff-max-duration默认 20s、--copy-status-backoff-max-retries默认 40控制服务端复制状态轮询的退避策略。Amazon Simple Storage ServiceS3mimirtool blocks copy \ --source.backend s3 \ --destination.backend s3 \ --s3.source.bucket-name source bucket name \ --s3.source.access-key-id source access key id \ --s3.source.secret-access-key source secret access key \ --s3.source.endpoint source endpoint \ --s3.destination.bucket-name destination bucket name \ --s3.destination.access-key-id destination access key id \ --s3.destination.secret-access-key destination secret access key \ --s3.destination.endpoint destination endpoint \ --copy-period 24h \ --min-block-duration 13h \ --dry-runS3 服务端复制由目标桶发起因此可能需要为目标桶配置额外的跨桶访问权限若不想处理授权直接加--client-side-copy。S3 相关可选参数见 s3.go--s3.source|destination.secure默认true使用 HTTPS设为false走 HTTP--s3.source|destination.part-size分片大小0时对象大小已知且适合多段上传则使用默认最小值 16 MiB。S3 凭证解析链若--s3.source|destination.access-key-id与--s3.source|destination.secret-access-key同时省略凭证从环境解析支持EKS 上的 IRSAIAM Roles for Service AccountsECS task roleEC2 instance metadata该场景下可以让一个同时拥有两个桶访问权限的 IAM Role 同时认证源与目标客户端无需传入静态凭证。底层凭证链定义在 s3.go依次尝试环境变量EnvAWS、凭证文件FileAWSCredentials、IAM 链。注意两者必须同时提供或同时省略否则校验报错s3.go。跨对象存储厂商复制源与目标分别按上述示例组合即可例如从 S3 复制到 ABSmimirtool blocks copy \ --source.backend s3 \ --destination.backend azure \ --s3.source.bucket-name source bucket name \ --s3.source.access-key-id source access key \ --s3.source.secret-access-key source secret access key \ --s3.source.endpoint source endpoint \ --azure.destination.container-name destination container name \ --azure.destination.account-name destination account name \ --azure.destination.account-key destination account key \ --copy-period 24h \ --min-block-duration 13h \ --dry-run跨厂商复制自动采用客户端复制toCopyFunc中后端不同即走客户端复制无需也不能依赖服务端复制。回填backfill到 Mimir 实例--destination.backend backfill通过 Mimir 的块上传 API/api/v1/upload/block/...把对象存储中的块上传到 Mimir常用于历史数据回填。示例mimirtool blocks copy \ --source.backend s3 \ --destination.backend backfill \ --s3.source.bucket-name source bucket name \ --s3.source.access-key-id source access key id \ --s3.source.secret-access-key source secret access key \ --s3.source.endpoint source endpoint \ --backfill.address Mimir address \ --backfill.id tenant id \ --backfill.key token used in basic auth \ --min-time 2026-01-15T00:00:00Z \ --max-time 2026-02-15T00:00:00Z \ --dry-run回填配置在backfillConfigcopy.go与 pkg/mimirtool/client/client.go 的RegisterConnectionFlagsWithPrefix中定义--backfill.addressMimir 实例地址必填--backfill.id租户 ID作为X-Scope-OrgID请求头必填且必须是合法租户 ID--backfill.keyBasic Auth 密码用户名为租户 ID--backfill.auth-tokenBearer Token 认证与--backfill.key最多只能设置一个--backfill.tls-*TLS 配置如--backfill.tls-ca-path、--backfill.tls-cert-path、--backfill.tls-key-path--backfill.sleep-time轮询块上传状态的间隔默认 20s。回填的完整上传流程见 pkg/mimirtool/client/backfill.go先读取源桶meta.json并补全thanos.files文件清单GetBlockMeta然后依次调用start→ 逐个上传块文件files?path...→finish→check轮询状态直到状态为complete目标返回 413/422 时判定为永久无效ErrBlockInvalid返回冲突则视为已存在ErrConflict。约束--user-mapping不能与 backfill 目标同时使用copy.go因为回填目标租户固定由--backfill.id指定校验逻辑会直接报错-user-mapping cannot be used with -destination.backendbackfill。运维实践周期运行、dry-run 与监控指标周期运行与停止--copy-period设为0默认执行一轮检查后退出适合一次性迁移--copy-period 24h之类的值持续运行按周期反复复制接收SIGINT/SIGTERM优雅退出copy.go。先 dry-run 再真正执行所有示例都带有--dry-run。先跑一遍确认would copy block日志符合预期再移除--dry-run执行真实复制是安全的上手流程。指标暴露工具启动内置 HTTP 服务默认:8080可用--http-listen-address修改/metrics暴露以下计数器定义见 copy.go指标含义cortex_blocks_copy_successful_cycles_total成功完成的复制周期数cortex_blocks_copy_failed_cycles_total失败的复制周期数cortex_blocks_copy_blocks_copied_total成功复制的块数cortex_blocks_copy_blocks_failed_total复制失败的块数cortex_blocks_copy_blocks_already_exist_total目标已存在而未复制的块数cortex_blocks_copy_blocks_invalid_total目标判定为永久无效的块数重新复制清理 copy 标记若需要让已复制的块可以被再次复制到同一目标使用--clear-copy-markers删除源桶中的对应标记支持--dry-run预览、--enabled-users/--disabled-users限定范围copy.go。清理完成后下次运行blocks copy会重新复制这些块。小结mimirtool blocks copy以 copy 标记机制保证了对象存储之间块复制的幂等性与可恢复性覆盖 S3、GCS、ABS 三大对象存储的同厂商服务端复制与跨厂商客户端复制并可通过 backfill 目标把历史块经块上传 API 导入 Mimir。实际使用建议先--dry-run校验范围再以小步--copy-period周期推进S3 场景视权限情况选择服务端复制或--client-side-copy跨租户复制使用--user-mapping但回填场景固定租户、不可映射。更多细节可继续阅读 docs/internal/tools/copyblocks.md 与核心实现 pkg/mimirtool/commands/blocks/copy/copy.go。赞分享时序数据库后端数据存储可观测性云原生【免费下载链接】mimirGrafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.项目地址https://gitcode.com/gh_mirrors/mimir/mimir点击查看免费下载相关推荐Grafana Mimir 运维实战用 mimirtool blocks mark 为 TSDB 数据块打删除/禁压缩标记Grafana Mimir 运维实战用 mimirtool blocks mark 为 TSDB 数据块打删除/禁压缩标记 mimirtool blocks时序数据库后端数据存储可观测性云原生Grafana Mimir 对象存储 Block 清单工具 listblocksmimirtool blocks list实战指南Grafana Mimir 对象存储 Block 清单工具 listblocksmimirtool blocks list实战指南 本指南系统讲解 Graf时序数据库后端数据存储可观测性云原生Grafana Mimir mimirtool blocks splitTSDB 块按时间跨度拆分完全指南Grafana Mimir mimirtool blocks splitTSDB 块按时间跨度拆分完全指南 导读 mimirtool blocks spl时序数据库后端数据存储可观测性云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考