Skip to content

Commit

Permalink
fix: Do not reload metadata if nothing changed in describeCollection
Browse files Browse the repository at this point in the history
  • Loading branch information
himank committed May 25, 2023
1 parent 8661eb9 commit 8fbaa6f
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 11 deletions.
4 changes: 4 additions & 0 deletions server/metadata/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -1995,6 +1995,10 @@ func (d *Database) Clone() *Database {
return &copyDB
}

func (d *Database) IsMetadataChange() bool {
return d.MetadataChange
}

// Name returns the internal database name.
func (d *Database) Name() string {
return d.name.Name()
Expand Down
4 changes: 1 addition & 3 deletions server/services/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,7 @@ func (s *apiService) CommitTransaction(ctx context.Context, _ *api.CommitTransac
}
}()

db, _ := session.GetTx().Context().GetStagedDatabase().(*metadata.Database)

if err := session.Commit(s.versionH, db != nil && db.MetadataChange, nil); err != nil {
if err := session.Commit(s.versionH, session.GetTx().Context().IsMetadataStateChanged(), nil); err != nil {
return nil, database.CreateApiError(err)
}

Expand Down
14 changes: 12 additions & 2 deletions server/services/v1/database/collection_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,24 @@ func (runner *CollectionQueryRunner) describe(ctx context.Context, tx transactio
return Response{}, ctx, err
}
}

metadataChange := false
// A legacy collection that needs to be updated
if coll.SecondaryIndexes.All == nil {
if err = tenant.UpgradeCollectionIndexes(ctx, tx, db, coll); err != nil {
return Response{}, ctx, err
}
metadataChange = true
}
if err = tenant.UpgradeSearchStatus(ctx, tx, db, coll); err != nil {
return Response{}, ctx, err
if coll.GetSearchState() == schema.UnknownSearchState {
if err = tenant.UpgradeSearchStatus(ctx, tx, db, coll); err != nil {
return Response{}, ctx, err
}
metadataChange = true
}
if !metadataChange {
// do not reload if nothing changed.
tx.Context().MarkNoMetadataStateChanged()
}

return Response{
Expand Down
6 changes: 3 additions & 3 deletions server/services/v1/database/sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ func (sessMgr *SessionManager) executeWithRetry(ctx context.Context, runner Quer
return Response{}, err
}

session.tx.Context().MetadataChangeSession(req.MetadataChange)

// use the same ctx assigned in the session
resp, session.ctx, err = session.Run(runner)
if changed, err1 := session.versionTracker.Stop(session.ctx); err1 != nil || changed {
Expand All @@ -310,9 +312,7 @@ func (sessMgr *SessionManager) executeWithRetry(ctx context.Context, runner Quer
continue
}

db, _ := session.GetTx().Context().GetStagedDatabase().(*metadata.Database)

err = session.Commit(sessMgr.versionH, (db == nil && req.MetadataChange) || (db != nil && db.MetadataChange), err)
err = session.Commit(sessMgr.versionH, session.tx.Context().IsMetadataStateChanged(), err)
log.Debug().Err(err).Msg("session.commit after")
if !IsErrConflictingTransaction(err) && !search.IsErrDuplicateFieldNames(err) {
return
Expand Down
29 changes: 26 additions & 3 deletions server/transaction/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,43 @@ type Tx interface {
Rollback(ctx context.Context) error
}

type stagedDatabase interface {
IsMetadataChange() bool
}

// SessionCtx is used to store any baggage for the lifetime of the transaction. We use it to stage the database inside
// a transaction when the transaction is performing any DDLs.
type SessionCtx struct {
db any
db stagedDatabase
noMetadataChanged bool
metadataChangeSession bool
}

func (c *SessionCtx) StageDatabase(db any) {
func (c *SessionCtx) MetadataChangeSession(mcs bool) {
c.metadataChangeSession = mcs
}

func (c *SessionCtx) StageDatabase(db stagedDatabase) {
c.db = db
}

func (c *SessionCtx) GetStagedDatabase() any {
func (c *SessionCtx) GetStagedDatabase() stagedDatabase {
return c.db
}

func (c *SessionCtx) MarkNoMetadataStateChanged() {
if c.db != nil {
// possible an interactive transaction
return
}

c.noMetadataChanged = true
}

func (c *SessionCtx) IsMetadataStateChanged() bool {
return ((c.db == nil && c.metadataChangeSession) || (c.db != nil && c.db.IsMetadataChange())) && !c.noMetadataChanged
}

// Manager is used to track all the sessions and provide all the functionality related to transactions. Once created
// this will create a session tracker for tracking the sessions.

Expand Down

0 comments on commit 8fbaa6f

Please sign in to comment.