select和truncate之间的死锁(postgresql)
表输出值\u center1和其他一些继承输出值。我定期截断表输出值并在一个事务中加载新数据。在这段时间内,用户可以请求一些数据,并收到错误消息。为什么选择查询只请求一条记录以及如何避免此类问题:select和truncate之间的死锁(postgresql),postgresql,deadlock,Postgresql,Deadlock,表输出值\u center1和其他一些继承输出值。我定期截断表输出值并在一个事务中加载新数据。在这段时间内,用户可以请求一些数据,并收到错误消息。为什么选择查询只请求一条记录以及如何避免此类问题: 2010-05-19 14:43:17 UTC ERROR: deadlock detected 2010-05-19 14:43:17 UTC DETAIL: Process 25972 waits for AccessShareLock on relation 2495092 of data
2010-05-19 14:43:17 UTC ERROR: deadlock detected
2010-05-19 14:43:17 UTC DETAIL: Process 25972 waits for AccessShareLock on relation 2495092 of database 16385; blocked by process 26102.
Process 26102 waits for AccessExclusiveLock on relation 2494865 of database 16385; blocked by process 25972.
Process 25972: SELECT * FROM "output_values" WHERE ("output_values".id = 122312) LIMIT 1
Process 26102: TRUNCATE TABLE "output_values_center1"
显然,如果只看上面链接的手册页,不清楚为什么查询父表会影响其子表。SELECT命令手册页的以下摘录对此进行了澄清:
我会在截短的伪代码中尝试:
#define NOWAIT_TIMES 100
#define SLEEPTIME_USECS (1000*100)
for ( i=0; ; i++ ) {
ok = query('start transaction');
if ( !ok ) raise 'Unable to start transaction!';
queries = array(
'lock table output_values in access exclusive mode nowait',
'truncate output_values_center1',
'commit'
);
if ( i>NOWAIT_TIMES ) {
// we will wait this time, as we tried NOWAIT_TIMES and failed
queries[0] = 'lock table output_values in access exclusive mode';
}
foreach q in queries {
ok = query(q);
if (!ok) break;
}
if (!ok) {
query('rollback');
usleep(SLEEPTIME_USECS);
} else {
break;
};
};
这样您就不会出现死锁,因为父表将被独占锁定。用户在执行truncate运行时只会阻塞一小部分秒,并在提交后自动恢复
但要做好准备,这可以在繁忙的服务器上运行几秒钟,因为当表正在使用时,锁将失败并重试。您能从该错误消息中展开关系ID吗?i、 e.选择2494865::regclass等。谢谢,问题比答案更有用,在查看关系id后,我了解问题在哪里: