このセクションの情報は、Unix プラットフォームと Windows プラットフォームの両方で実行されている NDB Cluster に適用されます。
NDB Cluster でのデータベーステーブルおよびデータの操作は、標準の MySQL での作業とほとんど異なりません。 留意すべき重要なポイントが 2 つあります。
-
クラスタ内でレプリケートされるテーブルでは、
NDBCLUSTER
ストレージエンジンを使用する必要があります。 これを指定するには、テーブルの作成時にENGINE=NDBCLUSTER
またはENGINE=NDB
オプションを使用します。CREATE TABLE tbl_name (col_name column_definitions) ENGINE=NDBCLUSTER;
または、異なるストレージエンジンを使用する既存のテーブルに対して
ALTER TABLE
を使用して、NDBCLUSTER
を使用するようにテーブルを変更します。ALTER TABLE tbl_name ENGINE=NDBCLUSTER;
すべての
NDBCLUSTER
テーブルには主キーがあります。 テーブルの作成時にユーザーが主キーを定義しなかった場合は、NDBCLUSTER
ストレージエンジンが隠し主キーを自動的に生成します。 このようなキーは、ほかのテーブルインデックスと同じサイズの領域を占有します。 (これらの自動的に作成されるインデックスを格納する十分なメモリーがないために問題が発生することは、珍しくありません。)
mysqldump の出力を使用して既存のデータベースからテーブルをインポートする場合は、SQL スクリプトをテキストエディタで開いて、テーブル作成ステートメントに ENGINE
オプションを追加するか、既存の ENGINE
オプションを置き換えることができます。 NDB 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 がこのテーブルに対して NDBCLUSTER
ストレージエンジンを使用するか確認する必要があります。 これを行うには 2 つの方法があります。 1 つは、テーブル定義をクラスタデータベースにインポートする前に変更することです。 例として 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 アドレスが 198.51.100.20
のマシン) で実行する必要があります。
SQL ノード上に world
データベース全体のコピーを作成するには、非クラスタサーバー上の mysqldump を使用して、world.sql
という名前のファイル (/tmp
ディレクトリなど) にデータベースをエクスポートします。 次に、前述のとおりにテーブル定義を変更し、このようにファイルをクラスタの SQL ノードにインポートします。
shell> mysql world < /tmp/world.sql
ファイルを別の場所に保存する場合は、それに合わせて前述の手順を調整してください。
SQL ノードでの SELECT
クエリーの実行は、MySQL サーバーのほかのインスタンスでの実行と違いはありません。 コマンド行からクエリーを実行するには、最初に通常の方法で (Enter password:
プロンプトで root
パスワードを指定して) MySQL Monitor にログインする必要があります。
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: 8.0.23-ndb-8.0.23
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
ここでは、MySQL サーバーの root
アカウントを使用し、MySQL サーバーのインストールに関する標準的なセキュリティー対策 (強力な root
パスワードの設定を含む) に従っていると仮定します。 詳細は、セクション2.10.4「初期 MySQL アカウントの保護」を参照してください。
NDB Cluster ノードは、相互にアクセスするときに MySQL 特権システムを使用しないことを考慮する価値があります。 MySQL ユーザーアカウント (root
アカウントを含む) の設定または変更は、SQL ノードにアクセスするアプリケーションにのみ影響し、ノード間のやり取りには影響しません。 詳細は、セクション23.5.17.2「NDB Cluster および MySQL の権限」を参照してください。
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
テーブルにアクセスできます。 アプリケーションは、管理ノードやデータノードではなく、SQL ノードにアクセスする必要があります。 この簡単な例では、ネットワーク上の別の場所にある Web サーバーで実行されている PHP 5.X の 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('198.51.100.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 Connector を使用して、MySQL で通常実行する同じデータの定義や操作のタスクを実行できます。