Fix MySQL import abort on setval for tables without id.

This commit is contained in:
2026-07-29 09:25:35 +03:00
parent 31ce2af622
commit 08750add83
+32 -8
View File
@@ -62,9 +62,14 @@ func ImportFile(ctx context.Context, pool *pgxpool.Pool, dumpPath string) error
} }
defer tx.Rollback(ctx) defer tx.Rollback(ctx)
// Temporarily disable FK checks via deferred constraints where possible // Temporarily disable FK checks (requires superuser). Use savepoint so failure does not abort TX.
if _, err := tx.Exec(ctx, `SET session_replication_role = replica`); err != nil { if _, err := tx.Exec(ctx, `SAVEPOINT sp_repl_role`); err == nil {
if _, err := tx.Exec(ctx, `SET LOCAL session_replication_role = replica`); err != nil {
log.Printf("warn: cannot set session_replication_role: %v", err) log.Printf("warn: cannot set session_replication_role: %v", err)
_, _ = tx.Exec(ctx, `ROLLBACK TO SAVEPOINT sp_repl_role`)
} else {
_, _ = tx.Exec(ctx, `RELEASE SAVEPOINT sp_repl_role`)
}
} }
inserts := map[string][]string{} inserts := map[string][]string{}
@@ -89,11 +94,25 @@ func ImportFile(ctx context.Context, pool *pgxpool.Pool, dumpPath string) error
} }
} }
// Fix sequences // Fix sequences only for tables with BIGSERIAL id.
for _, table := range tablesOrder { // Do not run setval on wg_config_settings — it has no id column.
_, _ = tx.Exec(ctx, fmt.Sprintf(` // In PostgreSQL any failed statement aborts the whole transaction even if Go ignores the error.
SELECT setval(pg_get_serial_sequence('%s','id'), COALESCE((SELECT MAX(id) FROM %s), 1), true) serialTables := []string{
"users", "site_status", "servers", "servers_simple", "countries",
"wg_configs", "demo_keys", "awg_configs", "amnezia_configs",
"vless_configs", "admin_uploads", "user_servers", "license_keys", "rate_limits",
}
for _, table := range serialTables {
_, err := tx.Exec(ctx, fmt.Sprintf(`
SELECT setval(
pg_get_serial_sequence('%s', 'id'),
GREATEST(COALESCE((SELECT MAX(id) FROM %s), 1), 1),
true
)
`, table, table)) `, table, table))
if err != nil {
return fmt.Errorf("fix sequence %s: %w", table, err)
}
} }
_, err = tx.Exec(ctx, ` _, err = tx.Exec(ctx, `
@@ -101,11 +120,16 @@ func ImportFile(ctx context.Context, pool *pgxpool.Pool, dumpPath string) error
VALUES ('mysql_import_done', '1', NOW()) VALUES ('mysql_import_done', '1', NOW())
ON CONFLICT (key) DO UPDATE SET value = '1', updated_at = NOW()`) ON CONFLICT (key) DO UPDATE SET value = '1', updated_at = NOW()`)
if err != nil { if err != nil {
return err return fmt.Errorf("mark import done: %w", err)
} }
if _, err := tx.Exec(ctx, `SET session_replication_role = DEFAULT`); err != nil { if _, err := tx.Exec(ctx, `SAVEPOINT sp_repl_role_end`); err == nil {
if _, err := tx.Exec(ctx, `SET LOCAL session_replication_role = DEFAULT`); err != nil {
log.Printf("warn: restore session_replication_role: %v", err) log.Printf("warn: restore session_replication_role: %v", err)
_, _ = tx.Exec(ctx, `ROLLBACK TO SAVEPOINT sp_repl_role_end`)
} else {
_, _ = tx.Exec(ctx, `RELEASE SAVEPOINT sp_repl_role_end`)
}
} }
if err := tx.Commit(ctx); err != nil { if err := tx.Commit(ctx); err != nil {