我正在使用 python 脚本将一些数据加载到我的 postgres 数据库中。这些数据都在巨大的csv文件中,所以我懒洋洋地读取它们并对批量数据调用INSERT语句。然而,这些数据在某种意义上都是“连接的”,因此将整个数据加载管道维护为单个事务是很好的,这样如果其中的某些部分失败,则可以全部回滚。
我的问题是:我正在努力让这些巨大的 csv 文件在我的 python 脚本中保持在内存不足的状态,但是,由于整个数据加载是一个事务,所有数据最终都会在 postgres 端内存中吗东西的?单个 INSERT 事务是否必须将其所有数据完全放入内存中?
不,但它必须适合 WAL 文件的可用空间。
PostgreSQL 将未提交事务中的数据写入 WAL 和数据文件,就像任何其他数据一样。数据不必保存在内存中,WAL 文件在归档后也不必保留,并且不包含比最新检查点更新的数据。所以您不必担心该帐户。
如果您想知道 PostgreSQL 如何在内存中没有该事务的数据的情况下回滚该事务:PostgreSQL 从未真正执行回滚。如果您运行
ROLLBACK
(或错误中止事务),所发生的只是该事务在提交日志中被标记为“已中止” ,因此它写入的所有数据都变得不可见。中止事务中的数据仍存储在表中,直到下一次 autovacuum 运行将其删除。PostgreSQL 中长时间运行事务的风险是另一种风险:
你会长时间持有锁,这对并发性不利并且更有可能出现死锁
VACUUM
无法清理在长时间运行的事务启动后变得不可见的任何行版本,如果存在大量并发 DML 活动,这可能会导致表膨胀