Проблема, с которой вы столкнулись, заключается в том, что Vertica на самом деле не обновляет существующую строку, а помечает существующую строку как удаленную, добавляя новый вектор удаления в физическое хранилище, и вставляет новую строку. Это также включает исключительную блокировку стола. Ваши связи АВТОКОММИТНЫ? Если нет, попробуйте переключиться на AUTOCOMMIT и посмотрите, что произойдет. Если это не поможет, есть некоторые возможности дизайна ...
Я создал таблицу и четыре таких сценария:
SET SESSION AUTOCOMMIT TO OFF;
UPDATE log_table SET start_time = CURRENT_TIMESTAMP WHERE process_name = 'p1';
SELECT last_val FROM log_table WHERE process_name ='p1';
UPDATE log_table SET end_time = CURRENT_TIMESTAMP WHERE process_name = 'p1';
COMMIT;
Затем я использовал драйвер запроса для запуска четырех скрипты параллельно. Ожидание в течение двух секунд между выполнением каждого оператора в скрипте. Я также чередовал, добавляя или удаляя операторы BEGIN WORK
/ COMMIT WORK
. Боюсь, что я не смог вызвать тупик, поэтому я здесь вслепую.
Еще одна менее инвазивная альтернатива: разные контейнеры ROS на имя процесса:
ALTER TABLE log_table PARTITION BY process_name REORGANIZE;
Вам может повезти с dimini sh взаимоблокировками - хотя удаление (а обновление - это удаление, а затем вставка) всегда вызывает монопольную блокировку таблицы, но они могут блокировать друг друга немного реже.
Метод грубой силы:
CREATE TABLE log_p1 (last_val INT start_time TIMESTAMP,end_time TIMESTAMP);
CREATE TABLE log_p2 (last_val INT start_time TIMESTAMP,end_time TIMESTAMP);
CREATE TABLE log_p3 (last_val INT start_time TIMESTAMP,end_time TIMESTAMP);
CREATE TABLE log_p4 (last_val INT start_time TIMESTAMP,end_time TIMESTAMP);
CREATE VIEW log_table AS -- just for reporting, not for maintenance
SELECT 'p1' AS proc_name, * FROM log_p1
UNION ALL SELECT 'p2' AS proc_name, * FROM log_p2
UNION ALL SELECT 'p3' AS proc_name, * FROM log_p3
UNION ALL SELECT 'p4' AS proc_name, * FROM log_p4
;
И четыре скрипта будут отличаться только p4
от p1
:
SELECT * FROM p1; -- fetch single row output into your application
TRUNCATE TABLE p1;
-- bind "last_val" and "end_time" host variables
INSERT INTO p1 VALUES(? , CURRENT_TIMESTAMP, ?);
SELECT last_val FROM log_p1;
TRUNCATE TABLE p1;
-- bind "last_val" and "start_time" host variables
INSERT INTO p1 VALUES(? , ?, CURRENT_TIMESTAMP);
COMMIT;