fix shared-db tenant runtime gaps

This commit is contained in:
richjohnrambo
2026-09-22 19:28:33 +08:00
parent 49e43aa3cf
commit 9ddf6ec5ee
12 changed files with 346 additions and 58 deletions
+46 -24
View File
@@ -31,26 +31,6 @@ func ensureUserIdentitySchema(db *sqlx.DB) error {
}
defer conn.Close()
// Fast path: the last two steps of this migration drop the legacy im_usertags
// table and the im_users.tags column. If both are already gone, the migration
// has fully run (or the database was created fresh) and no lock is needed.
stale := false
if exists, err := identityTableExists(ctx, conn, "im_usertags"); err != nil {
return err
} else if exists {
stale = true
}
if !stale {
if exists, err := identityColumnExists(ctx, conn, "im_users", "tags"); err != nil {
return err
} else if exists {
stale = true
}
}
if !stale {
return nil
}
// PXC strict-mode clusters prohibit GET_LOCK; acquireMigrationLock falls back
// to lock-free execution in that case. The migration body is idempotent.
_, unlock, err := acquireMigrationLock(ctx, conn, userIdentityMigrationLock)
@@ -112,7 +92,7 @@ func ensureUserIdentitySchema(db *sqlx.DB) error {
return err
}
}
if err = ensureUserAccountNoSchema(ctx, conn); err != nil {
if err = ensureUserAccountNoSchema(ctx, conn, usersScoped); err != nil {
return err
}
if profilesExist {
@@ -173,6 +153,15 @@ func ensureUserIdentitySchema(db *sqlx.DB) error {
return fmt.Errorf("create unique phone index: %w", err)
}
}
if usersScoped {
if exists, err := identityIndexExists(ctx, conn, "im_users", "users_phone"); err != nil {
return err
} else if exists {
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_users DROP INDEX users_phone"); err != nil {
return err
}
}
}
usernameIndex := "users_username"
usernameColumns := "username"
if usersScoped {
@@ -186,6 +175,15 @@ func ensureUserIdentitySchema(db *sqlx.DB) error {
return fmt.Errorf("create unique username index: %w", err)
}
}
if usersScoped {
if exists, err := identityIndexExists(ctx, conn, "im_users", "users_username"); err != nil {
return err
} else if exists {
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_users DROP INDEX users_username"); err != nil {
return err
}
}
}
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_users MODIFY COLUMN username VARCHAR(32) NOT NULL"); err != nil {
return err
}
@@ -376,6 +374,15 @@ func migrateBasicAuthSchema(ctx context.Context, conn *sqlx.Conn, scoped bool) e
}
}
}
if scoped {
if exists, err = identityIndexExists(ctx, conn, "im_auth", "auth_userid"); err != nil {
return err
} else if exists {
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_auth DROP INDEX auth_userid"); err != nil {
return err
}
}
}
return nil
}
@@ -559,7 +566,7 @@ func identityCandidates(ctx context.Context, conn *sqlx.Conn, scoped bool, metho
return out, nil
}
func ensureUserAccountNoSchema(ctx context.Context, conn *sqlx.Conn) error {
func ensureUserAccountNoSchema(ctx context.Context, conn *sqlx.Conn, scoped bool) error {
if exists, err := identityColumnExists(ctx, conn, "im_users", "account_no"); err != nil {
return err
} else if !exists {
@@ -582,13 +589,28 @@ func ensureUserAccountNoSchema(ctx context.Context, conn *sqlx.Conn) error {
WHERE u.account_no=0`, start); err != nil {
return err
}
if exists, err := identityIndexExists(ctx, conn, "im_users", "uk_im_users_account_no"); err != nil {
indexName := "uk_im_users_account_no"
columns := "account_no"
if scoped {
indexName = "uk_im_users_tenant_account_no"
columns = "tenant_id,account_no"
}
if exists, err := identityIndexExists(ctx, conn, "im_users", indexName); err != nil {
return err
} else if !exists {
if _, err = conn.ExecContext(ctx, "CREATE UNIQUE INDEX uk_im_users_account_no ON im_users(account_no)"); err != nil {
if _, err = conn.ExecContext(ctx, "CREATE UNIQUE INDEX "+quoteIdent(indexName)+" ON im_users("+columns+")"); err != nil {
return fmt.Errorf("create unique user account number index: %w", err)
}
}
if scoped {
if exists, err := identityIndexExists(ctx, conn, "im_users", "uk_im_users_account_no"); err != nil {
return err
} else if exists {
if _, err = conn.ExecContext(ctx, "ALTER TABLE im_users DROP INDEX uk_im_users_account_no"); err != nil {
return err
}
}
}
return nil
}