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

Show documents that might be around after N1QL emptying fails #6624

Merged
merged 4 commits into from
Jan 2, 2024
Merged
Changes from all commits
Commits
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
42 changes: 30 additions & 12 deletions db/util_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,34 @@ func WaitForPrimaryIndexEmpty(ctx context.Context, store base.N1QLStore) error {
retryWorker,
base.CreateMaxDoublingSleeperFunc(60, 500, 5000),
)
var retryError *base.RetryTimeoutError
if errors.As(err, &retryError) {
documents, err := getPrimaryIndexDocuments(ctx, store, true)
if err != nil {
return fmt.Errorf("Error getting documents from primary index: %w", err)
}
return fmt.Errorf("Documents left behind after waiting for primary index to be emptied: %s", documents)
}
return err

}

// isPrimaryIndexEmpty returs true if there are no documents in the primary index
// isPrimaryIndexEmpty returns true if there are no documents in the primary index
func isPrimaryIndexEmpty(ctx context.Context, store base.N1QLStore) (bool, error) {
// only look for a single doc to make query faster
docs, err := getPrimaryIndexDocuments(ctx, store, false)
if err != nil {
return false, err
}
return len(docs) == 0, err
}

// getPrimaryIndexDocuments returs true if there are no documents in the primary index and returns the documents. If allDocuments is false, only check for a single document.
func getPrimaryIndexDocuments(ctx context.Context, store base.N1QLStore, allDocuments bool) ([]string, error) {
// Create the star channel query
statement := fmt.Sprintf("SELECT * FROM %s LIMIT 1", base.KeyspaceQueryToken)
statement := fmt.Sprintf("SELECT META().id FROM %s", base.KeyspaceQueryToken)
if !allDocuments {
statement += " LIMIT 1"
}
params := map[string]interface{}{}
params[QueryParamStartSeq] = 0
params[QueryParamEndSeq] = N1QLMaxInt64
Expand All @@ -62,18 +82,16 @@ func isPrimaryIndexEmpty(ctx context.Context, store base.N1QLStore) (bool, error
// If there was an error, then retry. Assume it's an "index rollback" error which happens as
// the index processes the bucket flush operation
if err != nil {
return false, err
return nil, err
}

// If it's empty, we're done
var queryRow map[string]interface{}
found := results.Next(ctx, &queryRow)
resultsCloseErr := results.Close()
if resultsCloseErr != nil {
return false, err
var documents []string
var queryRow map[string]string
for results.Next(ctx, &queryRow) {
documents = append(documents, queryRow["id"])
}

return !found, nil
err = results.Close()
return documents, err
}

func (db *DatabaseContext) CacheCompactActive() bool {
Expand Down