MCPcopy Create free account
hub / github.com/cortexproject/cortex / shipBlocks

Method shipBlocks

pkg/ingester/ingester.go:3172–3254  ·  view source on GitHub ↗

shipBlocks runs shipping for all users.

(ctx context.Context, allowed *users.AllowedTenants)

Source from the content-addressed store, hash-verified

3170
3171// shipBlocks runs shipping for all users.
3172func (i *Ingester) shipBlocks(ctx context.Context, allowed *users.AllowedTenants) {
3173 // Do not ship blocks if the ingester is PENDING or JOINING. It's
3174 // particularly important for the JOINING state because there could
3175 // be a blocks transfer in progress (from another ingester) and if we
3176 // run the shipper in such state we could end up with race conditions.
3177 if i.lifecycler != nil {
3178 if ingesterState := i.lifecycler.GetState(); ingesterState == ring.PENDING || ingesterState == ring.JOINING {
3179 level.Info(logutil.WithContext(ctx, i.logger)).Log("msg", "TSDB blocks shipping has been skipped because of the current ingester state", "state", ingesterState)
3180 return
3181 }
3182 }
3183
3184 // Number of concurrent workers is limited in order to avoid to concurrently sync a lot
3185 // of tenants in a large cluster.
3186 _ = concurrency.ForEachUser(ctx, i.getTSDBUsers(), i.cfg.BlocksStorageConfig.TSDB.ShipConcurrency, func(ctx context.Context, userID string) error {
3187 if !allowed.IsAllowed(userID) {
3188 return nil
3189 }
3190
3191 // Get the user's DB. If the user doesn't exist, we skip it.
3192 userDB, err := i.getTSDB(userID)
3193 if err != nil || userDB == nil || userDB.shipper == nil {
3194 return nil
3195 }
3196
3197 if userDB.deletionMarkFound.Load() {
3198 return nil
3199 }
3200
3201 if time.Since(time.Unix(userDB.lastDeletionMarkCheck.Load(), 0)) > cortex_tsdb.DeletionMarkCheckInterval {
3202 // Even if check fails with error, we don't want to repeat it too often.
3203 userDB.lastDeletionMarkCheck.Store(time.Now().Unix())
3204
3205 deletionMarkExists, err := users.TenantDeletionMarkExists(ctx, i.TSDBState.bucket, userID)
3206 if err != nil {
3207 // If we cannot check for deletion mark, we continue anyway, even though in production shipper will likely fail too.
3208 // This however simplifies unit tests, where tenant deletion check is enabled by default, but tests don't setup bucket.
3209 level.Warn(logutil.WithContext(ctx, i.logger)).Log("msg", "failed to check for tenant deletion mark before shipping blocks", "user", userID, "err", err)
3210 } else if deletionMarkExists {
3211 userDB.deletionMarkFound.Store(true)
3212
3213 level.Info(logutil.WithContext(ctx, i.logger)).Log("msg", "tenant deletion mark exists, not shipping blocks", "user", userID)
3214 return nil
3215 }
3216 }
3217
3218 // Run the shipper's Sync() to upload unshipped blocks. Make sure the TSDB state is active, in order to
3219 // avoid any race condition with closing idle TSDBs.
3220 if !userDB.casState(active, activeShipping) {
3221 level.Info(logutil.WithContext(ctx, i.logger)).Log("msg", "shipper skipped because the TSDB is not active", "user", userID)
3222 return nil
3223 }
3224 defer userDB.casState(activeShipping, active)
3225
3226 if idxs, err := bucketindex.ReadSyncStatus(ctx, i.TSDBState.bucket, userID, logutil.WithContext(ctx, i.logger)); err == nil {
3227 // Skip blocks shipping if the bucket index failed to sync due to CMK errors.
3228 if idxs.Status == bucketindex.CustomerManagedKeyError {
3229 level.Info(logutil.WithContext(ctx, i.logger)).Log("msg", "skipping shipping blocks due CustomerManagedKeyError", "user", userID)

Implementers 1

Ingesterpkg/ingester/ingester.go

Calls 14

getTSDBUsersMethod · 0.95
getTSDBMethod · 0.95
ForEachUserFunction · 0.92
TenantDeletionMarkExistsFunction · 0.92
ReadSyncStatusFunction · 0.92
IsAllowedMethod · 0.80
LoadMethod · 0.80
casStateMethod · 0.80
StoreMethod · 0.65
SyncMethod · 0.65
GetStateMethod · 0.45