在事务中有什么是不能做的(然后安全回滚)?
我的事务是对生产数据库中重大的破坏性更改的简单测试。包裹在事务中的 SQL 代码由如下语句组成。 SQL 代码在测试数据库中运行,数据量很小,它在其中运行并可以很好地回滚,每个事务占用 0.5 秒。我想在生产中测量代码的性能,删除几 GB 的数据然后写入事务,估计最多需要 30 分钟。
ALTER TABLE
UPDATE ...
DROP VIEW ... CASCADE
CREATE OR REPLACE VIEW ...
CREATE MATERIALIZED VIEW ...
CREATE UNIQUE INDEX ... ON <the materialized view just created above> ...
-- I can omit "CONCURRENTLY" if needed:
REFRESH MATERIALIZED VIEW CONCURRENTLY <the materialized view just created above>
CREATE OR REPLACE VIEW ...
相关:
如果可能的话,在生产数据库的副本上运行侵入性测试,不要冒破坏生产数据库的风险。即使一切顺利,你的存在也不会被忽视。您可能会减慢或阻止并发活动。
在同一个数据库集群中创建副本的最快方法——同时没有并发会话:
CREATE DATABASE mydb_test TEMPLATE mydb;
参见:
避免直接摩擦、堵塞和破损。但是在同一台服务器上测试时,你仍然会争夺资源。在不同的服务器上进行测试也可以避免这种情况......
ROLLBACK
在 Postgres 中,绝大多数 DML 和 DDL 命令都是完全事务性的(可以在事务块内运行)并且它们的效果可以回滚。只要确保你不
COMMIT
不小心。
值得注意的例外包括:(这些列表都不全面)
有些命令一开始就不能在事务上下文中运行。所以它们也不能回滚。如果你试图在你的事务中包含其中任何一个,Postgres 甚至会在它们运行之前引发异常。所以除了已经完成的工作之外没有任何损失 - 并且被回滚。
CREATE DATABASE
, DROP DATABASE
CREATE TABLESPACE
, DROP TABLESPACE
CREATE INDEX CONCURRENTLY
, DROP INDEX CONCURRENTLY
, REINDEX CONCURRENTLY
REINDEX
- 当包含分区索引或表时
VACUUM
BEGIN
,START TRANSACTION
,COMMIT
,ROLLBACK
-显然。那些开始和结束交易并且不能在inside one中运行。如果在错误的地方被调用,只提出WARNING
。
CALL
- 如果被调用的过程包含事务控制命令(见上文)。
DO
- 如果代码块包含事务控制命令(见上文)。
那些是你真正需要注意的。喜欢:
setval()
和nextval()
的效果,由serial
和IDENTITY
列隐式使用。因此,预计序列号会有差距。参见:
写入日志文件的任何内容
任何退还给客户的东西
dblink 调用(或类似)的效果。参见:
不是 MVCC 安全的。截断后,表格会出现 对并发事务为空,如果它们使用的是快照 在截断发生之前。有关更多信息,请参见第 13.6 节 细节。TRUNCATE
对于表中的数据是事务安全的: 截断将安全地回滚,如果周围 事务不提交。TRUNCATE
相关:
有一些离群的命令(例如 F.H. 在评论中说的“创建数据库”)但在事物的“正常运行”中没有任何命令。
但是 - 你可能想要小心锁。如果您要删除很多行或更改外键等,那么其他事务可能会在您的测试之后被阻止,等待它是提交还是回滚。