mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +00:00
17953e9040
Even though this is a feature it's released as fix so that we can back port to earlier revisions. As reported by multiple users startup of ZITADEL after leaded to downtime and worst case rollbacks to the previously deployed version. The problem starts rising when there are too many events to process after the start of ZITADEL. The root cause are changes on projections (database tables) which must be recomputed. This PR solves this problem by adding a new step to the setup phase which prefills the projections. The step can be enabled by adding the `--init-projections`-flag to `setup`, `start-from-init` and `start-from-setup`. Setting this flag results in potentially longer duration of the setup phase but reduces the risk of the problems mentioned in the paragraph above.
90 lines
2.5 KiB
Go
90 lines
2.5 KiB
Go
package setup
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"embed"
|
|
"time"
|
|
|
|
"github.com/cockroachdb/cockroach-go/v2/crdb"
|
|
"github.com/zitadel/logging"
|
|
|
|
"github.com/zitadel/zitadel/internal/database"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
)
|
|
|
|
var (
|
|
//go:embed 10/10_create_temp_table.sql
|
|
correctCreationDate10CreateTable string
|
|
//go:embed 10/10_fill_table.sql
|
|
correctCreationDate10FillTable string
|
|
//go:embed 10/cockroach/10_update.sql
|
|
//go:embed 10/postgres/10_update.sql
|
|
correctCreationDate10Update embed.FS
|
|
//go:embed 10/10_count_wrong_events.sql
|
|
correctCreationDate10CountWrongEvents string
|
|
//go:embed 10/10_empty_table.sql
|
|
correctCreationDate10Truncate string
|
|
)
|
|
|
|
type CorrectCreationDate struct {
|
|
dbClient *database.DB
|
|
FailAfter time.Duration
|
|
}
|
|
|
|
func (mig *CorrectCreationDate) Execute(ctx context.Context, _ eventstore.Event) (err error) {
|
|
ctx, cancel := context.WithTimeout(ctx, mig.FailAfter)
|
|
defer cancel()
|
|
|
|
for i := 0; ; i++ {
|
|
logging.WithFields("mig", mig.String(), "iteration", i).Debug("start iteration")
|
|
var affected int64
|
|
err = crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error {
|
|
if mig.dbClient.Type() == "cockroach" {
|
|
if _, err := tx.Exec("SET experimental_enable_temp_tables=on"); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
_, err := tx.ExecContext(ctx, correctCreationDate10CreateTable)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logging.WithFields("mig", mig.String(), "iteration", i).Debug("temp table created")
|
|
|
|
_, err = tx.ExecContext(ctx, correctCreationDate10Truncate)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.ExecContext(ctx, correctCreationDate10FillTable)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logging.WithFields("mig", mig.String(), "iteration", i).Debug("temp table filled")
|
|
|
|
res := tx.QueryRowContext(ctx, correctCreationDate10CountWrongEvents)
|
|
if err := res.Scan(&affected); err != nil || affected == 0 {
|
|
return err
|
|
}
|
|
|
|
updateStmt, err := readStmt(correctCreationDate10Update, "10", mig.dbClient.Type(), "10_update.sql")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.ExecContext(ctx, updateStmt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logging.WithFields("mig", mig.String(), "iteration", i, "count", affected).Debug("creation dates updated")
|
|
return nil
|
|
})
|
|
logging.WithFields("mig", mig.String(), "iteration", i).Debug("end iteration")
|
|
if affected == 0 || err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
func (mig *CorrectCreationDate) String() string {
|
|
return "10_correct_creation_date"
|
|
}
|