GVKun编程网logo

SQL Server AlwaysOn读写分离配置图文教程(sqlserver读写分离方案)

18

本文将介绍SQLServerAlwaysOn读写分离配置图文教程的详细情况,特别是关于sqlserver读写分离方案的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时

本文将介绍SQL Server AlwaysOn读写分离配置图文教程的详细情况,特别是关于sqlserver读写分离方案的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于AlwaysOn 进阶 Level 1:What is "SQL Server AlwaysOn"?、Mysql 5.5 主从/读写分离配置、mysql Proxy读写分离配置与php mysql读写分离类、Mysql Router 读写分离配置的知识。

本文目录一览:

SQL Server AlwaysOn读写分离配置图文教程(sqlserver读写分离方案)

SQL Server AlwaysOn读写分离配置图文教程(sqlserver读写分离方案)

概述

Alwayson相对于数据库镜像最大的优势就是可读副本,带来可读副本的同时还添加了一个新的功能就是配置只读路由实现读写分离;当然这里的读写分离稍微夸张了一点,只能称之为半读写分离吧!看接下来的文章就知道为什么称之为半读写分离。

sqlServer2014

配置可用性组

可用性副本概念辅助角色支持的连接访问类型

1.无连接


不允许任何用户连接。 辅助数据库不可用于读访问。 这是辅助角色中的默认行为。

2.仅读意向连接


辅助数据库仅接受ApplicationIntent=ReadOnly的连接,其它的连接方式无法连接。

3.允许任何只读连接


辅助数据库全部可用于读访问连接。 此选项允许较低版本的客户端进行连接。

主角色支持的连接访问类型

1.允许所有连接


主数据库同时允许读写连接和只读连接。 这是主角色的默认行为。

2.仅允许读/写连接

允许ApplicationIntent=ReadWrite或未设置连接条件的连接。 不允许ApplicationIntent=ReadOnly的连接。 仅允许读写连接可帮助防止客户错误地将读意向工作负荷连接到主副本。

配置语句

rush:sql;"> ---查询可用性副本信息 SELECT * FROM master.sys.availability_replicas ---建立read指针 - 在当前的primary上为每个副本建立副本对于的tcp连接 ALTER AVAILABILITY GROUP [Alwayson22] MODIFY REPLICA ON N'db01' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://db01.ag.com:1433')) ALTER AVAILABILITY GROUP [Alwayson22] MODIFY REPLICA ON N'db02' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://db02.ag.com:1433')) ALTER AVAILABILITY GROUP [Alwayson22] MODIFY REPLICA ON N'db03' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://db03.ag.com:1433')) ----为每个可能的primary role配置对应的只读路由副本 --list列表有优先级关系,排在前面的具有更高的优先级,当db02正常时只读路由只能到db02,如果db02故障了只读路由才能路由到DB03 ALTER AVAILABILITY GROUP [Alwayson22] MODIFY REPLICA ON N'db01' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('db02','db03'))); ALTER AVAILABILITY GROUP [Alwayson22] MODIFY REPLICA ON N'db02' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('db01','db03'))); --查询优先级关系 SELECT ar.replica_server_name,rl.routing_priority,( SELECT ar2.replica_server_name FROM sys.availability_read_only_routing_lists rl2 JOIN sys.availability_replicas AS ar2 ON rl2.read_only_replica_id = ar2.replica_id WHERE rl.replica_id = rl2.replica_id AND rl.routing_priority = rl2.routing_priority AND rl.read_only_replica_id = rl2.read_only_replica_id ) AS 'read_only_replica_server_name' FROM sys.availability_read_only_routing_lists rl JOIN sys.availability_replicas AS ar ON rl.replica_id = ar.replica_id

包括备份、作业等。

到此只读路由已配置完成,不要忘记在每个alwayson副本上创建登入用户。

登入方式

C#连接字符串server=侦听IP;database=;uid=;pwd=;ApplicationIntent=ReadOnly

ssms:其它连接参数

---仅意向读连接
ApplicationIntent=ReadOnly
---读写连接
ApplicationIntent=ReadWrite配置hosts

rush:sql;"> 配置使用监听ip进行连接192.168.1.22 db01.ag.com 192.168.1.23 db02.ag.com192.168.1.24 db03.ag.com--配置使用hostname进行连接192.168.1.22 db01192.168.1.23 db02192.168.1.24 db03

数据库服务器端不需要配置此项!!!

连接测试

1.ReadOnly

可以看到使用ApplicationIntent=ReadOnly连接属性正确的连接到了只读副本DB02上。ApplicationIntent=ReadWrite同理。

20170714补充

sqlServer2016支持多个只读副本负载分担只读操作,只读路由列表修改如下:

rush:sql;"> ALTER AVAILABILITY GROUP [Alwayson21] MODIFY REPLICA ON N'HD21DB01' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=(('HD21DB02','HD21DB03','HD21DB04'),'HD21DB01'))); ALTER AVAILABILITY GROUP [Alwayson21] MODIFY REPLICA ON N'HD21DB02' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=(('HD21DB01','HD21DB02')));

当HD21DB01作为主节点时,HD21DB02,HD21DB03,HD21DB04平均分摊读的压力,当HD21DB02,HD21DB04都无法访问时读连接访问HD21DB01;演示如下:

概述

从上面我们可以看到只读路由的读写分离是通过连接属性ApplicationIntent=ReadOnly\ReadWrite使得连接是连向主副本还是辅助副本,这意味着需要在应用端配置多个连接串手动的配置代码是走写还是只读。这也就是为什么一开始我说这是半读写分离的原因。还有一个缺陷就是虽然配置了两个只读副本,但是每次只有优先级高的那个只读副本能提供只读连接,只有当优先级高的那个只读副本故障了才能路由到下一个只读副本。这也就意味着当前只有2个副本在提供读写操作,多个只读副本之间不能做到同时提供读操作的负载均衡。

总结

以上所述是小编给大家介绍的sql Server AlwaysOn读写分离配置,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小编网站的支持!

AlwaysOn 进阶 Level 1:What is

AlwaysOn 进阶 Level 1:What is "SQL Server AlwaysOn"?

By Perry Whittle,2016/02/24(首次发布:2014/09/24)

关于系列

本文属于进阶系列:Stairway to AlwaysOn

AlwaysOn是一套复杂的技术,往往被误解。在这个阶梯中,您将学习AlwaysOn技术,它们如何适应高可用性堆栈,以及如何充分利用它们。

欢迎来到“SQL Server AlwaysOn的阶梯”系列的第一个级别。在这篇1级文章中,我们将发现“AlwaysOn”,“故障转移群集实例”(FCI)和“Windows Server故障转移群集”技术。我们将详细介绍每个细节并总结它们所在的高可用性堆栈的位置。这将为我们提供一个良好的基础,这对上升的楼梯水平是必不可少的。较高级别的楼梯将研究AlwaysOn可用性组和FCI使用的所需基础架构和不同的存储要求和选项。

在每个楼梯层次之后,您将进一步了解AlwaysOn结构如何构建。尽管作为DBA,您可能没有与AlwaysOn和FCI下面的核心基础设施项目进行任何直接交互,但是有助于全面了解所有技术如何集成。最后的楼梯将导致一个功能AlwaysOn配置。

我们首先要看基础知识,其中包括对已经提到的3种技术的简要描述。

AlwaysOn描述中使用了许多首字母缩写词和缩写词。本文结尾处包含了一个常用术语表。

不用多说,让我们深入了解每种技术。

Windows服务器故障转移群集

Windows Server故障转移群集(WSFC)是位于所有Microsoft高可用性应用程序下的核心高可用性(HA)产品。 WSFC是Windows Server操作系统软件套件的一部分。在创建SQL Server的故障转移群集实例,AlwaysOn高可用性组或甚至Microsoft Exchange邮件服务器群集之前,您需要部署和配置WSFC。

Windows Server故障转移群集提供了将多个计算机节点(物理和/或虚拟)组合起来为一组应用程序提供高可用性的能力。应用程序是服务器软件,如SQL Server或Exchange,我们希望能够在任何节点上运行。通过向客户端呈现包括唯一IP地址和唯一计算机名称或“虚拟网络名称”的虚拟接入点来使应用高度可用。此地址和虚拟名称成为应用程序组中的资源,并在参与节点(如令牌)之间传递。活动计算机节点的严重硬件故障将导致在该节点上运行的组服务的丢失。群集服务将根据故障类型(硬件或软件)自动尝试重新启动当前节点或伙伴节点上的组。

在较高级别上,客户端访问点详细信息与任何磁盘和服务资源一起传输到故障转移伙伴节点。群集实例的故障转移会导致客户端连接断开;一旦服务在另一个节点上可用,则客户端可以重新连接。常见的故障通常是其中之一,但是应用程序的任何故障都可能导致服务移动到另一个节点:

使用WSFC时,群集应用程序被安装到单独的组或“应用程序”中,其中包含一组资源,如磁盘,服务,IP地址等。组及其资源在任何时候都由单个节点拥有,而除非有计划的交换机或故障转移到该节点,否则不能从任何其他伙伴节点访问资源。

下面显示了Windows Server故障转移群集的典型视图。群集节点全部通过网络连接,域控制器和DNS服务与WSFC一起工作,以允许客户端连接到虚拟IP或虚拟网络名称,无论服务在哪个节点上运行。


为了部署FCI,计算机节点必须使用共享存储,这些存储通常从SAN出现给每个节点。为了部署一个典型的AlwaysOn组,节点利用自己的本地存储,而不是与其他集群伙伴共享。

尽管群集节点可能具有不同的硬件,但通常最好将节点间的硬件保持一致,以避免功能较弱的节点无法处理超出其功能的负载。但是,节点必须使用相同的操作系统补丁级别和网络配置;在部署Windows Server故障转移群集之前验证您的配置时,这将变得清晰。 Windows Server版本(Windows 2003中的8个节点,Windows 2008中的16个节点和Windows 2012中的64个节点)的最大群集节点数量不同。

部署强大的Windows Server故障转移群集需要仔细的设计,支持的硬件和相应版本的Windows Server操作系统。地理分散的集群(跨多个WAN的集群)进一步增加了所需的设计和规划的数量,并显着增加了成本。

知道WSFC仅提供故障转移伙伴功能很重要。应用程序在节点之间没有负载平衡或扩展。每个服务都运行在一个且只有一个节点上。

通常,在大型多节点群集中,您可以在Windows Server故障转移群集节点的子集上安装群集应用程序。在所有节点上安装应用程序的错误都可能导致一些不希望的故障转移,我们将在后面看到,也违反了AlwaysOn组限制策略,这可以确保所有AlwaysOn实例驻留在集群中的不同节点上。

WSFC需要某种形式的中介来控制群集资源所有权。此仲裁以Cluster Quorum的形式提供。自Windows 2003 SP1以来,此Quorum采用节点投票系统的形式,维持Quorum所需的多数选票。您还可以使用磁盘形式的其他仲裁资源进行本地化群集,也可以使用多站点群集的远程文件共享。从Windows Server 2012开始,法定人数使用动态节点权重配置在计划中断期间动态平衡群集投票,以防止不必要的故障转移。我们将在未来的层面更详细地讨论法定人数。

故障转移群集实例

SQL Server的故障转移群集实例一直是SQL Server产品中流行的高可用性技术。 SQL Server高度可用的实例是集群化的,以减轻任何节点硬件故障和任何潜在的软件故障。 这里唯一的薄弱环节是存储; 存储子系统成为单点故障。

故障转移群集实例是默认或命名的SQL Server实例,已作为群集应用程序安装到WSFC上。 群集应用程序通常具有以下资源:

独立实例共享相同的基本要求,不同之处在于,使用独立实例时,IP地址和网络名称将从计算机节点本身获取,而磁盘存储由计算机的本地磁盘资源提供。

参考上面的图,我们看到了具有单个FCI的2节点集群的典型视图。 SQL Server的群集实例将使用已呈现给WSFC节点的任何共享存储。通常这种存储将采取从SAN提供的LUN的形式。 SQL Server的FCI部署在一个两步的过程中,这个过程将在稍后的阶梯中介绍。现在,下面是部署SQL Server的故障转移群集实例的两步过程的基本概述:

  1. 在将参与FCI的第一个计算机节点上启动“新建SQL Server故障转移群集安装”向导。一旦完成并成功完成,您就可以进入第二阶段了。
  2. 在希望加入新的SQL Server FCI的WSFC中的任何计算机节点上启动“将节点添加到SQL Server故障转移群集”向导。

注意:尽管标准版将FCI限制为2个节点,但并不指定有多少节点具有Windows群集的成员资格(您可能有任何数字,直到操作系统的最大值)。该限制是在SQL Server安装程序级别执行的。

FCI有点像一个跑道接力队的传球过程;计算机节点拥有群集的SQL Server应用程序及其资源,然后为客户端提供对SQL Server服务(持有接力棒)的访问权限。当活动的计算机节点失败(下落接力棒)时,合作伙伴节点进入并获得集群应用程序及其资源的所有权(接上接力棒)。

AlwaysOn可用性组

多年来,故障转移群集一直是为SQL Server提供高可用性的主要方法。当一个节点失败时,另一个节点接管向客户端提供SQL Server服务。 AlwaysOn与Windows Server故障转移群集技术集成,提供更具弹性的高可用性平台。

尽管群集在实例级别上工作,但AlwaysOn在数据库级别配置。 AlwaysOn可用性组是SQL Server 2012中引入的新技术,用于将预定义的数据库组复制到AlwaysOn中已知的一组只读伙伴实例或副本。多个节点各自托管一个AlwaysOn数据库的同步副本,并且最好通过监听器的配置来提供访问(稍后会详细介绍)。

AlwaysOn可用性组需要一个或多个辅助副本来托管高可用性数据库的副本。这些辅助数据库可能是可读或不可读的。它们也可以以异步或同步的方式进行更新。异步副本仅支持手动强制故障转移,而同步副本支持自动或手动故障转移。

次要只读副本可以配置为响应只读查询,您也可以将目标的次要目标作为备份/维护操作以减轻主数据库的压力。这种主从关系也是可逆的,以确保真正的高可用性。任何经过适当配置的只读伙伴在系统发生故障时都可能承担主角色。

AlwaysOn依靠WSFC核心功能实现AO提供的高可用性,但不需要与FCI相关的以下任何共享资源。

这个共享资源规则有一个例外。创建AlwaysOn组侦听器时,将创建将由AO组副本共享的IP地址和网络名称资源。

正如我们所发现的,故障转移群集实例链中的薄弱环节是共享存储。这里有很多方法可以实现冗余,但是通常成本很高,而且安装和维护通常很困难。当然,如前所述,故障转移群集实例只能缓解服务器硬件。它不提供单个或甚至多个辅助数据库。我们在SQL Server 2012之前的SQL Server版本中有数据库镜像,但这些仅为单个不可读的辅助数据库提供了范围。

AlwaysOn仍然使用熟悉的SQL Server端点作为实例通信。端点在使用可用性组部署向导时自动配置。向导驱动的部署提供了最简单的部署路径,而手动部署需要大量的手动交互。尽管如此,一个基本的AlwaysOn组配置仍然非常容易部署和配置,并提供以前不可用的HA级别,而无需采用复杂的功能集成级别。

您也可以创建一个高可用的侦听器服务,您将使用该服务来接受到可用性组的传入连接。监听器由一个唯一的IP地址和一个唯一的虚拟网络名称组成。这是使组内数据库高度可用的最重大变化之一。

在创建AlwaysOn可用性组期间,将在Windows Server故障转移群集内创建一个群集角色,并包含一个资源。此资源在AlwaysOn组故障转移期间在伙伴节点之间进行故障转移,并标识AlwaysOn组的主副本。

AlwaysOn听众

监听程序在配置时将作为资源创建,并驻留在AlwaysOn可用性组的故障转移群集应用程序角色中。资源是:

侦听器使用TCP端口来接受传入的连接,并默认连接到主副本。当只读路由已配置时,指向只读意向连接的监听程序的连接将被路由到辅助伙伴而不是主要副本。这是我们可以减轻主副本负载的另一种方式。

在AlwaysOn组的故障转移期间,群集中的节点之间的群集应用程序及其资源将发生故障转移。群集应用程序的节点位置跟​​踪主副本及其底层节点,并根据需要在群集中移动。在主副本是SQL Server的群集实例的情况下,侦听器由该FCI 副本的主动节点拥有。

结论

这就是阶梯1的结尾,它提供了3个核心技术的快速介绍,用来使我们的SQL Server实例及其对象高度可用。 在我们的高可用性堆栈中,我们将WSFC作为基本级别,这是安装FCI或AlwaysOn可用性组的主要要求。 接下来,我们有了位于WSFC顶部的FCI,它依靠群集来服务和保护SQL Server实例。 最后,我们有AlwaysOn组,坐在SQL Server的独立实例和SQL Server的“故障转移群集实例”之上。

在2级中,我们将查看SQL Server High Availability中可用的存储类型及其典型用法。 这将帮助您了解系列中未来的阶梯级别。

词汇表

AO AlwaysOn可用性组
FCI SQL Server的故障转移群集实例
TCPIP 传输控制协议/互联网协议。 Microsoft客户端网络使用的网络协议
OS / NOS 网络操作系统
WSFC Windows Server故障转移群集
LAN 局域网
WAN 广域网
DNS 域名系统
DHCP 动态主机配置协议,自动为网络计算机分配IP地址
IP Address 32位(IPV4),分配给计算机对象的唯一地址
AD Active Directory,目录服务。 用于Windows域中的对象管理的Microsoft技术
DR 灾难恢复
SPF 单点故障
SCSI 小型计算机系统接口
iSCSI Internet小型计算机系统接口
FC 光纤通道
Replica SQL Server AlwaysOn可用性组中使用的术语引用作为特定AlwaysOn组的一部分的SQL Server实例

Mysql 5.5 主从/读写分离配置

Mysql 5.5 主从/读写分离配置

数据库配置

主数据库:172.20.17.211
从数据库:172.20.17.210

一、创建主/从数据同步账户( 主从两台数据库都要执行 )

# 开启远程访问支持
/usr/local/mysql/bin/mysql -h172.20.17.211 -uroot -pwoshishui             # 登录数据库
update mysql.user set Host=''%'' where User=''root'' and Host=''localhost'';    # 开启Mysql远程访问支持
select Host,User,Password from mysql.user limit 10 \G;                    # 查看修改结果
flush privileges;                                                         # 刷新权限

# 主/从数据库添加授权账户
CREATE USER ''xzdesk''@''%'' IDENTIFIED BY ''woshishui'';                        # 创建授权账户xzdesk 密码woshishui
GRANT ALL ON *.* TO ''xzdesk''@''127.0.0.1'';                                  # 授权xzdesk用户拥有全部数据库的所有权限
GRANT ALL ON `ceshi`.* TO ''xzdesk''@''%'';                                    # 授权xzdesk用户拥有ceshi数据库的所有权限

# 第二种 授权和添加账户一起操作
# GRANT ALL ON `ceshi`.* TO ''xzdesk''@''127.0.0.1'' IDENTIFIED BY ''woshishui'';

# 撤销用户授权
REVOKE ALL ON *.* TO ''xzdesk''@''%'';                                        # 撤销xzdesk的所有授权
# REVOKE delete ON databasename.tablename FROM ''username''@''host'';         # 没搞明白撒意思,不用执行



# 创建授权用户
#insert into mysql.user(Host,User,Password) values(''172.20.17.210'',''xzdesk'',password(''woshishui''));
# 删除xzdesk用户( 授权信息无法删除 )
#DELETE FROM user WHERE User="xzdesk" and Host="%";

二、主服务器配置(172.20.17.211)

/usr/local/mysql/bin/mysql -h172.20.17.211 -uroot -pwoshishui
create database ceshi;                                                    # 创建ceshi数据库
flush tables with read lock;                                              # 数据库只读锁定命令

# 导出主服务器数据库
/usr/local/mysql/bin/mysqldump -h172.20.17.211 -uroot -pwoshishui ceshi > /data/ceshi_20160609.sql
unlock tables;                                                            # 解除锁定


# 主服务器数据导入从服务器
    # 第一种方法
    /usr/local/mysql/bin/mysql -h172.20.17.210 -uroot -pwoshishui         # 进入从服务器MySQL控制台
    create database ceshi;                # 创建数据库
    use ceshi                             # 进入数据库
    /usr/local/mysql/bin/mysql -h172.20.17.210 -uroot -pwoshishui ceshi < /data/ceshi_20160609.sql

    # 第二种方法
    /usr/local/mysql/bin/mysql -h172.20.17.210 -uroot -pwoshishui         # 进入从服务器MySQL控制台
    create database ceshi;                                                # 创建数据库
    use ceshi                                                             # 进入数据库
    source /data/ceshi_20160609.sql                                       # 导入备份文件到数据库

四、配置MySQL主服务器的my.cnf文件

vim /etc/my.cnf               # 编辑配置文件,在[mysqld]部分添加下面内容
server-id=1                   # 设置服务器id,为1表示主服务器,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
log_bin=mysql-bin             # 启动MySQ二进制日志系统,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
binlog-do-db=ceshi            # 需要同步的数据库名,如果有多个数据库,可重复此参数,每个数据库一行
binlog-ignore-db=mysql        # 不同步mysql系统数据库
binlog-ignore-db=performance_schema
binlog-ignore-db=information_schema
:wq!    #保存退出

service mysqld  restart      # 重启MySQL
mysql -u root -p             # 进入mysql控制台
show master status;          # 查看主服务器,出现以下类似信息
+------------------+----------+--------------+---------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            |
+------------------+----------+--------------+---------------------------------------------+
| mysql-bin.000006 |      575 | ceshi        | mysql,performance_schema,information_schema |
+------------------+----------+--------------+---------------------------------------------+

五、配置MySQL从服务器的my.cnf文件

vim /etc/my.cnf                       # 编辑配置文件,在[mysqld]部分添加下面内容
server-id=2                           # 配置文件中已经有一行server-id=1,修改其值为2,表示为从数据库
log-bin=mysql-bin                     # 启动MySQ二进制日志系统,注意:如果原来的配置文件中已经有这一行,就不用再添加了。
replicate-do-db=ceshi                 # 需要同步的数据库名,如果有多个数据库,可重复此参数,每个数据库一行
replicate-ignore-db=mysql             # 不同步mysql系统数据库
replicate-ignore-db=performance_schema
replicate-ignore-db=information_schema
:wq!    #保存退出

service mysqld restart               # 重启MySQL
/usr/local/mysql/bin/mysql -h172.20.17.210 -uroot -pwoshishui
slave stop;                          # 停止slave同步进程
change master to master_host=''172.20.17.211'',master_user=''xzdesk'',master_password=''woshishui'',master_log_file=''mysql-bin.000006'' ,master_log_pos=575;    #执行同步语句
slave start;                         # 开启slave同步进程
SHOW SLAVE STATUS\G                  # 查看slave同步信息,出现以下内容

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.20.17.211
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 341
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 487
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes         # 此状态必须YES
            Slave_SQL_Running: Yes         # 此状态必须YES
              Replicate_Do_DB: ceshi
          Replicate_Ignore_DB: mysql,performance_schema,information_schema

注意:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)。
注意:MySQL 5.1.7版本之后,已经不支持把master配置属性写入my.cnf配置文件中了,只需要把同步的数据库和要忽略的数据库写入即可。

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. ?>
    复制代码


    Mysql Router 读写分离配置

    Mysql Router 读写分离配置

    1.安装

    rpm -ivh mysql-router-2.0.4-1.el6.x86_64.rpm

    2.配置

    cat >/etc/mysqlrouter/mysqlrouter.ini <<EOF
    
    [DEFAULT]
    logging_folder = /var/log/mysqlrouter/
    plugin_folder = /usr/lib64/mysqlrouter
    runtime_folder = /var/run/mysqlrouter
    config_folder = /etc/mysqlrouter
    hostname=192.168.1.201
    
    [logger]
    level = info
    
    # If no plugin is configured which starts a service, keepalive
    # will make sure MySQL Router will not immediately exit. It is
    # safe to remove once Router is configured.
    #[keepalive]
    #interval = 60
    
    [routing:read_write]
    #将router绑定到哪个NIC
    bind_address = {hostname}:7001
    #将路由的后端db列表,rw模式将采用first available模式轮训
    #ro模式采用round-robin模式轮训
    destinations = {hostname}:3306
    mode = read-write
    # default 512,like mysql''s max_connections
    max_connections = 1024
    #default 100,like mysql''s ax_connect_errors 
    max_connect_errors = 100
    #default 9,like mysql''s connect_timeout 
    client_connect_timeout = 9
    
    [routing:read_only]
    bind_address = {hostname}:7002
    destinations = {hostname}:3306,{hostname}:3307,{hostname}:3308
    mode = read-only
    max_connections = 65535
    max_connect_errors = 100
    client_connect_timeout = 9
    EOF

    3.启动

    service mysqlrouter start

    4.测试

    [root@localhost ~]# netstat -ntpl|grep mysqlrouter
    tcp        0      0 192.168.1.201:7001          0.0.0.0:*                   LISTEN      20498/mysqlrouter   
    tcp        0      0 192.168.1.201:7002          0.0.0.0:*                   LISTEN      20498/mysqlrouter 

    5.连接

    mysql -uroot -p123456 -P7002 -h192.168.1.201

     

    关于SQL Server AlwaysOn读写分离配置图文教程sqlserver读写分离方案的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于AlwaysOn 进阶 Level 1:What is "SQL Server AlwaysOn"?、Mysql 5.5 主从/读写分离配置、mysql Proxy读写分离配置与php mysql读写分离类、Mysql Router 读写分离配置的相关信息,请在本站寻找。

    本文标签:

    上一篇SQL update 多表关联更新的实现代码

    下一篇SQL Server 2016 Alwayson新增功能图文详解(sql server 2016 always on)