具有表和数据的NDB群集示例
注意本节中的信息适用于在Unix和Windows平台上运行的NDB Cluster。
在NDB Cluster中使用数据库表和数据与在标准MySQL中进行操作没有太大区别。有两点要牢记:
对于要在群集中复制的表,它必须使用
NDBCLUSTER
存储引擎。要指定此选项,请在创建表时使用ENGINE=NDBCLUSTER
或ENGINE=NDB
选项:CREATE TABLE tbl_name (col_name column_definitions)ENGINE =NDBCLUSTER ;或者,对于使用不同存储引擎的现有表,可使用
ALTER TABLE
将表更改为使用NDBCLUSTER
:ALTER TABLE tbl_nameENGINE =NDBCLUSTER ;- 每个
NDBCLUSTER
表都有一个主键。如果在创建表时用户未定义主键,则NDBCLUSTER
存储引擎会自动生成一个隐藏的主键。这样的键就像其他任何表索引一样占用空间。(由于内存不足,无法容纳这些自动创建的索引,遇到问题的情况并不罕见。)
如果要使用mysqldump的输出从现有数据库导入表,则可以在文本编辑器中打开SQL脚本,并将该ENGINE
选项添加到任何表创建语句中,或替换任何现有ENGINE
选项。假设您world
在另一台不支持NDB群集的MySQL服务器上具有示例数据库,并且想要导出该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 NULLauto_increment , `Name ` char(35) NOT NULLdefault '', `CountryCode` char(3) NOT NULLdefault '', `District` char(20) NOT NULLdefault '', `Population` int(11) NOT NULLdefault '0',PRIMARY KEY (`ID`) )ENGINE =MyISAMDEFAULT 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);(remainingINSERT statements omitted)
您需要确保MySQL使用NDBCLUSTER
该表的存储引擎。有两种方法可以实现。其中之一是在将表定义导入群集数据库之前对其进行修改。以该City
表为例,修改ENGINE
定义的选项,如下所示:
DROP TABLE IF EXISTS `City`;CREATE TABLE `City` ( `ID` int(11) NOT NULLauto_increment , `Name ` char(35) NOT NULLdefault '', `CountryCode` char(3) NOT NULLdefault '', `District` char(20) NOT NULLdefault '', `Population` int(11) NOT NULLdefault '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); (remainingINSERT statements omitted)
必须对要成为集群数据库一部分的每个表进行定义。做到这一点最简单的方法是做一个搜索和替换包含定义和替换的所有实例的文件或用。如果您不想修改文件,则可以使用未修改的文件来创建表,然后使用来更改它们的存储引擎。详细信息将在本节后面给出。TYPE=engine_name
ENGINE=engine_name
ENGINE=NDBCLUSTER
ALTER TABLE
假设您已经创建了一个world
在集群的SQL节点上命名的数据库,则可以使用mysql命令行客户端读取city_table.sql
,并以通常的方式创建并填充相应的表:
shell>mysql world < city_table.sql
请记住,必须在运行SQL节点的主机上(在这种情况下,在IP地址为的机器上198.51.100.20
)执行前面的命令,这一点非常重要。
要world
在SQL节点上创建整个数据库的副本,请在非集群服务器上使用mysqldump将数据库导出到名为world.sql
(例如,在/tmp
目录中)的文件中。然后按照上述说明修改表定义,并将文件导入群集的SQL节点,如下所示:
shell>mysql world < /tmp/world.sql
如果将文件保存到其他位置,请相应地调整上述说明。
SELECT
在SQL节点上运行查询与在MySQL服务器的任何其他实例上运行查询没有什么不同。要从命令行运行查询,您首先需要以通常的方式登录到MySQL Monitor(root
在Enter password:
提示符下指定密码):
shell> mysql -u root -p Enterpassword : Welcometo the MySQL monitor. Commandsend with ; or \g. Your MySQLconnection id is 1to server version: 8.0.20-ndb -8.0.20Type 'help;' or '\h'for help .Type '\c'to clear the buffer. mysql>
我们仅使用MySQL服务器的root
帐户,并假定您已遵循安装MySQL服务器的标准安全预防措施,包括设置强root
密码。有关更多信息,请参见“保护初始MySQL帐户”。
值得考虑的是,NDB群集节点在彼此访问时不使用MySQL特权系统。设置或更改MySQL用户帐户(包括root
帐户)只会影响访问SQL节点的应用程序,而不会影响节点之间的交互。有关更多信息,请参见“ NDB群集和MySQL特权”。
如果ENGINE
在导入SQL脚本之前未修改表定义中的子句,则此时应运行以下语句:
mysql>USE world; mysql>ALTER TABLE CityENGINE =NDBCLUSTER ; mysql>ALTER TABLE CountryENGINE =NDBCLUSTER ; mysql>ALTER TABLE CountryLanguageENGINE =NDBCLUSTER ;
选择数据库并对数据库中的表运行SELECT查询也可以通过通常的方式完成,就像退出MySQL Monitor一样:
mysql>USE world; mysql>SELECT Name , PopulationFROM CityORDER BY PopulationDESC 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节点,而不是管理或数据节点。这个简短的示例说明了如何SELECT
使用mysqli
运行在网络上其他位置的Web服务器上的PHP 5.X 扩展名来执行刚刚显示的语句:
<!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, databaseif ( 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 wrongecho 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连接器来执行数据定义和操作的任务,就像通常使用MySQL一样。