Minecraftサーバーを動かす知識

Minecraftサーバー向けのMySQL設定

投稿:  更新:  By: HimaJyun

ここではBukkitプラグインなどでよく使われるデータベースであるMySQLのインストールや設定を解説します。

データベースは「データベースエンジニア」という職業が存在するくらい高度な技術ですが、Minecraftに使うだけならそこまで凝った設定は必要ありません。

MySQLとMariaDB

MySQLから分岐して開発されているソフトウェアとしてMariaDBというものが存在します。

基本的に互換性があり、バージョンによる微妙な差異はあるかもしれませんが同じ使い方で使えます。

どちらを選ぶかは自由ですが、OSによってはパッケージ管理システムでMariaDBしか提供されていない場合もあります。(CentOSなど)

なおこのページではMariaDB 10.1.38を基準に設定を解説します。

インストール

基本的にaptやyumなどのパッケージ管理システムを利用してインストールすることを推奨します。

Ubuntuであればmysql-servermariadb-serverを指定してインストールします。

sudo apt install mariadb-server
#sudo apt install mysql-server

CentOSではmariadb-serverしか提供されていません。

sudo yum install mariadb-server
sudo systemctl enable mariadb
sudo systemctl start mariadb

yumでインストールできるものはバージョンが古いです(記事執筆時CentOS7で5.5.60)、MariaDBの公式リポジトリを使用してより新しいバージョンをインストールする方がいいでしょう。

設定

設定ファイルはUbuntuでは/etc/mysql/my.cnf、CentOSでは/etc/my.cnfにあります。

ネットで検索するといろいろな設定項目がありますが、実際に調整する必要のある設定はそこまで多くありません。

文字コード

基本的にutf8mb4で大丈夫です。

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_bin

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4

collation-serverは大文字小文字などをどれくらい厳密に文字の比較を行うか設定する項目です。

デフォルトではutf8mb4_general_ciなのですが、これ、ちょっとクセが強いので個人的にはutf8mb4_binで設定しています。

パフォーマンス関係

とくに重要なのはinnodb_flush_methodO_DIRECTにしてinnodb_buffer_pool_sizeを調整することです。

[mysqld]
# InnoDB関係の設定
innodb_large_prefix = ON
innodb_file_per_table = ON
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_default_row_format = DYNAMIC

# クエリキャッシュを無効にする
query_cache_type = 0
query_cache_size = 0

# スロークエリログを取る
slow_query_log = ON
long_query_time = 2
slow_query_log_file = /var/log/mysql/mysql-slow.log

# バッファープールサイズ(重要)
innodb_buffer_pool_size = 2G

# ログファイルサイズ
innodb_log_file_size = 128M
innodb_log_files_in_group = 2
innodb_log_buffer_size = 16M

# その他
innodb_flush_method = O_DIRECT
# SSDの場合は設定する
#innodb_flush_neighbors = 0
# MariaDBでのみ利用可能
#thread_handling = pool-of-threads

上から順に説明してきましょう。

まずはInnoDBのフォーマット関係の設定から

innodb_large_prefix = ON
innodb_file_per_table = ON
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_default_row_format = DYNAMIC

これは「Specified key was too long; max key length is 767 bytes」などのエラーを回避するための設定です。

比較的新しいバージョンのMySQLではデフォルト値がこの状態だったりするので、通常はこの状態で何も問題ありません。

次にクエリキャッシュ関係の設定。

query_cache_type = 0
query_cache_size = 0

「キャッシュ」と聞くと良さそうなイメージがありますが、クエリキャッシュはそうでもありません。

クエリキャッシュはマルチコアでの性能向上の妨げになります。MySQL 5.6からはデフォルトで無効ですし、そもそもMySQL 8.0で廃止されています。今更使うメリットはないでしょう。

どのみちMinecraftとクエリキャッシュは相性が悪いです(多くのプラグインがより効率のいいキャッシュを備えていますし、Minecraftは更新が多く、同じ参照が複数回行われることも少ないため)

次にスロークエリログの設定です

slow_query_log = ON
long_query_time = 2
slow_query_log_file = /var/log/mysql/mysql-slow.log

スロークエリ(実行に時間がかかっているSQL)のログは取得しておきましょう。動作の怪しいプラグインの特定にもきっと役立ちます。

long_query_timeはデフォルトで10ですが、Minecraftで10秒(200チック)も停止するとそれはもう完全に「世界が止まっている」状態です。

そのため、long_query_timeは短めに設定しておく方がいいでしょう。

次に、バッファープールサイズの設定

innodb_buffer_pool_size = 2G

例では2Gに設定していますが、実際にはサーバーのスペック(空きメモリ)に合わせて調整する必要があります。

多ければ多いほど良いのですが、ただ、あまり多すぎると滅多に使われないデータでバッファーが埋められてしまう(OSがディスクキャッシュとして使えるメモリが減ってしまう)という事態にも繋がるので少なすぎず多すぎない状態を目指しましょう。

もちろんMySQLサーバーとMinecraftサーバーが別のマシンになっている場合はめいっぱい割り当てて構いません。

次に、ログファイルサイズの設定です。

innodb_log_file_size = 128M
innodb_log_files_in_group = 2
innodb_log_buffer_size = 16M

ログの設定です。innodb_buffer_pool_sizeと一緒に増やしましょう。

innodb_log_file_sizeで指定したサイズのファイルがinnodb_log_files_in_groupで指定した数だけディスク上に作成されます。合計がinnodb_buffer_pool_size以下でなければなりません。ファイルはディスク上に作成されるので値を大きくしてもメモリを圧迫したりはしません。

innodb_log_buffer_sizeはあまり大きくしても意味がないでしょう。8~16Mもあれば十分です。

innodb_log_file_sizeを変更した場合はログファイルを削除して再起動する必要があります。基本的に次のコマンドでやれば問題ありません。

sudo mysql -e "SET GLOBAL innodb_fast_shutdown=0;"
# CentOSの場合はmariadbです。
#sudo systemctl stop mariadb
sudo systemctl stop mysql
sudo rm -v /var/lib/mysql/ib_logfile*
#sudo systemctl start mariadb
sudo systemctl start mysql

最後に、その他の設定をいくつか行っておきましょう。

innodb_flush_method = O_DIRECT
# SSDの場合は設定する
innodb_flush_neighbors = 0
# MariaDBでのみ利用可能
thread_handling = pool-of-threads

innodb_flush_methodは可能な限りO_DIRECTにしましょう。具体的に言えば、データがinnodb_buffer_pool_sizeに収まる場合はO_DIRECTにするべきです。

O_DIRECTを使用するとOSのディスクキャッシュを使わなくなるためキャッシュ制御の負荷が減り、ディスクキャッシュがムダなデータで圧迫されたりしなくなります。要するにMinecraftのデータをキャッシュするために使えるメモリが増える、という事。

innodb_flush_neighborsはSSDの場合0にしましょう。これはHDD向けの最適化機能ですが、SSDでは必要ありません。

MariaDBの場合はthread_handlingpool-of-threadsを指定できます。(MySQLでもできるにはできるのですが……有料版限定の機能です)

pool-of-threadsがどのような用途に適しているかはMariaDBの公式ドキュメントに書いてあります。簡単に紹介するとクエリが低負荷(短時間)で完了する場合です。

Bukkitプラグインなどで実行されるクエリは多くの場合短時間で完了するでしょうから、設定しておくと良いと思います。

運用

実際にデータベースサーバーを運用する際に必要となる最小限の手順をご紹介しておきましょう。

データベースの作成

実際に使用する際にはデータベースを作成する必要があります。

基本的に1プラグイン1データベースで運用しましょう。

プラグイン側での対応次第では1つのデータベースに複数のプラグインのデータを押し込んで動かすことも不可能ではないのですが、カオスになるのでやめましょう。

データベースを作成する際はrootでmysqlにログインする必要があります。

sudo mysql
# もしくは
#mysql -u root -p

ログインしたらCREATE DATABASEでデータベースを作成します。たとえばminecraftという名前のデータベースを作成する場合は次のように

CREATE DATABASE `minecraft`;

後はこれを各種プラグインの設定ファイルに設定するだけです。

ユーザーの作成と追加

rootユーザーをそのままプラグインから使うのは行儀が悪いのでやめましょう。必ずMinecraft用にユーザーを作成して利用しましょう。

次の例はminecraftユーザーを作成する例です。

CREATE USER 'minecraft'@'localhost' IDENTIFIED BY 'パスワード';

'ユーザー名'@'ホスト名'の部分ですが、例のようにlocalhostや127.0.0.1などを指定すると外部から接続できなくなり安全です。(逆に、どこからでもアクセスできるようにするためには%を指定します)

一般的にユーザーというとユーザー名+パスワードのイメージがありますが、MySQLの場合はユーザー名+ホスト名+パスワードです。要するに同じユーザー名でもアクセス元別に違うパスワード……という設定も可能なわけです。

CREATE USERをしただけではユーザーしかできていない(データベースを操作する権限が与えられていない)ので、次にデータベースを操作する権限を与えましょう。

たとえばCREATE DATABASE `foo`;で作成したfooデータベースを操作できるようにするには次のように

GRANT ALL ON `foo`.* TO 'minecraft'@'localhost';

構文はGRANT 権限 ON データベース名.テーブル名 TO ユーザー名@ホスト名です。

権限はより細かく設定することが可能なのですが、これにはプラグインが利用するSQLを把握する必要があるため普通はALLで良いでしょう。

データベース名は単純にデータベース名をそのまま入れればOKです。テーブル名は個別に設定することができるのですが、あまり意味がないので基本的にすべて(*)を指定すればOKです。

ユーザー名、ホスト名はCREATE USERと同じです。もちろんアクセス元別に異なる権限レベルを設定することも可能です。

ちなみにGRANT文でそのままユーザーを作成する例もありますが、個人的には推奨しません。

バックアップ

MySQLのバックアップにはmysqldumpコマンドを使用します。

次のように使用します。

mysqldump データベース名 > backup.sql

たとえばfooデータベースをバックアップするなら次のように

mysqldump foo > backup.sql
# 必要なら
#mysqldump -u root -p foo > backup.sql

mysqldumpにはいくつかのオプションが設定できます。個人的によく使うのは--quote-names--flush-logs--hex-blobの3つ。それからInnoDBなら--single-transactionです。

--quote-namesはテーブル名などをバッククオートで囲むオプションです。付けていないとプラグインによっては失敗するかもしれません。

--flush-logsはバイナリログという物に関するオプションです、整合性を保つために指定しています。

--hex-blobはバイナリなどのデータを16進数に変換するオプションです、バックアップデーターをテキストエディターなどで閲覧する際に役立ちます。

--single-transactionはロックなどをせずにバックアップを行うオプションです、バックアップ中に他の処理が止まってしまうのを防ぎます。InnoDBに対してしか使えません。

あるデータベースがInnoDBだけで構成されているか確認するには次のSQLが使えます。

SELECT table_name,engine FROM information_schema.tables WHERE table_schema = 'データベース名';

他のストレージエンジン(MyISAM)などが混ざっている場合は--single-transactionを使えません。

すべて指定した場合の例

mysqldump --quote-names --flush-logs --hex-blog --single-transaction foo > backup.sql

ちなみにmysqldumpだけが実行できるユーザーは次のように作成できます。

-- ユーザー名は何でも構いません
CREATE USER 'system'@'localhost' IDENTIFIED BY 'password';
GRANT RELOAD,FILE,SELECT,SHOW VIEW,TRIGGER,LOCK TABLES ON *.* TO 'system'@'localhost';

MySQLは本物の(ビジネスで利用される)サーバーの一種なので色々なことが可能なようになっています。一見すると複雑ですが、慣れるとそうでもないので頑張って使ってみましょう。