apache / incubator-hugegraph

A graph database that supports more than 100+ billion data, high performance and scalability (Include OLTP Engine & REST-API & Backends)
https://hugegraph.apache.org
Apache License 2.0
2.62k stars 517 forks source link

hugegraph 备份出错 #1274

Open wisdoms opened 3 years ago

wisdoms commented 3 years ago

Expected behavior 期望表现

能正常备份

Actual behavior 实际表现

备份出错, 消息: Caused by : com .baidu.hugegraph.hugeException: Can't write json: undefined index label with id : '2320" (through reference chain" java.util.arrayList[143])

Steps to reproduce the problem 复现步骤

  1. 执行备份 命令
  2. 备份报错 3

Status of loaded data 数据状态

Vertex/Edge summary 数据量

< 10000

Vertex/Edge example 数据示例

{type something here...}

Schema(VertexLabel, EdgeLabel, IndexLabel) 元数据结构

{type something here...}

Specifications of environment 环境信息

wisdoms commented 3 years ago

在删除 顶点的时候,也会报同样的错误 : com .baidu.hugegraph.hugeException: Can't write json: undefined index label with id : '2320" (through reference chain" java.util.arrayList[143])

javeme commented 3 years ago

@wisdoms 可以提供一下复现流程吗?

wisdoms commented 3 years ago

因为整个操作在内网进行,操作过程就是不断的批量导入 数据,批量每次最多100条, 然后再删除,再导,这样重复了2-3 次,就出现了上面 的这种情况。

javeme commented 3 years ago

@wisdoms 使用的什么后端存储?是怎么删除的?可以提供一下各步骤的语句吗?

wisdoms commented 3 years ago

后端使用的是 rockdb 存储, 删除的语句是这样的,这个语句是参考了 hugegraph 源码中的删除顺序 :

public boolean clearData(String labelName) {
        logger.info("clearData labelName:{} ", labelName);
        if (StringUtils.isBlank(labelName)) {
            // Clear edge
            getEdgeAPI().list(-1).results().forEach(edge -> {
                edgeAPI.delete(edge.id());
            });
            // Clear vertex
            getVertexAPI().list(-1).results().forEach(vertex -> {
                try {
                    vertexAPI.delete(vertex.id());
                } catch (Exception e) {
                    logger.info("clearData labelName:{}  message: {}", labelName, e.getMessage());
                    e.printStackTrace();
                }
            });
            // Clear schema
            List<Long> ilTaskIds = new ArrayList<>();
            getIndexLabelAPI().list().forEach(indexLabel -> {
                ilTaskIds.add(indexLabelAPI.delete(indexLabel.name()));
            });

            List<Long> elTaskIds = new ArrayList<>();
            getEdgeLabelAPI().list().forEach(edgeLabel -> {
                elTaskIds.add(edgeLabelAPI.delete(edgeLabel.name()));
            });

            List<Long> vlTaskIds = new ArrayList<>();
            getVertexLabelAPI().list().forEach(vertexLabel -> {
                vlTaskIds.add(vertexLabelAPI.delete(vertexLabel.name()));
            });

            getPropertyKeyAPI().list().forEach(propertyKey -> {
                propertyKeyAPI.delete(propertyKey.name());
            });
            // Clear system
            getTaskAPI().list(null, -1).forEach(task -> {
                taskAPI.delete(task.id());
            });
        } else {
            // Clear edge
            getEdgeAPI().list(-1).results().forEach(edge -> {
                if (edge.sourceLabel().equals(labelName)) {
                    edgeAPI.delete(edge.id());
                }

            });
            // Clear vertex
            getVertexAPI().list(-1).results().forEach(vertex -> {
                try {
                    if (vertex.label().equals(labelName)) {
                        vertexAPI.delete(vertex.id());
                    }
                } catch (Exception e) {
                    logger.info("clearData labelName:{}  message: {}", labelName, e.getMessage());
                }
            });
            // Clear schema
            List<Long> ilTaskIds = new ArrayList<>();
            getIndexLabelAPI().list().forEach(indexLabel -> {
                if (indexLabel.name().indexOf(labelName) > -1) {
                    ilTaskIds.add(indexLabelAPI.delete(indexLabel.name()));
                }
            });

            List<Long> elTaskIds = new ArrayList<>();
            getEdgeLabelAPI().list().forEach(edgeLabel -> {
                if (edgeLabel.name().indexOf(labelName) > -1) {
                    elTaskIds.add(edgeLabelAPI.delete(edgeLabel.name()));
                }
            });

            List<Long> vlTaskIds = new ArrayList<>();
            getVertexLabelAPI().list().forEach(vertexLabel -> {
                if (vertexLabel.name().equals(labelName)) {
                    vlTaskIds.add(vertexLabelAPI.delete(vertexLabel.name()));
                }
            });

/*            getPropertyKeyAPI().list().forEach(propertyKey -> {
                propertyKeyAPI.delete(propertyKey.name());
            });*/
            // Clear system
            getTaskAPI().list(null, -1).forEach(task -> {
                if (task.name().indexOf(labelName) > -1) {
                    taskAPI.delete(task.id());
                }
            });
        }
        return true;
    }
wisdoms commented 3 years ago

我想能不能把图库的数据按查询的条件导出,然后再清空图库,再初始化,这样可能 很麻烦,如果 不这样的话,图库备份不了, 请问李老师,有没有比这个更有效的方法?

wisdoms commented 3 years ago

请问各位老师,这种情况 该 怎么备份或修复?

javeme commented 3 years ago

@wisdoms 方便把堆栈信息提供一下吗?应该是个bug,可以通过HugeGraph公众号管理员联系我们,根据具体问题来进行修复。

wisdoms commented 3 years ago

好的,最近 有些忙,不好意,回复有些慢。 堆栈信息如下 : thread "main" class com.baidu.hugegraph.HugeException: Failed to serialize edgelabels at com.baidu.hugegraph.exception.ServerException.fromResponse(ServerException.java:44) at com.baidu.hugegraph.client.RestClient.checkStatus(RestClient.java:100) at com.baidu.hugegraph.rest.RestClient.get(RestClient.java:193) at com.baidu.hugegraph.api.schema.EdgeLabelAPI.list(EdgeLabelAPI.java:69) at com.baidu.hugegraph.driver.SchemaManager.getEdgeLabels(SchemaManager.java:174) at com.baidu.hugegraph.driver.SchemaManager.getEdgeLabels(BackupManager.java:178) at com.baidu.hugegraph.manager.BackupManager.backup(BackupManager.java:111) at com.baidu.hugegraph.cmd.HugeGraphCommand.exccute(HugeGraphComamand.java:142) at com.baidu.hugegraph.cmd.HugeGraphComamand.min(HugeGraphComamand.java:379) caused by: com.baidu.hugegraph.HugeException: Can't write json: Undefined index label with id '2320'(through reference chain: java.util.ArrayList[143])

javeme commented 3 years ago

@wisdoms 看起来可能是存在竞争条件,导致删除index-label时未成功更新edge-labe中的indexLabels域,具体原因我们会进一步分析,也欢迎提供一些复现步骤。

wisdoms commented 3 years ago

具体的复现步骤是这样的:

  1. 批量在图库中导入了 1万左右个事件类型的顶点 , 每个顶点有几个到20多个属性,导入时,发现顶点名称有中文标点符号,主要是 (),”“,逗号,《》号还有:号
  2. 导入的逻辑是这样的,以顶点名为 nid, 每次导入前查询 该labelName 下有无相同的名称的顶点,有的话进行更新,更新时,属性是动态添加的,没有属性追加,有属性就更新值, 然后就是创建索引,首先是检查索引是否存在,如果 存在,就不创建,不存在就创建
  3. 在导入后,发现顶点labelName名称有中文符号,想去掉中文符号,就通过 g.V().fileter(properties('事件类型')) 来删除顶点
  4. 删除方法是通过上面粘贴的 删除方法,来删除顶点,边,索引
  5. 在删除完后,进行 graph.schema().getEdgelabels() 就会出错 ,报 undefined index label 2320
  6. 至今,这个问题仍然没有解决,数据也没法导出再导入,只能通过备份 rocksdb-data 文件夹来备份数据 (后端 是 rockdb 存储)
  7. 在使用 edgeAPI.list() 时也会报 undefined index label 2320 8
wisdoms commented 3 years ago

` public boolean clearData(String labelName) { logger.info("clearData labelName:{} ", labelName); if (StringUtils.isBlank(labelName)) { // Clear edge getEdgeAPI().list(-1).results().forEach(edge -> { edgeAPI.delete(edge.id()); }); // Clear vertex getVertexAPI().list(-1).results().forEach(vertex -> { try { vertexAPI.delete(vertex.id()); } catch (Exception e) { logger.info("clearData labelName:{} message: {}", labelName, e.getMessage()); e.printStackTrace(); } }); // Clear indexLabel getIndexLabelAPI().list().forEach(indexLabel -> { indexLabelAPI.delete(indexLabel.name()); });

        // clear edgeLabel
        getEdgeLabelAPI().list().forEach(edgeLabel -> {
            logger.info("delete  edgelagel: {}", edgeLabel.name());
            edgeLabelAPI.delete(edgeLabel.name());
        });

        // vertexLabel
        getVertexLabelAPI().list().forEach(vertexLabel -> {
            vertexLabelAPI.delete(vertexLabel.name());
        });

        getPropertyKeyAPI().list().forEach(propertyKey -> {
            propertyKeyAPI.delete(propertyKey.name());
        });
        // Clear system
        getTaskAPI().list(null, -1).forEach(task -> {
            taskAPI.delete(task.id());
        });
    } else {
        // Clear edge
        try {
            getEdgeAPI().list(-1).results().forEach(edge -> {
                if (edge.label().indexOf(labelName) > -1) {
                    edgeAPI.delete(edge.id());
                }

            });
        } catch (Exception e) {
            logger.info("clearData labelName:{}  message: {}", labelName, e.getMessage());
        }
        // Clear vertex
        getVertexAPI().list(-1).results().forEach(vertex -> {
            try {
                if (vertex.label().equals(labelName)) {
                    vertexAPI.delete(vertex.id());
                }
            } catch (Exception e) {
                logger.info("clearData labelName:{}  message: {}", labelName, e.getMessage());
            }
        });
        // Clear schema
        getIndexLabelAPI().list().forEach(indexLabel -> {
            if (indexLabel.name().indexOf(labelName) > -1) {
                indexLabelAPI.delete(indexLabel.name());
            }
        });

        try {
            getEdgeLabelAPI().list().forEach(edgeLabel -> {
                if (edgeLabel.name().indexOf(labelName) > -1) {
                    logger.info("delete  edgelagel: {}", edgeLabel.name());
                    edgeLabelAPI.delete(edgeLabel.name());
                }
            });
        } catch (Exception e) {
            logger.info("clearData labelName:{}  message: {}", labelName, e.getMessage());
        }

        getVertexLabelAPI().list().forEach(vertexLabel -> {
            if (vertexLabel.name().equals(labelName)) {
                vertexLabelAPI.delete(vertexLabel.name());
            }
        });

/ getPropertyKeyAPI().list().forEach(propertyKey -> { propertyKeyAPI.delete(propertyKey.name()); });/ // Clear system getTaskAPI().list(null, -1).forEach(task -> { if (task.name().indexOf(labelName) > -1) { taskAPI.delete(task.id()); } }); } return true; }`

javeme commented 3 years ago

@wisdoms 收到,谢谢。

@lxb1111 尝试下复现看看。