Skip to content

Commit 97659d8

Browse files
author
Bogdan Tsechoev
committed
Merge branch '605-physical-mode-snapshot-retention' into 'dle-4-0'
fix: busy system snapshot detection in physical mode (#605) See merge request postgres-ai/database-lab!1008
2 parents 5fa6b71 + c71121f commit 97659d8

File tree

2 files changed

+43
-45
lines changed

2 files changed

+43
-45
lines changed

Diff for: engine/internal/provision/thinclones/zfs/zfs.go

+17-24
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ func (m *Manager) CleanupSnapshots(retentionLimit int) ([]string, error) {
508508
busySnapshots := m.getBusySnapshotList(clonesOutput)
509509

510510
cleanupCmd := fmt.Sprintf(
511-
"zfs list -t snapshot -H -o name -s %s -s creation -r %s | grep -v clone | head -n -%d %s"+
511+
"zfs list -t snapshot -H -o name -s %s -s creation -r %s | grep -v clone | grep _pre$ | head -n -%d %s"+
512512
"| xargs -n1 --no-run-if-empty zfs destroy -R ",
513513
dataStateAtLabel, m.config.Pool.Name, retentionLimit, excludeBusySnapshots(busySnapshots))
514514

@@ -527,10 +527,10 @@ func (m *Manager) CleanupSnapshots(retentionLimit int) ([]string, error) {
527527
}
528528

529529
func (m *Manager) getBusySnapshotList(clonesOutput string) []string {
530-
systemClones, userClones := make(map[string]string), make(map[string]struct{})
531-
branchingSnapshots := []string{}
530+
systemClones := make(map[string]string)
531+
branchingSnapshotDatasets := []string{}
532532

533-
userClonePrefix := m.config.Pool.Name + "/"
533+
systemDatasetPrefix := fmt.Sprintf("%s/%s/%s/clone_pre_", m.config.Pool.Name, branching.BranchDir, branching.DefaultBranch)
534534

535535
for _, line := range strings.Split(clonesOutput, "\n") {
536536
cloneLine := strings.FieldsFunc(line, unicode.IsSpace)
@@ -539,39 +539,32 @@ func (m *Manager) getBusySnapshotList(clonesOutput string) []string {
539539
continue
540540
}
541541

542-
// Keep the user-defined snapshot and the snapshot it is based on.
543-
if strings.HasPrefix(cloneLine[0], userClonePrefix+"branch") {
544-
branchingSnapshots = append(branchingSnapshots, cloneLine[0], cloneLine[1])
545-
542+
// Make dataset-snapshot map for system snapshots.
543+
if strings.HasPrefix(cloneLine[0], systemDatasetPrefix) {
544+
systemClones[cloneLine[0]] = cloneLine[1]
546545
continue
547546
}
548547

549-
//nolint:lll
550-
if cloneName, _ := strings.CutPrefix(cloneLine[0], userClonePrefix); strings.HasPrefix(cloneLine[0], userClonePrefix) && !strings.Contains(cloneName, m.config.PreSnapshotSuffix) {
551-
origin := cloneLine[1]
552-
553-
if idx := strings.Index(origin, "@"); idx != -1 {
554-
origin = origin[:idx]
548+
// Keep snapshots related to the user-defined datasets.
549+
if strings.HasPrefix(cloneLine[1], systemDatasetPrefix) {
550+
systemDataset, _, found := strings.Cut(cloneLine[1], "@")
551+
if found {
552+
branchingSnapshotDatasets = append(branchingSnapshotDatasets, systemDataset)
555553
}
556554

557-
userClones[origin] = struct{}{}
558-
559555
continue
560556
}
561-
562-
systemClones[cloneLine[0]] = cloneLine[1]
563557
}
564558

565-
busySnapshots := make([]string, 0, len(userClones))
559+
busySnapshots := make([]string, 0, len(branchingSnapshotDatasets))
566560

567-
for userClone := range userClones {
568-
if systemClones[userClone] != "" {
569-
busySnapshots = append(busySnapshots, systemClones[userClone])
561+
for _, busyDataset := range branchingSnapshotDatasets {
562+
busySnapshot, ok := systemClones[busyDataset]
563+
if ok {
564+
busySnapshots = append(busySnapshots, busySnapshot)
570565
}
571566
}
572567

573-
busySnapshots = append(busySnapshots, branchingSnapshots...)
574-
575568
return busySnapshots
576569
}
577570

Diff for: engine/internal/provision/thinclones/zfs/zfs_test.go

+26-21
Original file line numberDiff line numberDiff line change
@@ -116,29 +116,34 @@ func TestFailedListClones(t *testing.T) {
116116

117117
func TestBusySnapshotList(t *testing.T) {
118118
const preSnapshotSuffix = "_pre"
119-
m := Manager{config: Config{Pool: &resources.Pool{Name: "dblab_pool"}, PreSnapshotSuffix: preSnapshotSuffix}}
120-
121-
out := `dblab_pool -
122-
dblab_pool/clone_pre_20210127105215 dblab_pool@snapshot_20210127105215_pre
123-
dblab_pool/clone_pre_20210127113000 dblab_pool@snapshot_20210127113000_pre
124-
dblab_pool/clone_pre_20210127120000 dblab_pool@snapshot_20210127120000_pre
125-
dblab_pool/clone_pre_20210127123000 dblab_pool@snapshot_20210127123000_pre
126-
dblab_pool/clone_pre_20210127130000 dblab_pool@snapshot_20210127130000_pre
127-
dblab_pool/clone_pre_20210127133000 dblab_pool@snapshot_20210127133000_pre
128-
dblab_pool/clone_pre_20210127140000 dblab_pool@snapshot_20210127140000_pre
129-
dblab_pool/cls19p20l4rc73bc2v9g dblab_pool/clone_pre_20210127133000@snapshot_20210127133008
130-
dblab_pool/cls19p20l4rc73bc2v9g dblab_pool/clone_pre_20210127123000@snapshot_20210127133008
131-
dblab_pool/branch/main/20241121094823 dblab_pool@snapshot_20241121094523
132-
`
133-
expected := []string{"dblab_pool@snapshot_20210127133000_pre", "dblab_pool@snapshot_20210127123000_pre", "dblab_pool/branch/main/20241121094823",
134-
"dblab_pool@snapshot_20241121094523"}
119+
m := Manager{config: Config{Pool: &resources.Pool{Name: "test_dblab_pool"}, PreSnapshotSuffix: preSnapshotSuffix}}
120+
121+
out := `test_dblab_pool -
122+
test_dblab_pool/branch -
123+
test_dblab_pool/branch/main -
124+
test_dblab_pool/branch/main/clone_pre_20250403061908 -
125+
test_dblab_pool/branch/main/clone_pre_20250403061908/r0 test_dblab_pool@snapshot_20250403061908_pre
126+
test_dblab_pool/branch/main/clone_pre_20250403085500 -
127+
test_dblab_pool/branch/main/clone_pre_20250403085500/r0 test_dblab_pool@snapshot_20250403085500_pre
128+
test_dblab_pool/branch/main/clone_pre_20250403090000 -
129+
test_dblab_pool/branch/main/clone_pre_20250403090000/r0 test_dblab_pool@snapshot_20250403090000_pre
130+
test_dblab_pool/branch/main/clone_pre_20250403090500 -
131+
test_dblab_pool/branch/main/clone_pre_20250403090500/r0 test_dblab_pool@snapshot_20250403090500_pre
132+
test_dblab_pool/branch/main/cvn2j50n9i6s73as3k9g -
133+
test_dblab_pool/branch/main/cvn2j50n9i6s73as3k9g/r0 test_dblab_pool/branch/main/clone_pre_20250403061908/r0@snapshot_20250403061908
134+
test_dblab_pool/branch/main/cvn2kdon9i6s73as3ka0 -
135+
test_dblab_pool/branch/main/cvn2kdon9i6s73as3ka0/r0 test_dblab_pool/branch/new001@20250403062641
136+
test_dblab_pool/branch/new001 test_dblab_pool/branch/main/cvn2j50n9i6s73as3k9g/r0@20250403062503
137+
test_dblab_pool/branch/new001/cvn4n38n9i6s73as3kag -
138+
test_dblab_pool/branch/new001/cvn4n38n9i6s73as3kag/r0 test_dblab_pool/branch/new001@20250403062641
139+
`
140+
expected := []string{
141+
"test_dblab_pool@snapshot_20250403061908_pre",
142+
}
135143

136144
list := m.getBusySnapshotList(out)
137-
require.Equal(t, 4, len(list))
138-
assert.Contains(t, list, expected[0])
139-
assert.Contains(t, list, expected[1])
140-
assert.Contains(t, list, expected[2])
141-
assert.Contains(t, list, expected[3])
145+
require.Len(t, list, len(expected))
146+
assert.ElementsMatch(t, list, expected)
142147
}
143148

144149
func TestExcludingBusySnapshots(t *testing.T) {

0 commit comments

Comments
 (0)