1、 "NDB" 是什么意思?
它的意思是: "网络数据库
".NDB(也叫NDB Cluster
或者NDBCLUSTER
),使用它才能让MySQL支持集群.
在复制系统中,一个MySQL主服务器会更新一个或多个从服务器.事务是顺序地提交的,因此一个慢事务就可能导致从服务器比主服务器落后一段时间.这也意味着,如果主服务器出错失败了,那么从服务器可能会缺少记录最后的那一小部分事务日志.如果使用的是事务安全存储引擎的话,例如InnoDB
,那么事务日志则会完全记录到从服务器上去或者完全不记录,但是复制不能保证主和从服务器上的数据总是保持一致性.在MySQL集群中,所有的数据总是保持同步,在任何数据节点上提交的事务都同步到所有其他的数据节点上了.如果有一个数据节点失败了,其他正常的数据节点照样能保持数据的一致性.
3、是否需要特定的网络结构才能使用集群呢?集群中的计算机是如何通信的?
MySQL集群适合用于高速带宽的环境中,采用TCP/IP方式连接.它的性能跟主机间的连接速率有直接关系.集群中的最小速率要求是常规的100Mb以太网或者等同的网络.我们建议可能的话就采用G级网络. 参见Section 15.10, “Using High-Speed Interconnects with MySQL Cluster”,
集群最少要求有3台计算机.不过我们建议
最好是4台;有2台分别运行管理节点和SQL节点,另外2台作为数据节点.采取2台数据节点的目的是提高数据的冗余度,管理节点放在一个独立的主机上是为了能够保证在万一有一台数据节点失败的情况下提供仲裁服务.
MySQL集群既又物理也有逻辑组织,每台计算机都作为物理基础元素.集群中的逻辑基础元素称为 节点
,集群中的每个逻辑和功能基础元素也称为 集群主机
.共有3中节点类型,每个在集群中都有对应的不同角色,分别如下:
-
管理节点(MGM node): 提供整个集群的管理服务,包括启动,关闭,备份,数据配置等.管理节点是由
ndb_mgmd
应用程序来提供的;管理节点的客户端用ndb_mgm
. -
数据节点: 存储和复制数据.数据节点的功能都是由一个NDB数据节点进程
ndbd
来处理的. -
SQL 节点: 这只是一个简单的MySQL服务器实例(mysqld),它启动的时候使用
--ndb-cluster
选项,使之支持NDB Cluster
存储引擎.
MySQL集群支持大部分的类Unix操作系统,包括Linux, Mac OS X, Solaris, BSD, HP-UX, AIX, IRIX,除此之外,还有Novell Netware.现在MySQL集群还不支持Windows.不过,我们正在努力,使得让集群都能支持其他平台,例如Windows,我们的目标是让MySQL支持的所有平台上也都能支持集群.
详情请看 http://www.mysql.com/support/supportedplatforms.html.
MySQL集群可以运行在任何启用NDB的平台上.显然,CPU越快,内存越大,对集群性能提升越明显,64位的CPU也可能比32位的处理器更快.每个作为数据节点的机器都必须有足够的内存来保存共享数据库(详情请看 How much RAM do I Need?).节点之间通过TCP/IP网络和硬件通信.想要使用SCI的话,就必须有特定的网络设备了.
在MySQl 5.0中,集群只能基于内存.意思是所有表的数据(包括索引)都保存在内存中.如果你的数据有1GB那么大,你想要复制一份到集群中的话,那么就必须要2GB的内存才行(每份复制占用1GB),这是运行集群的计算机上相对其他操作系统额外要求的内存.
如果一个数据节点上的内存使用超出了可用的范围,则操作系统会使用交换内存来达到上限值 DataMemory
.不过这会导致性能严重下降,并且可能导致相应时间变慢.正是由于这个原因,我们不推荐在生产环境中使用磁盘交换空间.在任何情况下,只要达到 DataMemory
上限了,那么所有的操作请求(比如插入)都会失败.
我们已经在MySQL 5.1中实现了基于磁盘存储的集群,但是并没有打算在5.0中也加入这个功能.
可以使用以下公式来估算一个集群数据节点大概需要多少内存:
<span style="color:#0000ff">(SizeofDatabase × NumberOfReplicas × 1.1 ) / NumberOfDataNodes
</span>
想要计算确切的需要多少内存,就需要找到数据库中每个表的每条记录占用多少空间,然后乘以每个表的记录数,每条记录占用多少空间请参考( href="/docs/MySQL_51_zh/mysql_51.html" target="_blank" title="11.5. Data Type Storage Requirements">Section 11.5, “Data Type Storage Requirements”).
还必须关注以下几点关于每个字段的索引:
-
NDBCluster
表中的每个主键或者哈希索引记录都需要 21-25 个字节.这些索引使用IndexMemory
. -
每个排序索引记录需要 10 字节,它们使用
DataMemory
. -
创建主键或唯一索引的同时也创建排序索引,除非创建索引时指定
USING HASH
了.换句话说就是:-
集群数据表中的每个主键或者唯一索引记录通常占用 31-35 字节.
-
尽管如此,如果创建主键或者唯一索引时指定
USING HASH
,那么每个记录只需要 21-25 字节.
-
注意,MySQL集群中创建主键或唯一索引是如果指定 USING HASH
的话,那么通常会导致那个表运行起来较快 -
有些时候,更新数据的话通常能比不用 USING HASH
的表快
20-30%.这是由于它只需要较少的内存(因为没有创建排序索引),用到比较少的CPU资源(因为只需读取/更新较少的索引).不过,这也意味着如果查询不是使用范围(range)扫描的话,就会导致查询比较慢.
计算集群需要多少内存是,你可以从 MySQLForge 上找到一个工具,叫做 ndb_size.pl
.这个Perl脚本连接到当前的MySQL服务器(不是MySQL集群)上,然后报告如果当前的数据库如果转换成 NDBCluster
需要多少空间.详情请看 Section 15.9.13, "ndb_size.pl".
需要特别注意: 每个MySQL集群表都需要主键.如果没有定义主键,则 NDB
存储引擎会自动创建一个,并且不是指定 USING HASH
的方式.
在指定的任何时候都无法十分准确地计算出MySQL集群索引所需要多少内存;不过,当使用了超过80%的 DataMemory
或 IndexMemory
的时候,就会写一条信息到日志中,然后是85%,90%,依此类推.
9、配置集群的时候,正在加载的进程非正常中断了,并且报错信息如下,为什么会这样?
ERROR 1114: The table 'my_cluster_table' is full
I'm trying to populate a Cluster database. The loading process terminates prematurely and I get an error message like this one:
<strong>ERROR 1114: The table 'my_cluster_table' is full
</strong>
Why is this happening?
原因很有可能是因为你设置的内存不足以装下所有的数据表及其索引,包括 NDB
存储引擎中所需的主键以及如果没有定义主键时自动创建的索引.
所有的数据节点的内存大小都要一样,由于集群中任何数据节点都不能使用比其他数据节点最小内存还多的内存.换句话说,如果集群中有4台计算机,如果有3台计算机的内存都是3GB,而另外一台只有1GB,那么每个数据节点最多只能拿出1GB内存用于集群.
10、MySQL 集群使用TCP/IP协议,这是否意味着我可以跨越Internet网,把某些节点放在远程,来使用集群呢?
在这种条件下,那么MySQL集群不大可能有稳定的表现,因为MySQL集群是设计和实现在良好的高速连接速率环境下,如100Mbps LAN或者G级以太网 - 后者尤佳.我们没有在更慢的条件下做测试因此也不能保证它的性能.
同样地,要清楚地意识到MySQL集群的2个节点之间的通信是不安全的;它们没有经过任何保护机制加密或者防护.安全的集群是放在防火墙之内的私网中,在外界中无法直接访问数据和管理节点(SQL节点也要和其他MySQL服务器一样注意安全防护).
11、我是否需要学习新的编程语言或者查询语言才能使用MySQL集群呢?
不需要.尽管有一些特定的命令使用来管理和设置集群的,但其他标准的(My)SQL查询和命令如下:
-
创建/修改/删除表
-
插入/更新/删除数据
-
创建/修改主键/唯一索引
设置MySQL集群所需的特定配置参数和文件请看 Section 15.4.4, “Configuration File”.
MySQL集群中一些简单的管理客户端命令,如用来启动或关闭集群节点等.详情请看 Section 15.7.2, “Commands in the Management Client”.
12、使用MySQL集群的时候,我怎么知道某些警告/错误信息是什么意思呢?
有2中方法,如下:
-
在
mysql
客户端中,执行命令SHOW ERRORS
或SHOW WARNINGS
就能直接查看报错或警告信息.在 MySQL Query Browser 中也能显示错误及警告信息. -
在系统shell提示符中,执行命令
perror --ndb error_code.
13、MySQL集群是事务安全的吗?它支持什么样的事务隔离级别?
是的.NDB
存储引擎的表都支持事务.在MySQL 5.0中,集群只支持 READ COMMITTED
隔离级别.
14、What storage engines are supported by MySQL Cluster?
MySQL集群只支持 NDB
存储引擎.也就是说,想要让一个表在集群节点中共享,就必须指定 ENGINE=NDB
(或 ENGINE=NDBCLUSTER
也一样).
MySQL集群中也可以使用 MyISAM
或 InnoDB
存储引擎来创建数据表,但是那些非 NDB
的表不会存储在集群节点间共享;它们独立于创建的MySQL服务器或者实例中.
15、哪个MySQL版本才支持集群?是否需要从源代码中编译?
在MySQL 5.0的全部MySQL-max二进制发布系列中都支持集群,下文列出了想要注意的例外情况.你可以使用语句 SHOW VARIABLES LIKE 'have_%'
或 SHOW ENGINES
来确定是否支持 NDB
存储引擎,详情请看 Section 5.3, “The mysqld-max Extended MySQL Server”.
Linux用户需要注意,标准的MySQL服务器RPM包中 没有 包含 NDB
.从MySQL 5.0.4开始,RPM包开始把 NDB 存储引擎和附带的管理工具分开;详情请查看MySQL 5.0下载页面中关于NDB RPM下载的部分 (在 5.0.4 以前,必须下载 -max
的 .tar.gz
压缩包.以后还可能会这样,但不是必须的,可能使用你更习惯的Linux RPM包管理器).也可以从 -max
源码中编译支持 NDB
,不过没必要这么麻烦.想要下载最新版本,请看 http://dev.mysql.com/downloads/mysql/5.0.html.
16、在发生灾难性事故时 - 比如说,整个城市都断电了,就连UPS也断了,那么我是否会丢失所有的数据呢?
所有提交的事务都已经记录到日志中了.因此,在一个突发的灾难中可能会丢失一些数据,但也是很有限.通过减少事务中的操作数量,也能减少丢失的数据.(在任何事务中总是执行大量的操作很不明智)
17、集群中是否能用 FULLTEXT
索引?
在MySQL 5.0中,NDB
存储引擎不支持 FULLTEXT
索引,其他除了 MyISAM
存储引擎外也不支持.我们正努力使将来的发布版本中也能支持.
18、我能否在一个计算机上运行多个节点?
可以,但不建议.首先,使用集群就是为了提高数据冗余度,因此每个节点最好是在不同的计算机上.如果把多个节点放在同一个计算机上,那么如果它宕机了,就会丢失这些节点了.MySQL集群可以运行在低成本(无成本)的操作系统,基于商用机之上;为了保护重要不能丢失的数据,那么扩展一两个额外的机器是值得的.这个任务在由一台200MHz奔腾CPU和足够内存的操作系统上的 ndb_mgmd
和 ndb_mgm
进程来完成,并且开销很少.
如果是出于学习或者测试目的把MySQL集群中的多个数据节点放在一个机器上是可以接受的;不过,这 不能 用于生产环境.
19、能否不用重启就能在集群中加入一个节点?
现在还不行.往集群中添加一个新的MGM或者SQL节点需要重启.添加新的数据节点的话就更复杂了,需要以下几个步骤:
-
备份集群中的所有数据.
-
完全关闭集群及集群节点的相关进程.
-
附加选项
--initial
启动集群. -
把备份数据还原到集群中.
在未来的MySQL 集群发布系列版本中,我们希望能实现 "热"(在线) 方式重设集群的功能,以减少增加新节点带来的麻烦.不过,在MySQL 5.0中不会实现
20、使用MySQL集群的时候是否有什么限制?
MySQL 5.0中的 NDB
表存在以下局限性:
-
不支持临时表;执行
CREATE TEMPORARY TABLE
语句时如果指定ENGINE=NDB
或ENGINE=NDBCLUSTER
参数就会报错. -
不支持
FULLTEXT
索引以及前缀索引.只能对整个字段进行索引. -
不支持空间数据类型.详情请看 Chapter 16, Spatial Extensions.
-
只支持完全的回滚事务.不支持部分回滚和回滚到保存点也不支持.
-
一个表最大的属性数为128,并且每个属性名不能超过31个字符.对每个表来说,数据库和表明的联合长度最大是122个字符.
-
表中一条记录最大值为8KB,不包含
BLOB
的值.表的大小取决于各种制约因素,尤其是每个数据节点最大的可用内存. -
NDB
存储引擎不支持外键.跟MyISAM
一样,它们都不支持.
想要知道更多的限制,请查看 Section 15.11, “Known Limitations of MySQL Cluster”.
21、如何把已存在的一个MySQL数据库导入到集群中?
你可以把各种版本的MySQL数据导入到集群中去.除了本FAQ中其他地方提到的限制条件 title="15.11. Known Limitations of MySQL Cluster">Section 15.11, “Known Limitations of MySQL
Cluster”,唯一的要求就是要导入的表必须是 NDB
存储引擎,也就是用 ENGINE=NDB
或 ENGINE=NDBCLUSTER
方式创建的表.
22、集群中的节点和其他节点是如何通信的?
集群节点间可以通过一下方式来通信:TCP/IP, SHM(共享内存), SCI(可伸缩一致性接口).如果可能,安装在同一台集群主机上的多个节点间默认用SHM来通信;不过,在MySQL 5.0中这只是出于试验目的.SCI是高速的(每秒1GB或更高),高可靠协议用于搭建可伸缩的多处理器系统;它需要有特殊的硬件以及驱动.详情请看 Section 15.10, “Using High-Speed Interconnects with MySQL Cluster”.
23、什么是"arbitrator(仲裁节点)"?
如果一个和多个节点宕机(或者其他原因失败了),那么就需要让其他节点能 看见
这种情况.实际上,在分区网络中,有可能会出现2组节点互相隔绝,这也叫做 "脑裂
".出现这种情况当然不好了,因为每组节点都想认为自己是集群中的一分子.
当集群的某个节点宕了,则有2种可能性.如果超过50%的节点能互通,有时也叫 "多数原则
",则这组节点被认为是集群.如果这组节点的数量正好是一半,那么仲裁服务器该发挥作用了:这种情况下,仲裁服务器所在的那组节点被当做是集群,而另外那组则被关闭.
前面的信息有些简单了.以下是一个比较复杂的节点分组案例解析:
如果至少一个节点分组中的所有节点都是可用的,那么分区网络就不在此范围,因为这样的话集群中的任意部分都不能组成新的集群.只有在没有任何一个节点分组的节点中全部都可用时才有问题,这个时候就有可能出现分区网络("脑裂
")了.这时就需要有仲裁了.所有的集群节点都认可一个仲裁服务器,那就是管理服务器;不过,可以把集群中的任意服务器配置称为仲裁服务器.仲裁服务器接受第一组集群节点,连接它们,并且关闭剩下的其他集群组.仲裁服务器的选择是由MySQL服务器和管理节点服务器的 ArbitrationRank
参数控制的(详情请看 Section 15.4.4.4, “Defining the Management Server”) 同时也要注意到,选定作为仲裁角色的服务器无需承担高负荷,因此它不要求速度很快和内存很大.
24、MySQL集群都支持什么数据类型?
MySQL集群支持所有常用的数据类型,除了跟MySQL相关的空间扩展类型(详情请看 Chapter 16, Spatial Extensions).另外,NDB
表的索引也有些不同. 注意: MySQL集群表(即 NDB
或 NDBCLUSTER
类型表)只支持固定长度记录.这也意味着(举例)如果有一条记录包含有 VARCHAR(255)
字段,那么它就会需要用到255个字符的空间(和数据表使用的字符集和校验所要求的空间一样大),而不管实际存储的字符数.这个问题在未来的发行版中会得到解决.
详情请看 Section 15.11, “Known Limitations of MySQL Cluster”.
需要按以下顺序分别启动集群中的各个节点:
-
用
ndb_mgmd
命令启动管理节点. -
用
ndbd
分别启动每个数据节点. -
用
mysqld_safe --user=mysql &
命令启动每个SQL节点.
上面的命令都需要在系统的shell下运行(在服务器上执行或通过终端都可以).可以在管理节点上的 ndb_mgm
客户端工具中执行 SHOW
或 ALL STATUS
命令来确认集群是否在运行状态.
在 MGM 客户端中运行 SHUTDOWN
命令即可关闭运行中的集群.另外,也可以在管理节点主机中执行一下命令来关闭:
shell> ndb_mgm -e "SHUTDOWN"
注意,括号中的内容可以是别的,并且 SHUTDOWN
可以不区分大小写.
这些命令的任何一个都能平和地关闭 ndb_mgm
, ndb_mgmd
(笔误?), ndbd
中的任何进程.运行MySQL集群的SQL节点服务器则通过 mysqladmin shutdown
来关闭.
更多详情请看 Section 15.7.2, “Commands in the Management Client” 和 Section 15.3.6, “Safe Shutdown and Restart”.
26、当集群关闭之后,集群中的数据会怎么办?
本来保存在内存中的集群数据都会写到磁盘中,下次集群启动的时候就会重新载入到内存中.
27、 集群中使用多个管理节点是否更好?
这有助于自动防故障.任何时候只能有一个MGM节点来控制集群,但是也可以配置一个主MGM控制器,一个或者多个附加控制器作为主控制器发生故障时的备用.
配置集群管理节点详情请看 Section 15.4.4, “Configuration File”,
28、能否在MySQL集群中混合使用多种不同的硬件以及操作系统?
是的.只要所有的机器和操作系统都有 "endianness
"
即可(所有的大尾或小尾,这个词比较难理解,请自己用搜索引擎搜一下看看).不同节点间还有可能使用不同版本的MySQL集群发行版.不过,我们推荐这只是作为滚动升级步骤的一部分,详情请看 Section 15.5.1, “Performing a Rolling Restart of the Cluster”.
29、 能否在一个主机上运行2个数据节点?或者2个SQL节点?
是的,可以这么做.如果有多个数据节点,我们建议(不是必须)不同的数据目录都有各自的节点.如果想要在同一个机器上运行多个数据节点,那么每个mysqld
实例就必须使用不同的 TCP/IP 端口了.不过,在每个机器上运行多个集群节点不支持生产环境使用.
30、MySQL集群中能否是用主机名?
是的,集群主机可以使用DNS或者DHCP.不过,如果你的应用程序要求 "5个9(99.999%)" 可靠性的话,我们推荐使用固定ip地址.可以在故障自动防护系统中引入 DNS 或 DHCP 服务,最好比较少用它们.
31、 在一个多个MySQL服务器的集群中如何处理MySQL用户?
访问MySQL集群的不同MySQL服务器间不会自动同步帐号和权限信息.因此,必须在每个SQL节点间都复制一份.