feat(eventstore): increase parallel write capabilities (#5940)

This implementation increases parallel write capabilities of the eventstore.
Please have a look at the technical advisories: [05](https://zitadel.com/docs/support/advisory/a10005) and  [06](https://zitadel.com/docs/support/advisory/a10006).
The implementation of eventstore.push is rewritten and stored events are migrated to a new table `eventstore.events2`.
If you are using cockroach: make sure that the database user of ZITADEL has `VIEWACTIVITY` grant. This is used to query events.
This commit is contained in:
Silvan
2023-10-19 12:19:10 +02:00
committed by GitHub
parent 259faba3f0
commit b5564572bc
791 changed files with 30326 additions and 43202 deletions

View File

@@ -1,13 +1,12 @@
package model
import (
"encoding/json"
"net"
"github.com/zitadel/logging"
caos_errs "github.com/zitadel/zitadel/internal/errors"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/eventstore"
)
type AuthRequest struct {
@@ -23,8 +22,8 @@ type BrowserInfo struct {
RemoteIP net.IP `json:"remoteIP,omitempty"`
}
func (a *AuthRequest) SetData(event *es_models.Event) error {
if err := json.Unmarshal(event.Data, a); err != nil {
func (a *AuthRequest) SetData(event eventstore.Event) error {
if err := event.Unmarshal(a); err != nil {
logging.Log("EVEN-T5df6").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-yGmhh", "could not unmarshal event")
}

View File

@@ -1,12 +1,11 @@
package model
import (
"encoding/json"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/crypto"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/user/model"
)
@@ -22,7 +21,7 @@ type OTPVerified struct {
UserAgentID string `json:"userAgentID,omitempty"`
}
func (u *Human) appendOTPAddedEvent(event *es_models.Event) error {
func (u *Human) appendOTPAddedEvent(event eventstore.Event) error {
u.OTP = &OTP{
State: int32(model.MFAStateNotReady),
}
@@ -37,17 +36,17 @@ func (u *Human) appendOTPRemovedEvent() {
u.OTP = nil
}
func (o *OTP) setData(event *es_models.Event) error {
func (o *OTP) setData(event eventstore.Event) error {
o.ObjectRoot.AppendEvent(event)
if err := json.Unmarshal(event.Data, o); err != nil {
if err := event.Unmarshal(o); err != nil {
logging.Log("EVEN-d9soe").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-lo023", "could not unmarshal event")
}
return nil
}
func (o *OTPVerified) SetData(event *es_models.Event) error {
if err := json.Unmarshal(event.Data, o); err != nil {
func (o *OTPVerified) SetData(event eventstore.Event) error {
if err := event.Unmarshal(o); err != nil {
logging.Log("EVEN-BF421").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-GB6hj", "could not unmarshal event")
}

View File

@@ -1,13 +1,13 @@
package model
import (
"encoding/json"
"time"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/crypto"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
@@ -32,42 +32,42 @@ type PasswordChange struct {
UserAgentID string `json:"userAgentID,omitempty"`
}
func (u *Human) appendUserPasswordChangedEvent(event *es_models.Event) error {
func (u *Human) appendUserPasswordChangedEvent(event eventstore.Event) error {
u.Password = new(Password)
err := u.Password.setData(event)
if err != nil {
return err
}
u.Password.ObjectRoot.CreationDate = event.CreationDate
u.Password.ObjectRoot.CreationDate = event.CreatedAt()
return nil
}
func (u *Human) appendPasswordSetRequestedEvent(event *es_models.Event) error {
func (u *Human) appendPasswordSetRequestedEvent(event eventstore.Event) error {
u.PasswordCode = new(PasswordCode)
return u.PasswordCode.SetData(event)
}
func (pw *Password) setData(event *es_models.Event) error {
func (pw *Password) setData(event eventstore.Event) error {
pw.ObjectRoot.AppendEvent(event)
if err := json.Unmarshal(event.Data, pw); err != nil {
if err := event.Unmarshal(pw); err != nil {
logging.Log("EVEN-dks93").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-sl9xlo2rsw", "could not unmarshal event")
}
return nil
}
func (c *PasswordCode) SetData(event *es_models.Event) error {
func (c *PasswordCode) SetData(event eventstore.Event) error {
c.ObjectRoot.AppendEvent(event)
c.CreationDate = event.CreationDate
if err := json.Unmarshal(event.Data, c); err != nil {
c.CreationDate = event.CreatedAt()
if err := event.Unmarshal(c); err != nil {
logging.Log("EVEN-lo0y2").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-q21dr", "could not unmarshal event")
}
return nil
}
func (pw *PasswordChange) SetData(event *es_models.Event) error {
if err := json.Unmarshal(event.Data, pw); err != nil {
func (pw *PasswordChange) SetData(event eventstore.Event) error {
if err := event.Unmarshal(pw); err != nil {
logging.Log("EVEN-ADs31").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-BDd32", "could not unmarshal event")
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/zitadel/zitadel/internal/database"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
user_repo "github.com/zitadel/zitadel/internal/repository/user"
)
@@ -16,13 +15,13 @@ import (
type Token struct {
es_models.ObjectRoot
TokenID string `json:"tokenId" gorm:"column:token_id"`
ApplicationID string `json:"applicationId" gorm:"column:application_id"`
UserAgentID string `json:"userAgentId" gorm:"column:user_agent_id"`
Audience database.StringArray `json:"audience" gorm:"column:audience"`
Scopes database.StringArray `json:"scopes" gorm:"column:scopes"`
Expiration time.Time `json:"expiration" gorm:"column:expiration"`
PreferredLanguage string `json:"preferredLanguage" gorm:"column:preferred_language"`
TokenID string `json:"tokenId" gorm:"column:token_id"`
ApplicationID string `json:"applicationId" gorm:"column:application_id"`
UserAgentID string `json:"userAgentId" gorm:"column:user_agent_id"`
Audience database.TextArray[string] `json:"audience" gorm:"column:audience"`
Scopes database.TextArray[string] `json:"scopes" gorm:"column:scopes"`
Expiration time.Time `json:"expiration" gorm:"column:expiration"`
PreferredLanguage string `json:"preferredLanguage" gorm:"column:preferred_language"`
}
func (t *Token) AppendEvents(events ...*es_models.Event) error {
@@ -36,8 +35,7 @@ func (t *Token) AppendEvents(events ...*es_models.Event) error {
}
func (t *Token) AppendEvent(event *es_models.Event) error {
switch eventstore.EventType(event.Type) {
case user_repo.UserTokenAddedType:
if event.Typ == user_repo.UserTokenAddedType {
err := t.setData(event)
if err != nil {
return err

View File

@@ -8,7 +8,6 @@ import (
"github.com/zitadel/zitadel/internal/errors"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/user/model"
@@ -40,7 +39,7 @@ func (u *User) AppendEvents(events ...*es_models.Event) error {
func (u *User) AppendEvent(event *es_models.Event) error {
u.ObjectRoot.AppendEvent(event)
switch eventstore.EventType(event.Type) {
switch event.Type() {
case user.UserV1AddedType,
user.HumanAddedType,
user.MachineAddedEventType,
@@ -72,11 +71,11 @@ func (u *User) AppendEvent(event *es_models.Event) error {
u.Machine.user = u
return u.Machine.AppendEvent(event)
}
if strings.HasPrefix(string(event.Type), "user.human") || event.AggregateVersion == "v1" {
if strings.HasPrefix(string(event.Typ), "user.human") || event.AggregateVersion == "v1" {
u.Human = &Human{user: u}
return u.Human.AppendEvent(event)
}
if strings.HasPrefix(string(event.Type), "user.machine") {
if strings.HasPrefix(string(event.Typ), "user.machine") {
u.Machine = &Machine{user: u}
return u.Machine.AppendEvent(event)
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/zitadel/zitadel/internal/crypto"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/user/model"
@@ -50,7 +49,7 @@ func (p *Human) AppendEvents(events ...*es_models.Event) error {
}
func (h *Human) AppendEvent(event *es_models.Event) (err error) {
switch eventstore.EventType(event.Type) {
switch event.Type() {
case user.UserV1AddedType,
user.UserV1RegisteredType,
user.UserV1ProfileChangedType,

View File

@@ -7,7 +7,6 @@ import (
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
user_repo "github.com/zitadel/zitadel/internal/repository/user"
)
@@ -29,7 +28,7 @@ func (sa *Machine) AppendEvents(events ...*es_models.Event) error {
}
func (sa *Machine) AppendEvent(event *es_models.Event) (err error) {
switch eventstore.EventType(event.Type) {
switch event.Type() {
case user_repo.MachineAddedEventType, user_repo.MachineChangedEventType:
err = sa.setData(event)
}
@@ -66,7 +65,7 @@ func (key *MachineKey) AppendEvents(events ...*es_models.Event) error {
func (key *MachineKey) AppendEvent(event *es_models.Event) (err error) {
key.ObjectRoot.AppendEvent(event)
switch eventstore.EventType(event.Type) {
switch event.Type() {
case user_repo.MachineKeyAddedEventType:
err = json.Unmarshal(event.Data, key)
if err != nil {

View File

@@ -1,11 +1,10 @@
package model
import (
"encoding/json"
"github.com/zitadel/logging"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/user/model"
)
@@ -62,21 +61,21 @@ func GetWebauthn(webauthnTokens []*WebAuthNToken, id string) (int, *WebAuthNToke
return -1, nil
}
func (w *WebAuthNVerify) SetData(event *es_models.Event) error {
if err := json.Unmarshal(event.Data, w); err != nil {
func (w *WebAuthNVerify) SetData(event eventstore.Event) error {
if err := event.Unmarshal(w); err != nil {
logging.Log("EVEN-G342rf").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-B6641", "could not unmarshal event")
}
return nil
}
func (u *Human) appendU2FAddedEvent(event *es_models.Event) error {
func (u *Human) appendU2FAddedEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
return err
}
webauthn.ObjectRoot.CreationDate = event.CreationDate
webauthn.ObjectRoot.CreationDate = event.CreatedAt()
webauthn.State = int32(model.MFAStateNotReady)
for i, token := range u.U2FTokens {
if token.State == int32(model.MFAStateNotReady) {
@@ -88,7 +87,7 @@ func (u *Human) appendU2FAddedEvent(event *es_models.Event) error {
return nil
}
func (u *Human) appendU2FVerifiedEvent(event *es_models.Event) error {
func (u *Human) appendU2FVerifiedEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
@@ -105,7 +104,7 @@ func (u *Human) appendU2FVerifiedEvent(event *es_models.Event) error {
return caos_errs.ThrowPreconditionFailed(nil, "MODEL-4hu9s", "Errors.Users.MFA.U2F.NotExisting")
}
func (u *Human) appendU2FChangeSignCountEvent(event *es_models.Event) error {
func (u *Human) appendU2FChangeSignCountEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
@@ -118,7 +117,7 @@ func (u *Human) appendU2FChangeSignCountEvent(event *es_models.Event) error {
return caos_errs.ThrowPreconditionFailed(nil, "MODEL-5Ms8h", "Errors.Users.MFA.U2F.NotExisting")
}
func (u *Human) appendU2FRemovedEvent(event *es_models.Event) error {
func (u *Human) appendU2FRemovedEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
@@ -135,13 +134,13 @@ func (u *Human) appendU2FRemovedEvent(event *es_models.Event) error {
return nil
}
func (u *Human) appendPasswordlessAddedEvent(event *es_models.Event) error {
func (u *Human) appendPasswordlessAddedEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
return err
}
webauthn.ObjectRoot.CreationDate = event.CreationDate
webauthn.ObjectRoot.CreationDate = event.CreatedAt()
webauthn.State = int32(model.MFAStateNotReady)
for i, token := range u.PasswordlessTokens {
if token.State == int32(model.MFAStateNotReady) {
@@ -153,7 +152,7 @@ func (u *Human) appendPasswordlessAddedEvent(event *es_models.Event) error {
return nil
}
func (u *Human) appendPasswordlessVerifiedEvent(event *es_models.Event) error {
func (u *Human) appendPasswordlessVerifiedEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
@@ -170,7 +169,7 @@ func (u *Human) appendPasswordlessVerifiedEvent(event *es_models.Event) error {
return caos_errs.ThrowPreconditionFailed(nil, "MODEL-mKns8", "Errors.Users.MFA.Passwordless.NotExisting")
}
func (u *Human) appendPasswordlessChangeSignCountEvent(event *es_models.Event) error {
func (u *Human) appendPasswordlessChangeSignCountEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
@@ -186,7 +185,7 @@ func (u *Human) appendPasswordlessChangeSignCountEvent(event *es_models.Event) e
return caos_errs.ThrowPreconditionFailed(nil, "MODEL-2Mv9s", "Errors.Users.MFA.Passwordless.NotExisting")
}
func (u *Human) appendPasswordlessRemovedEvent(event *es_models.Event) error {
func (u *Human) appendPasswordlessRemovedEvent(event eventstore.Event) error {
webauthn := new(WebAuthNToken)
err := webauthn.setData(event)
if err != nil {
@@ -203,23 +202,23 @@ func (u *Human) appendPasswordlessRemovedEvent(event *es_models.Event) error {
return nil
}
func (w *WebAuthNToken) setData(event *es_models.Event) error {
func (w *WebAuthNToken) setData(event eventstore.Event) error {
w.ObjectRoot.AppendEvent(event)
if err := json.Unmarshal(event.Data, w); err != nil {
if err := event.Unmarshal(w); err != nil {
logging.Log("EVEN-4M9is").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-lo023", "could not unmarshal event")
}
return nil
}
func (u *Human) appendU2FLoginEvent(event *es_models.Event) error {
func (u *Human) appendU2FLoginEvent(event eventstore.Event) error {
webauthn := new(WebAuthNLogin)
webauthn.ObjectRoot.AppendEvent(event)
err := webauthn.setData(event)
if err != nil {
return err
}
webauthn.ObjectRoot.CreationDate = event.CreationDate
webauthn.ObjectRoot.CreationDate = event.CreatedAt()
for i, token := range u.U2FLogins {
if token.AuthRequest.ID == webauthn.AuthRequest.ID {
u.U2FLogins[i] = webauthn
@@ -230,14 +229,14 @@ func (u *Human) appendU2FLoginEvent(event *es_models.Event) error {
return nil
}
func (u *Human) appendPasswordlessLoginEvent(event *es_models.Event) error {
func (u *Human) appendPasswordlessLoginEvent(event eventstore.Event) error {
webauthn := new(WebAuthNLogin)
webauthn.ObjectRoot.AppendEvent(event)
err := webauthn.setData(event)
if err != nil {
return err
}
webauthn.ObjectRoot.CreationDate = event.CreationDate
webauthn.ObjectRoot.CreationDate = event.CreatedAt()
for i, token := range u.PasswordlessLogins {
if token.AuthRequest.ID == webauthn.AuthRequest.ID {
u.PasswordlessLogins[i] = webauthn
@@ -248,9 +247,9 @@ func (u *Human) appendPasswordlessLoginEvent(event *es_models.Event) error {
return nil
}
func (w *WebAuthNLogin) setData(event *es_models.Event) error {
func (w *WebAuthNLogin) setData(event eventstore.Event) error {
w.ObjectRoot.AppendEvent(event)
if err := json.Unmarshal(event.Data, w); err != nil {
if err := event.Unmarshal(w); err != nil {
logging.Log("EVEN-hmSlo").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-lo023", "could not unmarshal event")
}