2013-01-19 17:41:45 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorSetupCheckMySQL extends PhabricatorSetupCheck {
|
|
|
|
|
|
|
|
protected function executeChecks() {
|
|
|
|
$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);
|
|
|
|
|
|
|
|
$recommended_minimum = 1024 * 1024;
|
|
|
|
if ($max_allowed_packet < $recommended_minimum) {
|
|
|
|
$message = pht(
|
|
|
|
"MySQL is configured with a very small 'max_allowed_packet' (%d), ".
|
|
|
|
"which may cause some large writes to fail. Strongly consider raising ".
|
|
|
|
"this to at least %d in your MySQL configuration.",
|
|
|
|
$max_allowed_packet,
|
|
|
|
$recommended_minimum);
|
|
|
|
|
|
|
|
$this->newIssue('mysql.max_allowed_packet')
|
|
|
|
->setName(pht('Small MySQL "max_allowed_packet"'))
|
|
|
|
->setMessage($message);
|
|
|
|
}
|
2013-02-06 22:37:31 +01:00
|
|
|
|
2014-06-09 20:36:49 +02:00
|
|
|
$mode_string = queryfx_one($conn_raw, 'SELECT @@sql_mode');
|
2014-02-23 19:59:59 +01:00
|
|
|
$modes = explode(',', $mode_string['@@sql_mode']);
|
|
|
|
if (!in_array('STRICT_ALL_TABLES', $modes)) {
|
|
|
|
$summary = pht(
|
2014-06-09 20:36:49 +02:00
|
|
|
'MySQL is not in strict mode, but using strict mode is strongly '.
|
|
|
|
'encouraged.');
|
2013-02-06 22:37:31 +01:00
|
|
|
|
2014-02-23 19:59:59 +01:00
|
|
|
$message = pht(
|
2014-04-23 22:04:57 +02:00
|
|
|
"On your MySQL instance, the global %s is not set to %s. ".
|
|
|
|
"It is strongly encouraged that you enable this mode when running ".
|
|
|
|
"Phabricator.\n\n".
|
|
|
|
"By default MySQL will silently ignore some types of errors, which ".
|
|
|
|
"can cause data loss and raise security concerns. Enabling strict ".
|
|
|
|
"mode makes MySQL raise an explicit error instead, and prevents this ".
|
|
|
|
"entire class of problems from doing any damage.\n\n".
|
2014-02-23 19:59:59 +01:00
|
|
|
"You can find more information about this mode (and how to configure ".
|
|
|
|
"it) in the MySQL manual. Usually, it is sufficient to add this to ".
|
2014-04-23 22:04:57 +02:00
|
|
|
"your %s file (in the %s section) and then restart %s:\n\n".
|
2014-02-23 19:59:59 +01:00
|
|
|
"%s\n".
|
|
|
|
"(Note that if you run other applications against the same database, ".
|
|
|
|
"they may not work in strict mode. Be careful about enabling it in ".
|
|
|
|
"these cases.)",
|
2014-04-23 22:04:57 +02:00
|
|
|
phutil_tag('tt', array(), 'sql_mode'),
|
|
|
|
phutil_tag('tt', array(), 'STRICT_ALL_TABLES'),
|
|
|
|
phutil_tag('tt', array(), 'my.cnf'),
|
|
|
|
phutil_tag('tt', array(), '[mysqld]'),
|
|
|
|
phutil_tag('tt', array(), 'mysqld'),
|
|
|
|
phutil_tag('pre', array(), 'sql_mode=STRICT_ALL_TABLES'));
|
2014-02-23 19:59:59 +01:00
|
|
|
|
|
|
|
$this->newIssue('mysql.mode')
|
|
|
|
->setName(pht('MySQL STRICT_ALL_TABLES Mode Not Set'))
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message);
|
|
|
|
}
|
2014-08-14 00:34:09 +02:00
|
|
|
|
|
|
|
$stopword_file = queryfx_one($conn_raw, 'SELECT @@ft_stopword_file');
|
|
|
|
$stopword_file = $stopword_file['@@ft_stopword_file'];
|
|
|
|
if ($stopword_file == '(built-in)') {
|
|
|
|
if (!PhabricatorDefaultSearchEngineSelector::shouldUseElasticSearch()) {
|
|
|
|
|
|
|
|
$root = dirname(phutil_get_library_root('phabricator'));
|
|
|
|
$stopword_path = $root.'/resources/sql/stopwords.txt';
|
|
|
|
$stopword_path = Filesystem::resolvePath($stopword_path);
|
|
|
|
|
|
|
|
$namespace = PhabricatorEnv::getEnvConfig('storage.default-namespace');
|
|
|
|
|
|
|
|
$summary = pht(
|
|
|
|
'MySQL is using a default stopword file, which will prevent '.
|
|
|
|
'searching for many common words.');
|
|
|
|
|
|
|
|
$message = pht(
|
|
|
|
"Your MySQL instance is using the builtin stopword file for ".
|
|
|
|
"building search indexes. This can make Phabricator's search ".
|
|
|
|
"feature less useful.\n\n".
|
|
|
|
"Stopwords are common words which are not indexed and thus can not ".
|
|
|
|
"be searched for. The default stopword file has about 500 words, ".
|
|
|
|
"including various words which you are likely to wish to search ".
|
|
|
|
"for, such as 'various', 'likely', 'wish', and 'zero'.\n\n".
|
|
|
|
"To make search more useful, you can use an alternate stopword ".
|
|
|
|
"file with fewer words. Alternatively, if you aren't concerned ".
|
|
|
|
"about searching for common words, you can ignore this warning. ".
|
|
|
|
"If you later plan to configure ElasticSearch, you can also ignore ".
|
|
|
|
"this warning: this stopword file only affects MySQL fulltext ".
|
|
|
|
"indexes.\n\n".
|
|
|
|
"To choose a different stopword file, add this to your %s file ".
|
|
|
|
"(in the %s section) and then restart %s:\n\n".
|
|
|
|
"%s\n".
|
|
|
|
"(You can also use a different file if you prefer. The file ".
|
|
|
|
"suggested above has about 50 of the most common English words.)\n\n".
|
|
|
|
"Finally, run this command:\n\n".
|
|
|
|
"%s",
|
|
|
|
phutil_tag('tt', array(), 'my.cnf'),
|
|
|
|
phutil_tag('tt', array(), '[mysqld]'),
|
|
|
|
phutil_tag('tt', array(), 'mysqld'),
|
|
|
|
phutil_tag('pre', array(), 'ft_stopword_file='.$stopword_path),
|
|
|
|
phutil_tag(
|
|
|
|
'pre',
|
|
|
|
array(),
|
|
|
|
"mysql> REPAIR TABLE {$namespace}_search.search_documentfield;"));
|
|
|
|
|
|
|
|
$this->newIssue('mysql.ft_stopword_file')
|
|
|
|
->setName(pht('MySQL is Using Default Stopword File'))
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message);
|
|
|
|
}
|
|
|
|
}
|
2013-01-19 17:41:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|