使用MySQL内建复制功能来最佳化可用性

 更新时间:2016年11月25日 16:40  点击:1693

在Soundbreak我们天天24小时不间断之播放实况音频和视频,所以对于MySQL之新增之复制特性,我们不能做出很令人信服之测试。通过测试我们发现,可以使用这个特性来与备份数据库服务器保持数据同步,这样当主服务器因为某种原因处理失效时,能够使用备份机处理所有之查询。对于这样之要求,配置两台服务器并不困难。我将具体讨论整个处理过程,同时讨论一下当主服务器失效时,如何使用PHP来重定向查询。

  MySQL内部复制功能是建立在两个或两个以上服务器之间,通过设定它们之间之主-从关系来实现之。其中一个作为主服务器,其它之作为从服务器。我将具体讨论如何配置两台服务器,将一个设为主服务器,另一个设为从服务器。并且描述一下在它们之间进行切换之处理过程。我是在MySQL之3.23.23版本上进行之配置设置过程,并且也是在这个版本上进行之测试。MySQL开发人员建议最好使用最新版本,并且主-从服务器均使用相同之版本。同时MySQL 3.23版本仍然是beta测试版,而且这个版本可能不能向下兼容。所以因为这个原因,在实际之网站中,我现在还没有使用这个版本。拥有容错能力具有一个好处是,在不需中断任何查询之情况下,对服务器进行升级。

第一步:配置主服务器
  在这篇文章之剩下篇幅中,我将指定两台服务器。A(IP为10.1.1.1)作为主服务器(简称为主机)。B(IP为10.1.1.2)作为后备服务器(简称为备机)。

  MySQL之复制功能之实现过程为:备机(B)与主机(A)连接,然后读出主机之二进制更新日志,再将发生之变化合并到自已之数据库中。备机需要一个用户帐号来与主机连接,所以在主机上创建一个帐号,并只给它FILE权限,如下操作:

GRANT FILE ON *.* TO replicate@10.1.1.2 IDENTIFIED BY password;

  为了备机能够与主机连接,要在主机上运行FLUSH PRIVILEGES,不过不要担心,因为我们将在下面之步骤中停掉服务器。

  现在我们需要主机数据库之一个快照,并且对主机进行配置,答应生成二进制之更新日志。首先编辑my.cnf文件,以便答应二进制更新日志,所以在[mysqld]部分之下面某个之方增加一行:log-bin。在下一次服务器启动时,主机将生成二进制更新日志(名为:<主机名>-bin.<增量序号#>)。为了让二进制更新日志有效,关闭MySQL服务程序,然后将主机上之所有数据库目录到另一个目录中,接着重新启动mysqld。
请确定得到了所有数据库,否则在进行复制时,假如一个表在主机上存在但在备机上不存在,将因为出错而退出。现在你已经得到了数据之快照,和一个从建立快照以来之二进制日志,上面记录着任何对数据库之修改。请注重MySQL数据文件(*.MYD,*.MYI和*.frm)是依靠于文件系统之,所以你不能仅仅进行文件传输,如从Solaris到Linux。假如你处于一个异种之服务器环境,你将不得不使用mysqldump实用程序或其它之定制脚本来得到数据快照。

第二步:配置备机
  让我们继续。停掉备机上之MySQL服务程序,并且把从主机上拷贝来之数据库目录移到备机上之data目录下。请确认将目录之拥有者和属组改变为MySQL用户相应值,并且修改文件模式为660(只对拥有者和属组可读、可写),目录本身为770(只对拥有者和属组可读、可写和可执行)。

  继续。在备机上启动MySQL服务程序,确认MySQL工作正常。运行几个select查询(不要update或insert查询),看一看在第一步中得到之数据快照是否成功。接着,在测试成功后关掉MySQL服务程序。

  在备机上配置需要访问之主机,以便接收主机之更改。所以需要编辑务机上之my.cnf文件,在[mysqld]部分中增加下面几行:

master-host=10.1.1.1
master-user=replicate
master-password=password

  在启动备机服务程序后,备机服务程序将查看在my.cnf文件中所指定之主机,查看是否有改变,并且将这些改变合并到自已之数据库中。备机保持了主机之更新记录,这些记录是从主机之master.info文件中接收下来之。备机线程之状态可以通过sql命令SHOW SLAVE-STATUS看到。在备机上处理二进制日志中假如
发生错误,都将导致备机线程之退出,并且在*.err之日志文件中生成一条信息。然后错误可以被改正,接着可以使用sql语句SLAVE START来重新启动备机线程。线程将从主机二进制日志处理中断之之方继续处理。

  至此,在主机上所发生之数据改变应该已经复制到备机上了,要测试它,你可以在主机上插入或更新一条记录,而在备机上选择这条记录。

  现在我们拥有了从A机到B机之这种主-从关系,这样当A机可能当机之时候,答应我们将所有之查询重定向到B机上去,但是当A机恢复时,我们没有办法将发生之改变恢复到A机中去。为了解决这个问题,我们创建从B机到A机之主-从关系。

第三步:创建相互之主从关系
  首先在B机上之my.cnf文件中,在[mysqld]部分中加入log-bin,接着重新启动mysqld,然后创建可在它之上面执行复制功能之用户帐号,使用:

GRANT FILE ON *.* TO replicate@10.1.1.1 IDENTIFIED BY password;

  在B机上运行FLUSH PRIVILEGES命令,以便装入在加入复制用户后之新之授权表,接着回到A机上,在它之my.cnf中加入下面几行:

master-host=10.1.1.2
master-user=replicate
master-password=password

  在重启A机之服务程序之后,现在我们一拥有了在A机与B机之间之相互主-从关系。不管在哪个服务器上更新一条记录或插入一条记录,都将被复制到另一台服务器上。要注重之是:我不敢确定一个备机合并二进制日志变化之速度有多快,所以用这种方法来进行插入或更新语句之负载平衡可能不是一个好办法。

第四步:修改你之数据库连接程序
  既然你已经在A机和B机之间建立了一个相互之关系,你需要修改数据库连接程序,以便从这种方式中得到好处。下面之函数首先试图与A机连接,假如不能建立连接则与B机连接。


/********************************************************
function db_connect()



returns a link identifier on success, or false on error
********************************************************/
function db_connect(){
$username = "replUser";
$password = "password";

当工作在非常大的表上时,你可能偶然需要运行很多查询获得一个大量数据的小的子集,不是对整个表运行这些查询,而是让MySQL每次找出所需的少数记录,将记录选择到一个临时表可能更快
些,然后多这些表运行查询。

创建临时表很轻易,给正常的CREATE TABLE语句加上TEMPORARY要害字:

CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
)

临时表将在你连接MySQL期间存在。当你断开时,MySQL将自动删除表并释放所用的空间。当然你可以在仍然连接的时候删除表并释放空间。

DROP TABLE tmp_table

假如在你创建名为tmp_table临时表时名为tmp_table的表在数据库中已经存在,临时表将有必要屏蔽(隐藏)非临时表tmp_table。

假如你声明临时表是一个HEAP表,MySQL也答应你指定在内存中创建它:

 CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
) TYPE = HEAP
 

因为HEAP表存储在内存中,你对它运行的查询可能比磁盘上的临时表快些。然而,HEAP表与一般的表有些不同,且有自身的限制。详见MySQL参考手册。

正如前面的建议,你应该测试临时表看看它们是否真的比对大量数据库运行查询快。假如数据很好地索引,临时表可能一点不快。

关于数据库在WEB编程当中,数据库的作用已经越来越不容忽视。提到数据库,应当说PHP具有非常强大的数据库支持功能,从FileMaker到 Oracle,几乎与所有的数据库系统都可以实现无缝连接。为了方便本文的讲解,我们将主要以MySQL为例进行说明。不过对于其它的数据库应用也同样适用。

  使用PHP进行数据库操作一般需要包括以下语句:

  <?
  $Host="localhost";
  $MySQL_UserName="root";
  $MySQL_UserPass="password";
  $MySQL_Database="db";
  $Query="SELECT * FROM domain";
  mysql_connect ($Host, $MySQL_UserName, $MySQL_UserPass);
  mysql_select_db ($MySQL_Database);
  $Result_ID=mysql_query ($Query);
  while ($Result=mysql_fetch_row($Result_ID)){
  print ------------------<BR>;
  print "$Result[0]<BR>";
  print "$Result[1]<BR>";
  print "$Result[2]<BR>";
  print "$Result[3]<BR>";
  print -------------------<BR>;
  }?>

  基本步骤包括建立与MySQL数据库的连接,选择数据库操作对象,然后执行查询语句。对于在上述过程中出现的错误的提示信息一般来说都能够较为准确和具体的描述所出现的问题。例如,“Connection failed due to a bad username”错误报告就清楚的指出由于用户名错误而导致与数据库的连接失败。

  我们可以对以上所提到的这些函数的返回值加以利用,从而减少出现不必要的麻烦。例如,mysql_connect函数在连接成功时会返回一个连接ID标识,假如连接失败则发出错误提示。对此,我们可以进行如下利用:

  if (!mysql_connect (’localhost’, ’root’, ’password’)){
  print "Cannot connect to MySQL<BR>";
  exit;
  }

  当与数据库的连接出现问题时,我们可以输出错误提示,并终止程序的执行。从长远来看,这是一项非常好的防范措施。以此方式,我们重新编写脚本如下:

  <?
  $Host="localhost";
  $MySQL_UserName="root";
  $MySQL_UserPass="password";
  $MySQL_Datab ="db";
  $Query="SELECT * FROM domain";
  if (!mysql_connect ($Host, $MySQL_UserName, $MySQL_UserPass)){
  print "Cannot connect to MySQL: ".mysql_error();
  exit;
  }
  if (!mysql_select_db ($MySQL_Database)){
  print "Cannot select db<BR>";
  exit;
  }
  if (!$Result_ID=mysql_query ($Query)){
  print "Query Error: ".mysql_error();
  exit;
  }
  while ($Result=mysql_fetch_row($Result_ID)){
  print ------------------<BR>;
  print "$Result[0]<BR>";
  print "$Result[1]<BR>";
  print "$Result[2]<BR>";
  print "$Result[3]<BR>";
  print -------------------<BR>;
  }?>

  这样,当程序出现问题时,我们就可以马上找到错误的根源,从而能够做到有的放矢。

  接下来,我们就可以对数据库进行查询。不过,很多时候,当我们运行编写好的查询语句时,却得不到任何返回数据。到底是什么地方出错了呢?最好的解决方法是把SQL语句赋予一个变量,例如:

  <?
  ....
  $SQL="SELECT * FROM $TableName WHERE $ColumnName > $Limit";
  $Result_ID=mysql_query($QUERY);
  ...?>

  然后当出现问题时,使用“print”或“echo”命令显示该语句。注重检查$ColumnName和$Limit的拼写是否正确,是否无意当中创建了新的变量。使用输出显示的方法可以很轻易的找到并解决拼写错误的问题。但是假如我们将SQL语句显示出来之后仍然没有找到明显的错误该怎么办呢?这里我们可以把输出的语句粘贴到象Mysql命令行接口这样的命令行工具中,看一看是否能够返回数据。假如还是无法解决问题,就应该查看一下所使用帐号的用户权限。

  如今,我们可以使用许多免费提供的类完成绝大部分的数据库操作。PHP Classes(http://phpclasses.upperdesign.com/)上就有许多相关的信息,可以供有爱好的用户参考。其中, MetaBase能够提供不依靠某种数据库系统的查询和治理。假如用户正在同时使用几种不同的数据库系统,或者希望自己的程序能够移植到其它的数据库平台上的话,可以留意一下MetaBase的使用。

  注重事项最后,我们把使用PHP进行编程的过程中所应当注重的一些问题进行一下汇总,希望能够对大家有所帮助。

  1.检查(),[],以及{}等符号,看看是否成对出现。
  2.检查字符串,注重假如要想在“”当中再使用“”的话,必须使用转义符“”。

#这是我的MySql数据的配置
#本文中我的用计算机的mysql数据库安装目录是“d:webservermysql”
#我的数据库目录是“f:sun datamysql data”
#我的计算机的IP地址为192.168.0.2假如是公网IP也是一样
#[mysqld]部分为mysql的环境配置部分
#[WinMySQLadmin]为数据库启动部分
[code]到[/code]之间的为配置环境变量及事务处理数据库的部分

#本文中使用"#"的部分为注释行正文部分带有“#”的为可选的,可以打开

#本文参考了部分mysql的阅读文件。

[mysqld]
basedir=d:/webserver/mysql
#bind-address=192.168.0.2
datadir=F:/Sun Date/mysql data/
#language=d:/webserver/mysql/share/your language directory
#slow query log#=
#tmpdir#=
#port=3306
[WinMySQLadmin]
Server=d:/webserver/mysql/bin/mysqld-max-nt.exe
user=启动数据库的用户名
password=启动数据库的密码
[code]
innodb_data_file_path = ibdata1:1000M;ibdata2:1000M
innodb_data_home_dir = d:webservermysqlibdata
set-variable = innodb_mirrored_log_groups=1
innodb_log_group_home_dir = d:webservermysqliblogs
innodb_flush_log_at_trx_commit=1
innodb_log_arch_dir = d:webservermysqliblogs
innodb_log_archive=0
set-variable = innodb_buffer_pool_size=80M
set-variable = innodb_additional_mem_pool_size=10M
set-variable = innodb_file_io_threads=4
set-variable = innodb_lock_wait_timeout=50
set-variable = innodb_log_files_in_group=3
set-variable = innodb_log_file_size=30M
set-variable = innodb_log_buffer_size=8M
#set-variable = key_buffer=16M
[/code]

以下是在Linux下通过Apache PHP对Mysql数据库的备份的文件代码:

文件一、Listtable.php (文件列出数据库中的所有表格,供选择备份)

<html>
<head>
<title>
使用XML备份Mysql数据库</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF" text="#000000">
请选择要备份的表格:
<?
$con=mysql_connect('localhost','root','xswlily');
$lists=mysql_list_tables("embed",$con);
//数据库连接代码
$i=0;
while($i<mysql_num_rows($lists)){
$tb_name=mysql_tablename($lists,$i);
echo "<a href=backup.php?table=".$tb_name.">".$tb_name."</a>
";
//列出所有的表格
$i ;}

?>
</body>
</html>


文件二、Backup.php

<?if ($table=="") header("Location:listtable.php");?><html>
<head>
<title>
使用XML备份Mysql数据库</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<?
$con=mysql_connect('localhost','root','xswlily');
$query="select * from $table ";
//数据库查询
$result=mysql_db_query("embed",$query,$con);
$filestr="<"."?xml version="1.0" encoding="GB2312"?".">";
$filestr.="<".$table."s>";
while ($row=mysql_fetch_array($result))
//列出所有的记录
{$filestr.="<".$table.">";
$fields=mysql_list_fields("embed",$table,$con);
$j=0;
//$num_fields=mysql_field_name($fields,$j);
//echo $num_fields;
while ($j<mysql_num_fields($fields)){
$num_fields=mysql_field_name($fields,$j);
$filestr.="<".$num_fields.">";
$filestr.=$row[$j];
$filestr.="</".$num_fields.">";
$j ;}
$filestr.="</".$table.">";
}
$filestr.="</".$table."s>";
echo $filestr;
//以下是文件操作代码
$filename=$table.".xml";
$fp=fopen("$filename","w");
fwrite($fp,$filestr);
fclose($fp);
Echo "数据表".$table."已经备份成功!";?>
</body>
</html>

通过以上文件的操作就可以实现对数据库中选定的表格进行备份.

以上主要介绍了通过PHP实现XML备份数据库的操作方法,其实并不复杂,通过XML,我们可以备份各种各样的数据库,当然也可以通过相关的方法将备份的XML文档恢复到数据库中,这里就不具体描述了。

[!--infotagslink--]

相关文章

  • 图解PHP使用Zend Guard 6.0加密方法教程

    有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
  • ps怎么使用HSL面板

    ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。 &#8195;...2017-07-06
  • MySQL快速复制数据库数据表的方法

    某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库。使用以下方法,可以非常简单地实现。假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb。步骤如下:1. 首先创建新的数据库newd...2015-10-21
  • Plesk控制面板新手使用手册总结

    许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
  • 使用insertAfter()方法在现有元素后添加一个新元素

    复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • 使用percona-toolkit操作MySQL的实用命令小结

    1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24
  • 如何使用php脚本给html中引用的js和css路径打上版本号

    在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24
  • jQuery 1.9使用$.support替代$.browser的使用方法

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31
  • 安装和使用percona-toolkit来辅助操作MySQL的基本教程

    一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24
  • C#注释的一些使用方法浅谈

    C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
  • MySQL日志分析软件mysqlsla的安装和使用教程

    一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
  • php语言中使用json的技巧及json的实现代码详解

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • php类的使用实例教程

    php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25
  • 双冒号 ::在PHP中的使用情况

    前几天在百度知道里面看到有人问PHP中双冒号::的用法,当时给他的回答比较简洁因为手机打字不大方便!今天突然想起来,所以在这里总结一下我遇到的双冒号::在PHP中使用的情况!双冒号操作符即作用域限定操作符Scope Resoluti...2015-11-08
  • 浅析Promise的介绍及基本用法

    Promise是异步编程的一种解决方案,在ES6中Promise被列为了正式规范,统一了用法,原生提供了Promise对象。接下来通过本文给大家介绍Promise的介绍及基本用法,感兴趣的朋友一起看看吧...2021-10-21
  • 使用jquery修改表单的提交地址基本思路

    基本思路: 通过使用jquery选择器得到对应表单的jquery对象,然后使用attr方法修改对应的action 示例程序一: 默认情况下,该表单会提交到page_one.html 点击button之后,表单的提交地址就会修改为page_two.html 复制...2014-06-07
  • PHP mysql与mysqli事务使用说明 分享

    mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02
  • Postman安装与使用详细教程 附postman离线安装包

    这篇文章主要介绍了Postman安装与使用详细教程 附postman离线安装包,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-05