likes
comments
collection
share

Mysql迁移数据到SQLite以及go-sqlite3 requires cgo的坑博客的`Mysql`数据库切换成`

作者站长头像
站长
· 阅读数 18

前言

去年双十一购买的一年期的新人优惠服务器(2C 4G)快到期了,这几天准备购买一个海外的服务器。但海外的服务器价格比较昂贵,也是第一次使用,所以想先买一个1C 1G的。

现在的4G的服务器内存占用率差不多是50%多一点,其中占用比较大的是docker中跑的Elastic Search服务和Mysql服务。

目前我的博客就正在使用其中的Mysql服务,如果要把博客系统迁移到新的服务器上,同时也要把Mysql迁移过去。

如果从4G降低到1G,内存可能就不够用了,所以就想着把博客的Mysql数据库切换成SQLite数据库,从而降低内存的使用。

欢迎来到我的博客🎉

从Mysql迁移数据到SQLite

把当前服务器中的Mysql的数据库迁移SQLite只需要两步:

  • 使用mysqldump命令输出dump.sql文件
  • 使用mysql2sqliteshell工具来生成sqlite.db

为什么使用mysql2sqlite来迁移

尝试过在DataGrip(Jetbrains家的数据库管理客户端)去Copy Data,但关于一些日期的处理不好,所以我选择mysql2sqlite。事实证明这个迁移脚本确实比较好用。

生成sql文件

在一台安装了mysql-client(mysql的shell客户端)的机器上进行SQL文件的输出,mysqldump是默认安装在该库中的命令。

以我所在的MacOS机器上为例,如果想要安装mysql-client,最简单的方式就是使用brew install mysql-client

然后使用mysqldump命令进行mysql数据的文件导出:

mysqldump -u root -P 3306 -h your_mysql_ip_address -p --skip-extended-insert your_database > dump_mysql.sql

生成sqlite.db

Unix机器上,比如Linux和MacOS下载「mysql2sqlite」,去执行下面的命令:

./mysql2sqlite dump_mysql.sql | sqlite3 sqlite3.db

然后就能得到sqlite的数据库文件了。接下来就可以直接访问这个数据库了。

MacOS 和 Linux上的很多系统都自带Sqlite3,使用sqlite3命令查看是否已有该数据库环境。

进行切换

代码修改

从这个「commit」开始进行代码的改造,其实改造起来非常简单,但中间还是遇到了一个小坑耽误了不少时间。

我在go的后端工程中使用「XORM」来作为数据库的ORM,它本身就支持MysqlSQLite3数据库的支持,我只需要在底层把Mysql的引擎切换成SQLite3即可,其他的都不需要改变。

package infrastructure

import (
	_ "github.com/mattn/go-sqlite3"
	"log"
	"time"
	"tunan-blog/env"
	"xorm.io/xorm"
	"xorm.io/xorm/names"
)

var Sqlite *xorm.Engine

func init() {

	println("sqlite3 connect db file", env.Prop.Sqlite3.File)
	newEngine, err := xorm.NewEngine("sqlite3", env.Prop.Sqlite3.File)

	if err != nil {
		log.Println(err)
		return
	}

	// 设置驼峰转换
	newEngine.SetMapper(names.GonicMapper{})

	// 时区
	newEngine.TZLocation, _ = time.LoadLocation("Asia/Shanghai")

	err = newEngine.Ping()
	if err != nil {
		log.Println(err)
		return
	}

	Sqlite = newEngine
}

当我在本地完成编译调试完成,将GO的可执行文件打包好,上传到服务器上执行时,就报错连接不上数据库了。

go-sqlite3 requires cgo的坑

一开始没有很好的打印出报错日志(大晚上的脑袋昏昏沉沉),导致我排查了很久:

  • 文件路径
  • 文件权限
  • 文件是否损坏

这些问题都不存在,最后尝试去询问XORM的开发者:

Mysql迁移数据到SQLite以及go-sqlite3 requires cgo的坑博客的`Mysql`数据库切换成`

没有回复后,我就去洗澡去了,等洗完澡回来后发现我打印的ERR有问题,当我把真正的ERR

Binary was compiled with 'CGO_ENABLED=0, go-sqlite3 requires cgo to work. This is a stub'

打印出来后,发现是需要将CGO_ENABLED=1设置成这样来编译。

正如前文说的,我是在本地(MacOS)中使用CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o tunan-blog cmd/tunan-blog/main.go来打包成Linux上的可执行文件,然后上传到服务器上执行的。

当我设置CGO_ENABLED=1去打包时,再次报错了:

implicit declaration of function 'setresgid' is invalid in C99

在上面的这个issue中发现了解决方法,来自惊帆的BLOG的一篇文章: 使用go语言进行交叉编译的时候遇到的一些问题

通过上面文章中的解决方案:

  1. MacOS上安装musl-cross
brew install FiloSottile/musl-cross/musl-cross
  1. 修改打包命令为
apt-get -y install musl
  1. 执行可执行文件的Linux(我的是Ubuntu系统)上安装musl
CGO_ENABLED=1 GOOS=linux  GOARCH=amd64  CC=x86_64-linux-musl-gcc  CXX=x86_64-linux-musl-g++ go build -o tunan-blog cmd/tunan-blog/main.go

然后重新运行即可。

结束

最后成功将底层的Mysql切换成了SQLite3,等新的服务器买了之后,只要把sqlite.db文件Copy过来就可以了,比Mysql轻量且方便!

转载自:https://juejin.cn/post/7418117491720781833
评论
请登录