Tag Archives: MySQL

1台のサーバに複数のMySQLをインストールしてみた。

前回はApacheだったが、今回は1台のサーバに複数のMySQL5.0をインストールするメモ。

Source downloads」から「Compressed GNU TAR archive」をダウンロード。



■今回の環境

以下の環境を想定して解説する。

サーバ:CentOS 5
ビット:64bit
MySQLインストールディレクトリ:/home/hoge/mysql
ポート番号:1235



■MySQLインストール

# su - hoge
# wget http://hoge.hoge.hoge/hoge/mysql-5.0.51a.tar.gz
# tar -xvzf mysql-5.0.51a.tar.gz
# cd mysql-5.0.51a
# ./configure --prefix=/home/hoge/mysql \
--with-mysqld-user=hoge \
--with-charset=utf8 \
--with-extra-charsets=all \
--with-tcp-port=1235
...
checking for tgetent in -lncurses... no
checking for tgetent in -lcurses... no
checking for tgetent in -ltermcap... no
checking for tgetent in -ltinfo... no
checking for termcap functions library... configure: error: No curses/termcap library found

上記のようなエラーが発生。

どうやらcursesとかいうものが指定されていないっぽい。これも64bitだからか?



configureのhelpを見たら「with-named-curses-libs」なるものが。

試しにオプションつけて再度実行。

# ./configure --prefix=/home/hoge/mysql \
--with-mysqld-user=hoge \
--with-charset=utf8 \
--with-extra-charsets=all \
--with-tcp-port=1235 \
--with-named-curses-libs=/usr/lib64/libncurses.so.5
# make
# make install

正常にいった。



my-medium.cnfをコピーする。

# cp /home/hoge/mysql-5.0.51a/support-files/my-medium.cnf /home/hoge/mysql/my.cnf

my.cnfを編集する。まずmysql.sockのパスが重複しそうなので変更する。

(修正前) socket = /tmp/mysql.sock
(修正後) socket = /home/hoge/mysql/mysql.sock

ポート番号もconfigure時に設定した値になっているか確認する。



■mysql_install_db

データベースの初期化を行なう。

# cd /home/hoge/mysql-5.0.51a/scripts
# ./mysql_install_db --user=hoge --datadir=/home/hoge/mysql/data



■MySQL起動、動作チェック

デフォルトのmy.cnfを読み込まないようmysqld_safeのオプションで指定する。

# ./mysqld_safe --defaults-file=/home/hoge/mysql/my.cnf \
--pid-file=/home/hoge/mysql/mysqld.pid \
--log-error=/home/hoge/mysql/log/mysqld.log &



ポート番号とmysql.sockを指定してログインする。

念のため、/home/hoge/mysql/bin以下のmysqlを使用した方がよいかもね。

# /home/hoge/mysql/bin/mysql -u root -P1235 --socket=/home/hoge/mysql/mysql.sock

MySQLではPostgreSQLでいうsetvalに似たものがない?

一応調べたんだが、MySQLにはsetvalのようなPostgreSQLの関数が無いようだ。



PostgreSQLのsetvalだが、auto_increment部分を操作するクエリだ。

なぜこんなことをMySQLで行いたいかというと、

IDがリレーションにつながった2つのテーブルをコピーしたいから。

それに加えてPostgreSQLからMySQLへの移行作業も行なう。

なおかつテーブル構造も変更している。



そんで今回とった方法がプログラムによってINSERTコピー。

まぁ、急ぎでもないし、これが一番安全かなと。



コピーが無事完了した。

auto_incrementが1のままだからコピーした分だけ

更新しなくてはならないと思ったわけ。・・・検索しても無い。



なんで?で「show table status」してみたわけ。

そしたら「auto_increment」って部分が登録値の最大になってるわけ。



で、試しにINSERTしてみたら、ちゃんと登録できたw



細かいことは調べたくないけど、まぁsetvalは必要ないみたい。

[MySQL]MERGEテーブル検証(テクニック編)

MERGEテーブルについて調査していて、新しい事実が発覚。
以下のSQLに注目。

CREATE DATABASE merge_test;
USE merge_test;

CREATE TABLE item2006 (
  id integer PRIMARY KEY AUTO_INCREMENT,
  title character varying(64) NOT NULL
);
CREATE UNIQUE INDEX u_idx_item_title ON item2006 (title);

INSERT INTO item2006 (title) VALUES('title1');
INSERT INTO item2006 (title) VALUES('title2');
INSERT INTO item2006 (title) VALUES('title3');
INSERT INTO item2006 (title) VALUES('title4');

CREATE TABLE item2007 (
  id integer PRIMARY KEY AUTO_INCREMENT,
  title character varying(64) NOT NULL
);
CREATE UNIQUE INDEX u_idx_item_title ON item2007 (title);

CREATE TABLE item (
  id integer PRIMARY KEY AUTO_INCREMENT,
  title character varying(64) NOT NULL
) TYPE=MERGE UNION=(item2006,item2007) INSERT_METHOD=LAST;
CREATE UNIQUE INDEX u_idx_item_title ON item (title);

特にMERGEテーブル作成時のUNION、INSERT_METHODに注目。

UNION=(item2006,item2007) INSERT_METHOD=LAST

SELECT時、UNIONで囲われた先頭のテーブルから検索を開始し、
結果が得られた時にSELECTが終了する。

ということは、最新のデータを取得することが多いテーブルでは、

UNION=(item2007,item2006) INSERT_METHOD=LAST

の方が効率が良い。

しかし、INSERT_METHOD=LASTが原因で、このままだとitem2006テーブルに
データが登録されてしまう。そこで、

UNION=(item2007,item2006) INSERT_METHOD=FIRST

と定義することで、UNIONの最初に定義したテーブルにINSERTを行う。

で、最終的なMERGEテーブルは、

CREATE TABLE item (
  id integer PRIMARY KEY AUTO_INCREMENT,
  title character varying(64) NOT NULL
) TYPE=MERGE UNION=(item2007,item2006) INSERT_METHOD=FIRST;
CREATE UNIQUE INDEX u_idx_item_title ON item (title);

となる。

実際にINSERT,SELECTを行なうと理解できる。

mysql> INSERT INTO item (title) VALUES('title5');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO item (title) VALUES('title6');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM item;
+----+--------+
| id | title  |
+----+--------+
|  5 | title5 |
|  6 | title6 |
|  1 | title1 |
|  2 | title2 |
|  3 | title3 |
|  4 | title4 |
+----+--------+
6 rows in set (0.00 sec)

mysql> SELECT * FROM item2007;
+----+--------+
| id | title  |
+----+--------+
|  5 | title5 |
|  6 | title6 |
+----+--------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM item2006;
+----+--------+
| id | title  |
+----+--------+
|  1 | title1 |
|  2 | title2 |
|  3 | title3 |
|  4 | title4 |
+----+--------+
4 rows in set (0.00 sec)

item2007テーブルにデータが登録されているし、
idが5,6を先にSELECTしてるっぽい。
完璧。