相关文章推荐
坚强的馒头  ·  c ...·  1 年前    · 
心软的柿子  ·  Java ...·  1 年前    · 
踢足球的酸菜鱼  ·  html - ...·  1 年前    · 
怕考试的鼠标  ·  android - How is ...·  1 年前    · 

连接池

更新时间:

PolarDB 支持会话级连接池和事务级连接池,您可以根据业务场景选择合适的连接池,帮助降低因大量连接导致的数据库负载压力。

注意事项

  • 更改连接池设置后,仅对新建连接生效。如何修改连接池设置,请参见 配置数据库代理

  • 当前连接池功能不支持同一个账号对不同IP有不同的权限。如果您为同一个账号的不同IP设置了不同的库或者表权限,开通连接池可能会导致权限错误问题。例如, user@192.xx.xx.1 设置了 database_a 的权限,而 user@192.xx.xx.2 没有 database_a 的权限,可能会导致连接复用时权限出错。

  • 本文介绍的功能是 PolarDB 数据库代理的连接池功能。该功能并不影响客户端的连接池功能,如果客户端已经支持连接池,则可以不使用 PolarDB 数据库代理的连接池功能。

会话级连接池

  • 工作原理 2

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

  • 使用限制

    • 会话级连接池并不能减少数据库的并发连接数。该优化只能通过降低应用与数据库的建连速率来减少MySQL主线程的开销,从而更好地处理业务请求,但是连接池里空闲的连接会短暂占您的连接数。

    • 会话级连接池也不能解决由于存在大量慢SQL,导致的连接堆积问题,此类问题的核心是先解决慢SQL问题。

事务级连接池

  • 工作原理 1

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

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

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

    开启事务级连接池后,当客户端发送请求时,会先与 PolarDB 代理建连,代理不会马上将其与后端数据库建连,而是先从事务级连接池里查找是否存在可用的连接(判断是否为可用连接的条件: user dbname 和系统变量这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_mode character_set_server collation_server time_zone 这四个变量以外,如果业务依赖其他会话级别的系统变量,那么需要客户端在建连之后显式进行SET语句执行,否则连接池可能会复用系统变量已经被更改过的连接。

    • 由于连接可能会被复用,所以使用 select connection_id() 查询当前连接的 thread id 可能会变化。

    • 由于连接可能会被复用,所以 show processlist 或者 SQL洞察 中显示的IP地址和端口,可能会与客户端实际的IP地址和端口不一致。

    • 数据库代理会将所有节点上的SHOW PROCESSLIST结果合并后再返回最终结果,而在事务级连接池开启后,前端连接和后端连接的 thread id 无法对应。这导致执行KILL命令时可能会返回错误:ERROR 1094 (HY000): Unknown thread id:xxx。

连接池的选择

您可以根据如下建议评估选择是否开启连接池以及开启何种类型的连接池:

  • 若业务使用的多为长连接且连接数较少,或者业务本身已具备较好的连接池,那么您可以不使用 PolarDB 的连接池功能。

  • 若业务使用的连接数较多(如连接数需求上万)或使用的是Serverless服务(即连接数会随着业务端服务器的扩容而线性增加),且确认您的业务不涉及上述事务级连接池使用限制的场景,那么您可以选择开启事务级连接池。

  • 若业务使用的纯短连接,且业务使用场景中包含上述事务级连接池使用限制的场景,那么您可以考虑开启会话级连接池。