MySQL v4.0.27 から v5.6 へ

旧サーバで動いていたMySQL v4.0.27 のデータを、まるっと直接 新サーバの MySQL v5.6 へ移動させた作業の覚書。
MySQLサーバは、default-character-set=sjis で動いていた。

新サーバにインストールされているMySQL v5.1 を削除する

# rpm -qa | grep mysql
mysql-devel-5.1.71-1.el6.x86_64
mysql-5.1.71-1.el6.x86_64
mysql-libs-5.1.71-1.el6.x86_64

# yum erase mysql
Removed:
mysql.x86_64 0:5.1.71-1.el6
Dependency Removed:
mysql-devel.x86_64 0:5.1.71-1.el6

次に、mysql-libsも削除しようとしたが、依存関係で crontabs や postfix が削除されてしまうので中止

# yum erase mysql-libs
Dependencies Resolved
Removing:
mysql-libs
Removing for dependencies:
cronie
cronie-anacron
crontabs
postfix
redhat-lsb-core
sysstat
yum-cron

しかし、古いmysql-libs のまま MySQL v5.6 をインストールしようとすると、一部のファイル(errmsg.sys)が競合してしまう。

これを解消するには、以下のページに書いてある通り、自分がインストールしたいバージョンの MySQL-shared-compat を
インストールしてからmysql-libsを削除すれば良いらしい
http://d.hatena.ne.jp/R-H/20120505/1336187294
http://dev.mysql.com/doc/refman/5.6/en/linux-installation-rpm.html

MySQL-shared-compatをインストール

# wget []http://download.softagency.net/MySQL/Downloads/MySQL-5.6/MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm[]
# rpm -ivh MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm
1:MySQL-shared-compat ########################################### [100%]

mysql-libs 削除

# yum erase mysql-libs
Removed:
mysql-libs.x86_64 0:5.1.71-1.el6

MySQL v5.6 インストール(RPM

# wget []http://download.softagency.net/MySQL/Downloads/MySQL-5.6/MySQL-server-5.6.14-1.el6.x86_64.rpm[]
# wget []http://download.softagency.net/MySQL/Downloads/MySQL-5.6/MySQL-client-5.6.14-1.el6.x86_64.rpm[]
# wget []http://download.softagency.net/MySQL/Downloads/MySQL-5.6/MySQL-devel-5.6.14-1.el6.x86_64.rpm[]
# wget []http://download.softagency.net/MySQL/Downloads/MySQL-5.6/MySQL-shared-5.6.14-1.el6.x86_64.rpm[]
# rpm -ivh MySQL*.rpm
MySQL-5.5.6以降のMySQL-shared-compatは、過去バージョンのライブラリのみ提供に変わったらしいのでMySQL-sharedもインストールしました。
http://y-ken.hatenablog.com/entry/inside-of-libmysqlclient-with-mysql-shared-compat

MySQL-5.5.6以降のMySQL-shared-compatでは、現行バージョンのものは含まずに過去のバージョンのライブラリのみ提供します。
そのため、MySQL-sharedとは独立したものとして、MySQL-shared-compatもインストールすることが出来ます。

MySQL-server インストール時に以下のような警告が表示される

[Warning] TIMESTAMP with implicit DEFAULT value is deprecated.
Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
この警告は、MySQL 5.6.6 から追加された explicit_defaults_for_timestamp 設定項目によるもの。
booleanでデフォルトはFALSE(0)。動的変更は不可となる。
(起動時のオプションか、my.cnfで設定可能)
http://d.hatena.ne.jp/hiroi10/20121104/1352037845
http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp


MySQL-server のインストールが完了すると以下のようなメッセージが表示される。

A RANDOM PASSWORD HAS BEEN SET FOR THE MySQL root USER !
You will find that password in '/root/.mysql_secret'.

You must change that password on your first connect,
no other statement but 'SET PASSWORD' will be accepted.
See the manual for the semantics of the 'password expired' flag.

Also, the account for the anonymous user has been removed.

In addition, you can run:

/usr/bin/mysql_secure_installation

which will also give you the option of removing the test database.
This is strongly recommended for production servers.

See the manual for more instructions.

Please report any problems with the /usr/bin/mysqlbug script!

The latest information about MySQL is available on the web at

http://www.mysql.com

Support MySQL by buying support/licenses at http://shop.mysql.com

New default config file was created as /usr/my.cnf and
will be used by default by the server when you start it.
You may edit this file to change server settings

rootユーザーのランダムパスワードを /root/.mysql_secret に保存したので
初回ログインはそこに記されているパスワードを使ってログインしてパスワードを変更すべし。
その上で、
/usr/bin/mysql_secure_installation
を実行することをお奨めする。----ということらしい。

rootのランダムパスワードの確認と変更

まずこれをやらないと先へ進めない。

# cat /root/.mysql_secret
# The random password set for the root user at Thu Jul 07 22:40:33 2014 (local time): ********
「********」の部分が、今回生成の MySQL root パスワード

# service mysql start
Starting MySQL.... [ OK ]
# mysql -u root -p
Enter password:********
mysql> SET PASSWORD FOR root@localhost=PASSWORD('新しいパスワード');
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye

/usr/bin/mysql_secure_installation 実行

# /usr/bin/mysql_secure_installation
Enter password:(新しいパスワード)

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!

In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n
... skipping.

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
... Success!

Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
... Success!

By default, MySQL comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
... skipping.

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
... Success!

All done! If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

Cleaning up...

設定ファイル(/usr/my.cnf)編集

/etc/my.cnf ではなく、 /usr/my.cnf がデフォルトの位置に変わったようです。

/usr/my.cnf
[mysqld]
character-set-server = utf8mb4
explicit_defaults_for_timestamp = TRUE

キャラクターセットの設定値は以下のようになる

mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
※character_set_filesystem は、LOAD DATA INFILE、SELECT ... INTO OUTFILE 文と LOAD_FILE()関数で、ファイル名を参照している文字列を解釈するために使われる。
デフォルト値は変換が発生しないことを意味する「binary」。

必要なユーザーを登録する

前にユーザー情報が記録されているmysql.user テーブルをインポートして mysql_upgrade したら悲惨なことになったので、ここは手作業でひとつずつ登録。

【例】

mysql> SELECT ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password';

mysqldump で旧mySQLサーバのデータをダンプ

MySQLサーバ(v5.6)から旧MySQLサーバ(v4.0.27)へ接続し、mysqldump にてデータをダンプします。
mysqlデータベースはダンプしません。

この時、旧MySQLサーバにパスワードなしのユーザーを作成しておく。そうしないと、パスワードの形式が古いと言われ、旧MySQLサーバにアクセスできない。
セキュリティのため、接続ホスト制限等で自分以外はアクセスできないようにすると良い。

$ mysqldump -u username -h hostname --databases databasename --default-character-set=cp932 --add-drop-database --no-tablespaces -q -Q > /home/username/mysql-backup/4.0.27/dump-databasename.sql
※「--default-character-set=cp932」オプションを入れておかないと、新サーバにリストアする際にエラーが発生する。
※「--no-tablespaces」オプションは、MySQLのバージョンがサーバ側とクライアント側で異なる時、tablespace のダンプ時に発生するエラーを回避するために入れた。

dumpファイルを新MySQLサーバに合わせて修正

dumpファイルは結構大きいので、サーバ上に置いたまま、Perlスクリプトで修正します。
変更箇所は以下の5カ所です

  1. 「CREATE DATABASE..」文の前に「character_set_results = NULL;」行を挿入
  2. 「CREATE DATABASE..」文の最後に「DEFAULT CHARACTER SET cp932 DEFAULT COLLATE cp932_japanese_ci」を追加
  3. 「SET character_set_client = utf8」を、「SET character_set_client = cp932」に変更
  4. 「TYPE=(MyISAM|InnoDB)」を「ENGINE=(MyISAM|InnoDB)」に変更
  5. 「timestamp(14)」を「DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」に変更

MySQLサーバは、設定ファイルに「default-character-set=sjis」を指定して動いていました。
MySQLサーバでは、設定ファイルには「character-set-server = utf8mb4」を指定し、今後新しく作成するデータベースはUTF-8 で作成されるようにし、旧MySQLサーバから移したデータベースに限り、cp932 で動かすものとします。

dump ファイルを流し込み

$ cd /home/username/mysql-backup/4.0.27
$ mysql -u root -p --default-character-set=cp932 < dump-databasename.sql
Enter password:

各テーブルと MySQL サーバとの互換性をチェックするため、mysql_upgradeを実行

# mysql_upgrade -u root -p
Enter password:

データベースに接続する各種アプリケーションの修正

◎cp932データベースを扱う時には、データベース接続直後に

SET character_set_client = cp932
SET character_set_connection = cp932
SET character_set_results = NULL

を実行する。

◎timestamp(14)だったカラムに、NULL値を挿入している箇所が無いことを確認。


今のところ文字化けもなく、無事動いているようです。