ikaros-dev / ikaros

Dedicated to ACGMN's Content Management System (CMS). | 专注于ACGMN的内容管理系统(CMS)。
https://ikaros.run
GNU Affero General Public License v3.0
579 stars 24 forks source link

[Bug] 迁移到POSTGRESQL数据库后 bad SQL grammar [SELECT subject.* FROM subject]错误 #742

Closed pein0saga closed 15 hours ago

pein0saga commented 16 hours ago

提问前查询

组件

服务端 (server)

运行环境

WIN 10 POSTGRESQL 17

JAVA20

java 20.0.1 2023-04-18 Java(TM) SE Runtime Environment (build 20.0.1+9-29) Java HotSpot(TM) 64-Bit Server VM (build 20.0.1+9-29, mixed mode, sharing)

报错相关的日志

2024-12-03 22:41:21 [reactor-tcp-nio-1] ERROR reactor.core.publisher.Operators - Operator called default onErrorDropped
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.r2dbc.BadSqlGrammarException: executeMany; bad SQL grammar [SELECT subject.* FROM subject]
Caused by: org.springframework.r2dbc.BadSqlGrammarException: executeMany; bad SQL grammar [SELECT subject.* FROM subject]
        at org.springframework.r2dbc.connection.ConnectionFactoryUtils.convertR2dbcException(ConnectionFactoryUtils.java:243)
        at org.springframework.r2dbc.core.DefaultDatabaseClient.lambda$inConnectionMany$8(DefaultDatabaseClient.java:150)
        at reactor.core.publisher.Flux.lambda$onErrorMap$28(Flux.java:7123)
        at reactor.core.publisher.Flux.lambda$onErrorResume$29(Flux.java:7176)
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94)
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredError(FluxUsingWhen.java:398)
        at reactor.core.publisher.FluxUsingWhen$RollbackInner.onComplete(FluxUsingWhen.java:475)
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205)
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260)
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209)
        at reactor.pool.SimpleDequePool.maybeRecycleAndDrain(SimpleDequePool.java:531)
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerInner.onComplete(SimpleDequePool.java:761)
        at reactor.core.publisher.Operators.complete(Operators.java:137)
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerMono.subscribe(SimpleDequePool.java:873)
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260)
        at reactor.core.publisher.Operators.complete(Operators.java:137)
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263)
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51)
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240)
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89)

发生了什么

因为担心H2数据库的可靠性想要换数据库载体。把之前的ikaros配置文件清空以后,连接到POSTGRESQL出现报错

无法运行启动;浏览器显示

{"exception":"org.springframework.r2dbc.BadSqlGrammarException","message":"executeMany; bad SQL grammar [SELECT custom.* FROM custom WHERE (custom.c_group = $1) AND (custom.version = $2) AND (custom.kind = $3) AND (custom.name = $4) LIMIT 2]"}

POSTGRESQL数据库是提前自建空的,不知道有没有什么要求硬性要求

预期是怎样

浏览器显示显示管理界面

如何复现

FAST JAR 带参数启动

java -jar "C:\Games\ikaros\ikaros-server.jar" --spring.profiles.active=win --spring.sql.init.platform=postgresql --spring.r2dbc.url=r2dbc:pool:postgresql://127.0.0.1:5432/ikaros --spring.r2dbc.username=ikaros --spring.r2dbc.password='mmfXXXXXX9B2'

其它补充内容

error.log ikaros.log

pein0saga commented 16 hours ago

题外话,

如果H2 IKAROS运行的时候运行命令,好像会自动尝试用flyway迁移,那时候会这样报错(那边是linux环境):

Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database (jdbc:h2:file:/var/services/homes/XXXX/.ikaros/database/ikaros) for user 'admin': Wrong user name or password [28000-214]

这里的 user 'admin'可能是H2数据库自带的user?匹配不上POSTGRESQL的新数据库的user?所以flyway大失败了?不知道flyway这里扮演了什么角色,照理说H2数据库已经受到IKAROS账号密码保护了

https://github.com/flyway/flyway

chivehao commented 16 hours ago

FAST JAR 带参数启动

java -jar "C:\Games\ikaros\ikaros-server.jar" --spring.profiles.active=win --spring.sql.init.platform=postgresql --spring.r2dbc.url=r2dbc:pool:postgresql://127.0.0.1:5432/ikaros --spring.r2dbc.username=ikaros --spring.r2dbc.password='mmfXXXXXX9B2'

可能是参数问题,

r2dbc和flyway都需要配置数据库配置,可以参考dockercompose的配置:

https://docs.ikaros.run/docs/getting-started/install/docker-compose


          - --logging.charset.console=UTF-8
          - --logging.charset.file=UTF-8
          # log level for package, such as INFO or DEBUG
          - --logging.level.run.ikaros.server=INFO
          - --logging.level.run.ikaros.plugin=INFO
          - --logging.level.run.ikaros.jellyfin=INFO
          - --sun.jnu.encoding=UTF-8
          - --spring.r2dbc.url=r2dbc:pool:postgresql://ikaros_database/ikaros
          - --spring.r2dbc.username=ikaros
          # PostgreSQL 的密码,请保证与下方 POSTGRES_PASSWORD 的变量值一致。
          - --spring.r2dbc.password=openpostgresql
          # Flayway
          - --spring.flyway.url=jdbc:postgresql://ikaros_database/ikaros
          - --spring.flyway.locations=classpath:db/postgresql/migration
          - --spring.flyway.user=ikaros
          - --spring.flyway.password=openpostgresql
          # ikaros 外部访问地址 需要根据自己的情况进行修改 影响的功能包括不限于API文档等
          - --ikaros.external-url=http://localhost:9999
          # 初始化的超级管理员用户名
          - --ikaros.security.initializer.master-username=tomoki
          # 初始化的超级管理员密码
          - --ikaros.security.initializer.master-password=tomoki
chivehao commented 16 hours ago

题外话,

如果H2 IKAROS运行的时候运行命令,好像会自动尝试用flyway迁移,那时候会这样报错(那边是linux环境):

Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database (jdbc:h2:file:/var/services/homes/XXXX/.ikaros/database/ikaros) for user 'admin': Wrong user name or password [28000-214]

这里的 user 'admin'可能是H2数据库自带的user?匹配不上POSTGRESQL的新数据库的user?所以flyway大失败了?不知道flyway这里扮演了什么角色,照理说H2数据库已经受到IKAROS账号密码保护了

https://github.com/flyway/flyway

这似乎是因为你没配置flyway数据库连接配置

pein0saga commented 16 hours ago

FAST JAR 带参数启动 java -jar "C:\Games\ikaros\ikaros-server.jar" --spring.profiles.active=win --spring.sql.init.platform=postgresql --spring.r2dbc.url=r2dbc:pool:postgresql://127.0.0.1:5432/ikaros --spring.r2dbc.username=ikaros --spring.r2dbc.password='mmfXXXXXX9B2'

可能是参数问题,

  • --spring.profiles.active=win 修改为:--spring.profiles.active=win,postgresql
  • 还需要加上flyway的连接配置:--spring.flyway.url=jdbc:postgresql://localhost:5432/postgres --spring.flyway.user=xxx --spring.flyway.password=xxx

r2dbc和flyway都需要配置数据库配置,可以参考dockercompose的配置:

https://docs.ikaros.run/docs/getting-started/install/docker-compose


          - --logging.charset.console=UTF-8
          - --logging.charset.file=UTF-8
          # log level for package, such as INFO or DEBUG
          - --logging.level.run.ikaros.server=INFO
          - --logging.level.run.ikaros.plugin=INFO
          - --logging.level.run.ikaros.jellyfin=INFO
          - --sun.jnu.encoding=UTF-8
          - --spring.r2dbc.url=r2dbc:pool:postgresql://ikaros_database/ikaros
          - --spring.r2dbc.username=ikaros
          # PostgreSQL 的密码,请保证与下方 POSTGRES_PASSWORD 的变量值一致。
          - --spring.r2dbc.password=openpostgresql
          # Flayway
          - --spring.flyway.url=jdbc:postgresql://ikaros_database/ikaros
          - --spring.flyway.locations=classpath:db/postgresql/migration
          - --spring.flyway.user=ikaros
          - --spring.flyway.password=openpostgresql
          # ikaros 外部访问地址 需要根据自己的情况进行修改 影响的功能包括不限于API文档等
          - --ikaros.external-url=http://localhost:9999
          # 初始化的超级管理员用户名
          - --ikaros.security.initializer.master-username=tomoki
          # 初始化的超级管理员密码
          - --ikaros.security.initializer.master-password=tomoki

谢谢。

希望能完善下fast jar文档(至少提示下重点,从compose的配置复制一下),

毕竟现在docker泛滥成灾了,对于我这些资源有限的人还是会用FAST JAR的,而且也不熟悉容器

chivehao commented 16 hours ago

我在文档上没有写清楚需要配置flyway数据库配置,后面有空我更新下文档。

https://docs.ikaros.run/docs/getting-started/install/fast-jar

pein0saga commented 15 hours ago

我在文档上没有写清楚需要配置flyway数据库配置,后面有空我更新下文档。

https://docs.ikaros.run/docs/getting-started/install/fast-jar

您好,请教一下,为什么dockercompose的配置这边是数据库ikaros_database/ikaros,用户名ikaros

      - --spring.r2dbc.url=r2dbc:pool:postgresql://ikaros_database/ikaros
      - --spring.r2dbc.username=ikaros

而fast-jar这边是自定义的?

spring.r2dbc.username 数据库用户名 spring.r2dbc.password 数据库密码

是因为容器提前准备好了更多数据让免去我们自建,还是说容器会先自动创建H2数据库ikaros然后通过flayway无缝迁移到P-SQL?

chivehao commented 15 hours ago

我在文档上没有写清楚需要配置flyway数据库配置,后面有空我更新下文档。 https://docs.ikaros.run/docs/getting-started/install/fast-jar

您好,请教一下,为什么dockercompose的配置这边是数据库ikaros_database/ikaros,用户名ikaros

      - --spring.r2dbc.url=r2dbc:pool:postgresql://ikaros_database/ikaros
      - --spring.r2dbc.username=ikaros

而fast-jar这边是自定义的?

spring.r2dbc.username 数据库用户名 spring.r2dbc.password 数据库密码

是因为容器提前准备好了更多数据让免去我们自建,还是说容器会先自动创建H2数据库ikaros然后通过flayway无缝迁移到P-SQL?

需要结合上下文, r2dbc:pool:postgresql://ikaros_database/ikaros 里的 ikaros_databasedocker-compose.yaml 里配置的容器名称,相当于 localhost:5432,数据库名称就是 ikaros

我截取的是docker-compose.yaml文件里的部分内容,里面已经定义了数据库容器:

    # ikaros database
    ikaros_database:
        image: postgres:latest
        container_name: ikaros_database
        restart: on-failure:3
        networks:
          ikaros_networks:
        volumes:
          - ./database:/var/lib/postgresql/data
        healthcheck:
          test: [ "CMD", "pg_isready" ]
          interval: 10s
          timeout: 5s
          retries: 5
        environment:
          - POSTGRES_DB=ikaros
          - POSTGRES_USER=ikaros
          - POSTGRES_PASSWORD=openpostgresql

完整文件请看:https://docs.ikaros.run/docs/getting-started/install/docker-compose 的场景创建 Ikaros + PostgreSQL 的实例

chivehao commented 15 hours ago

r2dbc和flyway的jdbc,这两边要连同一个数据库哈,数据库地址,端口、啥的配置都需要相同

pein0saga commented 15 hours ago

我在文档上没有写清楚需要配置flyway数据库配置,后面有空我更新下文档。 https://docs.ikaros.run/docs/getting-started/install/fast-jar

您好,请教一下,为什么dockercompose的配置这边是数据库ikaros_database/ikaros,用户名ikaros

      - --spring.r2dbc.url=r2dbc:pool:postgresql://ikaros_database/ikaros
      - --spring.r2dbc.username=ikaros

而fast-jar这边是自定义的? spring.r2dbc.username 数据库用户名 spring.r2dbc.password 数据库密码 是因为容器提前准备好了更多数据让免去我们自建,还是说容器会先自动创建H2数据库ikaros然后通过flayway无缝迁移到P-SQL?

需要结合上下文, r2dbc:pool:postgresql://ikaros_database/ikaros 里的 ikaros_databasedocker-compose.yaml 里配置的容器名称,相当于 localhost:5432,数据库名称就是 ikaros

我截取的是docker-compose.yaml文件里的部分内容,里面已经定义了数据库容器:

    # ikaros database
    ikaros_database:
        image: postgres:latest
        container_name: ikaros_database
        restart: on-failure:3
        networks:
          ikaros_networks:
        volumes:
          - ./database:/var/lib/postgresql/data
        healthcheck:
          test: [ "CMD", "pg_isready" ]
          interval: 10s
          timeout: 5s
          retries: 5
        environment:
          - POSTGRES_DB=ikaros
          - POSTGRES_USER=ikaros
          - POSTGRES_PASSWORD=openpostgresql

完整文件请看:https://docs.ikaros.run/docs/getting-started/install/docker-compose 的场景创建 Ikaros + PostgreSQL 的实例

已经成功了,谢谢。