PolarDB数据库代理是位于数据库和应用之间的网络代理服务,支持自动读写分离、事务拆分、连接池等高级功能。您可以连接PolarDB集群地址使用数据库代理的各项功能。

PolarDB架构及PolarDB数据库代理介绍

PolarDB架构

PolarDB集群版是一个由多节点构成的数据库集群,包括一个主节点,多个只读节点。对外默认提供两个地址,分别为主地址和集群地址。其中,集群地址功能由PolarDB数据库代理提供,集群地址分为只读和可读可写两种读写模式,可读可写模式支持读写分离,只读模式支持按连接数负载。

使用限制

PolarDB集群版支持集群地址和数据库代理相关功能。PolarDB单节点历史库采用单节点架构无需集群地址和数据库代理功能。

注意事项

  • 使用集群地址后,若未启用事务拆分,事务内的所有请求都会路由到主节点。
  • 使用集群地址后,当执行SHOW PROCESSLIST命令时,系统会将所有节点的结果合并后返回。
  • 若执行了Multi Statements或调用了存储过程,当前连接的后续请求会全部路由到主节点,需断开当前连接并重新连接才能恢复读写分离功能。
  • PolarDB集群地址本身并没有最大连接数的限制,连接数的限制主要由后端数据库中计算节点的规格决定。
  • 新增只读节点或重启只读节点之后新建的读写分离连接,会转发请求到该只读节点。新增只读节点或重启只读节点之前建立的读写分离连接,不会转发请求到新增的只读节点或重启后的只读节点上,需要断开该连接并重新建立连接,例如,重启应用。
  • 请勿在运行Multi Statements或调用存储过程时修改环境变量,例如set names utf8mb4;select * from t1;。如果在运行Multi Statements或存储过程中修改了环境变量,可能会导致请求路由到只读节点和主节点查到的数据不一致。

自定义集群地址

PolarDB支持自定义集群地址,您可以自定义集群地址的读写模式、一致性级别等配置,来满足不同的业务场景,增强业务的灵活性。

  • 读写模式
    • 可读可写(自动读写分离)

      该模式下创建的自定义集群地址至少包含2个节点。不论是否包含主节点,写请求都只会发往主节点。支持如事务拆分、连接池等读写分离功能。

    • 只读

      该模式下支持创建仅包含一个只读节点的自定义集群地址,主节点不会参与路由,也不支持事务拆分、连接池等功能。

      当自定义集群地址的读写模式设置为只读时,PolarDB会根据自定义集群地址下配置的只读节点轮循分配连接,即一个客户端连接仅对应到一个只读节点的一个连接,而主节点不会参与到该分配,可用的业务连接总数是所有只读节点上的连接数之和。

    说明 关于自定义集群地址的详细操作步骤,请参见新增自定义集群地址修改和释放集群地址
  • 适用场景
    • 适用于纯只读的业务。
    • 适用于有隔离需求的业务。PolarDB集群支持设置最多3个自定义集群地址,您可以根据业务需要将有隔离需求的业务连接至对应的自定义集群地址,并将该集群地址的读写模式设置为可读可写(自动读写分离)只读

      假设购买了包含1个主节点和4个只读节点的PolarDB集群,现在需要将A业务(纯只读)和B业务(可读可写)都连接至该集群。您可以将只读节点1和只读节点2组成一个自定义集群地址a(只读模式)提供给业务A,主节点、只读节点3和只读节点4组成一个自定义集群地址b(可读可写(自动读写分离)模式)提供给业务B,以实现两个业务在数据库使用上的物理隔离,避免相互影响。

读写分离

PolarDB集群版自带读写分离功能。应用程序只需连接一个集群地址,写请求会自动发往主节点,读请求会自动根据各节点的负载(当前未完成的请求数)发往主节点或只读节点,详情请参见读写分离

连接池

  • 连接池的类型
    • 会话级连接池:2

      会话级连接池用于减少短连接业务频繁建立新连接导致MySQL负载高。当您的连接断开时,系统会判断当前的连接是否是一个闲置的连接,如果是闲置连接,系统将会代理该连接并保留在连接池中一小段时间,如果这时新的连接建立的话就会直接从连接池里获得连接(命中的条件包括userclientipdbname等),从而减少与数据库的建连开销。如果没有可用的连接,则走正常连接流程,重新与数据库建立一个新的连接。

      说明
      • 会话级连接池并不能减少数据库的并发连接数。该优化只能通过降低应用与数据库的建连速率来减少MySQL主线程的开销,从而更好地处理业务请求,但是连接池里空闲的连接会短暂占您的连接数。
      • 会话级连接池也不能解决由于存在大量慢SQL,导致的连接堆积问题,此类问题的核心是先解决慢SQL问题。
    • 事务级连接池:

      事务级连接池主要用于减少直接连接到数据库的业务连接数,以及减少短连接场景下频繁建连带来的负载。

      1

      开启事务级连接池后,客户端与PolarDB代理间可以存在上千个连接,但代理与后端数据库间可能只存在几十或几百个连接。

      PolarDB代理本身并没有最大连接数的限制,连接数的限制主要由后端数据库中计算节点的规格决定。未开启事务级连接池时,每条由客户端发起的连接都需要在后端主节点和所有只读节点上各创建一个对应的连接。

      开启事务级连接池后,当客户端发送请求时,会先与PolarDB代理建连,代理不会马上将其与后端数据库建连,而是先从事务级连接池里查找是否存在可用的连接(判断是否为可用连接的条件:userdbname和系统变量这3个参数值是否一致)。若不存在,代理会与数据库创建一个新连接;若存在,则从连接池里直接拿出并使用,并在当前事务结束后将该连接放回事务级连接池,方便下个请求继续使用。

      使用限制如下:

      • 当执行以下行为时,锁定连接,直至连接结束,即该连接不会再被放到连接池里供其它用户连接使用。
        • 执行PREPARE语句或命令
        • 创建临时表
        • 修改用户变量
        • 大报文(例如16 MB以上)
        • 使用lock table
        • 多语句
        • 存储过程调用
      • 不支持FOUND_ROWS、ROW_COUNT和LAST_INSERT_ID函数的调用,这些函数可以调用成功,但是无法保证调用结果的正确性。其中:
        • 1.13.11及以上的数据库代理版本支持在SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT *语句后直接使用SELECT FOUND_ROWS()命令。但MySQL官方已不推荐该用法,建议您将SELECT FOUND_ROWS()替换为SELECT COUNT(*) FROM tb1进行查询,详情请参见FOUND_ROWS()
        • 支持在INSERT后直接使用SELECT LAST_INSERT_ID()语句,来保证查询结果正确性。
      • 对于设置了wait_timeout的连接,wait_timeout在客户端的表现可能不会生效。因为每次请求都会从连接池中获取连接,当wait_timeout超时后,只有连接池中的后端连接会断开,而后端连接断开并不会导致客户端连接断开。
      • 除了sql_modecharacter_set_servercollation_servertime_zone这四个变量以外,如果业务依赖其他会话级别的系统变量,那么需要客户端在建连之后显式进行SET语句执行,否则连接池可能会复用系统变量已经被更改过的连接。
      • 由于连接可能会被复用,所以使用select connection_id()查询当前连接的thread id可能会变化。
      • 由于连接可能会被复用,所以show processlist中显示的IP地址和端口,可能会与客户端实际的IP地址和端口不一致。
      • 数据库代理会将所有节点上的SHOW PROCESSLIST结果合并并返回,而在事务级连接池开启后,前端连接和后端连接的thread id无法对应。这导致KILL命令会可能返回一个错误,但是实际上KILL命令已经正常执行成功,可再通过SHOW PROCESSLIST确定相应的连接是否断开。
  • 连接池的选择
    您可以根据如下建议评估选择是否开启连接池以及开启何种类型的连接池:
    • 若业务使用的多为长连接且连接数较少,或者业务本身已具备较好的连接池,那么您可以不使用PolarDB的连接池功能。
    • 若业务使用的连接数较多(如连接数需求上万)或使用的是Serverless服务(即连接数会随着业务端服务器的扩容而线性增加),且确认您的业务不涉及上述事务级连接池使用限制的场景,那么您可以选择开启事务级连接池。
    • 若业务使用的纯短连接,且业务使用场景中包含上述事务级连接池使用限制的场景,那么您可以考虑开启会话级连接池。
说明
  • 更改连接池设置后,仅对新建连接生效。如何修改连接池设置,详细步骤请参见修改集群地址
  • 当前连接池功能不支持同一个账号对不同IP有不同的权限。如果您为同一个账号的不同IP设置了不同的库或者表权限,开通连接池可能会导致权限错误问题。例如user@192.xx.xx.1设置了database_a的权限,而user@192.xx.xx.2没有database_a的权限,可能会导致连接复用时权限出错。
  • 该功能是指PolarDB数据库代理的连接池功能,不影响客户端的连接池功能,如果客户端已经支持连接池,则可以不使用PolarDB数据库代理的连接池功能。

并行查询

并行查询是PolarDB MySQL8.0引入的并行查询框架。PolarDB会根据成本和规则的考虑,启动这个查询框架。更多关于并行查询的介绍请参见并行查询(Parallel Query)

FAQ

  • Q:为什么刚插入的语句,立即查的时候查不到?

    A:读写分离的架构下,主节点和只读节点之间复制会有延迟,但PolarDB支持会话一致性,即同一个会话内保证能读到之前的更新。

  • Q:为什么只读节点没有压力?

    A:默认情况下事务中的请求都会路由到主节点,若是用Sysbench做压测,0.5版本的Sysbench可以加上--oltp-skip-trx=on,1.0版本的Sysbench可以加上--skip-trx=on去掉事务,若业务上因为事务较多导致只读库负载过低,可以提交工单开启读写分离下的事务拆分功能。

  • Q:为什么某个节点的请求数比别的节点多?

    A:当前是根据负载来分发请求的,负载小的节点接收的请求数会更多。

  • Q:是否支持0毫秒延迟的读取?

    A:PolarDB集群的主节点和只读节点在正常负载情况下,具有毫秒级的延迟,读写分离连接地址暂时不支持在数据写入后0毫秒的读取。如果要求0毫秒延迟的读取,可使用主地址(动态指向PolarDB主节点)将读写请求发给主节点。

  • Q:新增的只读节点会自动加入到读写分离吗?

    A:新增只读节点之后新建的读写分离连接才会转发请求到该只读节点。若需要使新增只读节点之前建立的读写分离连接也转发请求到新增的只读节点,则您需要通过重启应用等操作断开该连接并重新建立连接。

相关API

API 描述
CreateDBEndpointAddress 创建PolarDB集群的公网地址。
CreateDBClusterEndpoint 创建PolarDB自定义集群地址。
DescribeDBClusterEndpoints 查询PolarDB集群的地址信息。
ModifyDBClusterEndpoint 修改PolarDB集群地址属性。
ModifyDBEndpointAddress 修改PolarDB集群的连接地址(如自定义集群地址)。
DeleteDBEndpointAddress 释放PolarDB集群地址(除了自定义集群地址的私网地址)。
DeleteDBClusterEndpoint 释放PolarDB自定义集群地址。