PostgreSQL逻辑备份,锁,长时间导出数据与备份

PostgreSQL逻辑备份, 指通过pg_dump或者直接调用COPY进行的备份方法.
一般来说, PostgreSQL 使用pg_dump备份数据库时, 会
1. 开启一个repeatable read事务, 
2. 然后需要从系统表以及传入的参数, 生成备份集, 
3. 备份开始前, 需要一次性把需要备份的所有对象都加上access share lock, 这个锁与DML不冲突, 只和DDL冲突, 例如TRUNCATE表会和pg_dump发生冲突(当需要备份的表被执行DDL时, 只要pg_dump未结束, DDL就会处于等待状态).

所以如果需要备份的数据集很大的话, 备份程序pg_dump持有access share lock的时间就越长, 这段时间如果程序需要对备份的表做出DDL操作(如drop, truncate), DDL SQL就要进入等待.
同样的道理, 如果系统正在跑比较长的事务或函数, 并且事务或函数中使用了表的DDL, 例如truncate. 那么备份这些表也将被堵塞知道长事务或函数结束.

这样的情况其实很容易发生, 例如凌晨是比较空闲的时间, 备份和统计作业可能都会放到凌晨来处理.
假设1点开始备份, 备份到5点结束. 备份作业包含了以下truncate操作的表.
2点的时候开始一个统计作业, 统计函数里面如果用到truncate操作的话, 这个操作可能要等到5点才能获得锁而继续下去.
这种场景的备份需要排除需要truncate的表, 那么就不会发生锁冲突.

pg_dump有一个参数来排除不需要备份的表.
  -T, --exclude-table=TABLE   do NOT dump the named table(s)
另外还有一个参数, 指定锁等待时间, 当pg_dump不能在这个时间内获得access share lock的话, 就报错.
       --lock-wait-timeout=timeout
              Do  not  wait forever to acquire shared table locks at the beginning of the dump. Instead fail if unable
              to lock a table within the specified timeout. The timeout  may  be  specified  in  any  of  the  formats
              accepted  by SET statement_timeout. (Allowed values vary depending on the server version you are dumping
              from, but an integer number of milliseconds is accepted by  all  versions  since  7.3.  This  option  is
              ignored when dumping from a pre-7.3 server.)

上一篇:推荐一款 IDEA 神器 ,人工智能帮你写代码,再也不用加班了!!


下一篇:机房安全监控设备连接图及指令发送