最近进行了网站服务器的整理优化后,才发现之前安装 Gitea 时埋了一个坑。
因为那时我的 MySQL 没有 Docker 化,容器内的 Gitea 无法通过内网连接宿主机器的 MySQL,所以在安装配置 Gitea 时,我选择了 SQLite3 数据库。
而如今为了便于统一管理,我还是决定将 Gitea 的 SQLite3 迁移至 MySQL,原本以为只是简单的数据库信息迁移,没想到折腾了八个小时才解决,因此记录下踩过的坑,和最终的解决方案。
使用 SQLite3 命令行
刚开始搜索“SQLite 转 MySQL”时,文心一言给出的方案是,使用 sqlite3 original.db .dump > result.sql
这一终端操作。
我半信半疑地试了下,发现在我的 Windows 11 机器上面,确实有 sqlite3
这么个命令行工具,并且这个命令确实能生成 .sql
文件。但我尝试将其导入到 MySQL 时,它从第一行内容就开始报错……
去搜索了之后才得知,前几行的内容是 SQLite 特有的指令,也难怪 MySQL 会报错。但我将其删除后,仍旧无法导入。
使用 phpMyAdmin 手动添加数据后,进行命令比对才发现,.sql
执行的语句的格式还是与我的导出格式存在差异(比如所有的数字都会以字符串的形式输入,不知道是不是这个原因导致报错)
使用第三方软件
网上很多人的方案是使用 Navicat 进行 SQLite → MySQL 的转换。
首先我去搜了下,需要使用的版本是 Navicat Premium,而这是一个商业软件。因此这种方案颇有一种为了一碗醋包了一碟饺子的感觉…
但解决需求要紧,通过一些开心的手段最终是用上了这个软件。
网上有两种方法:
- 直接在表中将所有数据进行导出
- 使用菜单栏的“工具”→“数据传输”
这两种方法我都试过,方法一存在语法规范问题(比如表名会加上双引号,数字不会以字符串形式输入),且会将每一个表单独导出为一个 .sql
文件,咱还得合并或者多次导入;而方法二导出的 .sql
文件虽然已经很接近 phpMyAdmin 导出的 .sql
文件了,但在导入时仍旧会报错。
我也尝试在使用方法一时,将其导出为 .csv
文件,但仍旧在导入时出现问题……
使用在线工具
毕竟咱要操作的是数据库,把数据库丢到云端处理,多少还是有些不放心,但最后实在是没办法了,所以我尝试使用 RebaseData 的转换服务,并且为了导出完整数据,还注册了一个账号…
最终结果,既有好消息也有坏消息,好消息是,该在线工具确实可以将 Gitea 的 SQLite3 数据库文件转为 MySQL 的 .sql
文件,且能正常导入到 MySQL;坏消息是,导入之后我的 Gitea 直接 502 了……
尝试了很多次,排查了各种其他问题后,最终确定仍旧是数据库没有正确转换。
最终解决方案
在 Google 上使用英文关键词找到了有效的解决方案
https://github.com/go-gitea/gitea/issues/26862
原来 Gitea 是有命令行工具的,而该命令行工具支持生成转储文件,且能指定生成的转储文件中的数据库导出格式。
所以最后按照 Gitea 官方教程 使用 gitea dump --database mysql
即可获得包括可导入的 .sql
文件在内的转储文件压缩包。
只不过在 Docker 内,卷的映射和写入权限有一丢丢麻烦。这里我是修改了 Gitea 的容器,重新映射了一个新的 \backups
文件夹到容器内,然后在该文件夹内执行上述命令,即可得到最终的转储文件压缩包。
至于该如何在 Docker 内执行终端命令的话……我的面板的容器管理界面是可以进入该容器的终端的,所以直接以非 root 身份登录 Gitea 容器的终端即可(比如我的 Gitea 是以 git
账户运行的)
总结
除了上述尝试过的方案,其实还有其他理论可行的方案,例如编写 Python 脚本,实现一对一地将 SQLite3 的数据库条目写入到 MySQL 数据库中。但出于时间成本和生产环境的考虑,我没有尝试该方法。而且不排除 Gitea 对 SQLite3 和 MySQL 的数据存储方式有区别,可能仍会出错。有兴趣的小伙伴可以试试。
其实最初文心一言也给过我 使用 Gitea 终端工具
的类似方案,但那时我没有看到它的这一结果的信息来源,以为是某些不可靠的信息拼凑出来的结果。现在想想,AI 工具还是挺有前途的~
好文收藏下
扯句题外话,Docker 容器是可以访问宿主机端口的,如果 Docker 网桥的网段是 172.17.0.0/24,那么容器可以通过访问 172.17.0.1:3306 连接到宿主机数据库。如果宿主机数据库配置了 IP 限制,那么需要放通 172.17.0.0/24 的访问(默认是只有 127.0.0.1 放通的)
@ChrisKim 好好好,原来还能这么干,涨知识了。