GVKun编程网logo

php实现的mysqldb读写分离操作类示例(php mysql读写分离实现)

15

对于php实现的mysqldb读写分离操作类示例感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍phpmysql读写分离实现,并为您提供关于CentOS7,MySQL主从配置和读写分离(MySQ

对于php实现的mysqldb读写分离操作类示例感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍php mysql读写分离实现,并为您提供关于CentOS7,MySQL主从配置和读写分离(MySQL主从、MySQL读写分离、MySQL分布式、数据库读写分离、主从配置)(亲测)、django+centos+mariadb读写分离完美实现(上)-mysql主从备份实现、Linux 使用Mycat实现读写分离(基于Mysql的读写分离)、mysql Proxy读写分离配置与php mysql读写分离类的有用信息。

本文目录一览:

php实现的mysqldb读写分离操作类示例(php mysql读写分离实现)

php实现的mysqldb读写分离操作类示例(php mysql读写分离实现)

本文实例讲述了PHP实现的MysqLdb读写分离操作类。分享给大家供大家参考,具体如下:

MysqLdb($dbarray); } function MysqLdb($dbarray,$dbcharset='utf8',$pcontent=0) { if(!is_array($dbarray[0])) { echo "数据库参数错误"; return false; } $this->charset = $dbcharset; $this->pconnect = $pconnect; $this->dbconfig['master'] = $dbarray[0]; $dbServerNum = count($dbarray); if($dbServerNum > 1) { /* * 当x=1 时,$dbarray[0]不作slave * 当x=0 时,$dbarray[0]作slave */ $x = 1; $rand = rand($x,$dbServerNum-1); $this->dbconfig['slave'] = $dbarray[$rand]; } else { $this->dbconfig['slave'] = false; } } function connect($dbhost,$dbuser,$dbpw,$dbname) { if($this->pconnect) { $link = @MysqL_pconnect($dbhost,$dbpw); } else { $link = @MysqL_connect($dbhost,1); } if($link) { if($this->version($link) > '4.1') { if($this->charset) { @MysqL_query("SET character_set_connection=".$this->charset.",character_set_results=".$this->charset.",character_set_client=binary",$link); } if($this->version($link) > '5.0.1') { @MysqL_query("SET sql_mode=''",$link); } } if($dbname) { @MysqL_select_db($dbname,$link); } //print_r($link); return $link; } else { return false; } } function connectM() { if(!$this->linkw = $this->connect($this->dbconfig['master'][0],$this->dbconfig['master'][1],$this->dbconfig['master'][2],$this->dbconfig['master'][3])) { exit("主数据库连接失败!"); } //echo "
##connectM!.
"; } function connectS() { if($this->dbconfig['slave']) { if(!$this->linkr = $this->connect($this->dbconfig['slave'][0],$this->dbconfig['slave'][1],$this->dbconfig['slave'][2],$this->dbconfig['slave'][3])) { $this->dbconfig['slave'] = false; $this->connectS(); } //echo "
##connectS!.
"; } else { if(!$this->linkw) { $this->connectM(); } $this->linkr = $this->linkw; } } // db read function query($sql,$type = '') { if(!$this->linkr) { $this->connectS(); } $func = $type == 'UNBUFFERED' && @function_exists('MysqL_unbuffered_query') ? 'MysqL_unbuffered_query' : 'MysqL_query'; $query = $func($sql,$this->linkr); $this->querynum++; return $query; } function fetch_array($query,$result_type = MysqL_ASSOC) { return @MysqL_fetch_array($query,$result_type); } function fetch_row($query) { $query = MysqL_fetch_row($query); return $query; } function fetch_One($sql) { $query = $this->query($sql); return $this->fetch_row($query); } /* 获取分页方法 */ function fetch_page($sql,$pagenum) { $page = intval($_GET['page']); $query = $this->query($sql); $countnum = $this->num_rows($query); $countpage = ceil($countnum/$pagenum); if($page<1) { $page=1; } if($page>$countpage) { $page=$countpage; } $limitstart = ($page-1)*$pagenum; /* 获取数据结果集 */ for ($i=0; $i<($limitstart+$pagenum); $i++) { if($i>=$countnum) { break; } if($i>=$limitstart) { $result[] = $this->fetch_array($query); } else { $this->fetch_array($query); } } /* 生成url */ $url = $_SERVER['QUERY_STRING']; $url = preg_replace("/&?page=[0-9]+/i","",$url); $array['countnum'] = $countnum; $array['countpage'] = $countpage; $array['result'] = $result; $array['page'] = $page; if($page>1) { $array['preurl'] = "?".$url."&page=".($page-1); $array['prepage'] = $page-1; } else { $array['preurl'] = "?".$url."&page=1"; $array['prepage'] = 1; } if($page<$countpage) { $array['nexturl'] = "?".$url."&page=".($page+1); $array['nextpage'] = $page+1; } else { $array['nexturl'] = "?".$url."&page=".$countpage; $array['nextpage'] = $countpage; } $array['firsturl'] = "?".$url."&page=1"; $array['firstpage'] = 1; $array['lasturl'] = "?".$url."&page=".$countpage; $array['lastpage'] = $countpage; $array['nopage'] = "?".$url."&page="; return $array; } // db write function queryw($sql,$type = '') { if(!$this->linkw) { $this->connectM(); } $func = $type == 'UNBUFFERED' && @function_exists('MysqL_unbuffered_query') ? 'MysqL_unbuffered_query' : 'MysqL_query'; $query = $func($sql,$this->linkw); $this->querynum++; return $query; } function update($table,$where,$array) { $whereset = $set = $dot = ''; foreach($array as $key=>$value) { $set .= $dot." `$key`='$value'"; $dot = ','; } $whereset = $dot = ''; foreach($where as $k=>$v) { $whereset .= $dot." `$k`='$v'"; $dot = ' and '; } $sql = "update $table set $set where $whereset"; return $this->queryw($sql); } function insert($table,$array) { $col = $v = $dot = ''; foreach($array as $key=>$value) { $v .= $dot."'$value'"; $col .= $dot."`$key`"; $dot = ','; } $sql = "insert into $table ($col) values ($v)"; if($this->queryw($sql)) { return $this->insert_id(); } else { return false; } } function insert_id() { return ($id = MysqL_insert_id($this->linkw)) >= 0 ? $id : $this->result($this->queryw("SELECT last_insert_id()"),0); } // db other function affected_rows($link) { return MysqL_affected_rows($link); } function error($link) { return (($link) ? MysqL_error($link) : MysqL_error()); } function errno($link) { return intval(($link) ? MysqL_errno($link) : MysqL_errno()); } function result($query,$row) { $query = @MysqL_result($query,$row); return $query; } function num_rows($query) { $query = MysqL_num_rows($query); return $query; } function num_fields($query) { return MysqL_num_fields($query); } function free_result($query) { return MysqL_free_result($query); } function fetch_fields($query) { return MysqL_fetch_field($query); } function version($link) { return MysqL_get_server_info($link); } function close($link) { return MysqL_close($link); } } /* 测试例子 // * $dbarray[] = array('localhost','bevin','password','test'); * $dbarray[] = array('ilaopo.net','root','test'); * $dbarray[] = array('192.168.1.77','cxh','test'); * $newdb = new MysqLdb($dbarray,'utf8'); * $array = array('name' => date("Y-m-d H:i:s")); * $id = $newdb->insert("test",$array); * $result = $newdb->fetch_page("select * from test order by id desc",'10'); * print_r($result); * $id = $newdb->insert("test",$array); * echo $id; */

PS:

为便于读者阅读源码,上述代码使用在线工具进行了格式化处理。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》、《》及《》

希望本文所述对大家PHP程序设计有所帮助。

CentOS7,MySQL主从配置和读写分离(MySQL主从、MySQL读写分离、MySQL分布式、数据库读写分离、主从配置)(亲测)

CentOS7,MySQL主从配置和读写分离(MySQL主从、MySQL读写分离、MySQL分布式、数据库读写分离、主从配置)(亲测)

一、实验目标
搭建两台MySQL服务器,一台作为主服务器,一台作为从服务器,主服务器进行写操作,从服务器进行读操作。

二、测试环境
主数据库: CentOS7, MySQL15.1 , 192.168.190.133
从数据库: CentOS7, MySQL15.1 , 192.168.190.134

三、主从配置步骤

1、确保主数据库与从数据库里的数据一样
例如:主数据库里的a的数据库里有b,c,d表,那从数据库里的就应该有一个模子刻出来的a的数据库和b,c,d表
我这里在两台MySQL上都创建了个名为“test”的数据库来测试,如图:

2、在主数据库里创建一个同步账号

1)每个从数据库会使用一个MySQL账号来连接主数据库,所以我们要在主数据库里创建一个账号,并且该账号要授予 REPLICATION SLAVE 权限,你可以为每个从数据库分别创建账号,当然也可以用同一个!)

2)你可以用原来的账号不一定要新创账号,但你应该注意,这个账号和密码会被明文存放在master.info文件中,因此建议单独创一个只拥有相关权限的账号,以减少对其它账号的危害!)

3)创建新账号使用“CREATE USER”,给账号授权使用“GRANT”命令,如果你仅仅为了主从复制创建账号,只需要授予REPLICATION SLAVE权限。

4)下面来创建一个账号,账号名:repl,密码:repl123,只允许192.168.190.的IP段登录,如下:

    mysql> CREATE USER ''repl''@''192.168.190.%'' IDENTIFIED BY ''repl123'';
    mysql> GRANT REPLICATION SLAVE ON *.* TO ''repl''@''192.168.190.%'';

5)如果开发防火墙,可能要配置下端口,如下:

    firewall-cmd --zone=public --add-port=3306/tcp --permanent
    firewall-cmd --reload

3、配置主数据库

1)要主数据库,你必须要启用二进制日志(binary logging),并且创建一个唯一的Server ID,这步骤可能要重启MySQL。
2)主服务器发送变更记录到从服务器依赖的是二进制日志,如果没启用二进制日志,复制操作不能实现(主库复制到从库)。
3)复制组中的每台服务器都要配置唯一的Server ID,取值范围是1到(232)−1,你自己决定取值。
4)配置二进制日志和Server ID,你需要关闭MySQL和编辑my.cnf或者my.ini文件,在 [mysqld] 节点下添加配置。
5)下面是启用二进制日志,日志文件名以“mysql-bin”作为前缀,Server ID配置为1,如下:

    [mysqld]
    log-bin=mysql-bin
    server-id=1
    #网络上还有如下配置
    #binlog-do-db=mstest //要同步的mstest数据库,要同步多个数据库,就多加几个replicate-db-db=数据库名 #binlog-ignore-db=mysql //要忽略的数据库

提示1:如果你不配置server-id或者配置值为0,那么主服务器将拒绝所有从服务器的连接。
提示2:在使用InnoDB的事务复制,为了尽可能持久和数据一致,你应该在my.cnf里配置innodb_flush_log_at_trx_commit=1 和 sync_binlog=1;
For the greatest possible durability and consistency in a replication setup using InnoDB with transactions, you should useinnodb_flush_log_at_trx_commit=1 and sync_binlog=1 in the master my.cnf file.
提示3:确保主服务器里的skip-networking选项未启用,如果网络被禁用,你的从服务器将不能与主服务器通信并且复制失败。

注意:
实际操作发现 /etc/my.cnf文件和教材说的不一样,可能我装的是MariaDB,如下:

目测文件被放到了 /etc/my.cnf.d 目录里,如下:

在 /etc/my.cnf.d/server.cnf 增加相关配置,如下

 

重启mariadb,如图:

查看主服务器状态,mysql> show master status;, 如图:

(注意:记录好File和Position,后面要用)


4、配置从数据库

1)从服务器,同理,要分配一个唯一的Server ID,需要关闭MySQL,修改好后再重启,如下:

    [mysqld]
    server-id=2
    #可以指定要复制的库
    replicate-do-db = test #在master端不指定binlog-do-db,在slave端用replication-do-db来过滤
    replicate-ignore-db = mysql #忽略的库
    #网上还有下面配置
    #relay-log=mysqld-relay-bin

提示1:如果有多个从服务器,每个服务器的server-id不能重复,跟IP一样是唯一标识,如果你没设置server-id或者设置为0,则从服务器不会连接到主服务器。
提示2:一般你不需要在从服务器上启用二进制日志,如果你在从服务器上启用二进制日志,那你可用它来做数据备份和崩溃恢复,或者做更复杂的事情(比如这个从服务器用来当作其它从服务器的主服务器)

 

这是主服务器192.168.190.133

副服务器192.168.190.134配置, MASTER_LOG_FILE=''mysql-bin.000003'', MASTER_LOG_POS=245;这个两个参数一定要对应主机的

5、测试数据同步
 
测试,连接主服务器 192.168.190.133,添加了表 t_dnat,
CREATE TABLE `t_dnat` (
`id` int ( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT,
`sourceAddress` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''来源地址'' ,
`sourceNetmask` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''来源掩码位数'' ,
`sourceAddresstype` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''来源地址类型,1:单ip,2:ip段'' ,
`targetAddress` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''目的地址'' ,
`targetNetmask` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''目的掩码位数'' ,
`targetPort` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''目的端口'' ,
`targetAddresstype` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''目的地址类型,1:单ip,2:ip段'' ,
`nicName` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''网卡'' ,
`targetIpConverTo` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''目的的地址转换为'' ,
`targetPortConverTo` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''目的地址转换端口'' ,
`sort` int ( 11 ) NOT NULL COMMENT ''排序'' ,
`isLog` tinyint ( 2 ) NULL DEFAULT 1 COMMENT ''是否记录日志,0否,1是'' ,
`status` tinyint ( 2 ) NULL DEFAULT NULL COMMENT ''状态:1:启用 0:不启用'' ,
`dnatName` varchar ( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ''名称'' ,
PRIMARY KEY ( `id` ) USING BTREE,
UNIQUE INDEX `sort` ( `sort` ) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic ;
 
-- ----------------------------
-- Records of t_dnat
-- ----------------------------
INSERT INTO `t_dnat` VALUES ( 5 , ''172.168.2.8'' , ''25'' , ''1'' , ''172.168.2.188'' , ''26'' , ''80'' , ''1'' , '''' , ''192.168.2.105'' , ''80'' , 2 , 1 , 1 , ''test1'' );
INSERT INTO `t_dnat` VALUES ( 6 , ''172.168.2.100'' , ''172.168.2.200'' , ''2'' , ''192.168.2.100'' , ''192.168.2.200'' , ''80'' , ''2'' , '''' , ''172.16.2.105'' , ''80'' , 3 , 1 , 1 , ''test2'' );
INSERT INTO `t_dnat` VALUES ( 13 , '''' , '''' , ''1'' , ''192.168.1.56'' , ''24'' , ''80'' , ''1'' , '''' , ''192.168.1.57'' , ''80'' , 1 , 0 , 1 , ''test201710131516'' );
 
SET FOREIGN_KEY_CHECKS = 1 ;
 
然后再连接上 192.168.190.134,发现也自己同步创建了表 t_dnat,如图:
 
至此,主从的配置已经完成了, 目前是在从库里面配置复制“test”这个库,
如果要添加其它库,可以在主服务器中添加“binlog-do-db”配置,或者在从服务器中添加“replicate-do-db”配置。

django+centos+mariadb读写分离完美实现(上)-mysql主从备份实现

django+centos+mariadb读写分离完美实现(上)-mysql主从备份实现

首先画图一张,用来展示今天要做的事情,读写分离,个人理解就是使用mysql主从备份的原理,让两个数据库同时为自己提供服务。其中主库负责数据保存,从库负责数据展示,可以一主一从,也可以一主多从。从而降低数据库同时处理读写的压力。

 1、环境如下

         master 10.10.101.83

         slave 10.10.101.184

        

 2、接着搭建数据库备份,使用的是centos7.4+mariadb

  2-1-两台服务器安装Mariadb数据库

  (ps:mariadb是免费版的mysql,操作很相似,注意,两台服务器都安装)

  yum install mariadb mariadb-server -y

        

        2-2-两台服务器启动mariadb服务

        systemctl start mariadb

   

         mariadb默认处于一种类似调试模式的模式当中,不用密码也可以登录,所以现在两台服务器的mariadb要使用工作模式

         mysql_secure_installation

         

    

         

         

         

        master端操作

  进行授权

        grant replication slave on *.* to "root"@"%" identified by "123" with grant option;

   

   刷新授权表

        flush privileges;

   

   创建要备份的数据库和表

          

    导出数据库

         mysqldump -h localhost -u root -p123 qshop > qshop.sql

         

         通过scp命令将qshop.sql传递到slave上

         scp qshop.sql root@10.10.101.184:/opt/ 

   

   slave端操作

         客户端创建要备份的qshop

     

         导入传递过来时qshop数据库

    

    查看效果

   

   开始备份

  关闭两台服务器的防火墙和selinux

   

      

    修改配置文件 

    master 

    

         

            保存,退出,重启mysql服务 

             

    slave

    

            

            保存,退出,重启mysql服务

   

    查看master端状态

   

      slave端进行编写备份命令

    change master to master_host="10.10.101.83",master_user="root",master_password="123",master_log_file="mysql-bin?.000004",master_log_pos=245;

    

    启动备份

    

    查看备份状态

   

    测试备份

     salve

     

          master端插入

     

      slave端已经同步可以查询

     

 

Linux 使用Mycat实现读写分离(基于Mysql的读写分离)

Linux 使用Mycat实现读写分离(基于Mysql的读写分离)


各位同学大家好,今天给大家分享一下用Mycat进行数据库的读写分离,本篇文章是基于上一篇的mysql主从复制。Linux上实现Mysql的主从复制(为Mycat读写分离作准备)
在上一篇文章中,我们在两个服务器使用同版本的操作系统和mysql:
服务器1:centos7.3,mysql5.6
服务器2:centos7.3,mysql5.6
接下来,我们来看一下实现读写分离的方法和优缺点。


顾名思义,读写分离基本的原理是让主数据库处理事务性增、改、删操作,而从数据库处理查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
这里写图片描述

实现方式有很多,但是不外乎分为内部配置和使用中间件,下面列举几个常用的方法:
1.:增加,删除,修改操作访问对应数据,查询访问对应数据,不同数据库做好的数据一致性的处理。由于此方法相对易懂,简单,不做过多介绍。
2. :此方案通过Spring的AOP,AspactJ来实现动态织入,通过编程继承实现Spring中的AbstractRoutingDataSource,来实现数据库访问的动态切换,不仅可以方便扩展,不影响现有程序,而且对于此功能的增删也比较容易。
3. :使用mycat提供的读写分离功能,mycat连接多个数据库,数据源只需要连接mycat,对于开发人员而言他还是连接了一个数据库(实际是mysql的mycat中间件),而且也不需要根据不同业务来选择不同的库,这样就不会有多余的代码产生。


每个方法都有优缺点,我们选择对程序代码改动最小(只改数据源)的方法三,讲解mycat的配置和使用。

这里写图片描述
按Esc,输入:wq保存退出

这里写图片描述

好了,mycat启动成功,我们来看一下读写分离的配置和mycat的连接配置!

根目录
这里写图片描述
进到conf文件夹里面查看配置文件:
这里写图片描述

以下是两种配置方式和配置说明
1. 提供一个数据库内所有表的权限:
这里写图片描述
2. 只显示一个数据库的指定表:
这里写图片描述

这样对于数据库的读写信息就配置完成了;一般刚开始做,先使用第一种方法。
这里写图片描述


设置端口和mycat连接信息
这里写图片描述
这里写图片描述

 

balance指的负载均衡类型,目前的取值有4种:
1. balance=”0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
2. balance=”1”,全部的readHost与stand bywriteHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
3. balance=”2”,所有读操作都随机的在writeHost、readhost上分发。
4. balance=”3”,所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
注意:balance=3只在1.4及其以后版本有,1.3没有。


writeType属性:
1.writeType=”0”,所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后以切换后的为准,切换记录在配置文件中:dnindex.properties.
2.writeType=”1”,所有写操作都随机地发送到配置的writeHost,1.5以后废弃不推荐出国英语学习


switchType指的是切换的模式,目前的取值也有4种:
1. switchType=’-1’ 表示不自动切换
2. switchType=’1’ 默认值,表示自动切换
3. switchType=’2’ 基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status
4. switchType=’3’基于MySQLgalary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like ‘wsrep%’。


注意:估计Mycat1.4才开始支持switchType。1.3版本配置该属性的话,日志里会报错:org.xml.sax.SAXParseException;lineNumber: 61; columnNumber: 86; Attribute “switchType” must bedeclared for element type “dataHost”。
MyCAT心跳检查询句配置为 show slave status ,dataHost 上定义两个新属性: switchType=”2” 与slaveThreshold=”100”,此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制,Mycat心跳机制通过检测 show slave status 中的 “Seconds_Behind_Master”,”Slave_IO_Running”,”Slave_SQL_Running”三个字段来确定当前主从同步的状态及Seconds_Behind_Master主从复制时延,当Seconds_Behind_Master>slaveThreshold时,读写分离筛选器会过滤掉此Slave机器,防止读到很久以前的旧数据,当主节点宕机后,切换逻辑会检查Slave上的Seconds_Behind_Master是否为0,为0时则表示主仅同步,可安全切换,否则不会切换。


Mycat的配置到这里就算完成了,现在我们重启Mycat并连接测试

测试连接:
这里写图片描述
项目开发中,我们只需要将mysql的连接地址换成mycat的地址即可,无需任何其余操作,更不会造成多余的业务逻辑,好了,mycat的简单配置和使用就介绍到这里了!

mysql Proxy读写分离配置与php mysql读写分离类

mysql Proxy读写分离配置与php mysql读写分离类

  1. mysql-proxy \
  2. –proxy-backend-addresses=narcissus:3306 \
  3. –proxy-backend-addresses=nostromo:3306
复制代码

3、数据库读写分离,192.168.18.110负责写入,192.168.18.107负责读取数据,当然也可以再增加读取数据的服务器。

  1. mysql-proxy \
  2. –proxy-backend-addresses=192.168.18.110:3306 \
  3. –proxy-read-only-backend-addresses=192.168.18.107:3306
复制代码

这种方式并不是读写分离。 mysql-proxy不能区分哪些是发往从服务器的,还需要自己用脚本控制,见第四种方式。

4、 Lua 脚本能很好的控制连接和分布, 以及查询及返回的结果集. 使用Lua脚本时,必须使用 –proxy-lua-script 指定脚本的名称。 直到产生连接时才会读取脚本,也就是修改脚本后不用重新启动服务。 mysql-proxy –proxy-lua-script=rw-splitting.lua –proxy-backend-addresses=192.168.18.110:3306 –proxy-read-only-backend-addresses=192.168.18.107:3306

注意问题: 1、proxy的读写分离机制是先把最初的几条查询发到master上建立连接, 当发送到master上的查询数超过连接池的最小值时开始把查询

2、LAST_INSERT_ID不能发送到主服务器上, 226 行修改为下面的就可以了 elseif not is_insert_id and token.token_name == “TK_FUNCTION” then

3、使用默认的rw-splitting.lua时,会提示找不到proxy-command,我把mysql-proxy的路径设置为系统路径,然后在 share目录下运行就一切Ok了,在运行中输入cmd,然 后cd C:\tools\mysql-proxy\share。

4、字符乱码 通过proxy连上数据库之后,查到的字符串始终是乱码,即便手工执行了set names ‘utf8′也没有效果。 解决办法,mysql server必须设置

  1. class mysql_rw_php {
  2. //查询个数
  3. var $querynum = 0;
  4. //当前操作的数据库连接
  5. var $link = null;
  6. //字符集
  7. var $charset;
  8. //当前数据库
  9. var $cur_db = '''';
  10. //是否存在有效的只读数据库连接
  11. var $ro_exist = false;
  12. //只读数据库连接
  13. var $link_ro = null;
  14. //读写数据库连接
  15. var $link_rw = null;
  16. function mysql_rw_php(){
  17. }
  18. function connect($dbhost, $dbuser, $dbpw, $dbname = '''', $pconnect = 0, $halt = TRUE) {
  19. if($pconnect) {
  20. if(!$this->link = @mysql_pconnect($dbhost, $dbuser, $dbpw)) {
  21. $halt && $this->halt(''Can not connect to MySQL server'');
  22. }
  23. } else {
  24. if(!$this->link = @mysql_connect($dbhost, $dbuser, $dbpw)) {
  25. $halt && $this->halt(''Can not connect to MySQL server'');
  26. }
  27. }
  28. //只读连接失败
  29. if(!$this->link && !$halt) return false;
  30. //未初始化rw时,第一个连接作为rw
  31. if($this->link_rw == null)
  32. $this->link_rw = $this->link;
  33. if($this->version() > ''4.1'') {
  34. if($this->charset) {
  35. @mysql_query("SET character_set_connection=$this->charset, character_set_results=$this->charset, character_set_client=binary", $this->link);
  36. }
  37. if($this->version() > ''5.0.1'') {
  38. @mysql_query("SET sql_mode=''''", $this->link);
  39. }
  40. }
  41. if($dbname) {
  42. $this->select_db($dbname);
  43. }
  44. }
  45. //连接一个只读的mysql数据库
  46. function connect_ro($dbhost, $dbuser, $dbpw, $dbname = '''', $pconnect = 0){
  47. if($this->link_rw == null)
  48. $this->link_rw = $this->link;
  49. $this->link = null;
  50. //不产生halt错误
  51. $this->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, false);
  52. if($this->link){
  53. //连接成功
  54. //echo "link ro sussess!
    ";
  55. $this->ro_exist = true;
  56. $this->link_ro = $this->link;
  57. if($this->cur_db){
  58. //如果已经选择过数据库则需要操作一次
  59. @mysql_select_db($this->cur_db, $this->link_ro);
  60. }
  61. }else{
  62. //连接失败
  63. //echo "link ro failed!
    ";
  64. $this->link = &$this->link_rw;
  65. }
  66. }
  67. //设置一系列只读数据库并且连接其中一个
  68. function set_ro_list($ro_list){
  69. if(is_array($ro_list)){
  70. //随机选择其中一个
  71. $link_ro = $ro_list[array_rand($ro_list)];
  72. $this->connect_ro($link_ro[''dbhost''], $link_ro[''dbuser''], $link_ro[''dbpw'']);
  73. }
  74. }
  75. function select_db($dbname) {
  76. //同时操作两个数据库连接
  77. $this->cur_db = $dbname;
  78. if($this->ro_exist){
  79. @mysql_select_db($dbname, $this->link_ro);
  80. }
  81. return @mysql_select_db($dbname, $this->link_rw);
  82. }
  83. function fetch_array($query, $result_type = MYSQL_ASSOC) {
  84. return mysql_fetch_array($query, $result_type);
  85. }
  86. function fetch_one_array($sql, $type = '''') {
  87. $qr = $this->query($sql, $type);
  88. return $this->fetch_array($qr);
  89. }
  90. function query($sql, $type = '''') {
  91. $this->link = &$this->link_rw;
  92. //判断是否select语句
  93. if($this->ro_exist && preg_match ("/^(\s*)select/i", $sql)){
  94. $this->link = &$this->link_ro;
  95. }
  96. $func = $type == ''UNBUFFERED'' && @function_exists(''mysql_unbuffered_query'') ?
  97. ''mysql_unbuffered_query'' : ''mysql_query'';
  98. if(!($query = $func($sql, $this->link)) && $type != ''SILENT'') {
  99. $this->halt(''MySQL Query Error'', $sql);
  100. }
  101. $this->querynum++;
  102. return $query;
  103. }
  104. function affected_rows() {
  105. return mysql_affected_rows($this->link);
  106. }
  107. function error() {
  108. return (($this->link) ? mysql_error($this->link) : mysql_error());
  109. }
  110. function errno() {
  111. return intval(($this->link) ? mysql_errno($this->link) : mysql_errno());
  112. }
  113. function result($query, $row) {
  114. $query = @mysql_result($query, $row);
  115. return $query;
  116. }
  117. function num_rows($query) {
  118. $query = mysql_num_rows($query);
  119. return $query;
  120. }
  121. function num_fields($query) {
  122. return mysql_num_fields($query);
  123. }
  124. function free_result($query) {
  125. return mysql_free_result($query);
  126. }
  127. function insert_id() {
  128. return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
  129. }
  130. function fetch_row($query) {
  131. $query = mysql_fetch_row($query);
  132. return $query;
  133. }
  134. function fetch_fields($query) {
  135. return mysql_fetch_field($query);
  136. }
  137. function version() {
  138. return mysql_get_server_info($this->link);
  139. }
  140. function close() {
  141. return mysql_close($this->link);
  142. }
  143. function halt($message = '''', $sql = '''') {
  144. $dberror = $this->error();
  145. $dberrno = $this->errno();
  146. echo "
  147. MySQL Error
  148. Message: $message
  149. SQL: $sql
  150. Error: $dberror
  151. Errno.: $dberrno
";
  • exit();
  • }
  • }
  • ?>
  • 复制代码

    调用示例:

    1. /****************************************
    2. *** mysql-rw-php version 0.1
    3. *** http://bbs.it-home.org
    4. *** http://code.google.com/p/mysql-rw-php/
    5. *** code modify from class_mysql.php (uchome)
    6. ****************************************/
    7. require_once(''mysql_rw_php.class.php'');
    8. //rw info
    9. $db_rw = array(
    10. ''dbhost''=>''bbs.it-home.org'',
    11. ''dbuser''=>''jbxue'',
    12. ''dbpw''=>''bbs.it-home.org'',
    13. ''dbname''=>''test''
    14. );
    15. $db_ro = array(
    16. array(
    17. ''dbhost''=>''bbs.it-home.org:4306'',
    18. ''dbuser''=>''jbxue'',
    19. ''dbpw''=>''bbs.it-home.org''
    20. )
    21. );
    22. $DB = new mysql_rw_php;
    23. //connect Master
    24. $DB->connect($db_rw[dbhost], $db_rw[dbuser], $db_rw[dbpw], $db_rw[dbname]);
    25. //Method 1: connect one server
    26. $DB->connect_ro($db_ro[0][dbhost], $db_ro[0][dbuser], $db_ro[0][dbpw]);
    27. //Method 2: connect one server from a list by rand
    28. $DB->set_ro_list($db_ro);
    29. //send to rw
    30. $sql = "insert into a set a=''test''";
    31. $DB->query($sql);
    32. //send to ro
    33. $sql = "select * from a";
    34. $qr = $DB->query($sql);
    35. while($row = $DB->fetch_array($qr)){
    36. echo $row[a];
    37. }
    38. ?>
    复制代码


    今天的关于php实现的mysqldb读写分离操作类示例php mysql读写分离实现的分享已经结束,谢谢您的关注,如果想了解更多关于CentOS7,MySQL主从配置和读写分离(MySQL主从、MySQL读写分离、MySQL分布式、数据库读写分离、主从配置)(亲测)、django+centos+mariadb读写分离完美实现(上)-mysql主从备份实现、Linux 使用Mycat实现读写分离(基于Mysql的读写分离)、mysql Proxy读写分离配置与php mysql读写分离类的相关知识,请在本站进行查询。

    本文标签:

    上一篇php实现的读取CSV文件函数示例(php 读取csv文件)

    下一篇PHP验证终端类型是否为手机的简单实例(php验证终端类型是否为手机的简单实例设置)