tidb-br-备份报错

一、背景

早晨收到了 TiDB 的备份报警,本质原因是因为我们的存储设置了单文件上传 100 M的限制

[2025/11/05 06:28:58.977 +08:00] [INFO] [collector.go:78] ["Full Backup failed summary"] [total-ranges=0] [ranges-succeed=0] [ranges-failed=0] [backup-total-ranges=533]
[2025/11/05 06:28:58.977 +08:00] [ERROR] [backup.go:54] ["failed to backup"] [error="EntityTooLarge: 参数“Content-Length=133570547”无效,有效值为:[0,100MB]\n\tstatus code: 400, request id: , host id: "] [errorVerbose="EntityTooLarge: 参数“Content-Length=133570547”无效,有效值为:[0,100MB]\n\tstatus code: 400, request id: , host id: \ngithub.com/pingcap/errors.AddStack\n\t/root/go/pkg/mod/github.com/pingcap/errors@v0.11.5-0.20240318064555-6bd07397691f/errors.go:178\ngithub.com/pingcap/errors.Trace\n\t/root/go/pkg/mod/github.com/pingcap/errors@v0.11.5-0.20240318064555-6bd07397691f/juju_adaptor.go:15\ngithub.com/pingcap/tidb/br/pkg/storage.(*S3Storage).WriteFile\n\t/workspace/source/tidb/br/pkg/storage/s3.go:561\ngithub.com/pingcap/tidb/br/pkg/metautil.(*MetaWriter).flushMetasV2\n\t/workspace/source/tidb/br/pkg/metautil/metafile.go:772\ngithub.com/pingcap/tidb/br/pkg/metautil.(*MetaWriter).FinishWriteMetas\n\t/workspace/source/tidb/br/pkg/metautil/metafile.go:664\ngithub.com/pingcap/tidb/br/pkg/task.RunBackup\n\t/workspace/source/tidb/br/pkg/task/backup.go:712\nmain.runBackupCommand\n\t/workspace/source/tidb/br/cmd/br/backup.go:53\nmain.newFullBackupCommand.func1\n\t/workspace/source/tidb/br/cmd/br/backup.go:143\ngithub.com/spf13/cobra.(*Command).execute\n\t/root/go/pkg/mod/github.com/spf13/cobra@v1.7.0/command.go:940\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\t/root/go/pkg/mod/github.com/spf13/cobra@v1.7.0/command.go:1068\ngithub.com/spf13/cobra.(*Command).Execute\n\t/root/go/pkg/mod/github.com/spf13/cobra@v1.7.0/command.go:992\nmain.main\n\t/workspace/source/tidb/br/cmd/br/main.go:58\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:267\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1650"] [stack="main.runBackupCommand\n\t/workspace/source/tidb/br/cmd/br/backup.go:54\nmain.newFullBackupCommand.func1\n\t/workspace/source/tidb/br/cmd/br/backup.go:143\ngithub.com/spf13/cobra.(*Command).execute\n\t/root/go/pkg/mod/github.com/spf13/cobra@v1.7.0/command.go:940\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\t/root/go/pkg/mod/github.com/spf13/cobra@v1.7.0/command.go:1068\ngithub.com/spf13/cobra.(*Command).Execute\n\t/root/go/pkg/mod/github.com/spf13/cobra@v1.7.0/command.go:992\nmain.main\n\t/workspace/source/tidb/br/cmd/br/main.go:58\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:267"]

二、解决办法

共有两种解决办法,元数据超过100M采用方法1,详细pr,数据超过100M采用方法2

1.更改元数据切分大小

1.1 报错原因

观测了几次备份的文件,发现在最近一次成功备份的 backupmeta.datafile.000000001 文件已经到了99.5M了,所以下一次备份出现了失败的情况,查看github源码发现,metafilesize 默认是128M 大小才会自动切分,详细代码见 github

 // MetaFileSize represents the limit size of one MetaFile
    MetaFileSize = 128 * units.MiB

1.2 准备 docker 环境

# Ubuntu/Debian 系统
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vi /etc/systemd/system/docker.service.d/proxy.conf
[Service]
# 代理服务器地址(HTTP 或 HTTPS)
Environment="HTTP_PROXY=http://代理IP:端口"
Environment="HTTPS_PROXY=http://代理IP:端口"
# 不需要代理的地址(可选,如内网仓库)
Environment="NO_PROXY=localhost,127.0.0.1,192.168.0.0/16,.example.com"
# 重新加载系统服务配置
sudo systemctl daemon-reload
# 重启 Docker 服务
sudo systemctl restart docker
sudo systemctl show --property=Environment docker

1.3 准备 linux 环境并重新编译

# 拉取镜像
docker pull centos:7

# 启动交互式容器
docker run -it --name centos7 centos:7 /bin/bash

# 安装编译包
yum install -y gcc make wget tar

# 拉取代码
git clone https://github.com/pingcap/tidb.git --branch v7.5.4

# 安装go环境
wget https://mirrors.aliyun.com/golang/go1.24.7.linux-amd64.tar.gz
tar zxf go1.24.7.linux-amd64.tar.gz
mv go /usr/local
export PATH=$PATH:/usr/local/go/bin
go version

# 修改br代码
vim /tidb/br/pkg/metautil/metafile.go
# 把 MetaFileSize 由 128 变成 64
# MetaFileSize = 128 * units.MiB -> MetaFileSize = 64 * units.MiB

# 编译br可执行文件
cd /tidb
make build_br

1.4 替换原本 br 二进制文件

替换后即可正常使用

2.取消限速

2.1 报错原因

观察源码发现,v7.5.4 中硬编码了分块上传的块大小为 5M,但是这个 5M 只有在 option.Concurrency > 1 的情况才起作用,而ratelimit 与 option.Concurrency 是互斥的,只要设置了 ratelimit 就是单线程备份,所以这个5M的分块无法限制,详细代码见 github
在这里插入图片描述

var hardcodedS3ChunkSize = 5 * 1024 * 1024

// S3Uploader does multi-part upload to s3.
type S3Uploader struct {
    svc           s3iface.S3API
    createOutput  *s3.CreateMultipartUploadOutput
    completeParts []*s3.CompletedPart
}

// Create creates multi upload request.
func (rs *S3Storage) Create(ctx context.Context, name string, option *WriterOption) (ExternalFileWriter, error) {
    var uploader ExternalFileWriter
    var err error
    if option == nil || option.Concurrency <= 1 {
        uploader, err = rs.createUploader(ctx, name)
        if err != nil {
            return nil, err
        }
    } else {
     // NewUploaderWithClient:https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#NewUploaderWithClient
        up := s3manager.NewUploaderWithClient(rs.svc, func(u *s3manager.Uploader) {
            u.Concurrency = option.Concurrency
            u.BufferProvider = s3manager.NewBufferedReadSeekerWriteToPool(option.Concurrency * hardcodedS3ChunkSize)
        })
        // ......
    return uploaderWriter, nil
}

// createUploader create multi upload request.
func (rs *S3Storage) createUploader(ctx context.Context, name string) (ExternalFileWriter, error) {
// ......
}

2.2 处理方式

备份时取消 --ratelimit 参数,指定 --concurrency

三、排查思路

1.修改 sst-max-size 参数

首先考虑到的是备份的 sst 文件超过了限制,所以选择调低 sst-max-size 参数,参数解释见官方文档

2.深度排查

将 sst-max-size 调低到 96M,80M 后备份依旧报错,于是决定深入排查

2.1 查看sst文件大小

通过排查发现确实会存在大于 100M 的 sst 文件

find ./ -type f -size +100M -exec ls -lh {} \;

-rw-r--r-- 1 tidb netease 105M Oct 25 00:36 ./23015469.sst
-rw-r--r-- 1 tidb netease 113M Oct 22 19:16 ./22657455.sst
-rw-r--r-- 1 tidb netease 127M Oct 23 08:33 ./22773838.sst
-rw-r--r-- 1 tidb netease 104M Oct 22 22:45 ./22697994.sst

2.2 排查历史备份数据文件大小

经过排查发现历史备份的数据文件大小最大为 85 M ,没有超过 100 M 的情况,所以更改 sst-max-size 参数不起作用,因为数据文件本身就没有超限制

/usr/bin/s3cmd ls   s3://backup-data/2025-10-19/363653751/ > tmp_bak.txt

cat tmp_bak.txt|awk -F ' ' '{print $3}'|sort -nr|head -10

2.3 排查历史备份元数据大小

观测了几次备份的文件,发现在 25 号的时候 meta 文件已经到了 99.5 M 了,所以下一次备份出现了失败的情况,基于此了解到真正触发报错是在备份 meta 文件的时候,所以才有了上面的解决办法

2025-08-18 23:35     87588691  s3://backup-data/2025-08-18/backupmeta.datafile.000000001
2025-10-19 22:44    102792275  s3://backup-data/2025-10-19/backupmeta.datafile.000000001
2025-10-22 22:45    103305170  s3://backup-data/2025-10-22/backupmeta.datafile.000000001
2025-10-25 22:47    104377670  s3://backup-data/2025-10-25/backupmeta.datafile.000000001
内容概要:本文介绍了基于贝叶斯优化的CNN-LSTM混合神经网络在时间序列预测中的应用,并提供了完整的Matlab代码实现。该模型结合了卷积神经网络(CNN)在特征提取方面的优势与长短期记忆网络(LSTM)在处理时序依赖问题上的强大能力,形成一种高效的混合预测架构。通过贝叶斯优化算法自动调参,提升了模型的预测精度与泛化能力,适用于风电、光伏、负荷、交通流等多种复杂非线性系统的预测任务。文中还展示了模型训练流程、参数优化机制及实际预测效果分析,突出其在科研与工程应用中的实用性。; 适合人群:具备一定机器学习基基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)础和Matlab编程经验的高校研究生、科研人员及从事预测建模的工程技术人员,尤其适合关注深度学习与智能优化算法结合应用的研究者。; 使用场景及目标:①解决各类时间序列预测问题,如能源出力预测、电力负荷预测、环境数据预测等;②学习如何将CNN-LSTM模型与贝叶斯优化相结合,提升模型性能;③掌握Matlab环境下深度学习模型搭建与超参数自动优化的技术路线。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注贝叶斯优化模块与混合神经网络结构的设计逻辑,通过调整数据集和参数加深对模型工作机制的理解,同时可将其框架迁移至其他预测场景中验证效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值