CouchDB 2中的序列号错误,或者是否有其他方法来比较序列号?

CouchDB 2中的序列号错误,或者是否有其他方法来比较序列号?,couchdb,couchdb-2.0,Couchdb,Couchdb 2.0,我正在深入研究CouchDB 2,发现一些序列号的意外排序。在一个例子中,我发现一个_changes提要中的早期更改具有序列号 99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3b

我正在深入研究CouchDB 2,发现一些序列号的意外排序。在一个例子中,我发现一个_changes提要中的早期更改具有序列号

99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3bOyDiKUalg2EBVoCu66KapazcUh41e69-GssjNIvcWWRokk2oNofwj0MNazy4QFURhGQ0J9LKI-SHPIBHEgiak51nxBhxnrRk
对于相同的DB,my_changes提要中的最后一个序列号为

228-g1AAAAJFeJyd0EkOgjAUBuAGTJCdN9AjlIKFruQm2jFAEFes9SZ6E72J3gQ7JW7QCGnyXtLhy-vfAgCWVSjAip96XglW-o5afRJQwNbDMDRVSOuj3ogQJRgiOnL_O8I2urKdd4B1KCRpkRcCxH0npKo7KX4ApQH2HogsAElOKOPTBjkY5-yd2DqKYqnItA91C13BRTdNXY0VWouRrV7JDOvmrLuxlLW4VAlJ5Qzr4aznJ2wskIIy-y9sh7wcYoMKLJKRXOACjTxr3uHcsBE
在浏览器控制台中,以下为false

'228-g1AAAAJFeJyd0EkOgjAUBuAGTJCdN9AjlIKFruQm2jFAEFes9SZ6E72J3gQ7JW7QCGnyXtLhy-vfAgCWVSjAip96XglW-o5afRJQwNbDMDRVSOuj3ogQJRgiOnL_O8I2urKdd4B1KCRpkRcCxH0npKo7KX4ApQH2HogsAElOKOPTBjkY5-yd2DqKYqnItA91C13BRTdNXY0VWouRrV7JDOvmrLuxlLW4VAlJ5Qzr4aznJ2wskIIy-y9sh7wcYoMKLJKRXOACjTxr3uHcsBE' > '99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3bOyDiKUalg2EBVoCu66KapazcUh41e69-GssjNIvcWWRokk2oNofwj0MNazy4QFURhGQ0J9LKI-SHPIBHEgiak51nxBhxnrRk'
这是一个bug还是我需要使用其他方法来比较序列号


在查看my_changes feed中的其他序列号时,看起来它们通常按照我的预期进行排序,但在这种情况下,当第一个数字(例如99)从2位跳到3位时,排序中断。如果将其归结为一个简单的字符串比较示例,您可以看到'228'>'99'=>false

以下答案包含@rnewson电子邮件线程的摘录。我希望它能帮助其他人理解CouchDB 2中的序列号。谢谢你,罗伯特

背景:

在2.0中没有比较它们的简单方法,也没有对它们的要求 井然有序。简言之,它们不是为了被检查或检查而设计的 在couchdb之外进行比较;用不透明的方式对待它们

前面的数字是各个更新序列的总和 在第二部分中编码,仅用于欺骗旧版本的 couchdb replicator开始创建检查点

序列字符串的后半部分是{node, 范围,seq}元组(其中seq是从 2.0之前的版本)。当一个序列字符串被传回时,作为 因为=参数,couchdb解码该字符串并传递 将适当的整数seq值分配给单个分片

尽管如此,总的来说,前线人数应该增加。全部 字符串本身是不可比较的,因为没有定义顺序 到编码列表(因此可以生成两个 编码方式不同,但解码到相同的元组列表,仅在 不同的顺序)

这方面的另一个方面是,changes提要并不完全可用 命令。对于给定的碎片,它是完全有序的(碎片是 与具有整数序列的2.0之前的数据库相同),couchdb 不洗牌该输出(尽管复制的正确性会 如果有,则保留)。集群数据库由多个数据库组成 但是碎片(q值,默认为4 iirc)。聚集的 changes feed将这些单独的changes feed合并为一个, 但没有努力在这上面强加一个完整的命令。我们不这样做 因为这样做既昂贵又不必要

如果您需要监听一个_changesfeed,然后重新启动,该解决方案 从您稍后结束的地方开始:

正确使用更改提要的算法是:

  • 读取/dbname/\u更改
  • 对每一行进行幂等处理
  • 定期(每X秒或每X行)存储您处理的最后一行的“seq”值
  • 如果您曾经崩溃,或者如果您没有使用continuous=true,您可以这样做 再次执行相同的程序,但在步骤1中进行了修改

    修订本1。读取/dbname/_更改?因为=X

    其中X是在步骤3中保存的值。如果你没有使用 连续模式下,您只需在 消耗非连续响应的结束。你冒着死亡的风险 不过,重新处理的项目要多得多

    使用此方案(复制器和所有索引器都遵循此方案),您可以 不管结果是否有问题,你不需要比较 任意两个seq值

    您确实需要确保能够正确处理相同的更改 多次。举个例子,考虑复制器 它从一个changes提要中看到一行,并询问目标数据库 包含该行的_id和_rev值。如果是这样的话 replicator移到下一行。如果没有,它会尝试写 将该行中的文档发送到目标数据库。如果发生 崩溃,因此对_的调用将从以前更改为seq值 处理该行时,它将询问目标数据库是否具有 _id/_rev,只有这一次目标会说是


    以下答案包含一封带有@rnewson的电子邮件的摘要。我希望它能帮助其他人理解CouchDB 2中的序列号。谢谢你,罗伯特

    背景:

    在2.0中没有比较它们的简单方法,也没有对它们的要求 井然有序。简言之,它们不是为了被检查或检查而设计的 在couchdb之外进行比较;用不透明的方式对待它们

    前面的数字是各个更新序列的总和 在第二部分中编码,仅用于欺骗旧版本的 couchdb replicator开始创建检查点

    序列字符串的后半部分是{node, 范围,seq}元组(其中seq是从 2.0之前的版本)。当一个序列字符串被传回时,作为 因为=参数,couchdb解码该字符串并传递 将适当的整数seq值分配给单个分片

    尽管如此,总的来说,前线人数应该增加。全部 字符串本身是不可比较的,因为没有定义顺序 到编码列表(因此可以生成两个 编码方式不同,但解码到相同的元组列表,仅在 不同的顺序)

    这方面的另一个方面是,changes提要并不完全可用 命令。对于给定的碎片,它是完全有序的(碎片是 与具有整数序列的2.0之前的数据库相同),couchdb 不洗牌该输出(尽管复制的正确性会 如果有,则保留)。集群数据库由多个数据库组成 碎片,虽然(q值,德福