一、背景
早晨收到了 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
1155

被折叠的 条评论
为什么被折叠?



