Memos数据迁移

去年年底时腾讯云轻量应用服务器做活动,2C2G配置13个月才80块钱不到,就将Memos部署在腾讯云上。公网IP随时随地都可以访问,但是服务器续费太贵,不准备续费,需要将数据迁移到本地。找了一圈,没找到现成的迁移工具。

因为数据存储方式选择的是sqlite,所以想着直接将服务器上的memos_prod.db数据库文件和assets文件夹拷贝到本地,再docker中运行memos镜像时挂载这个目录就可以,但是不知道什么原因,挂上之后数据不完整,比如用户信息是可以在页面展示的,而memo以及resource在页面加载时直接出现红色报错信息。

于是改了方案,先在本地将memos跑起来,再将数据用SQL复制到表中。这样做的缺点就是费时费力,并且有点坑的是,两次docker镜像的版本还不一致,表结构有变更,导致写SQL的时候还要对字段。

操作步骤:

  1. 从服务器上将挂载目录中的文件 memos_prod_db 和 assets 目录拷贝至本地存档

  2. 本地先将memos跑起来,确保能正常发布:

    # 创建 volume
    docker volume create memosdata
    # 拉取镜像
    docker pull neosmemo/memos:latest
    # 运行镜像
    docker run -d --name memos -p 5230:5230 -v memosdata:/var/opt/memos neosmemo/memos:latest
    
  3. 安装sqlite:

    sudo apt install sqlite3
    
  4. 打开两个数据库并拷贝数据:

    # 查看 memosdata 位置
    docker volume inspect memosdata
    # 打开 sqlite3
    sqlite3
    .open memosdata/memos_prod.db
    .open bak/memos_prod.db as db1
    # 查看表
    select * from sqlite_master where type = 'table';
    # 查看表结构
    PRAGMA table_info(memo);
    
    # 拷贝数据,主要有 memo, resource, tag, 其中 memo 表和 tag 表直接拷贝
    insert into memo
    select * from db1.memo where 1 = 1;
    
    insert into tag
    select * from db1.tag where 1 = 1;
    
    # resource 表原本 10 个字段,更新后多了一个字段,拷贝 SQL 需要做一下表连接
    insert into resource
    select a.id,
           a.creator_id,
           a.created_ts,
           a.updated_ts,
           a.filename,
           a.blob,
           a.external_link,
           a.type,
           a.size,
           a.internal_path,
           b.memo_id  -- 多出来的字段
    from db1.resource as a
        left join db1.memo_resource b
            on a.id = b.resource_id
    where 1 = 1;
    

    现在刷新页面,应该是 memos 的文字正常展示。

  5. 最后,将 assets 目录一整个拷贝至 memosdata 目录下,再刷新页面验证即可。

  6. 其他的表没做处理,目前看起来应该是没用到。