最近群里有同学问关于pg_dump失败的问题,但是最近老眼昏花脑子搭错线,看成mysqldump 还傻傻的问人家mysql那个版本。
所以基于这个pg_dump的问题的写一篇,pgdump对比mysqldump来说,的确从功能性和性能方面要比mysql 给的逻辑备份的方式要好的多,这里我们可以稍微浅浅的比较一下
1 pg_dump 提供了二进制的数据备份方式 mysqldump没有
2 pg_dump 有并发方式的数据备份,mysqldump没有 就是有的那个mysqlpump 也在8.X 的某个后续的版本中被去掉了
3 pg_dump 的命令丰富可以进行多种模式的备份,包含备份的数据直接压缩的方式。
基于其他的好处,大家可以在细致研究两个命令的功能区别和完成的工作项目来进行比对。
基于上面的问题,备份失败了,这里我们的需要分析几个问题
1 pg_dump 在去备份中,获取的锁是什么锁
2 pg_dump 在获取锁中,遇到困难,可以等待的时间是多长
3 pg_dump的角度我们可以怎么去尝试解决遇到的问题
1 基于这个同学在之前问过我 pg_dump 的并行的问题并且他在问问题的时候也沾了相关的命令,这里可以清晰的看到他使用了并行的方式进行数据的备份。
关于备份的部分,在官方的-j 参数是有解释的,这里核心的解释有两点
1 备份中基于是并发的方式对于数据库备份的形成部分,只能通过目录的方式进行备份数据的落盘
2 备份中会有对数据请求独占锁,导致备份失败,pg_dump 在并行运行备份对数据对象中请求共享锁 access share ,同时基于并发性需要确认备份中对于备份的对象没有人删除或改变其名字等,此表如果对于另一个访问对象正在使用独占锁时,备份申请的锁将不被授予,需要等待锁释放后,才能对表进行操作。
在工作中pg_dump工作进程会使用NOWAIT选项请求另一个共享锁,在无法获得共享锁,并超时时pg_dump 将终止备份的程序。注意PG的并行备份是在PG9.2开始支持的。
在进行全库备份中,pg_dump 需要以下的锁来支持工作
1 access share 锁,对于表的元数据进行包含
2 row share 在读取表行中,确保读取期间的表行的一致性
3 share update exclusive share update exclusive 锁主要的作用在于方式其他事物对于表进行并发访问,使用锁是可以允许其他事务对表进行读写,但禁止其他的事务同时申请 share update exclusive 锁,锁主要对于DDL 的部分的操作进行独占性的使用。
4 access exclusive access exclusive 锁主要在备份时保证备份的一致性,防止备份时数据变动导致数据备份的无法保证一致性的问题。
基于以上的问题,在备份中通过pg_dump进行全库备份需要注意
1 对于数据库的尤其的大型数据库的全库备份,不建议使用pg_dump来进行数据库的备份,而是建议使用备份软件或物理备份的方式进行数据的备份。
2 备份工作尽量放到非业务时间进行。
3 在使用pg_dump 备份数据库时,可以添加 --lock-wait-timeout 的方式 增加pg_dump 在遇到锁冲突时的等待时间,默认pg_dump等待的时间为 60秒
4 对于业务的热表,可以采用单独备份的方式,比如在全备时对于一些经常被锁定的表 排除在全备中,使用 --exclude-table 的方式来进行备份,并且单独对经常被锁定的表单独进行备份。
针对经常备份失败的时间,进行监控发现备份失败时间,数据库正在处理的事务,包含vacuum full 相关的工作,如果发现此时有相关工作建议与备份的时间分割开来。
另针对 GP greenplum 的数据库进行备份,可以考虑使用 gpbackup 来对全库进行备份,相关的命令请查询GP相关的信息。
如果还针对GP 通过pg_dump 来进行备份,则建议值备份某个表或某组表,这里类似与数据导出,
下面有一些通过pg_dump 进行备份的案例
1 并行备份
pg_dump -h 127.0.0.1 -p5432 -U backup -Fd -f /home/postgres/backup -j 4 postgres
2 全库备份成SQL模式
pg_dump -h 127.0.0.1 -p5432 -U backup -Fp -f /home/postgres/backup/backup.sql postgres
3 备份表结构
pg_dump -h 127.0.0.1 -p5432 -U backup -s -f /home/postgres/backup/backup.sql postgres
除此以外pg_dump 还有其他的备份的方式和用途,具体可以查询相关的详细参数与用法。