PgSQL - 如何在数据库完全清空时导入数据库转储?

hol*_*lms 9 postgresql database-backups ansible

用例实际上是自动执行此操作ansible.我想在数据库完全为空(内部没有表)时导入数据库转储.当然总有办法执行sql语句,但这是最后的手段,我相信应该有更优雅的解决方案.

pg_restore 就我看来,手册不提供此选项.

以下是我计划用ansible执行此操作的方法:

  - name: db_restore | Receive latest DB backup
    shell: s3cmd --skip-existing get `s3cmd ls s3://{{ aws_bucket }}/ | grep sentry | tail -1 | awk '{print $4}'` sql.latest.tgz
    args:
        chdir: /root/
        creates: sql.latest.tgz

  - name: db_restore | Check if file exists
    stat: path=/root/sql.latest.tgz
    register: sql_latest

  - name: db_restore | Restore latest DB backup if backup file found
    shell: PGPASSWORD={{ dbpassword }} tar -xzOf /root/sentry*.tgz db.sql | psql -U{{ dbuser }} -h{{ pgsql_server }} --set ON_ERROR_STOP=on {{ dbname }}
    when: sql_latest.stat.exists
    ignore_errors: True
Run Code Online (Sandbox Code Playgroud)

理想情况下,这应检查DB是否为空.不存在用于此目的的ansible模块.谷歌也在沉默..目前的解决方案实际上也有效,导入失败时会出错,我可以忽略错误,但看到误报有点痛苦.

Cra*_*ger 5

实际上没有"空"这样的东西; 它通常具有内置类型,默认的PL/PgSQL语言等,即使您是从中创建的template0.如果您使用其他模板创建,那么可能会有更多.

PostgreSQL没有记录第一次写入数据库的非模板,因此您也不能说"自创建后更改".

这就是为什么没有--if-empty选择的原因pg_restore.它没有多大意义.

到目前为止,最好的选择是执行psql查询information_schema并确定模式中是否有任何表public.或者,更好的是,查询转储会创建您知道的特定表和类型的存在.

例如

psql -qAt mydbname -c "select 1 from information_schema.tables where table_schema = 'public' and table_name = 'testtable';"
Run Code Online (Sandbox Code Playgroud)

然后,您可以测试stdout上返回的零/非零行.或者将其包装起来SELECT EXISTS(...)以获取布尔值psql.如果您需要零/非零退出状态,请使用表格存在的DO块.ERRORpsql


Hub*_*tus 3

要将数据库视为空数据库,我们必须知道从创建时起没有添加任何内容。由于 postgres 不跟踪这一点(正如 @Craig Ringer 已经提到的),我建议对 ansible 采用不同的方法。

因此,只需使用如下处理程序机制:

- name: Create zabbbix postgres DB
  postgresql_db: name="{{zabbix_db_name}}"
  notify:
    - Init zabbix database
Run Code Online (Sandbox Code Playgroud)