'safe' 重载插入导致 PK 违规
'safe' insert on heavy load lead to PK violation
我正在 Postgresql 9.4 上处理大分区 table(大约 0.5 TB 和 5 x10^9 行...)。这个 table 每天增长 8 x10^6 行,并面临大量 read/write 使用。
我需要填补部分插入可能发生的缺失分钟数的空白。我使用以下查询执行此操作:
INSERT INTO huge_partitioned_table(id, date_gmt, date_local)
SELECT
to_do.id AS id,
seq.seq AT TIME ZONE to_do.tz_lib AT TIME ZONE 'UTC' AS date_gmt,
seq.seq AS date_local
FROM to_do
CROSS JOIN LATERAL
generate_series(
to_do.date_needed::timestamp,
to_do.date_needed::timestamp + INTERVAL '1439 minutes',
INTERVAL '1 minute'
) seq
WHERE NOT EXISTS(
SELECT 1
FROM huge_partitioned_table hpt
WHERE
to_do.id = hpt.id
AND date_gmt = hpt.date_gmt
)
;
但这是我第二次在 PK(id, date_gmt)
上遇到 PK 违规,因为在 运行[] 此查询的同时完成了缺少分钟的插入=26=].
在这种情况下有没有办法避免PK违规? (pg 9.5 的 on duplicate key do nothing
非常适合,但我们不能仅为此更新)
具有忽略每个 duplicate key
规则的解决方案也不是很好,因为使用时区意味着我们犯了一些真正的错误并且想在那时击中 PK FAIL...
好的,经过一些测试后,我将在 table 上使用 explicit table write lock :
LOCK TABLE huge_partitioned_table IN SHARE ROW EXCLUSIVE MODE;
SHARE ROW EXCLUSIVE
Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This
mode protects a table against concurrent data changes, and is
self-exclusive so that only one session can hold it at a time.
This lock mode is not automatically acquired by any PostgreSQL command.
此解决方案允许在锁定时读取并将写入放在等待列表中。
我正在 Postgresql 9.4 上处理大分区 table(大约 0.5 TB 和 5 x10^9 行...)。这个 table 每天增长 8 x10^6 行,并面临大量 read/write 使用。
我需要填补部分插入可能发生的缺失分钟数的空白。我使用以下查询执行此操作:
INSERT INTO huge_partitioned_table(id, date_gmt, date_local)
SELECT
to_do.id AS id,
seq.seq AT TIME ZONE to_do.tz_lib AT TIME ZONE 'UTC' AS date_gmt,
seq.seq AS date_local
FROM to_do
CROSS JOIN LATERAL
generate_series(
to_do.date_needed::timestamp,
to_do.date_needed::timestamp + INTERVAL '1439 minutes',
INTERVAL '1 minute'
) seq
WHERE NOT EXISTS(
SELECT 1
FROM huge_partitioned_table hpt
WHERE
to_do.id = hpt.id
AND date_gmt = hpt.date_gmt
)
;
但这是我第二次在 PK(id, date_gmt)
上遇到 PK 违规,因为在 运行[] 此查询的同时完成了缺少分钟的插入=26=].
在这种情况下有没有办法避免PK违规? (pg 9.5 的 on duplicate key do nothing
非常适合,但我们不能仅为此更新)
具有忽略每个 duplicate key
规则的解决方案也不是很好,因为使用时区意味着我们犯了一些真正的错误并且想在那时击中 PK FAIL...
好的,经过一些测试后,我将在 table 上使用 explicit table write lock :
LOCK TABLE huge_partitioned_table IN SHARE ROW EXCLUSIVE MODE;
SHARE ROW EXCLUSIVE
Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode protects a table against concurrent data changes, and is self-exclusive so that only one session can hold it at a time.
This lock mode is not automatically acquired by any PostgreSQL command.
此解决方案允许在锁定时读取并将写入放在等待列表中。