使用Postgres的uuid_generate_v4时出现许多重复值

5
我们在拥有 8000 万行数据的数据库中添加了 UUID 列,并使用 postgres 中的 uuid_generate_v4() 函数生成默认值。
我们使用以下脚本填充 uuid:
current = 1
batch_size = 1000
last_id = 80000000

while current < last_id
  start_id = current
  end_id = current + batch_size
  puts "WORKING ON current: #{current}"
  ActiveRecord::Base.connection.execute <<-SQL.squish
    UPDATE table_name
    SET public_id = uuid_generate_v4()
    WHERE id BETWEEN '#{start_id}' and '#{end_id}' AND public_id IS NULL
  SQL
  current = end_id + 1
end

然而,在脚本结束时,我们发现有135个重复项,其中一些甚至有3个。这怎么可能?uuid_generate_v4()函数生成具有如此高概率的重复项吗?


可能值得在您的主机上检查 https://linux.die.net/man/3/uuid_generate_random - Vao Tsun
怀疑你的随机数源。请参见http://ralphbecket.blogspot.com.au/2011/09/birthday-paradox-and-guid-collisions.html。 - Craig Ringer
2个回答

0

https://doxygen.postgresql.org/uuid-ossp_8c.html#a9effb407a94b4ecc119d9546cd102c94

#ifdef HAVE_UUID_E2FS
    uuid_t      uu;

    uuid_generate_random(uu);

所以你可以尝试检查你的/dev/urandom,例如:

for i in $(seq 1 8000000); do uuidgen >>/tmp/u; done
-bash-4.2$ cat /tmp/u | sort | uniq -c | sort -r | head -3
      1 fffe894a-63e3-47e0-aea2-563f9652afd3
      1 fffbb781-61d5-4751-b4eb-e45a8ed684b7
      1 fffa7bff-ea37-46db-925b-d58f931512be

有些残酷,但如果你在这里看到了重复项(左边的1会超过一个),你可能应该使用uuid_generate_v1()或其他不依赖于/dev/urandom或使用一些时间戳的函数,或寻找其他解决方案... https://www.postgresql.org/docs/current/static/uuid-ossp.html

0

我们使用的是Heroku,它是Ubuntu系统。我们的Postgres数据库位于RDS上。 - Matthew Berman
@MatthewBerman 那我会向AWS寻求帮助。您使用的是哪个PostgreSQL版本?我在我的RDS PostgreSQL(9.5.4)上似乎无法重现您的问题。 - Jonathan Jacobson
我们正在使用RDS,基于PostgreSQL 9.4.7。 - Matthew Berman
@MatthewBerman,我建议您升级到最新的小版本更新9.4.14。 - Jonathan Jacobson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接