存档

‘Database相关’ 分类的存档

面向 PHP 开发人员的 CouchDB 基础知识[转]

2010年6月23日

CouchDB又一种关系数据库.

如果您是位典型的 PHP 开发人员,就不难通过以往的项目得到这样一个结论:在多数(如果不是全部)情况下,为了进行动态数据处理,您都会让 PHP 与数据库后端进行对话;而在这些实例中,99% 的情况下使用的都是 MySQL。

如今,使用关系型数据库无可厚非。如果所处理的数据结构复杂,并具有多种关系,那么这么做是很合理的。您可以顺利地(或是不太顺利地,取决于 您对 SQL 的熟悉程度)进行对模式、数据关系、表等等的处理。

不过,您所从事的项目有时也会让您不经意间心生疑问:“为什么我要做所有这些工作?” 您所从事的这个项目包含了一些简单的或难以预测的数据 — 在不同的日子获得的数据字段可能不同甚至事务之间的数据字段都不尽相同。若是创建一个模式来预测将会出现什么数据字段,结果很可能会得到内含大量空字段的 表或大量的映射表。

常用缩略语

  • Ajax:异步 JavaScript + XML
  • API:应用程序编程接口
  • GUID:全局惟一标示符
  • HTTP:超文本标记语言
  • JSON:JavaScript 对象注释
  • REST:具象状态传输
  • SQL:结构化查询语言
  • UUID:通用惟一标识符

对于这些项目,您需要采用一种不同的方式 — 不涉及关系型数据库。在这些情况下,您需要的是一个基于文档的、没有模式的、具有扁平地址空间的特别数据库。简言之,您需要 Apache CouchDB。

阅读全文…

Frank Database相关, PHP相关

又拍网架构中的分库设计[转]

2010年6月15日

又拍网是一个照片分享社区,从2005年6月至今积累了260万用户,1.1亿张照片,目前的日访问量为200多万。5年的发展历程里经历过许多起伏,也积累了一些经验,在这篇文章里,我要介绍一些我们在技术上的积累。

又拍网和大多数Web2.0站点一样,构建于大量开源软件之上,包括MySQLPHPnginxPythonmemcachedredisSolrHadoopRabbitMQ等等。又拍网的服务器端开发语言主要是PHPPython,其中PHP用于编写Web逻辑(通过HTTP和用户直接打交道), 而Python则主要用于开发内部服务和后台任务。在客户端则使用了大量的Javascript, 这里要感谢一下MooTools这个JS框架,它使得我们很享受前端开发过程。 另外,我们把图片处理过程从PHP进程里独立出来变成一个服务。这个服务基于nginx,但是是作为nginx的一个模块而开放REST API。

阅读全文…

Frank Database相关, Linux/Unix相关, PHP相关

通用权限系统设计[转]

2010年4月21日

通用权限系统设计是更换权限时候尽量不要涉及到代码修改

/*
03	*控制访问表
04	*  acl值    功能
05	*    1        需要登录
06	*    2         自身修改
07	*    4         需要组的权限集合
08	*    8         需要身份访问集合
09	*    16         身份被禁止访问
10	*    32         可访问的日期
11	*    64         可访问的周日
12	*    128         可访问的<span class="t_tag" onclick="tagshow(event)">时间</span>
13	*    256         输入密码才能访问
14	*    512         超级管理使用
15	*/
class aclACL extends acl {
    public $routername="acl";
    public $aclid='2';            //权限资源ID,如果登录人员没有拥用这个权限那么其(下面)它值都为0也不能访问
    public $roledisable=array(9); //禁用身份
    public $pwd=123456;           //密码访问 ACL-&gt;noPwd();
    public $date=array('begin'=&gt;0,'end'=&gt;0);   //允许日期之间
    public $hours=array('begin'=&gt;0,'end'=&gt;0);  //一日内小时区间
    public $weeks=array('begin'=&gt;0,'end'=&gt;0);  //一周内周一到周七
    public $aclgroup=array("create"=&gt;"4,45,8"); //create需要的组才能创建
    public $aclrole=array("all"=&gt;"6","create"=&gt;"7,95,78"); //create需要的角色才能创建,该组需要ID为6的角色才能访问
    public $acl=array("all"=&gt;0,
                      "index"=&gt;4,    //表列4表示检查组的组合
                      "delete"=&gt;1,   //删除只登录后删除,当然呆以设置为2或4
                      "update"=&gt;1,   //更新提交只能登录后才能更新,在这里做也防止非法、<span class="t_tag" onclick="tagshow(event)">post</span>,edit是不能访问显示编辑内容页
                      "createForm"=&gt;1, //也不能新提交<span class="t_tag" onclick="tagshow(event)">数据库</span>
                      "edit"=&gt;0,       //登录才显示编辑框
                      "show"=&gt;0,       //不用登录也能显示
                      "create"=&gt;1);    //创新表单需要登录操作 可以设置某个组才能创建 
 
}  
 
?&gt;

这个是要认证的文件模块是acl 每当用户访问acl模块时候,如果开启了认证那么会调用这个类 然后这个类会根据$acl 的all或index等值去做认证检查。 把这个文件放在router/acl目录里面就可以了,框架会自动认证如果用户没有相应的正向授权是无法访问相 应的限制的。 比如crud create方法 负向权限为17 那按照前面解释应该是 需要登录和组授权 就是$aclgroup 数组中create的4 45 8三个组, 首先会员没有登录将提示登录,如果会员不在这三个组是无法访问该方法的会提示没有权限。 目前router可以自己根据情况开启用acl控制 方法是在xxxxRouter.class.php文件中 添加 public function isAcl(){} 可以返回权限文件名比如返回curd,那么自动会调用curdACL.class.php类和名 curdRouter类设置验证


&lt;?php
class curdRouter extends controller{ 
 
    //返回 RBAC 控制访问列表验证类默认是跟router同名也就是curd
    //可以不写这个&lt;span href="tag.php?name=%BA%AF%CA%FD" onclick="tagshow(event)" class="t_tag"&gt;函数&lt;/span&gt;,那么不会启用通用权限系统。
    public function isAcl(){}
    public function index()
    {
       $booktype=M("booktype");
       $this-&gt;pager=C("pager");//取得分类
       $this-&gt;pager-&gt;setPager($booktype-&gt;count(),10,'page');//取得&lt;span href="tag.php?name=%CA%FD%BE%DD" onclick="tagshow(event)" class="t_tag"&gt;数据&lt;/span&gt;总数中,设置每页为10
       $this-&gt;assign("list",$booktype-&gt;orderby("bookid desc")-&gt;limit($this-&gt;pager-&gt;offset(),10)-&gt;fetch()-&gt;getRecord());
    }
 public function login(){  //登录&lt;span href="tag.php?name=%D2%B3%C3%E6" onclick="tagshow(event)" class="t_tag"&gt;页面&lt;/span&gt;
 
  }
  public function logout(){ //退出页面
 
      MY()-&gt;logout(); //退出登录
     redirect(url_for("guestbook/index"),"退出成功",3);
  }
  public function noAcl($mask) { //处理一下如果没有权限转向登录
      redirect(url_for("guestbook/login"),"需要登录",3);
  }
  public function loginpost() {  //登录提交地方 简单处理下登录认证
      if($_POST['author']=='queryphp'&amp;&amp;md5($_POST['pwd'])==md5('123456'))
    {
      MY()-&gt;setLogin(); //设置登录状态
      redirect(url_for("guestbook/adminlist"),"登录成功",3);
    }
    redirect(url_for("guestbook/login"),"登录失败",3);
  }
 
/////////////////////////////////////////////
缓存数据,登录时候恢复。
*/
 class mybase {
  public $options=array();
        public $uid;
  public $username;
  public $isadmin;
  public $role=array();  //我使用的身份
  public $group=array(); //我所在组
  public $grouprole=array(); //组的身份
  public $mygroupMar=array(); //我拥有管理的组
  public $mygroupOwn=array(); //属于我的组
  public $acl=array();       //主动控制表 groupacl和myacl控制权限集合 内容是rbac的rbacid
  public $groupacl=array();  //组拥用的控制权限
  public $myacl=array();     //我的身份拥用的控制权限
  public $loginfaild=0;      //登录失败次数 如果超过这个数应该禁止IP登录几分种
 
////////////////////////////////////////
//这是基本可以把myUser.class.php放在项目lib目录里面
////////////////////////////////////////

使用MY()函数就可以取得myUser了。


下载测试例子和chm手册
http://code.google.com/p/queryphp/downloads/list

原文

Frank Database相关, PHP相关

大型网站架构不得不考虑的10个问题

2010年3月11日

这里的大型网站架构只包括高互动性高交互性的数据型大型网站,基于大家众所周知的原因,我们就不谈新闻类和一些依靠HTML静态化就可以实现的架构 了,我们以高负载高数据交换高数据流动性的网站为例,比如海内,开心网等类似的web2.0系列架构。我们这里不讨论是PHP还是JSP或者.NET环 境,我们从架构的方面去看问题,实现语言方面并不是问题,语言的优势在于实现而不是好坏,不论你选择任何语言,架构都是必须要面对的。

这里讨论一下大型网站需要注意和考虑的问题

1、海量数据的处理

众所周知,对于一些相对小的站点来说,数据量并不是很大,select和update就可以解决我们面对的问题,本身负载量不是很大,最多再加几个 索引就可以搞定。对于大型网站,每天的数据量可能就上百万,如果一个设计不好的多对多关系,在前期是没有任何问题的,但是随着用户的增长,数据量会是几何 级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表联合查询)的成本的非常高的。

2、数据并发的处理

在一些时候,2.0的CTO都有个尚方宝剑,就是缓存。对于缓存,在高并发高处理的时候也是个大问题。在整个应用程序下,缓存是全局共享的,然而在 我们进行修改的时候就,如果两个或者多个请求同时对缓存有更新的要求的情况下,应用程序会直接的死掉。这个时候,就需要一个好的数据并发处理策略以及缓存 策略。

另外,就是数据库的死锁问题,也许平时我们感觉不到,死锁在高并发的情况下的出现的概率是非常高的,磁盘缓存就是一个大问题。

3、文件存贮的问题

对于一些支持文件上传的2.0的站点,在庆幸硬盘容量越来越大的时候我们更多的应该考虑的是文件应该如何被存储并且被有效的索引。常见的方案是对文 件按照日期和类型进行存贮。但是当文件量是海量的数据的情况下,如果一块硬盘存贮了500个G的琐碎文件,那么维护的时候和使用的时候磁盘的Io就是一个 巨大的问题,哪怕你的带宽足够,但是你的磁盘也未必响应过来。如果这个时候还涉及上传,磁盘很容易就over了。

也许用raid和专用存贮服务器能解决眼下的问题,但是还有个问题就是各地的访问问题,也许我们的服务器在北京,可能在云南或者新疆的访问速度如何 解决?如果做分布式,那么我们的文件索引以及架构该如何规划。

所以我们不得不承认,文件存贮是个很不容易的问题

阅读全文…

Frank Database相关, Linux/Unix相关, Network/Servers相关, 文章

实现业务系统中的用户权限管理–设计篇

2010年2月9日

B/S系统中的权限比C/S中的更显的重要,C/S系统因为具有特殊的客户端,所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检 测实现,而B/S中,浏览器是每一台计算机都已具备的,如果不建立一个完整的权限检测,那么一个“非法用户”很可能就能通过浏览器轻易访问到B/S系统中 的所有功能。因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测,让经过授权的用户可以正常合法的使用已授权功能,而对那些未经授权的“非 法用户”将会将他们彻底的“拒之门外”。下面就让我们一起了解一下如何设计可以满足大部分B/S系统中对用户功能权限控制的权限系统。

需求陈述

  • 不同职责的人员,对于系统操作的权限应该是不同的。优秀的业务系统,这是最基本的功能。

  • 可以对“组”进行权限分配。对于一个大企业的业务系统来说,如果要求管理员为其下员工逐一分配系统操作权限的话,是件耗时且不够方便的事情。所以,系统中就提出了对“组”进行操作的概念,将权限一致的人员编入同一组,然后对该组进行权限分配。

  • 权限管理系统应该是可扩展的。它应该可以加入到任何带有权限管理功能的系统中。就像是组件一样的可以被不断的重用,而不是每开发一套管理系统,就要针对权限管理部分进行重新开发。

  • 满足业务系统中的功能权限。传统业务系统中,存在着两种权限管理,其一是功能权限的管理,而另外一种则是资源权限的管理,在不同系统之间,功能权限是可以重用的,而资源权限则不能。

阅读全文…

Frank Database相关, PHP相关, 文章 , ,

PHP v5.3.0中 PDO无法连接数据库问题

2010年1月29日

这样的问题在PHP v5.3.0以下版本中不会出现。
错误信息:“[2002] 无效的参数 trying to connect via unix SQLSTATE[HY000] [2002] ”
搜索了一把,类似的解决方案不多,总结了下,大致有两种方案:
第一种方法:
原因求证:php5.3内置驱动有问题。开始使用php5.3内置mysqlnd编译:
–with-mysql=mysqlnd \
–with-mysqli=mysqlnd \
–with-pdo-mysql=mysqlnd \

解决办法:把编译选项改为:
–with-mysql=/path/to/mysql \
–with-pdo-mysql=/path/to/mysql \
–with-mysqli=/path/to/mysql/bin/mysql_config \

第二种方法:
在运行环境: xampp for linux ,
将配置文件的 ‘dbHost’=>’localhost’, 改成 ‘dbHost’=>’127.0.0.1
问题就解决了。

Frank Database相关, Linux/Unix相关 , ,

Linux下Mysql无法启动的原因

2010年1月29日

在Linux下遇到这个问题,Mysql无法启动,报错“Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ “,一个常见的问题,曾经只是把问题解决,没有去深入追究根源,今天再次碰到,追了个底,写出来作个记录。

遇到类似的问题,无论是启动Mysql,还是运行PHP报sock的错时,

首先,检查相应目录(/var/lib/mysql/mysql.sock)下,文件是否存在(mysql.sock是由mysqld自动创建)

其次,检查相应目录是否具有访问与创建文件权限,且是否属于Mysql用户组,
如没有操作下面命令:
# chmod +x dirname
# chown -R mysql:mysql dirname

最后,我们现在可以去启动Mysql,仍无法启动,同样的错误,别急慢慢来,现在我们得需要检查下,my.cnf 中的 sock选项 与 php.ini 中的 mysql.default_socket 选项 的设置是否与报错信息中的路径一致呢? 不相同就对了,有两个方法:
一:修改配置文件中sock选项的路径。(注意:需要保证此目录所属mysql用户组,不属于没关系,看看上面的命令)
二:建立一个软连接即可。(例:ln -s /var/lib/mysql/mysql.sock /var/lib/mysql/mysql.sock)

再启动Mysql看看,一切正常。

Frank Database相关, Linux/Unix相关 , ,

主要关系型数据库系统对比[转]

2009年10月23日

在以下的表格中,将对一些关系型数据库管理系统的基本信息和技术信息进行对比。请参考以下产品各自的条目以获得更详细的介绍。该表格不可能包罗万象,也许有些信息已过时。除非注明,以下产品为各自的稳定版本,且没有安装任何形式的扩展程序

维护者 首次发行日期 最新稳定版 软件授权协议
PostgreSQL PostgreSQL Global Development Group June 1989 8.2.4 BSD
4th Dimension 4D s.a.s 1984 2004.5 专有
Adaptive Server Enterprise Sybase 1987 15.0 专有
Apache Derby Apache 2004 10.2.2.0 Apache License
DB2 IBM 1982 9 专有
DBISAM Elevate Software ? 4.25 专有
ElevateDB Elevate Software ? 1.01 专有
Firebird Firebird Foundation July 25, 2000 2.0.1 Initial Developer’s Public License
Informix IBM 1985 10.0 专有
HSQLDB HSQL Development Group 2001 1.8.0 BSD
H2 H2 Software 2005 1.0 Freeware
Ingres Ingres Corp. 1974 Ingres 2006 II 9.0.4 GPL 与 专有
InterBase CodeGear 1985 2007 专有
MaxDB MySQL AB, SAP AG ? 7.6 GPL 或 专有
Microsoft SQL Server Microsoft 1989 9.00.3042 (2005 SP2) 专有
MonetDB The MonetDB Developer Team 2004 4.16 (Feb. 2007) MonetDB Public License v1.1
MySQL MySQL AB 1996年11月 5.0.41 GPL 或 专有
HP NonStop SQL Hewlett-Packard 1987 SQL MX 2.0 专有
Oracle Oracle Corporation 1979年11月 10g Release 2 专有
Oracle Rdb Oracle Corporation 1984 7.2 专有
OpenEdge Progress Software Corporation 1984 10.1B 专有
OpenLink Virtuoso OpenLink Software 1998 4.5.3 (April 2006) GPL 或 专有
Pervasive PSQL Pervasive Software ? 9 专有
Pyrrho DBMS University of Paisley 2005年11月 0.5 专有
SmallSQL SmallSQL April 16 2005 0.12 LGPL
SQL Anywhere Sybase 1992 10.0 专有
SQLite D. Richard Hipp August 17 2000 3.3.7 Public domain
Teradata Teradata 1984 V2R8.2 专有
Valentina Paradigma Software Febrary 1998 3.0.1 专有
维护者 首次发行日期 最新稳定版 软件授权协议

阅读全文…

Frank Database相关, 文章

MySQL存储过程例子,包含事务,参数,嵌套调用,游标,循环等

2009年3月24日
  1. drop procedure if exists pro_rep_shadow_rs;
  2. delimiter |
  3. ———————————-
  4. – rep_shadow_rs
  5. – 用来处理信息的增加,更新和删除
  6. – 每次只更新上次以来没有做过的数据
  7. – 根据不同的标志位
  8. – 需要一个输出的参数,
  9. – 如果返回为0,则调用失败,事务回滚
  10. – 如果返回为1,调用成功,事务提交
  11. – 测试方法
  12. – call pro_rep_shadow_rs(@rtn);
  13. – select @rtn;
  14. ———————————-
  15. create procedure pro_rep_shadow_rs(out rtn int)
  16. begin
  17. – 声明变量,所有的声明必须在非声明的语句前面
  18. declare iLast_rep_sync_id int default -1;
  19. declare iMax_rep_sync_id int default -1;
  20. – 如果出现异常,或自动处理并rollback,但不再通知调用方了
  21. – 如果希望应用获得异常,需要将下面这一句,以及启动事务和提交事务的语句全部去掉
  22. declare exit handler for sqlexception rollback;
  23. – 查找上一次的
  24. select eid into iLast_rep_sync_id from rep_de_proc_log where tbl=‘rep_shadow_rs’;
  25. – 如果不存在,则增加一行
  26. if iLast_rep_sync_id=-1 then
  27. insert into rep_de_proc_log(rid,eid,tbl) values(0,0,‘rep_shadow_rs’);
  28. set iLast_rep_sync_id = 0;
  29. end if;
  30. – 下一个数字
  31. set iLast_rep_sync_id=iLast_rep_sync_id+1;
  32. – 设置默认的返回值为0:失败
  33. set rtn=0;
  34. – 启动事务
  35. start transaction;
  36. – 查找最大编号
  37. select max(rep_sync_id) into iMax_rep_sync_id from rep_shadow_rs;
  38. – 有新数据
  39. if iMax_rep_sync_id>=iLast_rep_sync_id then
  40. – 调用
  41. call pro_rep_shadow_rs_do(iLast_rep_sync_id,iMax_rep_sync_id);
  42. – 更新日志
  43. update rep_de_proc_log set rid=iLast_rep_sync_id,eid=iMax_rep_sync_id where tbl=‘rep_shadow_rs’;
  44. end if;
  45. – 运行没有异常,提交事务
  46. commit;
  47. – 设置返回值为1
  48. set rtn=1;
  49. end;
  50. |
  51. delimiter ;
  52. drop procedure if exists pro_rep_shadow_rs_do;
  53. delimiter |
  54. ———————————
  55. – 处理指定编号范围内的数据
  56. – 需要输入2个参数
  57. – last_rep_sync_id 是编号的最小值
  58. – max_rep_sync_id 是编号的最大值
  59. – 无返回值
  60. ———————————
  61. create procedure pro_rep_shadow_rs_do(last_rep_sync_id int, max_rep_sync_id int)
  62. begin
  63. declare iRep_operationtype varchar(1);
  64. declare iRep_status varchar(1);
  65. declare iRep_Sync_id int;
  66. declare iId int;
  67. – 这个用于处理游标到达最后一行的情况
  68. declare stop int default 0;
  69. – 声明游标
  70. declare cur cursor for select id,Rep_operationtype,iRep_status,rep_sync_id from rep_shadow_rs where rep_sync_id between last_rep_sync_id and max_rep_sync_id;
  71. – 声明游标的异常处理,设置一个终止标记
  72. declare CONTINUE HANDLER FOR SQLSTATE ‘02000′ SET stop=1;
  73. – 打开游标
  74. open cur;
  75. – 读取一行数据到变量
  76. fetch cur into iId,iRep_operationtype,iRep_status,iRep_Sync_id;
  77. – 这个就是判断是否游标已经到达了最后
  78. while stop <> 1 do
  79. – 各种判断
  80. if iRep_operationtype=‘I’ then
  81. insert into rs0811 (id,fnbm) select id,fnbm from rep_shadow_rs where rep_sync_id=iRep_sync_id;
  82. elseif iRep_operationtype=‘U’ then
  83. begin
  84. if iRep_status=‘A’ then
  85. insert into rs0811 (id,fnbm) select id,fnbm from rep_shadow_rs where rep_sync_id=iRep_sync_id;
  86. elseif iRep_status=‘B’ then
  87. delete from rs0811 where id=iId;
  88. end if;
  89. end;
  90. elseif iRep_operationtype=‘D’ then
  91. delete from rs0811 where id=iId;
  92. end if;
  93. – 读取下一行的数据
  94. fetch cur into iId,iRep_operationtype,iRep_status,iRep_Sync_id;
  95. end while;  – 循环结束
  96. close cur; – 关闭游标
  97. end;
  98. |

Frank Database相关 ,

MySQL 集群配置 [转载]

2009年3月24日

(这篇文章写得不是很好,应该图文结合,更直观,但收藏起来吧)

本篇文档旨在介绍如何安装配置基于2台服务器MySQL集群。并且实现任意一台服务器出现问题或宕机时MySQL依然能够继续运行。

注意!
虽 然这是基于2台服务器的MySQL集群,但也必须有额外的第三台服务器作为管理节点,但这台服务器可以在集群启动完成后关闭。同时需要注意的是并不推荐在 集群启动完成后关闭作为管理节点的服务器。尽管理论上可以建立基于只有2台服务器的MySQL集群,但是这样的架构,一旦一台服务器宕机之后集群就无法继 续正常工作了,这样也就失去了集群的意义了。出于这个原因,就需要有第三台服务器作为管理节点运行。

另外,可能很多朋友都没有3台服务器的实际环境,可以考虑在VMWare或其他虚拟机中进行实验。本文即在在三台虚拟机环境下实现。

下面假设这3台服务的情况:

Server1: mysql1.vmtest.net 192.168.0.1
Server2: mysql2.vmtest.net 192.168.0.2
Server3: mysql3.vmtest.net 192.168.0.3

Servers1 和Server2作为实际配置MySQL集群的服务器。对于作为管理节点的Server3则要求较低,只需对Server3的系统进行很小的调整并且无需 安装MySQL,Server3可以使用一台配置较低的计算机并且可以在Server3同时运行其他服务。

二、在Server1和Server2上安装MySQL
=================================
http://www.mysql.com上下载mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz
注意:必须是max版本的MySQL,Standard版本不支持集群部署!

以下步骤需要在Server1和Server2上各做一次
# mv mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz /usr/local/
# cd /usr/local/
# groupadd mysql
# useradd -g mysql mysql
# tar -zxvf mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz
# rm -f mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz
# mv mysql-max-4.1.9-pc-linux-gnu-i686 mysql
# cd mysql
# scripts/mysql_install_db –user=mysql
# chown -R root .
# chown -R mysql data
# chgrp -R mysql .
# cp support-files/my-medium.cnf /etc/my.cnf
# cp support-files/mysql.server /etc/rc.d/init.d/mysqld
# chmod +x /etc/rc.d/init.d/mysqld
# chkconfig –add mysqld

此时不要启动MySQL!

三、安装并配置管理节点服务器(Server3)
=====================================
作为管理节点服务器,Server3需要ndb_mgm和ndb_mgmd两个文件:

http://www.mysql.com上下载mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz

# mkdir /usr/src/mysql-mgm
# cd /usr/src/mysql-mgm
# tar -zxvf mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz
# rm mysql-max-4.1.9-pc-linux-gnu-i686.tar.gz
# cd mysql-max-4.1.9-pc-linux-gnu-i686
# mv bin/ndb_mgm .
# mv bin/ndb_mgmd .
# chmod +x ndb_mg*
# mv ndb_mg* /usr/bin/
# cd
# rm -rf /usr/src/mysql-mgm

现在开始为这台管理节点服务器建立配置文件:

# mkdir /var/lib/mysql-cluster
# cd /var/lib/mysql-cluster
# vi config.ini

在config.ini中添加如下内容:

[NDBD DEFAULT]
NoOfReplicas=2
[MYSQLD DEFAULT]
[NDB_MGMD DEFAULT]
[TCP DEFAULT]
# Managment Server
[NDB_MGMD]
HostName=192.168.0.3 #管理节点服务器Server3的IP地址
# Storage Engines
[NDBD]
HostName=192.168.0.1 #MySQL集群Server1的IP地址
DataDir= /var/lib/mysql-cluster
[NDBD]
HostName=192.168.0.2 #MySQL集群Server2的IP地址
DataDir=/var/lib/mysql-cluster
# 以下2个[MYSQLD]可以填写Server1和Server2的主机名。
# 但为了能够更快的更换集群中的服务器,推荐留空,否则更换服务器后必须对这个配置进行更改。
[MYSQLD]
[MYSQLD]

保存退出后,启动管理节点服务器Server3:
# ndb_mgmd

启动管理节点后应该注意,这只是管理节点服务,并不是管理终端。因而你看不到任何关于启动后的输出信息。

四、配置集群服务器并启动MySQL
=============================
在Server1和Server2中都需要进行如下改动:

# vi /etc/my.cnf

[mysqld]
ndbcluster
ndb-connectstring=192.168.0.3 #Server3的IP地址
[mysql_cluster]
ndb-connectstring=192.168.0.3 #Server3的IP地址

保存退出后,建立数据目录并启动MySQL:

# mkdir /var/lib/mysql-cluster
# cd /var/lib/mysql-cluster
# /usr/local/mysql/bin/ndbd –initial
注意,执行此步时可能会报错,一般都是关天配置文件里面log-bin,server-id这些选项的,可以在/etc/my.cnf里面把这些相关的项注释掉即可。

# /etc/rc.d/init.d/mysqld start

可以把/usr/local/mysql/bin/ndbd加到/etc/rc.local中实现开机启动。
注意:只有在第一次启动ndbd时或者对Server3的config.ini进行改动后才需要使用–initial参数!

五、检查工作状态
================
回到管理节点服务器Server3上,并启动管理终端:

# /usr/bin/ndb_mgm
键入show命令查看当前工作状态:(下面是一个状态输出示例)

[root@mysql3 root]# /usr/bin/ndb_mgm
– NDB Cluster — Management Client –
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
———————
[ndbd(NDB)] 2 node(s)
id=2 @192.168.0.1 (Version: 4.1.9, Nodegroup: 0, Master)
id=3 @192.168.0.2 (Version: 4.1.9, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.0.3 (Version: 4.1.9)

[mysqld(API)] 2 node(s)
id=4 (Version: 4.1.9)
id=5 (Version: 4.1.9)

ndb_mgm>

如果上面没有问题,现在开始测试MySQL:
注意,这篇文档对于MySQL并没有设置root密码,推荐你自己设置Server1和Server2的MySQL root密码。

在Server1中:

# /usr/local/mysql/bin/mysql -u root -p
> use test;
> CREATE TABLE ctest (i INT) ENGINE=NDBCLUSTER;
> INSERT INTO ctest () VALUES (1);
> SELECT * FROM ctest;

应该可以看到1 row returned信息(返回数值1)。

如果上述正常,则换到Server2上重复上面的测试,观察效果。如果成功,则在Server2中执行INSERT再换回到Server1观察是否工作正常。
如果都没有问题,那么恭喜成功!

六、破坏性测试
==============
将Server1或Server2的网线拔掉,观察另外一台集群服务器工作是否正常(可以使用SELECT查询测试)。测试完毕后,重新插入网线即可。

如果你接触不到物理服务器,也就是说不能拔掉网线,那也可以这样测试:
在Server1或Server2上:

# ps aux | grep ndbd
将会看到所有ndbd进程信息:

root 5578 0.0 0.3 6220 1964 ? S 03:14 0:00 ndbd
root 5579 0.0 20.4 492072 102828 ? R 03:14 0:04 ndbd
root 23532 0.0 0.1 3680 684 pts/1 S 07:59 0:00 grep ndbd

然后杀掉一个ndbd进程以达到破坏MySQL集群服务器的目的:

# kill -9 5578 5579

之后在另一台集群服务器上使用SELECT查询测试。并且在管理节点服务器的管理终端中执行show命令会看到被破坏的那台服务器的状态。
测试完成后,只需要重新启动被破坏服务器的ndbd进程即可:

# ndbd
注意!前面说过了,此时是不用加–inital参数的!

至此,MySQL集群就配置完成了!

Frank Database相关 ,