MySQL Cluster のデータの作業はクラスタ無しの MySQL で行うのとそれほど違いはありません。考慮すべき点が 2 点あります。
クラスタでコピーするテーブルはには、
NDB Cluster
ストレージ
エンジンを使用する必要があります。これを指定するには
ENGINE=NDB
あるいは
ENGINE=NDBCLUSTER
テーブル
オプションを使用します。テーブルを作成する際にこのオプションを追加できます。
CREATE TABLE tbl_name
( ... ) ENGINE=NDBCLUSTER;
代わりに、異なるストレージ
エンジンを使用している既存のテーブルに対して、ALTER
TABLE
を使用してテーブルを変更して
NDB Cluster
を使用できます。
ALTER TABLE tbl_name
ENGINE=NDBCLUSTER;
各 NDB
テーブルにはプライマリ
キーが必要です。ユーザーがテーブルを作成したときにプライマリ
キーを定義しなかった場合、NDB
Cluster
ストレージ
エンジンが自動的に非表示のテーブルを生成します。(注:この非表示のテーブルは他のテーブル
インデックスと同じスペースを使用します。メモリ不足のためにこれらの自動的に作成されたインデックスを使用する際に問題に遭遇することは普通ではありません。
mysqldump
の出力を使用して既存のデータベースからテーブルをインポートする場合、テキスト
エディタの SQL
スクリプトを開きテーブルの作成ステートメントに
ENGINE
オプションを追加します。あるいは既存の
ENGINE
(あるいは TYPE
)
オプションを置き換えます。MySQL Cluster
をサポートしていない別の MySQL サーバーに
world
サンプルのデータベースを持っていて、City
テーブルをエクスポートするとします。
shell> mysqldump --add-drop-table world City > city_table.sql
その結果の city_table.sql
ファイルはテーブルの作成ステートメント(およびテーブル
データをインポートするために必要な
INSERT
ステートメント)
を含みます。
DROP TABLE IF EXISTS `City`;
CREATE TABLE `City` (
`ID` int(11) NOT NULL auto_increment,
`Name` char(35) NOT NULL default '',
`CountryCode` char(3) NOT NULL default '',
`District` char(20) NOT NULL default '',
`Population` int(11) NOT NULL default '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `City` VALUES (1,'Kabul','AFG','Kabol',1780000);
INSERT INTO `City` VALUES (2,'Qandahar','AFG','Qandahar',237500);
INSERT INTO `City` VALUES (3,'Herat','AFG','Herat',186800);
(remaining INSERT statements omitted)
MySQL が NDB ストレージ
エンジンをこのテーブルに使用していることを確認する必要があります。この確認の方法は
2 つあります。その 1 つは Cluster
データベースにインポートする前
before
にテーブルの定義を変更することです。例として
City
テーブルを使用し、以下のように定義の
ENGINE
オプションを変更します。
DROP TABLE IF EXISTS `City`;
CREATE TABLE `City` (
`ID` int(11) NOT NULL auto_increment,
`Name` char(35) NOT NULL default '',
`CountryCode` char(3) NOT NULL default '',
`District` char(20) NOT NULL default '',
`Population` int(11) NOT NULL default '0',
PRIMARY KEY (`ID`)
) ENGINE=NDBCLUSTER DEFAULT CHARSET=latin1;
INSERT INTO `City` VALUES (1,'Kabul','AFG','Kabol',1780000);
INSERT INTO `City` VALUES (2,'Qandahar','AFG','Qandahar',237500);
INSERT INTO `City` VALUES (3,'Herat','AFG','Herat',186800);
(remaining INSERT statements omitted)
クラスタ
テーブルの一部になる各テーブルの定義にこれを行う必要があります。これを行うための最も簡単な方法は定義を含むファイルに検索および置き換えを実行し、TYPE=
あるいは
engine_name
ENGINE=
のすべてのインスタンスを
engine_name
ENGINE=NDBCLUSTER
で置き換えることです。ファイルの変更を希望しない場合には、変更していないファイルを使用してテーブルを作成し、次に
ALTER TABLE
を使用してストレージ
エンジンを変更します。この項の後で詳細を説明します。
クラスタの SQL ノードで world
と呼ばれるデータベースを既に作成したとして、mysql
コマンド ライン クライアントを使用して
city_table.sql
を読み込み、そして次にいつもの方法で相当するテーブルを作成して移植します。
shell> mysql world < city_table.sql
前述のコマンドを SQL
ノードを実行している(この場合、IP
アドレスが 192.168.0.20
のマシンで)
ホストで忘れないで実行することが非常に重要です。
SQL ノードで world
全体のデータベースのコピーを作成するには、非クラスタ
サーバーの mysqldump
を使用してデータベースをファイル名
world.sql
にエクスポートします。例えば、/tmp
のティレクトりで行います。次にテーブルの定義を今説明したように変更し、以下のようにクラスタの
SQL ノードにそのファイルをインポートします。
shell> mysql world < /tmp/world.sql
ファイルを別のロケーションに保存した場合、前述の説明をしかるべく調整します。
MySQL の NDB Cluster
が 5.1
データベースのオートディスカバリをサポートしていないことを忘れずに覚えておくことがが重要です。(項14.13. 「MySQL Cluster の既知の制限」
参照。)このことは、データ
ノードでworld
データベースおよびそのテーブルを作成したら、CREATE
SCHEMA world
ステートメントを発行する必要があることを意味しています。
SELECT
クエリを SQL
ノードで実行することは MySQL
サーバーの他のインスタンスで実行するのと違いはありません。。コマンドラインからクエリを実行するには、最初に
MySQL Monitor にいつもの方法 (root
パスワードを Enter
password:
プロンプトで指定します)
でログインします。
shell> mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.1.15-beta
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
弊社では単純に MySQL サーバーの
root
アカウントを使用していますが、お客様は My SQL
サーバーのインストールの際は堅固な
root
パスワードの設定を含む標準的なセキュリティ対策を講じているものと想定しています。詳細は
項2.10.3. 「最初の MySQL アカウントの確保」
を参照してください。
クラスタ ノードがお互いにアクセスするときに
MySQL
権限システムを使用しないことを考慮する必要があります。MySQL
ユーザーアカウント(root
アカウントを含む)の設定あるいは変更によって、ノード間のインターラクションに影響を及ぼさず、SQL
ノードにアクセスするアプリケーションにのみ影響を及ぼします。
SQL
スクリプトのインポートに先立ちテーブル定義の
ENGINE
節を変更しなかった場合、この時点で以下のステートメントを実行する必要があります。
mysql>USE world;
mysql>ALTER TABLE City ENGINE=NDBCLUSTER;
mysql>ALTER TABLE Country ENGINE=NDBCLUSTER;
mysql>ALTER TABLE CountryLanguage ENGINE=NDBCLUSTER;
データベースを選択してそのデータベースのテーブルに対する SELECT クエリの実行も既存の MySQL Monitor と同様に通常の方法で実現できます。
mysql>USE world;
mysql>SELECT Name, Population FROM City ORDER BY Population DESC LIMIT 5;
+-----------+------------+ | Name | Population | +-----------+------------+ | Bombay | 10500000 | | Seoul | 9981619 | | São Paulo | 9968485 | | Shanghai | 9696300 | | Jakarta | 9604900 | +-----------+------------+ 5 rows in set (0.34 sec) mysql>\q
Bye shell>
MySQL を使用しているアプリケーションは標準の
API で NDB
テーブルにアクセスします。Iお客様のアプリケーションが、MGM
あるいはデータノードではなく SQL
ノードにアクセスすることを憶えておくことが重要です。この簡単な例ではネットワーク上の
Web サーバーで動作している PHP 5 の
mysqli
拡張を使用した場合のようにどのように
SELECT
ステートメントを実行するかを示しています。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>SIMPLE mysqli SELECT</title>
</head>
<body>
<?php
# connect to SQL node:
$link = new mysqli('192.168.0.20', 'root', 'root_password
', 'world');
# parameters for mysqli constructor are:
# host, user, password, database
if( mysqli_connect_errno() )
die("Connect failed: " . mysqli_connect_error());
$query = "SELECT Name, Population
FROM City
ORDER BY Population DESC
LIMIT 5";
# if no errors...
if( $result = $link->query($query) )
{
?>
<table border="1" width="40%" cellpadding="4" cellspacing ="1">
<tbody>
<tr>
<th width="10%">City</th>
<th>Population</th>
</tr>
<?
# then display the results...
while($row = $result->fetch_object())
printf(<tr>\n <td align=\"center\">%s</td><td>%d</td>\n</tr>\n",
$row->Name, $row->Population);
?>
</tbody
</table>
<?
# ...and verify the number of rows that were retrieved
printf("<p>Affected rows: %d</p>\n", $link->affected_rows);
}
else
# otherwise, tell us what went wrong
echo mysqli_error();
# free the result set and the mysqli connection object
$result->close();
$link->close();
?>
</body>
</html>
Web サーバー上で実行されているプロセスが SQL ノードの IP アドレスにアクセスできるものとします。
同様に、MySQL C API、Perl-DBI、Python-mysql、あるいは MySQL AB の自身のコネクタを使用してデータ定義および操作のタスクを MySQL で行うのと同様に実行できます。