Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

文章内容很长时无法保存 #2832

Closed
AnotiaWang opened this issue Dec 3, 2022 · 5 comments · Fixed by #2833
Closed

文章内容很长时无法保存 #2832

AnotiaWang opened this issue Dec 3, 2022 · 5 comments · Fixed by #2833
Assignees
Labels
area/core Issues or PRs related to the Halo Core

Comments

@AnotiaWang
Copy link

AnotiaWang commented Dec 3, 2022

是什么版本出现了此问题?

2.0.0

使用的什么数据库?

MySQL 5.7

使用的哪种方式部署?

Docker Compose

在线站点地址

https://blog.ataw.top

发生了什么?

有一篇 很长的文章,估计有几千字吧。编辑之后无法保存,也无法发布。

相关日志输出

halo  | 2022-12-04T01:50:17.690+08:00 ERROR 6 --- [   Thread-13697] a.w.r.e.AbstractErrorWebExceptionHandler : [834242c6-879]  500 Server Error for HTTP PUT "/apis/api.console.halo.run/v1alpha1/posts/14/content"
halo  | 
halo  | org.springframework.r2dbc.UncategorizedR2dbcException: executeMany; SQL [INSERT INTO extensions (name, data, version) VALUES (?, ?, ?)]; Data too long for column 'data' at row 1
halo  |         at org.springframework.r2dbc.connection.ConnectionFactoryUtils.convertR2dbcException(ConnectionFactoryUtils.java:238) ~[spring-r2dbc-6.0.2.jar:6.0.2]
halo  |         Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
halo  | Error has been observed at the following site(s):
halo  |         *__checkpoint ⇢ org.springframework.web.filter.reactive.ServerHttpObservationFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ AuthorizationWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ ExceptionTranslationWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ LogoutWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ ServerRequestCacheWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ LogoutPageGeneratingWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ LoginPageGeneratingWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ AnonymousAuthenticationWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ AuthenticationWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ AuthenticationWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ ReactorContextWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ CsrfWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ CorsWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ HttpHeaderWriterWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
halo  |         *__checkpoint ⇢ HTTP PUT "/apis/api.console.halo.run/v1alpha1/posts/14/content" [ExceptionHandlingWebHandler]
halo  | Original Stack Trace:
halo  |                 at org.springframework.r2dbc.connection.ConnectionFactoryUtils.convertR2dbcException(ConnectionFactoryUtils.java:238) ~[spring-r2dbc-6.0.2.jar:6.0.2]
halo  |                 at org.springframework.r2dbc.core.DefaultDatabaseClient.lambda$inConnectionMany$8(DefaultDatabaseClient.java:150) ~[spring-r2dbc-6.0.2.jar:6.0.2]
halo  |                 at reactor.core.publisher.Flux.lambda$onErrorMap$28(Flux.java:7123) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.Flux.lambda$onErrorResume$29(Flux.java:7176) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredError(FluxUsingWhen.java:398) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxUsingWhen$RollbackInner.onComplete(FluxUsingWhen.java:475) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2168) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2168) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onComplete(FluxDoFinally.java:128) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onComplete(FluxDoFinally.java:128) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:121) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:64) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.uniHandle(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.complete(Unknown Source) ~[na:na]
halo  |                 at com.github.jasync.sql.db.mysql.MySQLConnection$close$lambda-2$$inlined$onCompleteAsync$1.accept(FutureUtils.kt:110) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at com.github.jasync.sql.db.mysql.MySQLConnection$close$lambda-2$$inlined$onCompleteAsync$1.accept(FutureUtils.kt:92) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture$Completion.run(Unknown Source) ~[na:na]
halo  |                 at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
halo  | Caused by: com.github.jasync.r2dbc.mysql.JasyncDatabaseException: Data too long for column 'data' at row 1
halo  |         at com.github.jasync.r2dbc.mysql.JasyncStatement$execute$3.invoke(JasyncStatement.kt:129) ~[jasync-r2dbc-mysql-2.1.7.jar:na]
halo  |         Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
halo  | Error has been observed at the following site(s):
halo  |         *__checkpoint ⇢ SQL "INSERT INTO extensions (name, data, version) VALUES (?, ?, ?)" [DatabaseClient]
halo  | Original Stack Trace:
halo  |                 at com.github.jasync.r2dbc.mysql.JasyncStatement$execute$3.invoke(JasyncStatement.kt:129) ~[jasync-r2dbc-mysql-2.1.7.jar:na]
halo  |                 at com.github.jasync.r2dbc.mysql.JasyncStatement$execute$3.invoke(JasyncStatement.kt:100) ~[jasync-r2dbc-mysql-2.1.7.jar:na]
halo  |                 at reactor.kotlin.core.publisher.FluxExtensionsKt.onErrorMap$lambda-1(FluxExtensions.kt:171) ~[reactor-kotlin-extensions-1.2.0.jar:1.2.0]
halo  |                 at reactor.core.publisher.Flux.lambda$onErrorMap$28(Flux.java:7123) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.Flux.lambda$onErrorResume$29(Flux.java:7176) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.maybeOnError(FluxConcatMapNoPrefetch.java:326) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerError(FluxConcatMapNoPrefetch.java:297) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onError(FluxConcatMap.java:875) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:117) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:64) ~[reactor-core-3.5.0.jar:3.5.0]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.uniHandle(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) ~[na:na]
halo  |                 at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(Unknown Source) ~[na:na]
halo  |                 at com.github.jasync.sql.db.util.FutureUtilsKt.failed(FutureUtils.kt:18) ~[jasync-pool-2.1.7.jar:na]
halo  |                 at com.github.jasync.sql.db.mysql.MySQLConnection.failQueryPromise$lambda-11(MySQLConnection.kt:355) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at java.base/java.util.Optional.ifPresent(Unknown Source) ~[na:na]
halo  |                 at com.github.jasync.sql.db.mysql.MySQLConnection.failQueryPromise(MySQLConnection.kt:354) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at com.github.jasync.sql.db.mysql.MySQLConnection.setException(MySQLConnection.kt:205) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at com.github.jasync.sql.db.mysql.MySQLConnection.onError(MySQLConnection.kt:199) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at com.github.jasync.sql.db.mysql.codec.MySQLConnectionHandler.channelRead0(MySQLConnectionHandler.kt:125) ~[jasync-mysql-2.1.7.jar:na]
halo  |                 at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) ~[netty-transport-classes-epoll-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:499) ~[netty-transport-classes-epoll-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:397) ~[netty-transport-classes-epoll-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.85.Final.jar:4.1.85.Final]
halo  |                 at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
halo  | Caused by: com.github.jasync.sql.db.mysql.exceptions.MySQLException: Error 1406 - #22001 - Data too long for column 'data' at row 1
halo  |         at com.github.jasync.sql.db.mysql.MySQLConnection.onError(MySQLConnection.kt:198) ~[jasync-mysql-2.1.7.jar:na]
halo  |         at com.github.jasync.sql.db.mysql.codec.MySQLConnectionHandler.channelRead0(MySQLConnectionHandler.kt:125) ~[jasync-mysql-2.1.7.jar:na]
halo  |         at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) ~[netty-transport-classes-epoll-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:499) ~[netty-transport-classes-epoll-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:397) ~[netty-transport-classes-epoll-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.85.Final.jar:4.1.85.Final]
halo  |         at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.85.Final.jar:4.1.85.Final]
halo  |         at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]

附加信息

前端 console:
image

从 Halo 1.5 还是 1.6 迁移过来的,导入数据时没出问题,但是想更新文章就不行了。

@guqing
Copy link
Member

guqing commented Dec 3, 2022

/assign @JohnNiang
/area core

@f2c-ci-robot f2c-ci-robot bot added the area/core Issues or PRs related to the Halo Core label Dec 3, 2022
@JohnNiang
Copy link
Member

在 MySQL 中,Blob 类型字段的允许的长度:<= 2^16 + 2 bytes(约 64 KB),而 Halo 初始化 extension 表的 data 字段类型就是 blob。文章内容的 HTML 片段内容已经超过了限制。

Workaround(临时解决方案)

尝试修改 extension 表的 data 字段类型为:MEDIUMBLOB 或者 LONGBLOB

alter table extensions modify data mediumblob;

参考:

@AnotiaWang
Copy link
Author

已将 data 修改为 MEDIUMBLOB,目前使用正常

@AnotiaWang
Copy link
Author

我觉得比较理想的机制是这样的,不知是否正确:

用户保存/发布文章时,如果长度达到 data 当前类型允许的最大长度,并且还有更高一级的类型,则自动扩展;否则提示用户文章过长。

(可选)弄一个定时任务检查数据库中文章,如果长度都小于某个类型的 max size ,则将 data 的类型降级。

@JohnNiang
Copy link
Member

JohnNiang commented Dec 5, 2022

其实不用降级的。Blob、MediumBlob 和 LongBlob 本身就是变长的。

f2c-ci-robot bot pushed a commit that referenced this issue Dec 5, 2022
… at row 1" (#2833)

#### What type of PR is this?

/kind improvement
/area core
/milestone 2.0.1

#### What this PR does / why we need it:

See #2832 and #2832 (comment) for more.

For a workaround, please refer to:
- #2832 (comment)

But, there are still limitations here:
- For MySQL: ~4GB
- For PosgreSQL: ~1GB

#### Which issue(s) this PR fixes:

Fixes #2832

#### Does this PR introduce a user-facing change?

```release-note
修复因文章过长导致无法保存数据的问题
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core Issues or PRs related to the Halo Core
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants