我建立了一个PostgreSQL数据库(版本11.2),其中有一个表,该表中以半规则间隔(15-30分钟)插入新条目。插入是通过带有SQLAlchemy的python脚本和带有df.to_sql()
命令的Pandas完成的。现有的数据库非常大,复制/转储很可能会花费超过30分钟的时间。
运行CREATE TABLE new_table AS TABLE old_table;
是否会中断数据插入过程?如果是,是否还有另一种方法可以不受干扰?
该数据库在Red Hat Enterprise Server 7.6版上运行。我具有整个数据库的管理员权限,并且可以用PuTTy + psql -U username -d my_database
和pgAdmin访问它(如果有所不同)。我还没有尝试过任何操作,因为担心会中断收集过程。
答案 0 :(得分:1)
Postgresql中的一个事务,任何单个的,全有或全无的操作。一项交易被认为是原子性的:从其他交易的角度来看,它要么完全发生,要么根本不发生。
一个打开的事务到目前为止所做的更新对于其他事务是不可见的,直到该事务完成为止,随后所有更新同时变为可见。只有在使用{提交后,该事务才是真实的(或对其他事务可见)。 {1}}命令。
您的第一个insert命令可能只会锁定当前正在插入的那些行。这些行仅在插入事务已完成并落实后才可用。
回答您的问题:
1)将运行CREATE TABLE new_table作为TABLE old_table;打断 数据插入过程?
不。一点也不。
2)是,是否还有另一种方法可以不间断地进行此操作?
第一个问题得到解答。
这里的场景是create table命令将仅复制当前未被任何事务锁定的数据。因此,对于插入命令,此操作(通常)仅是当前插入的行。创建表将复制插入事务之前的所有数据。
您可以通过插入命令来检查锁,如下所示:
COMMIT;
这将输出类似的内容。
select * from pg_stat_activity;
由此,我们可以确定此过程创建的锁为:
-[ RECORD 2 ]----+--------------------------------
datid | 73103
datname | database
procpid | 28477
sess_id | 16424
usesysid | 10
usename | user
current_query | insert .....
waiting | f
query_start | 2019-05-20 06:10:21.126825+00
backend_start | 2019-05-20 05:43:51.600017+00
client_addr | 0.0.0.0
client_port |
application_name |
xact_start |
您可以在同一张表上更新,删除,插入许多事务,而事务不会相互阻塞-前提是每个事务都处理不同的行。如果第二个插入试图插入与第一个相同的主键(或唯一键)值,则两个插入只会互相阻塞。如果您不希望任何锁影响查询,则可以使用WITH NOLOCK,但要谨慎使用。
更多信息,请访问:
https://www.postgresql.org/docs/9.1/explicit-locking.html
https://www.postgresql.org/docs/9.1/transaction-iso.html