refactor(mysql): 适配PXC严格模式,替换全局锁方案
重构MySQL迁移逻辑,新增acquireMigrationLock适配Percona XtraDB Cluster的pxc_strict_mode限制,将原有的GET_LOCK迁移锁替换为更兼容的方案,同时为各迁移流程添加快速检查路径减少锁竞争
This commit is contained in:
@@ -5,7 +5,6 @@ package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -32,14 +31,35 @@ func ensureUserIdentitySchema(db *sqlx.DB) error {
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
var locked sql.NullInt64
|
||||
if err = conn.QueryRowContext(ctx, "SELECT GET_LOCK("+userIdentityMigrationLock+", 60)").Scan(&locked); err != nil {
|
||||
// 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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !locked.Valid || locked.Int64 != 1 {
|
||||
return errors.New("mysql: timed out waiting for user identity migration lock")
|
||||
if unlock != nil {
|
||||
defer unlock()
|
||||
}
|
||||
defer conn.ExecContext(ctx, "SELECT RELEASE_LOCK("+userIdentityMigrationLock+")")
|
||||
|
||||
usersExist, err := identityTableExists(ctx, conn, "im_users")
|
||||
if err != nil || !usersExist {
|
||||
|
||||
Reference in New Issue
Block a user