HomePhabricator

Distinguish between unreachable cluster database hosts and missing MySQL…

Description

Distinguish between unreachable cluster database hosts and missing MySQL databases

Summary:
Fixes T11577. When we connect to a host and try to select a database which does not exist, we currently treat it as though the host wasn't reachable.

This isn't correct, and prevents storage from being initialized while already in cluster mode, since the "config" database won't exist yet the first time we connect.

Instead, distinguish between AphrontSchemaQueryException (thrown on connection if the requested database is not present) and other errors.

Test Plan:

  • Put Phabricator into cluster database mode (cluster.databases = ...).
  • Swapped storage.default-namespace to force initialization of a new install.
  • Ran bin/storage upgrade.
    • Before patch: Immediate fatal about unreachablility.
    • After patch: Database initialized.
  • Also ran initialization steps in tranditional single-host mode (cluster.databases empty, mysql.host configured).

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11577

Differential Revision: https://secure.phabricator.com/D16489

Event Timeline

bin/config is breaking for me, bisected to this commit.

I'm using https://github.com/hach-que-docker/phabricator

./bin/config
[2016-09-02 22:31:48] EXCEPTION: (AphrontInvalidCredentialsQueryException) #1045: Access denied for user 'root'@'10.0.0.6' (using password: NO) at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:321]
arcanist(head=master, ref.master=9e82ef979e81), phabricator(head=d0013d08983a0ceeaa37bde36f1983cefa78e8a8, ref.master=31c5f39506bd), phutil(head=master, ref.master=c8b76485ef84)
  #0 AphrontBaseMySQLDatabaseConnection::throwCommonException(integer, string) called at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:334]
  #1 AphrontBaseMySQLDatabaseConnection::throwConnectionException(integer, string, string, string) called at [<phutil>/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php:72]
  #2 AphrontMySQLiDatabaseConnection::connect() called at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:101]
  #3 AphrontBaseMySQLDatabaseConnection::establishConnection() called at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:124]
  #4 AphrontBaseMySQLDatabaseConnection::requireConnection() called at [<phutil>/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php:15]
  #5 AphrontMySQLiDatabaseConnection::escapeBinaryString(string) called at [<phutil>/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php:11]
  #6 AphrontMySQLiDatabaseConnection::escapeUTF8String(string) called at [<phutil>/src/xsprintf/qsprintf.php:178]
  #7 xsprintf_query(AphrontMySQLiDatabaseConnection, string, integer, string, integer) called at [<phutil>/src/xsprintf/xsprintf.php:70]
  #8 xsprintf(string, AphrontMySQLiDatabaseConnection, array) called at [<phutil>/src/xsprintf/qsprintf.php:64]
  #9 qsprintf(AphrontMySQLiDatabaseConnection, string, string, string, string)
  #10 call_user_func_array(string, array) called at [<phutil>/src/xsprintf/queryfx.php:5]
  #11 queryfx(AphrontMySQLiDatabaseConnection, string, string, string, string)
  #12 call_user_func_array(string, array) called at [<phutil>/src/xsprintf/queryfx.php:13]
  #13 queryfx_all(AphrontMySQLiDatabaseConnection, string, string, string, string)
  #14 call_user_func_array(string, array) called at [<phutil>/src/aphront/storage/connection/AphrontDatabaseConnection.php:36]
  #15 AphrontDatabaseConnection::queryData(string, string, string, string)
  #16 call_user_func_array(array, array) called at [<phabricator>/src/infrastructure/storage/lisk/LiskDAO.php:535]
  #17 LiskDAO::loadRawDataWhere(string, string)
  #18 call_user_func_array(array, array) called at [<phabricator>/src/infrastructure/storage/lisk/LiskDAO.php:476]
  #19 LiskDAO::loadAllWhere(string, string) called at [<phabricator>/src/infrastructure/env/PhabricatorConfigDatabaseSource.php:19]
  #20 PhabricatorConfigDatabaseSource::loadConfig(string) called at [<phabricator>/src/infrastructure/env/PhabricatorConfigDatabaseSource.php:7]
  #21 PhabricatorConfigDatabaseSource::__construct(string) called at [<phabricator>/src/infrastructure/env/PhabricatorEnv.php:232]
  #22 PhabricatorEnv::buildConfigurationSourceStack() called at [<phabricator>/src/infrastructure/env/PhabricatorEnv.php:95]
  #23 PhabricatorEnv::initializeCommonEnvironment() called at [<phabricator>/src/infrastructure/env/PhabricatorEnv.php:75]
  #24 PhabricatorEnv::initializeScriptEnvironment() called at [<phabricator>/scripts/__init_script__.php:21]
  #25 init_phabricator_script() called at [<phabricator>/scripts/__init_script__.php:24]
  #26 require_once(string) called at [<phabricator>/scripts/setup/manage_config.php:5]

Please file a bug report (see Contributing Bug Reports) if you'd like us to look at an issue. I can't reproduce the issue you describe, and need reproduction instructions (see Providing Reproduction Steps). Note that we do not support third-party images / packages / install instructions.

thanks, will follow the instructions. Do you guys ever plan to create an official docker image for Phabricator?

We don't have any current plans to do so, no. See T4200 for discussion.