※今回の対応内容をGithubにもアップしました。
https://github.com/yKanazawa/yet-another-related-posts-plugin/pull/1/files
背景
WordPressのYet Another Related Posts Plugin (YARPP)は、バージョン4.4現在、MySQLのMyISAMしか対応していません。
wp-postsテーブルがInnoDBの場合、管理画面上で以下の警告が表示されます。
そして、関連スコア設定の「内容」と「カテゴリー」の選択が無効になり、選択できなくなります。
MySQLのFULLTEXTインデックスがMyISAMしかサポートしていなかったのが理由だと思われますが、MySQL5.6.4からInnoDBでもFULLTEXTインデックスがサポートされました。
※MySQL5.6登場当初、このことが話題になり、対応の要望が出ていたようです。
Support for InnoDB with full-text index
https://wordpress.org/support/topic/support-for-with-full-text-index/?replies=4
YARPPプラグインには、強制的にMyISAMと認識させるオプション(myisam_override)があり、それを有効にすればInnoDBでも使えるようです。
しかしながら、最近ではデフォルトでInnoDBを使うパターンも多くなったと思います。
特に、WordPressのDBをAWSのRDSで稼働させる場合、RDSは基本的にInnoDBのみのサポートで、MyISAMでは機能が制限されてしまいます。
そこで、MySQL5.6.4以上であれば、デフォルトでInnoDBでも動作するように修正してみました。
Fulltextインデックス判定処理の調査
Fulltextインデックスが必要なテーブルは、wp-postsです。
このテーブルがMyISAMになっていないと、管理画面で警告が表示されます。
しかし、wp-postsテーブルをInnoDBに変換しても、管理画面で警告が出るだけで、実際の動作は正常に行われてるようです。
そのため、管理画面でのチェック処理を修正するだけで良いはずです。
wp-postsテーブルがMyISAMかどうかの判定は、classes/YARPP_Core.php のdiagnostic_myisam_posts関数で行なっています。
show table status の出力結果のEngineカラムの値を取得しているようです。
/**
* DIAGNOSTICS
* @since 4.0 Moved into separate functions. Note return value types can differ.
*/
public function diagnostic_myisam_posts() {
global $wpdb;
$tables = $wpdb->get_results("show table status like '{$wpdb->posts}'");
foreach ($tables as $table) {
if ($table->Engine === 'MyISAM'){
return true;
} else {
return $table->Engine;
}
}
return 'UNKNOWN';
}
MySQLのバージョンは、select version()で取得できます。
mysql> select version();
+------------+
| version() |
+------------+
| 5.6.10-log |
+------------+
1 row in set (0.01 sec)
これが、5.6.4以上であればInnoDBでもFULLTEXTインデックスが使えるわけですが、MariaDBのパターンも考えると、バージョンで判定するのは良く無さそうです。
確実に判定するために、innodb_ft関連のパラメータが含まれているかどうかで判定することにしました。
mysql> show variables like 'innodb_ft%';
+---------------------------------+------------+
| Variable_name | Value |
+---------------------------------+------------+
| innodb_ft_aux_table | |
| innodb_ft_cache_size | 8000000 |
| innodb_ft_enable_diag_print | OFF |
| innodb_ft_enable_stopword | ON |
| innodb_ft_max_token_size | 84 |
| innodb_ft_min_token_size | 3 |
| innodb_ft_num_word_optimize | 2000 |
| innodb_ft_result_cache_limit | 2000000000 |
| innodb_ft_server_stopword_table | |
| innodb_ft_sort_pll_degree | 2 |
| innodb_ft_total_cache_size | 640000000 |
| innodb_ft_user_stopword_table | |
+---------------------------------+------------+
12 rows in set (0.00 sec)
修正内容
classes/YARPP_Core.php
292行目
/**
* DIAGNOSTICS
* @since 4.0 Moved into separate functions. Note return value types can differ.
*/
public function diagnostic_myisam_posts() {
global $wpdb;
$tables = $wpdb->get_results("show table status like '{$wpdb->posts}'");
foreach ($tables as $table) {
if ($table->Engine === 'MyISAM'){
return true;
} else {
return $table->Engine;
}
}
return 'UNKNOWN';
}
↓
関数名変更:diagnostic_myisam_posts → diagnostic_fulltext_posts
/**
* DIAGNOSTICS
* @since 4.0 Moved into separate functions. Note return value types can differ.
*/
public function diagnostic_fulltext_posts() {
global $wpdb;
$params = $wpdb->get_results("show variables like 'innodb_ft%';");
if (count($params) > 0) {
return true;
}
$tables = $wpdb->get_results("show table status like '{$wpdb->posts}'");
foreach ($tables as $table) {
if ($table->Engine === 'MyISAM'){
return true;
}
return false;
}
}
includes/yarpp_myisam_notice.php
34行目
$table_type = $yarpp->diagnostic_myisam_posts()
if ((bool) $table_type !== true) $yarpp->disable_fulltext();
↓
ファイル名変更:yarpp_myisam_notice.php → yarpp_fulltext_notice.php
$fulltext_posts = $yarpp->diagnostic_fulltext_posts();
if ($fulltext_posts === true) {
if ((bool) get_option('yarpp_fulltext_disabled', false) === true) {
$yarpp->enable_fulltext();
update_option('yarpp_fulltext_disabled', 0);
}
} else {
$yarpp->disable_fulltext();
}
49行目
sprintf(
'YARPP's "consider titles" and "consider bodies" relatedness criteria require your <code>%s</code> '.
'table to use the <code>MyISAM</code> engine'.
'fulltext indexing feature. Unfortunately your table seems to be using the <code>%s</code> engine. '.
'Because fulltext indexing is not supported by your current table engine, these two options have been disabled.',
$wpdb->posts,
$table_type
).
'</p>'.
'<p>'.
sprintf(
'To restore these features, please do the following:<br/>'.
↓
sprintf(
'YARPP's "consider titles" and "consider bodies" relatedness criteria require your <code>%s</code> '.
'table to use the fulltext indexing feature.<br/>' .
'Unfortunately your table does not seem to be able to use fulltext index.<br/>' .
'Fulltext indexing is supported in MyISAM, or InnoDB with MySQL 5.6.4 or higher. ',
$wpdb->posts
).
'</p>'.
'<p>'.
sprintf(
'If you are using MySQL 5.6.3 or earlier version, to restore these features, please do the following:<br/>'.
includes/yarpp_options.php
72行目
/* MyISAM Check */
include 'yarpp_myisam_notice.php';
↓
/* FullText Check */
include 'yarpp_fulltext_notice.php';
関数名変更
以下の箇所について
classes/YARPP_Core.php: public function diagnostic_myisam_posts() {
classes/YARPP_Core.php: $table_type = $this->diagnostic_myisam_posts();
classes/YARPP_Core.php: if (!$this->get_option('myisam_override') && $this->diagnostic_myisam_posts() !== true) {
classes/YARPP_Core.php: 'myisam_posts' => $this->diagnostic_myisam_posts(),
includes/yarpp_myisam_notice.php:$table_type = $yarpp->diagnostic_myisam_posts();
diagnostic_myisam_posts()
↓
diagnostic_fulltext_posts()
に関数名変更