使用用户 discourse 而非 DB_USER 或 multisite.yml 中的值进行多站点备份

编辑/Tl;dr:ActiveRecord::Base.connection_pool.db_config.configuration_hash 中的用户名在 user 而不是 username 中,但 Discourse 在查找 username

微小 PR:FIX: backup_restore.rb wants db user from user, not username by pfaffman · Pull Request #28229 · discourse/discourse · GitHub

我有一个使用 Digital Ocean 托管的 postgres 的多站点实例。它运行正常,但当我尝试备份时,我收到一个错误,即

[2024-08-05 16:13:31] pg_dump: error: connection to server at "private-forum-cluster-postgresql-prod-do-user-1230.j.db.ondigitalocean.com" (10.11.1.6), port 25060 failed: FATAL:  password authentication failed for user "discourse"

但用户不是 discourse。它在其他地方使用了正确的用户,包括 ActiveRecord::Base.connection_pool.db_config.configuration_hashBackupRestore.database_configuration(当我运行 RAILS_DB=sitename rails c 中的那些命令时)。PG_USER 不在环境变量中(据我所见)。

它看起来像是这个应该负责:

discourse/lib/backup_restore.rb at main · discourse/discourse · GitHub

我在容器中编辑了它(将其从 DISCOURSE_DB_USER 拉取,当时我认为这是一个好主意),现在备份工作正常。我不知道你是否应该能够从 multisite.yml 中拉取连接信息,但忽略 DB_USER 似乎是错误的。

或者我应该像其他人一样把用户设为 discourse

编辑:等等。不。

config['username'] 应该是 config['user']

    config = ActiveRecord::Base.connection_pool.db_config.configuration_hash

返回这个!


=> {:adapter=>"postgresql",
:database=>"theDatabase",
:pool=>25,
:port=>25060,
:timeout=>5000,
:host=>"private-forum-cluster-postgresql-prod-do-user-123-0.j.db.ondigitalocean.com",
:user=>"theCurrentUsername",
:password=>"supersecret",
:host_names=>["forum.example.com"],
:db_key=>"mydb",
:prepared_statements=>false}

所以

    config["username"] || username || ENV["USER"] || "postgres",

应该是

    config["user"] || username || ENV["USER"] || "postgres",
2 个赞

@pfaffman 抱歉,我们不得不撤销此更改,因为它破坏了我们生产环境中备份的恢复功能。

我们的多站点配置示例(以及生产环境的配置)将其放在“username”下:

2 个赞

非常抱歉!我仍然不清楚它除了备份之外是如何处理所有其他事情的。

嗯。

也许这就是我的问题。但为什么它对其他所有事情都有效呢?

也许其他所有内容都使用环境变量中的全局设置。

2 个赞

非常抱歉。

我没有意识到 ActiveRecord::Base.connection_pool.db_config.configuration_hash 只是我放入 multisite.yml 文件中的任何胡言乱语。

我将所有错误的 user: 字段重命名为 username:,现在我的备份可以正常工作了。

我的解释(我尚未测试过)是,Rails 的其余部分会覆盖 GlobalSettings 中的 db_username(如果在此处设置了),但在它获取信息以发出外部 pg_dump 调用时,它会从 multisite 配置中提取。

我仍然认为备份获取不同用户是一个错误,并且修复方法是将 env['DISCOURSE_DB_USERNAME'] 包含在那个赋值语句的某个地方,但我不想再次冒险破坏生产环境,现在它已经可以工作了。

你应该取消点赞我的帖子并移除我的徽章!:crying_cat_face:

2 个赞

完全没关系,这种事情时有发生。理想情况下,这应该在 CI 中被发现,但我猜我们没有覆盖这部分逻辑(也许很难,因为测试中的数据库设置完全不同)

感谢您记录您发现的问题——我相信它将在未来帮助到其他人。我同意这里的不一致性很糟糕,并且在某个时候应该修复。

3 个赞