在将新数据插入PostgreSQL表的同时,是否可以转储/复制PostgreSQL表?

时间:2019-05-20 08:59:07

标签: python pandas postgresql sqlalchemy psycopg2

我建立了一个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访问它(如果有所不同)。我还没有尝试过任何操作,因为担心会中断收集过程。

1 个答案:

答案 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