Edited at

WordPress YARPPプラグインのInnoDB対応

※今回の対応内容を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の場合、管理画面上で以下の警告が表示されます。

myisam_notice.png

そして、関連スコア設定の「内容」と「カテゴリー」の選択が無効になり、選択できなくなります。

myisam_disable.png

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&#39;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&#39;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()

に関数名変更