2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WordPress YARPPプラグインのInnoDB対応

Last updated at Posted at 2017-09-10

※今回の対応内容を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()
に関数名変更

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?