在YugabyteDB部署Keycloak Helm Chart时遇多主键约束错误
问题背景
技术栈:
- 云平台:Azure
- Kubernetes版本:1.27.3
- 部署方式:Terraform部署Keycloak Helm Chart
- 数据库:YugabyteDB(PostgreSQL兼容版本11.2-YB-2.19.0.0-b0)
部署时触发数据库迁移错误,具体日志:
base info: {databaseUrl=jdbc:postgresql://yugabyte.svc.cluster.local:5432/postgres, databaseUser=keycloak, databaseProduct=PostgreSQL 11.2-YB-2.19.0.0-b0, databaseDriver=PostgreSQL JDBC Driver 42.2.5}
INFO [org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider] (ServerService Thread Pool -- 62) Updating database. Using changelog META-INF/jpa-changelog-master.xml
ERROR [org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider] (ServerService Thread Pool -- 62) Error has occurred while updating the database: liquibase.exception.LiquibaseException: liquibase.exception.MigrationFailedException: Migration failed for change set META-INF/jpa-changelog-3.4.0.xml::3.4.0::keycloak:
Reason: liquibase.exception.DatabaseException: ERROR: multiple primary keys for table "realm_default_roles" are not allowed [Failed SQL: (0) ALTER TABLE public.REALM_DEFAULT_ROLES ADD CONSTRAINT CONSTRAINT_REALM_DEFAULT_ROLES PRIMARY KEY (REALM_ID, ROLE_ID)]
注:Keycloak在Kubernetes 1.23/1.24版本环境中可正常部署运行。
可能原因
- YugabyteDB与原生PostgreSQL的主键处理差异:YugabyteDB作为分布式数据库,在表主键的创建、识别逻辑上和原生PostgreSQL存在细微差异,Keycloak的Liquibase迁移脚本未适配这种差异。
- 数据库预存在主键约束:目标数据库中
realm_default_roles表可能已经通过其他方式创建了主键约束,而Liquibase脚本仍尝试重复添加主键。 - Keycloak Helm Chart版本变更:新部署使用的Chart版本与K8S 1.23/1.24环境中的版本不一致,导致迁移脚本逻辑变化,触发兼容性问题。
解决方案
1. 检查数据库现有主键约束
连接到YugabyteDB实例,执行以下SQL查询realm_default_roles表的主键情况:
SELECT conname, conkey, pg_get_constraintdef(c.oid) FROM pg_constraint c JOIN pg_class t ON c.conrelid = t.oid WHERE t.relname = 'realm_default_roles' AND contype = 'p';
如果查询结果显示已存在主键约束,说明Liquibase脚本的操作重复。
2. 手动处理数据库迁移
- 先手动删除现有主键约束(如果存在):
ALTER TABLE public.REALM_DEFAULT_ROLES DROP CONSTRAINT <现有主键约束名>;
- 执行Liquibase脚本中对应的主键添加语句:
ALTER TABLE public.REALM_DEFAULT_ROLES ADD CONSTRAINT CONSTRAINT_REALM_DEFAULT_ROLES PRIMARY KEY (REALM_ID, ROLE_ID);
- 修改Keycloak Helm Chart的配置,禁用自动数据库迁移:
在Terraform的Helm资源配置中添加参数:
set { name = "extraEnv[0].name" value = "KC_DB_MIGRATE_STRATEGY" } set { name = "extraEnv[0].value" value = "manual" }
重新部署Keycloak。
3. 适配YugabyteDB兼容模式
调整YugabyteDB的配置,开启PostgreSQL兼容性优化参数:
- 在YugabyteDB的集群配置中添加
yb_enable_ysql_pg_conf_compatibility=true,重启数据库后重新尝试部署Keycloak。
4. 回退Keycloak Helm Chart版本
使用在K8S 1.23/1.24环境中可正常运行的Keycloak Helm Chart版本进行部署,验证是否是新版本Chart的迁移脚本导致的兼容性问题。
内容的提问来源于stack exchange,提问作者Sathish Kumar

