From 6dd82d86a2b75bdf4f6be09f0b23ef30236dd1b9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 25 Aug 2014 11:41:40 -0700 Subject: [PATCH] Provide some hints for Amazon RDS configuration Summary: Fixes T2605. Provide some instructions on configuring RDS properly. The "DB Parameter Group" thing in the web UI seems pretty easy to use, it's just not obvious that it's what you should be using. Test Plan: Jiggled these warnings to trigger them, viewed the output, saw a table of values and a hint about RDS. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2605 Differential Revision: https://secure.phabricator.com/D10343 --- src/__phutil_library_map__.php | 2 + .../check/PhabricatorSetupCheckMySQL.php | 56 ++++++++++-------- .../config/issue/PhabricatorSetupIssue.php | 10 ++++ .../config/view/PhabricatorSetupIssueView.php | 59 +++++++++++++++++++ src/docs/user/userguide/amazon_rds.diviner | 27 +++++++++ .../PhabricatorBaseEnglishTranslation.php | 5 ++ 6 files changed, 133 insertions(+), 26 deletions(-) create mode 100644 src/docs/user/userguide/amazon_rds.diviner diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 2cf06ba8a8..0adb3af9db 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5560,6 +5560,7 @@ phutil_register_library_map(array( 'PhabricatorFlaggableInterface', 'PhabricatorSubscribableInterface', 'PhabricatorTokenReceiverInterface', + 'PhabricatorDestructibleInterface', ), 'PonderAnswerCommentController' => 'PonderController', 'PonderAnswerEditController' => 'PonderController', @@ -5588,6 +5589,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyInterface', 'PhabricatorTokenReceiverInterface', 'PhabricatorProjectInterface', + 'PhabricatorDestructibleInterface', ), 'PonderQuestionCommentController' => 'PonderController', 'PonderQuestionEditController' => 'PonderController', diff --git a/src/applications/config/check/PhabricatorSetupCheckMySQL.php b/src/applications/config/check/PhabricatorSetupCheckMySQL.php index b4614a11da..670a428d92 100644 --- a/src/applications/config/check/PhabricatorSetupCheckMySQL.php +++ b/src/applications/config/check/PhabricatorSetupCheckMySQL.php @@ -2,15 +2,21 @@ final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck { - protected function executeChecks() { + public static function loadRawConfigValue($key) { $conn_raw = id(new PhabricatorUser())->establishConnection('w'); - $max_allowed_packet = queryfx_one( - $conn_raw, - 'SHOW VARIABLES LIKE %s', - 'max_allowed_packet'); - $max_allowed_packet = idx($max_allowed_packet, 'Value', PHP_INT_MAX); + try { + $value = queryfx_one($conn_raw, 'SELECT @@%Q', $key); + $value = $value['@@'.$key]; + } catch (AphrontQueryException $ex) { + $value = null; + } + + return $value; + } + protected function executeChecks() { + $max_allowed_packet = self::loadRawConfigValue('max_allowed_packet'); $recommended_minimum = 1024 * 1024; if ($max_allowed_packet < $recommended_minimum) { $message = pht( @@ -22,11 +28,12 @@ final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck { $this->newIssue('mysql.max_allowed_packet') ->setName(pht('Small MySQL "max_allowed_packet"')) - ->setMessage($message); + ->setMessage($message) + ->addMySQLConfig('max_allowed_packet'); } - $mode_string = queryfx_one($conn_raw, 'SELECT @@sql_mode'); - $modes = explode(',', $mode_string['@@sql_mode']); + $modes = self::loadRawConfigValue('sql_mode'); + $modes = explode(',', $modes); if (!in_array('STRICT_ALL_TABLES', $modes)) { $summary = pht( 'MySQL is not in strict mode, but using strict mode is strongly '. @@ -57,16 +64,11 @@ final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck { $this->newIssue('mysql.mode') ->setName(pht('MySQL STRICT_ALL_TABLES Mode Not Set')) ->setSummary($summary) - ->setMessage($message); - } - - try { - $stopword_file = queryfx_one($conn_raw, 'SELECT @@ft_stopword_file'); - $stopword_file = $stopword_file['@@ft_stopword_file']; - } catch (AphrontQueryException $ex) { - $stopword_file = null; + ->setMessage($message) + ->addMySQLConfig('sql_mode'); } + $stopword_file = self::loadRawConfigValue('ft_stopword_file'); if (!PhabricatorDefaultSearchEngineSelector::shouldUseElasticSearch()) { if ($stopword_file === null) { $summary = pht( @@ -86,7 +88,8 @@ final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck { $this->newIssue('mysql.ft_stopword_file') ->setName(pht('MySQL ft_stopword_file Not Supported')) ->setSummary($summary) - ->setMessage($message); + ->setMessage($message) + ->addMySQLConfig('ft_stopword_file'); } else if ($stopword_file == '(built-in)') { $root = dirname(phutil_get_library_root('phabricator')); @@ -133,20 +136,20 @@ final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck { $this->newIssue('mysql.ft_stopword_file') ->setName(pht('MySQL is Using Default Stopword File')) ->setSummary($summary) - ->setMessage($message); + ->setMessage($message) + ->addMySQLConfig('ft_stopword_file'); } } - - $min_len = queryfx_one($conn_raw, 'SELECT @@ft_min_word_len'); - $min_len = $min_len['@@ft_min_word_len']; - if ($min_len == 4) { + $min_len = self::loadRawConfigValue('ft_min_word_len'); + if ($min_len >= 4) { if (!PhabricatorDefaultSearchEngineSelector::shouldUseElasticSearch()) { $namespace = PhabricatorEnv::getEnvConfig('storage.default-namespace'); $summary = pht( - 'MySQL is configured to only index words with at least 4 '. - 'characters.'); + 'MySQL is configured to only index words with at least %d '. + 'characters.', + $min_len); $message = pht( "Your MySQL instance is configured to use the default minimum word ". @@ -178,7 +181,8 @@ final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck { $this->newIssue('mysql.ft_min_word_len') ->setName(pht('MySQL is Using Default Minimum Word Length')) ->setSummary($summary) - ->setMessage($message); + ->setMessage($message) + ->addMySQLConfig('ft_min_word_len'); } } diff --git a/src/applications/config/issue/PhabricatorSetupIssue.php b/src/applications/config/issue/PhabricatorSetupIssue.php index c69f529aca..51f24f6cf5 100644 --- a/src/applications/config/issue/PhabricatorSetupIssue.php +++ b/src/applications/config/issue/PhabricatorSetupIssue.php @@ -15,6 +15,7 @@ final class PhabricatorSetupIssue { private $relatedPhabricatorConfig = array(); private $phpConfig = array(); private $commands = array(); + private $mysqlConfig = array(); public function addCommand($command) { $this->commands[] = $command; @@ -85,6 +86,15 @@ final class PhabricatorSetupIssue { return $this->phpConfig; } + public function addMySQLConfig($mysql_config) { + $this->mysqlConfig[] = $mysql_config; + return $this; + } + + public function getMySQLConfig() { + return $this->mysqlConfig; + } + public function addPhabricatorConfig($phabricator_config) { $this->phabricatorConfig[] = $phabricator_config; return $this; diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php index ca575adc8d..f8bea6539c 100644 --- a/src/applications/config/view/PhabricatorSetupIssueView.php +++ b/src/applications/config/view/PhabricatorSetupIssueView.php @@ -29,6 +29,11 @@ final class PhabricatorSetupIssueView extends AphrontView { $description[] = $this->renderPHPConfig($configs); } + $configs = $issue->getMySQLConfig(); + if ($configs) { + $description[] = $this->renderMySQLConfig($configs); + } + $configs = $issue->getPhabricatorConfig(); if ($configs) { $description[] = $this->renderPhabricatorConfig($configs); @@ -347,6 +352,58 @@ final class PhabricatorSetupIssueView extends AphrontView { )); } + private function renderMySQLConfig(array $config) { + $values = array(); + foreach ($config as $key) { + $value = PhabricatorSetupCheckMySQL::loadRawConfigValue($key); + if ($value === null) { + $value = phutil_tag( + 'em', + array(), + pht('(Not Supported)')); + } + $values[$key] = $value; + } + + $table = $this->renderValueTable($values); + + $doc_href = PhabricatorEnv::getDoclink('User Guide: Amazon RDS'); + $doc_link = phutil_tag( + 'a', + array( + 'href' => $doc_href, + 'target' => '_blank', + ), + pht('User Guide: Amazon RDS')); + + $info = array(); + $info[] = phutil_tag( + 'p', + array(), + pht( + 'If you are using Amazon RDS, some of the instructions above may '. + 'not apply to you. See %s for discussion of Amazon RDS.', + $doc_link)); + + $table_info = phutil_tag( + 'p', + array(), + pht( + 'The current MySQL configuration has these %d value(s):', + count($config))); + + return phutil_tag( + 'div', + array( + 'class' => 'setup-issue-config', + ), + array( + $table_info, + $table, + $info, + )); + } + private function renderValueTable(array $dict, array $hidden = array()) { $rows = array(); foreach ($dict as $key => $value) { @@ -374,6 +431,8 @@ final class PhabricatorSetupIssueView extends AphrontView { return phutil_tag('em', array(), 'true'); } else if ($value === '') { return phutil_tag('em', array(), 'empty string'); + } else if ($value instanceof PhutilSafeHTML) { + return $value; } else { return PhabricatorConfigJSON::prettyPrintJSON($value); } diff --git a/src/docs/user/userguide/amazon_rds.diviner b/src/docs/user/userguide/amazon_rds.diviner new file mode 100644 index 0000000000..442d499013 --- /dev/null +++ b/src/docs/user/userguide/amazon_rds.diviner @@ -0,0 +1,27 @@ +@title User Guide: Amazon RDS +@group config + +Discusses using Amazon RDS as a database. + +Overview +======== + +Phabricator works with Amazon RDS. However, most of our documentation and setup +checks assume you are using local MySQL, and upstream support is less available +for RDS. + +If you use RDS, you'll need to do a few things a bit differently than you would +with local MySQL, especially when configuring RDS. This document documents some +of the differences you'll encounter when using RDS. + +Configuration +============= + +The documentation and various setup warnings will sometimes direct you to make +configuration changes in `my.cnf`. In Amazon RDS, you don't have direct access +to `my.cnf` and thus can not make these changes in the configuration file. + +Instead, you can use [[ http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html | DB Parameter Groups ]]. +You can access these from your AWS console and use the web interface to make +necessary changes. The web UI will give you a user-friendly key-value table: +just identify the option you need to change, then select a new value for it. diff --git a/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php index d0888d496e..d717a780ae 100644 --- a/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php @@ -674,6 +674,11 @@ abstract class PhabricatorBaseEnglishTranslation 'The current Phabricator configuration has these values:', ), + 'The current MySQL configuration has these %d value(s):' => array( + 'The current MySQL configuration has this value:', + 'The current MySQL configuration has these values:', + ), + 'To update these %d value(s), run these command(s) from the command line:' => array( 'To update this value, run this command from the command line:', -- 2.51.2