br: --backupts accepts future timestamps without validation
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting your issue. Thanks!
### 1. Minimal reproduce step (Required)
```bash
# Using datetime format with a future timestamp
br backup full --pd "127.0.0.1:2379" --storage "local:///tmp/backup" --backupts "2099-12-31 23:59:59+0800"
# Or using a very large TSO-like number representing future time
br backup full --pd "127.0.0.1:2379" --storage "local:///tmp/backup" --backupts "999999999999999999"
```
### 2. What did you expect to see? (Required)
BR should reject the backup request with a clear error message:
```
Error: invalid backup timestamp: timestamp cannot be in the future (specified: 2099-12-31 23:59:59, current: 2026-02-14 15:30:00)
```
### 3. What did you see instead (Required)
BR accepts the future timestamp without validation. The backup operation proceeds without error, which is incorrect behavior because:
- Point-in-time backup should only work for past timestamps
- Future timestamps are semantically invalid for backup operations
- Users receive no feedback that they have provided an invalid parameter
### 4. What is your TiDB version? (Required)
**Affected versions:**
- TiDB v6.5.3
- Current master branch (commit: d7ce2f2faa)
### Root Cause Analysis
The validation logic has two gaps:
**1. In ParseTSString() function** (\`br/pkg/task/backup.go\` lines 789-814):
- Parses timestamp strings (both TSO and datetime formats)
- Converts to uint64 timestamp
- **Missing:** No check against current time
**2. In GetTS() function** (\`br/pkg/backup/client.go\` lines 458-497):
- Validates timestamp is not before GC safepoint (line 493)
- **Missing:** No check that timestamp is not in the future
### Code References
**Current validation (only checks GC safepoint):**
```go
// br/pkg/backup/client.go:492-496
// check backup time do not exceed GCSafePoint
err = gc.CheckGCSafePoint(ctx, bc.mgr.GetGCManager(), backupTS)
if err != nil {
return 0, errors.Trace(err)
}
```
**Flag definition:**
```go
// br/pkg/task/backup.go:119-120
flags.String(flagBackupTS, "", "the backup ts support TSO or datetime,"+
" e.g. '400036290571534337', '2018-05-11 01:42:23'")
```
### Proposed Solution
Add future timestamp validation in GetTS() function after the user-provided timestamp is set but before GC safepoint check:
**Location:** \`br/pkg/backup/client.go\` around line 470
```go
if ts > 0 {
backupTS = ts
// Validate timestamp is not in the future
p, l, err := bc.mgr.GetPDClient().GetTS(ctx)
if err != nil {
return 0, errors.Trace(err)
}
currentTS := oracle.ComposeTS(p, l)
if backupTS > currentTS {
return 0, errors.Annotatef(berrors.ErrInvalidArgument,
"backup timestamp cannot be in the future")
}
} else {
// ... existing code for getting current timestamp
}
```
### Related Issues
Part of tracking issue: #66279
Contributor guide
Assessment
This issue has not been assessed yet.