干了这么多年图数据库,我最怕听到的一句话就是“把数据迁一下”。说这话的人轻飘飘,干这活的人得掉层皮。尤其是Neo4j,社区版和企业版迁移逻辑完全两码事,数据量一旦上了千万级,稍不留神就能让你加班到怀疑人生。今天这篇,就把我从旧库到新库踩过的坑、总结出的套路,一次性倒给你。

先别急着敲命令,第一步得搞清楚你到底要迁什么。很多人以为迁移就是导数据,大错特错。你得先盘点:节点、关系、属性这些是基本盘,但索引、约束、存储过程、自定义函数、甚至密码策略,这些“隐形资产”才是真正要命的地方。我见过一个项目,数据导过去挺顺利,结果忘了重建唯一性约束,业务跑了两天,重复数据直接让报表炸了。所以,动手之前,拿张纸列个清单:数据文件、索引定义、约束条件、用户权限、配置参数,一项项勾掉再开工。
说到具体方法,社区版用户最常用的就是APOC和cypher-shell。APOC的导出,配合导入,听起来丝滑,但这里有个大坑:导出文件里带着索引和约束的创建语句,可如果你的新旧库版本不一致,比如从4.x迁到5.x,这些语句很可能语法不兼容,导入时直接报错。我自己的习惯是,导出时加个参数,把schema相关的语句单独拎出来,手动检查一遍再执行。另外,千万别用,那个格式丢类型信息,迁过去你会哭的。
企业版用户就舒服多了,有官方的和命令。这玩意儿是物理备份,快是真快,一个亿的节点,半小时搞定。但注意,它要求新旧库的版本必须完全一致,小版本都不能差。我之前吃过大亏,4.4.6导出的dump,往4.4.12上load,直接报“incompatible format”。后来学乖了,要么升到同版本再导,要么干脆用逻辑导出。还有,dump文件是压缩的,你最好先估算下磁盘空间,别导到一半硬盘满了,那才叫欲哭无泪。
数据量小,几千几万个节点,怎么折腾都行。但数据量一上来,比如千万级节点、上亿关系,你就得讲究策略了。我强烈建议分批次导,别一把梭。用cypher-shell执行脚本时,每批控制在一万到五万条,加,避免单个事务太大撑爆内存。同时,关闭所有索引和约束,等数据导完再重建,这个顺序能让你提速至少三倍。还有,导入前把JVM堆内存调大,别抠搜,反正导完再调回来。
说说迁移过程中那些让人抓狂的“隐形炸弹”。第一个是ID冲突,源库删过节点,ID有空洞,新库那边说不定就撞上了。别依赖内部ID,导数据时把业务主键单独存成属性,导入后再用属性建关系。第二个是关系方向,cypher导入时,如果原数据里关系方向搞反了,你导完查起来全是反的,排查起来能疯。第三个是中文乱码,导出文件编码格式没统一,Windows和Linux之间来回传,最容易出这幺蛾子。我的土办法:导出后先head一眼,看到乱码立刻用iconv转码,别等导入完才发现。
验证环节,很多人觉得随便查两条数据能返回就完事了,太天真。你得做三件事:一是对数量,节点数、关系数,新旧库逐一比对,差一个都不行;二是抽样式验证,随机挑几个复杂子图,比对属性值和关系路径;三是跑一遍业务核心查询,看看性能有没有缩水。尤其是那些带深度遍历的查询,旧库跑50毫秒,新库跑3秒,那你得检查索引是不是没建全。
说个实战案例。去年帮一个金融客户做迁移,数据量大概两亿节点、八亿关系,从4.2迁到5.7。我们一开始图省事,想直接用dump,结果版本不兼容,白白浪费一天。后来改成APOC逻辑导出,分模块导,每个模块单独验证,再统一校验。过程相当煎熬,前后折腾了一周。但最让我印象深刻的不是技术,而是沟通——客户那边业务方天天催,说“就导个数据怎么这么慢”。我后来学聪明了,每完成一个模块就给他们发进度截图和验证报告,他们看到具体数字,催的频率明显低了。所以啊,迁移这种事,技术只占一半,另一半是让人看得见你在干活。
说回正题,Neo4j迁移真没有一劳永逸的银弹。社区版就老老实实走逻辑导出,企业版优先考虑dump,但版本约束得盯死。无论选哪条路,记住几个底线:备份永远要有,验证永远要全,文档永远要写。别嫌麻烦,等你出问题的时候,这些就是你救命的稻草。从旧库到新库,这趟路不好走,但走通了,你就能底气十足地跟别人说,图数据库迁移,也就那么回事。


