MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / InitializeIndexes

Function InitializeIndexes

db/indexes.go:395–466  ·  view source on GitHub ↗

Initializes Sync Gateway indexes for datastore. Creates required indexes if not found, then waits for index readiness.

(ctx context.Context, n1QLStore base.N1QLStore, options InitializeIndexOptions)

Source from the content-addressed store, hash-verified

393
394// Initializes Sync Gateway indexes for datastore. Creates required indexes if not found, then waits for index readiness.
395func InitializeIndexes(ctx context.Context, n1QLStore base.N1QLStore, options InitializeIndexOptions) error {
396 if options.NumPartitions < 1 {
397 return fmt.Errorf("Invalid number of partitions specified: %d, needs to be greater than 0", options.NumPartitions)
398 }
399
400 requiredIndexes := make(sgIndexesToBuild, 0, len(sgIndexes))
401 for _, sgIndex := range sgIndexes {
402 if !sgIndex.shouldCreate(options) {
403 base.DebugfCtx(ctx, base.KeyAll, "Skipping index: %s ...", sgIndex.simpleName)
404 continue
405 }
406 fullIndexName := sgIndex.fullIndexName(options.UseXattrs, options.NumPartitions)
407 requiredIndexes = append(requiredIndexes, sgIndexToBuild{fullIndexName: fullIndexName, sgIndex: sgIndex})
408 }
409
410 if len(requiredIndexes) == 0 {
411 // not expected to get here - all our collections require at least one index ...
412 base.AssertfCtx(ctx, "No indexes to create - expected at least one index to be created, but none were found")
413 return nil
414 }
415
416 indexesMeta, err := base.GetIndexesMeta(ctx, n1QLStore, requiredIndexes.FullIndexNames())
417 if err != nil {
418 base.WarnfCtx(ctx, "Error getting indexes meta: %v - continuing to create", err)
419 }
420
421 // Happy-path optimization (for each collection):
422 // Drop indexes from the list if they're already online to avoid any per-index init cost.
423 requiredIndexes = slices.DeleteFunc(requiredIndexes, func(idx sgIndexToBuild) bool {
424 meta, exists := indexesMeta[idx.fullIndexName]
425 if exists && meta.State == base.IndexStateOnline {
426 base.DebugfCtx(ctx, base.KeyAll, "Index %s is already online", idx.fullIndexName)
427 // remove from list of indexes to create/wait for
428 return true
429 }
430 return false
431 })
432
433 if len(requiredIndexes) == 0 {
434 // all indexes are already online so we can return early without any per-index queries
435 base.InfofCtx(ctx, base.KeyAll, "Indexes ready - already online when checked")
436 return nil
437 }
438
439 base.InfofCtx(ctx, base.KeyAll, "Initializing %d indexes with numReplicas: %d...", len(requiredIndexes), options.NumReplicas)
440
441 for _, idx := range requiredIndexes {
442 err := idx.sgIndex.createIfNeeded(ctx, n1QLStore, options)
443 if err != nil {
444 if !errors.Is(err, base.ErrIndexBackgroundRetry) {
445 return base.RedactErrorf("Unable to install index %s: %v", base.MD(idx.sgIndex.simpleName), err)
446 }
447 }
448 }
449
450 fullIndexNames := requiredIndexes.FullIndexNames()
451 // Issue BUILD INDEX for any deferred indexes.
452 buildErr := base.BuildDeferredIndexes(ctx, n1QLStore, fullIndexNames)

Callers 7

RunMethod · 0.92
TestPostUpgradeFunction · 0.92
TestInitializeIndexesFunction · 0.92
util_testing.goFile · 0.85

Calls 14

DebugfCtxFunction · 0.92
AssertfCtxFunction · 0.92
GetIndexesMetaFunction · 0.92
WarnfCtxFunction · 0.92
InfofCtxFunction · 0.92
RedactErrorfFunction · 0.92
MDFunction · 0.92
BuildDeferredIndexesFunction · 0.92
ErrorfMethod · 0.80
shouldCreateMethod · 0.80
fullIndexNameMethod · 0.80
FullIndexNamesMethod · 0.80

Tested by 3

TestPostUpgradeFunction · 0.74
TestInitializeIndexesFunction · 0.74