跨平台迁移踩坑记:从路径大小写到国产操作系统的那些事

前段时间做一个国产化改造项目,需要把一套原本运行在 Windows Server 上的业务系统迁移到麒麟操作系统。

数据库使用的是金仓 KingbaseES。

项目启动的时候,大家对这次迁移都比较乐观。

业务量不大,数据库也就几百G,应用改造工作提前完成了,测试环境也验证过几轮。

按照最初的计划,数据库迁移应该是整个项目里最轻松的一环。

结果真正开始实施后,第一个把我绊住的反而是表空间。

现在回头看,这个问题并不复杂,但当时确实浪费了不少时间。


一开始我以为是运维漏建目录了

迁移完成后恢复数据库。

执行表空间相关脚本的时候直接报错。

提示路径不存在。

看到这个错误的时候,我第一反应很简单:

目录没建。

因为以前做 Oracle、PostgreSQL 迁移的时候也经常遇到类似情况。

于是直接登录服务器检查。

结果发现目录是存在的。

不仅存在,权限看起来也没什么问题。

ls -ld /data/kingbase/tablespace/order

目录有。

权限有。

属主也正确。

按理说数据库应该能正常访问。

可脚本依然报错。


后来怀疑是权限问题

目录存在以后,我开始往权限方向排查。

先检查数据库运行用户。

又检查目录属主。

甚至怀疑是不是迁移过程中 SELinux 或安全策略导致访问失败。

那天下午基本都在围绕权限排查。

现在想想其实方向已经偏了。

因为真正的问题根本不在权限上。


最后发现居然是大小写的问题

问题最终定位出来的时候,我自己都愣了一下。

Windows 环境中的表空间路径是这样记录的:

/data/Kingbase/TestData

而实际目录是:

/data/kingbase/testdata

如果是在 Windows 环境里,这种情况根本不会有任何异常。

因为 Windows 默认不区分大小写。

无论写:

TestData
testdata
TESTDATA

系统都会认为是同一个目录。

但是迁移到麒麟系统以后就完全不同了。

Linux 文件系统严格区分大小写。

数据库按照表空间定义去寻找:

/data/Kingbase/TestData

结果实际存在的是:

/data/kingbase/testdata

自然就报目录不存在。

问题找到之后,修改路径立即恢复正常。

但当时为了排查这个问题,前前后后折腾了接近两个小时。


顺着这个问题,又发现了一个挺实用的功能

后来查资料的时候,无意间看到一个参数:

SHOW auto_createtblspcdir;

返回值是:

on

这个参数叫:

auto_createtblspcdir

作用很直接。

以前创建表空间的时候,需要先在操作系统里创建目录。

例如:

mkdir -p /data/kingbase/tablespace/order
chown kingbase:kingbase /data/kingbase/tablespace/order

然后才能执行:

CREATE TABLESPACE order_data
LOCATION '/data/kingbase/tablespace/order';

如果目录不存在,建表空间直接失败。

很多运维脚本里都会提前做目录创建动作。


现在不一样了。

如果参数开启,可以直接执行:

CREATE TABLESPACE order_data
LOCATION '/data/kingbase/tablespace/order';

数据库会自动创建对应目录。

刚开始看到这个功能的时候觉得没什么。

后来想想其实很实用。

尤其是在迁移环境或者批量部署环境的时候。

几十个表空间逐个创建目录其实很容易遗漏。

数据库自动完成这一步,能减少不少人为操作。


另一个老问题:路径分隔符

除了大小写之外,还有一个问题几乎每次跨平台迁移都会碰到。

就是路径分隔符。

Windows习惯使用:

D:\kingbase\data\tablespace\app

Linux则使用:

/opt/kingbase/data/tablespace/app

很多老项目的 SQL 直接写死了 Windows 路径。

例如:

CREATE TABLESPACE app_data
LOCATION 'D:\kingbase\data\tablespace\app';

这种脚本拿到 Linux 环境基本都会出问题。

原因大家都知道。

反斜杠在很多场景下会被当作转义字符处理。

有些路径甚至会出现:

\t
\n
\r

被解释成特殊字符。

排查起来非常麻烦。


后来我们团队内部统一了一个规范。

无论系统最终部署在哪个平台。

路径全部使用正斜杠。

例如:

CREATE TABLESPACE app_data
LOCATION 'D:/kingbase/data/tablespace/app';

看起来有点奇怪。

但 Windows 和 Linux 都能够识别。

这样以后迁移环境的时候基本不用再改路径。

这个小习惯后来帮我们省了不少事。


国产操作系统环境还有个隐藏问题

最近几年做国产化项目越来越多。

麒麟、统信这些系统接触得也越来越频繁。

很多人觉得它们本质就是 Linux。

其实这么说没错。

至少在路径规则和大小写规则上确实和标准 Linux 一致。

但项目现场经常还会叠加一些安全能力。

例如文件加密。

例如安全增强。

例如访问控制策略。

这些东西一旦开启,问题就会变得复杂很多。


之前有个客户环境就遇到过类似情况。

目录权限完全正常。

数据库用户也没问题。

但是访问仍然失败。

最后发现和安全策略有关。

虽然这次项目没有碰到这个问题,但排查过程中我还是顺手验证了一下。

如果表空间目录位于加密文件系统下,比较稳妥的做法是:

先创建父目录。

先完成加密配置。

确认数据库用户拥有访问权限。

然后再执行:

CREATE TABLESPACE secure_data
LOCATION '/encrypted/kingbase/tablespace/secure_data';

让数据库自动创建最终目录。

这样创建出来的目录通常会继承父目录的安全属性。

避免后面再调整权限。


后来我把这些检查都做成了固定动作

这次迁移结束以后,我把一些检查动作整理进了迁移清单。

迁移前先看所有表空间位置:

SELECT
    spcname,
    pg_tablespace_location(oid)
FROM pg_tablespace;

导出以后重点检查:

  • 是否存在大小写混写目录
  • 是否使用 Windows 路径格式
  • 目录是否真实存在
  • 属主是否正确
  • 是否涉及加密目录

另外确认:

SHOW auto_createtblspcdir;

确保自动创建功能已经开启。

很多问题其实提前十分钟检查就能发现。

远比上线当天临时排查轻松得多。


写在最后

这次迁移让我感触挺深。

很多时候大家讨论数据库迁移,关注点都在兼容性、性能或者数据一致性上。

而真正耽误项目进度的,往往是这些不起眼的小细节。

一个目录大小写。

一个路径分隔符。

一个提前没有创建好的目录。

单独看都不是什么大问题。

但如果这些问题同时出现在迁移现场,足够让人折腾半天。

好在这次踩完坑之后,也顺带了解了金仓的自动创建表空间目录功能。对于经常做跨平台迁移或者国产化改造的项目来说,这个功能确实能减少不少运维工作量。

如果你的系统也准备从 Windows 迁移到麒麟、统信或者其他 Linux 环境,我的建议其实很简单:

先别急着恢复数据库。

先把表空间路径全部检查一遍。

因为很多时候,问题真不一定出在数据库本身。它可能只是藏在一个不起眼的目录名里。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐