MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  テーブルとデータを含む NDB Cluster の例

23.2.5 テーブルとデータを含む NDB Cluster の例

注記

このセクションの情報は、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 で通常実行する同じデータの定義や操作のタスクを実行できます。


関連キーワード:  NDB, テーブル, ndbinfo, ノード, ndb, データ, City, 実行, NDBCLUSTER, 構成