Help us understand the problem. What is going on with this article?

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()
に関数名変更

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした