Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make objects deleted in the same branch that created them continue to show up in older commits (#997) #1000

Merged
merged 38 commits into from
Dec 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b43ebf8
SSTable interface for committed data
itaiad200 Nov 22, 2020
703c4b6
Remove unnecessary funcs from iterator
itaiad200 Nov 22, 2020
84bd269
added test for merge with zero changes
tzahij Nov 22, 2020
0a4d19b
initial commit of tree
tzahij Nov 22, 2020
d2fa10a
Change iterator to match the existing scanners interfaces
itaiad200 Nov 22, 2020
1ed15b2
Merge branch '945-sstable-tree-interfaces' of https://github.com/tree…
itaiad200 Nov 22, 2020
2bce373
initial commit of tree
tzahij Nov 22, 2020
71ac20f
initial commit of tree
tzahij Nov 22, 2020
8550a6d
initial commit for rocks catalog interface
guy-har Nov 23, 2020
d32c46c
sstable initial implementation without repo seperation
itaiad200 Nov 23, 2020
3b721d0
Merge remote-tracking branch 'origin/master' into 945-sstable-tree-in…
itaiad200 Nov 23, 2020
8931903
initial catalog interface
guy-har Nov 24, 2020
99bdab8
Merge branch 'master' into feature/rocks-catalog-interface
guy-har Nov 24, 2020
acca7d9
initial catalog interface
guy-har Nov 24, 2020
f711b30
Merge branch 'master' into feature/rocks-catalog-interface
guy-har Nov 24, 2020
9feb2fd
initial catalog interface
guy-har Nov 25, 2020
9505288
Update catalog/rocks/catalog.go
guy-har Nov 25, 2020
8eec272
iterator interface
nopcoder Nov 25, 2020
864c5c8
diff type comment
nopcoder Nov 25, 2020
19bfe19
Merge branch 'feature/rocks-catalog-interface' of github.com:treevers…
nopcoder Nov 25, 2020
0834c13
continue talking about StagingManager
nopcoder Nov 25, 2020
a5cad17
initial commit of tree
tzahij Nov 25, 2020
238838a
Merge branch 'master' into 945-sstable-tree-interfaces
tzahij Nov 26, 2020
3162279
Merge branch 'feature/rocks-catalog-interface' into 945-sstable-tree-…
tzahij Nov 26, 2020
6da61db
just save changes - initial
tzahij Nov 26, 2020
36df291
working on apply
tzahij Nov 27, 2020
9768b34
working on apply
tzahij Nov 28, 2020
d30d1d5
working on apply
tzahij Nov 28, 2020
8ff22f1
Merge remote-tracking branch 'origin/master' into 945-sstable-interface
itaiad200 Nov 29, 2020
e486488
sstable interface
itaiad200 Nov 29, 2020
ab24d5b
changes
itaiad200 Nov 29, 2020
1cb8a36
Merge pull request #969 from treeverse/945-sstable-interface
tzahij Nov 29, 2020
a773731
Merge remote-tracking branch 'origin/master'
tzahij Dec 1, 2020
12c1e04
Merge remote-tracking branch 'origin/master'
tzahij Dec 4, 2020
6c4b572
fix to entry disappearing from a commit listing when it was deleted i…
tzahij Dec 5, 2020
71a41d3
Update catalog/mvcc/cataloger_delete_entry_test.go
tzahij Dec 5, 2020
b40208a
compare with get entry with catalog entry not found
nopcoder Dec 5, 2020
db47811
changes after review
tzahij Dec 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions catalog/mvcc/cataloger_delete_entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"errors"
tzahij marked this conversation as resolved.
Show resolved Hide resolved
"testing"

"github.com/treeverse/lakefs/testutil"

"github.com/treeverse/lakefs/catalog"
"github.com/treeverse/lakefs/db"
)
Expand Down Expand Up @@ -120,3 +122,94 @@ func testDeleteEntryCommitAndExpectNotFound(t *testing.T, ctx context.Context, c
t.Fatalf("DeleteEntry() get entry err = %s, want = %s", err, wantErr)
}
}

func TestCataloger_DeleteEntryAndCheckItRemainsInCommits(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think you can leave the second test as it cover this one - but it is just me ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous test is somewhat different, and it covers list by prefix (where a separate bug was fixed)

ctx := context.Background()
c := testCataloger(t)
repository := testCatalogerRepo(t, ctx, c, "repository", "master")
if err := c.CreateEntry(ctx, repository, "master", catalog.Entry{
Path: "/file2",
Checksum: "ff",
PhysicalAddress: "/addr2",
Size: 2,
Metadata: nil,
}, catalog.CreateEntryParams{}); err != nil {
t.Fatal("create entry for delete entry test:", err)
}
prevCommit, err := c.Commit(ctx, repository, "master", "commit before deletion test failed ", "tester", nil)
if err != nil {
t.Fatal("Failed to commit before expect not found:", err)
}
entry, err := c.GetEntry(ctx, repository, prevCommit.Reference, "/file2", catalog.GetEntryParams{})
_ = entry
err = c.DeleteEntry(ctx, repository, "master", "/file2")
if err != nil {
t.Fatal("delete failed: ", err)
}
nextCommit, err := c.Commit(ctx, repository, "master", "commit after deletion ", "tester", nil)
if err != nil {
t.Fatal("Failed to commit after delete:", err)
}
entry, err = c.GetEntry(ctx, repository, nextCommit.Reference, "/file2", catalog.GetEntryParams{})
entry, err = c.GetEntry(ctx, repository, prevCommit.Reference, "/file2", catalog.GetEntryParams{})
list, _, err := c.ListEntries(ctx, repository, nextCommit.Reference, "", "", "", 1000)
if len(list) != 0 {
t.Fatal("list entries returned deleted object")
}
list, _, err = c.ListEntries(ctx, repository, prevCommit.Reference, "", "", "", 1000)
if len(list) != 1 {
t.Fatal("list entries by commitID did not return deleted object from next commit")
}
list, _, err = c.ListEntries(ctx, repository, nextCommit.Reference, "", "", "/", 1000)
if len(list) != 0 {
t.Fatal("list entries by prefix returned deleted object")
}
list, _, err = c.ListEntries(ctx, repository, prevCommit.Reference, "", "", "/", 1000)
if len(list) != 1 {
t.Fatal("list entries by prefix on commitID did not return deleted object from next commit")
}
}

func TestCataloger_DeleteEntryVerifyExisting(t *testing.T) {
ctx := context.Background()
c := testCataloger(t)
repository := testCatalogerRepo(t, ctx, c, "repository", "master")

testCatalogerCreateEntry(t, ctx, c, repository, "master", "file1", nil, "")
commit1, err := c.Commit(ctx, repository, "master", "add file1", "committer", nil)
testutil.MustDo(t, "commit add file1", err)

_, err = c.CreateBranch(ctx, repository, "branch1", "master")
testutil.MustDo(t, "create branch1", err)

err = c.DeleteEntry(ctx, repository, "master", "file1")
testutil.MustDo(t, "delete file1", err)

_, err = c.Commit(ctx, repository, "master", "delete file1", "committer", nil)
testutil.MustDo(t, "commit delete file1", err)

// check file exists using reference, branch and listing
_, err = c.GetEntry(ctx, repository, commit1.Reference, "file1", catalog.GetEntryParams{})
testutil.MustDo(t, "get file1 by ref", err)

_, err = c.GetEntry(ctx, repository, "branch1", "file1", catalog.GetEntryParams{})
testutil.MustDo(t, "get file1 by branch", err)

entriesRef, _, err := c.ListEntries(ctx, repository, commit1.Reference, "", "", "", -1)
testutil.MustDo(t, "list using ref", err)
if len(entriesRef) != 1 {
t.Error("ListEntries of ref before delete should include a file")
}

entriesBranch, _, err := c.ListEntries(ctx, repository, "branch1", "", "", "", -1)
testutil.MustDo(t, "list using branch1", err)
if len(entriesBranch) != 1 {
t.Error("ListEntries of branch before delete should include a file")
}

// check the file is deleted on master
_, err = c.GetEntry(ctx, repository, "master", "file1", catalog.GetEntryParams{})
if !errors.Is(err, catalog.ErrEntryNotFound) {
t.Error("GetEntry should return not found on master branch:", err)
}
}
16 changes: 5 additions & 11 deletions catalog/mvcc/cataloger_list_entries.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,30 +286,24 @@ func findLowestResultInBranches(branchRanges map[int64][]entryPathPrefixInfo, br
func buildBaseLevelQuery(baseBranchID int64, lineage []lineageCommit, branchEntryLimit int,
topCommitID CommitID, prefixLen int, endOfPrefixRange string) map[int64]sq.SelectBuilder {
unionMap := make(map[int64]sq.SelectBuilder)
unionMap[baseBranchID] = selectSingleBranch(baseBranchID, true, branchEntryLimit, topCommitID, prefixLen, endOfPrefixRange)
unionMap[baseBranchID] = buildSingleBranchQuery(baseBranchID, branchEntryLimit, topCommitID, prefixLen, endOfPrefixRange)
for _, l := range lineage {
unionMap[l.BranchID] = selectSingleBranch(l.BranchID, false, branchEntryLimit, l.CommitID, prefixLen, endOfPrefixRange)
unionMap[l.BranchID] = buildSingleBranchQuery(l.BranchID, branchEntryLimit, l.CommitID, prefixLen, endOfPrefixRange)
}
return unionMap
}

func selectSingleBranch(branchID int64, isBaseBranch bool, branchBatchSize int, topCommitID CommitID, prefixLen int, endOfPrefixRange string) sq.SelectBuilder {
rawSelect := sq.Select("branch_id", "min_commit").
func buildSingleBranchQuery(branchID int64, branchBatchSize int, topCommitID CommitID, prefixLen int, endOfPrefixRange string) sq.SelectBuilder {
query := sq.Select("branch_id", "min_commit").
Distinct().Options(" ON (branch_id,path)").
Column("substr(path,?) as path_suffix", prefixLen+1).
Column("CASE WHEN max_commit >= ? THEN ? ELSE max_commit END AS max_commit", topCommitID, MaxCommitID).
From("catalog_entries").
Where("branch_id = ?", branchID).
Where("min_commit <= ?", topCommitID).
Where("path < ?", endOfPrefixRange).
OrderBy("branch_id", "path", "min_commit desc").
Limit(uint64(branchBatchSize))
var query sq.SelectBuilder
if isBaseBranch {
query = rawSelect.Column("max_commit")
} else {
query = rawSelect.
Column("CASE WHEN max_commit >= ? THEN ? ELSE max_commit END AS max_commit", topCommitID, MaxCommitID)
}
return query
}

Expand Down
17 changes: 11 additions & 6 deletions catalog/mvcc/views.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package mvcc

import (
"fmt"
"strconv"
"unicode/utf8"

Expand All @@ -14,11 +13,17 @@ const (
)

func sqEntriesV(requestedCommit CommitID) sq.SelectBuilder {
entriesQ := sq.Select("*",
fmt.Sprintf("min_commit != %d AS is_committed", MinCommitUncommittedIndicator),
"max_commit = 0 AS is_tombstone",
"ctid AS entry_ctid\n",
fmt.Sprintf("max_commit < %d AS is_deleted", MaxCommitID)).
var actualCommit CommitID
if requestedCommit == UncommittedID || requestedCommit == CommittedID {
actualCommit = MaxCommitID
} else {
actualCommit = requestedCommit
}
entriesQ := sq.Select("*").
Column("min_commit != ? AS is_committed", MinCommitUncommittedIndicator).
Column("max_commit = 0 AS is_tombstone").
Column("ctid AS entry_ctid\n").
Column("max_commit < ? AS is_deleted", actualCommit).
From("catalog_entries")
switch requestedCommit {
case UncommittedID: // no further filtering is required
Expand Down