PG长事务分析
示例
假设在时间点A有一个长事务正在运行,并且在时间点A+1执行了VACUUM FULL操作。以下是可能发生的情况:
- 时间点A :长事务开始并持有
ACCESS SHARE锁。 - 时间点A+1 :尝试执行
VACUUM FULL操作。VACUUM FULL需要ACCESS EXCLUSIVE锁,但长事务持有的ACCESS SHARE锁阻止了VACUUM FULL获取锁。VACUUM FULL进入等待状态,直到长事务结束并释放其锁。
- 时间点A+1以后 :
- 读操作 :后续的
SELECT操作可以继续执行,因为它们只需要ACCESS SHARE锁。 - 写操作 :后续的
INSERT、UPDATE或DELETE操作会被阻塞,因为它们需要ROW EXCLUSIVE锁或更高级别的锁,而这些锁与VACUUM FULL所需的ACCESS EXCLUSIVE锁不兼容。 - 其他高优先级操作 :后续的
ALTER TABLE、DROP TABLE等操作也会被阻塞。
- 读操作 :后续的
总结
- 在时间点A+1以后的事务是否会受到阻塞取决于它们需要获取的锁类型。
- 读操作通常不会被阻塞,因为它们只需要较低级别的锁。
- 写操作和其他需要较高级别锁的操作会被阻塞,直到
VACUUM FULL能够获取到ACCESS EXCLUSIVE锁并完成其操作。
Mysql长事务-+后面mysql导致系统崩溃
在MySQL中,FLUSH TABLES ... WITH READ LOCK 命令会锁定所有表,并阻止其他事务对这些表进行写操作。这意味着在执行 FLUSH TABLES ... WITH READ LOCK 之后的所有写操作都会被阻塞,直到锁被释放。
具体来说:
-
A时间点执行长事务select语句:假设在时间点A开始了一个长时间运行的SELECT查询,这个查询会持有读锁(取决于隔离级别和查询类型)。
-
A+1时间点执行flush table for lock :在时间点A+1,执行了
FLUSH TABLES ... WITH READ LOCK命令。这个命令会获取全局读锁,阻止所有其他写操作和某些读操作。
在这种情况下,以下几点需要注意:
- 所有写操作会被阻塞 :从时间点A+1开始,所有试图对表进行写操作的事务都会被阻塞,直到
FLUSH TABLES ... WITH READ LOCK命令完成并且锁被释放。 - 某些读操作也会被阻塞 :如果在执行
FLUSH TABLES ... WITH READ LOCK时,有新的读操作尝试访问被锁定的表,这些读操作也会被阻塞,直到锁被释放。 - 已存在的读操作不受影响:已经存在的读操作(例如时间点A开始的长事务SELECT查询)不会被阻塞,但新的读操作会被阻塞。
总结来说,从时间点A+1开始,所有新的写操作和某些新的读操作都会被阻塞,直到 FLUSH TABLES ... WITH READ LOCK 命令完成并且锁被释放。已存在的读操作则不会受到影响。