1

我在集群的 2 台 RHEL6 服务器上使用 MarkLogic 8。我在使用 mlcp 加载数据时遇到了 DEADLOCK(通知)错误。细节:

数据:500+ CSV 文件

File name Examples:
File1: 20170927_**ABC**_XX_YY.CSV
File2: 20170927_**DEF**_QX_QY.CSV
File3: 20170927_**DE**_QX_QY.CSV

要求:我需要加载这些文档,同时在加载过程中将每个 CSV 分配给一个集合。所以,File1 应该属于 ABC 集合,File2 应该属于 DEF 集合,File3 应该属于 DE 集合。

脚本:我试图通过使用 mlcp 单独加载每个 CSV 来实现这一点。

#!/bin/sh
listFiles=`ls -l /location/*.CSV | awk '{print $9}'`
for each in $listFiles
do
     collName=`echo $each | cut -d_ -f2`
     $MLCP_HOME/mlcp.sh import -mode local -options_file connect.txt \
     -input_file_path $each -input_file_type delimited_text \
     -generate_uri -output_collections $collName
done

问题:某些文件已加载到 MarkLogic 中而没有任何错误。但是,我在日志中看到“通知”级别的 DEADLOCK 消息,并且加载停止。

问题:我了解当 2 个或更多查询(更新)尝试在已持有写锁的 URI 上实现锁定时会发生死锁。

  1. 我希望任何数量的 mlcp load 线程一次将数据写入一个 URI。死锁怎么可能?
  2. 为什么当一个查询正在等待另一个查询完成时,它被称为死锁。不就是排队吗?

我看到以下代码是在 marklogic 文档中作为死锁示例给出的。我不明白为什么这是一个僵局。一个命令正在等待另一个命令完成。

(: the next line ensures this runs as an update statement :)
if ( 1 = 2) then ( xdmp:document-insert("foobar", <a/>) ) else (),
doc("/docs/test.xml"),
xdmp:eval("xdmp:node-replace(doc('/docs/test.xml')/a, <b>goodbye</b>)",
          (),
          <options xmlns="xdmp:eval">
            <isolation>different-transaction</isolation>
          </options>) ,
doc("/docs/test.xml")
4

1 回答 1

2

我真的不明白你为什么会陷入僵局。我仍然怀疑 MLCP 之外的某些东西正在生成这些消息。是否有一些时间表或只是一些完全独立的过程导致消息?

我可以尝试更多地解释有关 MLCP 的死锁。

当您在更新模式下接触文件时,通常会发生死锁,然后生成、调用或评估接触同一文件的代码。产生、调用或评估的请求尚未完成,因此尚未释放自动读取或写入锁。子进程确实看到了锁,并被迫等到它被释放。父进程将等待子进程完成,因此出现死锁。

使用 MLCP 会变得更复杂一些,因为 MLCP 将打开持久事务,并且会发出参与同一事务的多个调用。在整个持久事务被释放之前,这些自动锁不会被释放。所以如果 MLCP 试图在同一个事务中两次插入同一个文件,那就麻烦了。

可能有一种方法可以检查是否真的是 MLCP 导致了问题。有一些命令行参数可以控制使用多少线程,以及一个事务中包含多少请求。尝试使用:

-transaction_size 1 -batch_size 1

此外,如果您真的想按顺序处理文件,请另外添加:

-thread_count 1

您可以只使用import命令(不使用其他参数)运行 MLCP,以获取所有命令行选项的摘要。

于 2017-09-27T18:51:21.487 回答