侧边栏壁纸
  • 累计撰写 416 篇文章
  • 累计创建 65 个标签
  • 累计收到 150 条评论

目 录CONTENT

文章目录

Halo 升级1.6.0v并更换H2数据库为MySQL

Z同学
2022-11-20 / 3 评论 / 7 点赞 / 1,901 阅读 / 2,424 字
温馨提示:
本文最后更新于 2022-11-24,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1.情况

最近发现内容更新后,刷新内容时,容易出现 500的错误。这个错误在刷新过程中偶尔出现。

## 500

# Internal Server Error.

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet

通过后台日志看到的输出内容为:

Caused by: java.lang.IllegalStateException: java.lang.OutOfMemoryError: Direct buffer memory [1.4.199/3]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.store(MVStore.java:1194) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.commit(MVStore.java:1166) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.compactRewrite(MVStore.java:2169) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.compact(MVStore.java:2041) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.writeInBackground(MVStore.java:2776) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore$BackgroundWriterThread.run(MVStore.java:3123) ~[h2-1.4.199.jar!/:na]
Caused by: java.lang.OutOfMemoryError: Direct buffer memory
	at java.base/java.nio.Bits.reserveMemory(Bits.java:175) ~[na:na]
	at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:118) ~[na:na]
	at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317) ~[na:na]
	at java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:242) ~[na:na]
	at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:71) ~[na:na]
	at java.base/sun.nio.ch.FileChannelImpl.writeInternal(FileChannelImpl.java:850) ~[na:na]
	at java.base/sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:836) ~[na:na]
	at org.h2.store.fs.FileNio.write(FilePathNio.java:79) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.DataUtils.writeFully(DataUtils.java:439) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.FileStore.writeFully(FileStore.java:113) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.write(MVStore.java:935) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.storeNow(MVStore.java:1332) ~[h2-1.4.199.jar!/:na]
	at org.h2.mvstore.MVStore.store(MVStore.java:1190) ~[h2-1.4.199.jar!/:na]
	... 5 common frames omitted

因为缓冲区间内存溢出。都是发生在h2数据库的io请求上的。

如果单纯想扩展运行时分配的内存空间的话,可以通过修改 /etc/systemd/system/halo.service 文件。

 
ExecStart=/usr/bin/java -server -Xms1024m -Xmx1024m -XX:MaxDirectMemorySize=128m -jar /root/app/halo.jar

保存文件之后,停止halo 服务: service halo stop

然后执行: systemctl daemon-reload 让配置生效。

最后执行:service halo start 等待几秒,服务器启动成功。

就可以解决问题了。

页面刷新出现java.lang.OutOfMemoryError: Direct buffer memory 的问题得到了显著改善,

但是,H2的数据使用效果的确没有MySQL稳定。特别是随着内容的不断更新,服务器的长时间运行。渐渐感觉H2的操作不太方便,所以就想将数据库进行一次升级操作。

从H2升级到MySQL中来。顺便将Halo从1.5.4升级到1.6.0版本。

1.1 环境

在执行操作前,先简单介绍下我的服务器情况。

  1. 阿里云ESC 服务器,CentOS 8.0系统。
  2. 所有环境通过手动安装的,例如Java 11SDK, Nginx,Halo
  3. Halo 版本为 1.5.4

没有采用Docker镜像安装。服务器无MySQL。

1.2 步骤

我们如果要将现有的网站H2改为MySQL,主要步骤为:

  1. 通过Halo后台,进行数据备份为json。并将该json文件下载保存。
  2. 停止Halo 服务器。
  3. 修改application.yaml 配置文件,将连接服务器从H2改为MySQL。
  4. 启动Halo服务器,在初始化界面导入json。

注意

  1. 不用删除你已有的.halo配置目录。
  2. 更换H2到MySQL 不会造成数据丢失。
  3. 建议跟换数据库成功之后,再进行Halo升级。
  4. 建议在更新过程中,暂停服务器的域名访问,可以提高安全性。

2. MySQL配置

2.1 安装 MySQL

(如果已经安装过MySQL,可以跳过这个步骤)

既然要更换,那么就需要先安装好MySQL

第一步更新源: rpm -Uvh  http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm

第二步下载并安装:yum -y install mysql-community-server --nogpgcheck

第三步,查询MySql版本: mysql -V

最后有显示MySQL的版本号,就代表我们安装成功了。

想看详细的安装流程可以参考文章:https://zinyan.com/?p=374 这里就不展开了。

2.2 创建Halo数据库

安装完毕后,通过mysql -uroot -p 进行登录mysql

如果你忘记了MySQL的root密码,可以通过https://zinyan.com/?p=471 介绍的方法,找回root密码。

[root@iZufy ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.40 MySQL Community Server (GPL)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

然后执行数据库创建指令:create database halodb character set utf8mb4 collate utf8mb4_bin; 具体示例如下:

mysql> create database halodb character set utf8mb4 collate utf8mb4_bin;
Query OK, 1 row affected (0.00 sec)

mysql> 

这个时候我们可以执行show databases;命令看到我们创建的halodb数据库。示例如下:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| halodb             |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> 

之后,输入exit退出mysql命令模式。

mysql> exit
Bye
[root@iZufy ~]#

3. Halo配置

当我们将MySQL配置完毕后就开始修改halo的配置信息,将halo的datasource指向我们建立的MySQL。

但要指向之前,需要先将H2数据库中的信息进行备份导出成json。

3.1 H2数据备份

通过Halo后台管理面板,选择系统菜单–小工具选项。在博客备份中选择数据导出。然后点击备份按钮。

halo-data-export.png

将备份后的json文件下载到本地,作为备用操作。

3.2 修改 application.yaml文档

先暂停Halo,指令为:service halo stop。执行后根据性能可能会有些反应延时。等一会就好

[root@iZufy ~]# service halo stop
Redirecting to /bin/systemctl stop halo.service

然后修改application.yaml 文件。

[root@iZufy ~]# cd .halo
[root@iZufy .halo]# ls
application.yaml  db  logs  static  static_pages  templates  upload
[root@iZufy .halo]# vim application.yaml

将配置文件中的 H2 database configuration.部分注销,开放 MySQL database configuration.部分。示例如下:

server:
  port: 8080

  # Response data gzip.
  compression:
    enabled: true
spring:
  datasource:

    # H2 database configuration.
    # driver-class-name: org.h2.Driver
    # url: jdbc:h2:file:~/.halo/db/halo
    # username: admin
    # password: 123456
    #
  # H2 database console configuration.
  # h2:
  #  console:
  #    settings:
  #      web-allow-others: false
  #    path: /h2-console
  #    enabled: false

    # MySQL database configuration.
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/halodb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: 123456
halo:

把H2的相关配置注销,将MySQL的配置添加上去就可以了。

最后,将password 修改为你的root账户的密码就可以了。如果你的数据库创建的不是halodb那么这个地方就修改为自身创建的数据库名。

如果MySQL的端口号不是3306那么你还需要修改这个配置中的端口号。

如果你的MySQL是通过Docker容器部署的,你可以参考Halo官网介绍的指南进行配置。

3.3 导入json包

当配置文件修改完毕后,我们就执行:

[root@iZufy ~]# service halo start

启动当前Halo服务器。

请注意:

1.我们如果在1.5.4版本导出的json。那么也只有1.5.4版本的服务器才能支持json导入。否则会出现版本不匹配无法导入的问题。

2.建议执行更新配置的时候,关闭域名解析。避免其他人在初始化的时候污染我们的配置环境。

重启完毕后,打开我们的服务器会自动重定向到install安装配置界面。我们在该界面中导入我们在第一步获取的H2配置数据。

halo-data-import.png

导入完毕之后,清理浏览器缓存。刷新界面。网站就会恢复正常了。

我们的所有发表数据,配置信息,附件内容等都没有丢失。

那么我们如何判断数据库是切换成功了呢?

很简单:系统后台中的关于界面中原先的数据库:H2 已经变成了 数据库:MySQL了。

3.4 下载最新Halo 1.6 jar包

PS:

  1. 建议先进行备份,然后再下载最新Halo 1.6版本包。备份操作可以参考https://zinyan.com/?p=307

  2. 建议先执行Json包导入,切换完数据库后再进行更新。(备份json只支持当前Halo版本的导入)

我这里直接更新下载最新的Halo包:

[root@iZufy ~]# cd ~/app && wget https://dl.halo.run/release/halo-1.6.0.jar -O halo.jar

PS: 建议通过GitHub进行下载,最近https://dl.halo.run/release/的下载速度简直太感人了。慢

然后再推送到Linux服务器的~/app 目录下

下载完毕后,目录样式为:

[root@iZufy app]# ls
halo.jar.1.5.4  halo.jar
[root@iZufy app]# 

halo.jar是我刚才下载的,halo.jar.1.5.4 是我上一个版本的备份文件。

然后执行 service halo start 启动操作。

到这里,更新最新Halo 1.6版本。顺便替换了数据库,从H2改为了MySQL。

4. 其他

H2 可能安装和备份的时候比较方便,数据库完全不用管理。但是当数据量稍微多一些的情况下,还是没有MySQL的性能强。

7

评论区