【问题标题】:How to generate PostgreSQL backup with QProcess, from the Qt app如何从 Qt 应用程序使用 QProcess 生成 PostgreSQL 备份
【发布时间】:2021-10-24 08:25:40
【问题描述】:

我有以下代码。 我的问题如下: 当我单击我的按钮时,我收到消息,备份已生成,但在查看生成的文件时,它是空的。 另一件事是我如何在参数中传递服务器密码,因为我有另一个具有登录密码的 postgreSQL 实例,我将不胜感激。

void Widget::on_pushButton_6_clicked()
{
  QProcess* process=new QProcess(this);
  QString prog("C:/Program Files/PostgreSQL/13/bin/pg_dump.exe");
  QStringList params;

  params<<"-U"<<"postgres"<<"-v"<<"-Fc"<<"-f"<<"D:/base.backup"<<"monitoreo_db";
  bool res=process->startDetached(prog,params);
  if(!res){
    QMessageBox::critical(this,qApp->applicationName(),"Failed to execute command.\n");
    return;
  }
  QMessageBox::information(this,qApp->applicationName(),"backup was created successfully.\n"+
                                                            QString::number(process->exitStatus()));
}

【问题讨论】:

  • 使用 QProcess 来备份 PostgreSQL 数据库是绝对必要的吗?
  • 是的,因为我想从我的应用程序中执行此操作,或者还有其他方式。
  • 您使用的是哪个版本的 PostgreSQL?我想给你一个相关的答案。
  • 好的,我使用的是 PostgreSQL 版本 13.3 和 Qt 版本 5.15.2。

标签: c++ postgresql qt backup


【解决方案1】:

根据 PostgreSQL 文档,每个到 PostgreSQL 数据库实例的连接都是它自己的进程 (https://www.postgresql.org/docs/current/libpq-threading.html)。如果您正在应用诸如 read-modify-write、RMW 之类的开发模式,那么我建议如下:

  1. 当您的应用程序确定有必要执行备份操作时,将此操作包装在一个类中。(如果您不使用自己的线程库,请使用 Q_OBJECT 宏。)

  2. 您的 DatabaseBackupOperation 对象实例将接受打开与您的数据库实例的连接所需的所有参数:https://doc.qt.io/qt-5/qsqldatabase.html。您的对象是 QSqlDatabase 对象的简单包装器。

  3. 与你的包装类相关的有用方法被命名为:

pair{QSqlError,string relevantMessage} startDatabaseBackupOp(string label,...)

pair{QSqlError,string relevantMessage} stopDatabaseBackupOp();

其他参数很容易找到:https://www.postgresql.org/docs/current/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP。特别是第 25.3.3.1 节,标题为“进行非排他性低级备份”。根据引用的文档,确保您以有权执行 pg_start_backup 的用户或超级用户身份连接到数据库实例。我相信这回答了您关于如何输入密码的问题。

  1. 在调用上面列出的方法之前,DatabaseBackupOperation 的实例应该按照 databaseSize 的方式更新一个名为 something 的内部变量。您可以通过运行以下查询来获取此信息:

select pg_database_size('databaseName');

  1. 在上面列出的备份方法的定义中,您只需执行相应的 SQL 查询,如下所述:https://www.postgresql.org/docs/current/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP 第 25.3.3.1 节。

  2. 备份操作可能需要很长时间,具体取决于基础表的大小。您可以通过在备份运行时不时运行以下查询来检查数据库备份的进度:

select * from pg_current_wal_flush_lsn ()

显然,这会返回正在运行的操作的文件偏移量,特别是写入“持久存储”的内容。(https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-BACKUP) 不幸的是,这仅允许您返回备份进度估计,因为上面列出的查询返回大小您的数据库以字节为单位返回。我不记得这与推荐查询报告的“文件偏移量”有何关系。

上述建议非常适合 RMW 整体设计环境。如果这个整体设计假设过于严格,我深表歉意。但是,如果您按照建议将其包装在一个类中,则该建议可能会阻止您,直到您可以为您的应用程序和设计决策定义更强大的实现。

上面列出的步骤是解决问题的推荐方法。请让我知道它是否有效。我将在本周晚些时候有时间测试该建议。

【讨论】:

  • 感谢您的回答,我将测试我在代码中引用的内容,再次感谢。
  • 尽管从我在您共享的文档中可以阅读和看到的内容来看,pg_basebackup 会制作整个集群的备份副本,而我想要的只是备份我的数据库,而不是其余的服务器的,无论如何感谢您的回答,这对我很有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多