PHP 日本大会 2024

OCI8 连接处理和连接池

连接函数

OCI8 扩展提供三种不同的函数来连接到 Oracle。标准连接函数是 oci_connect()。这将创建一个到 Oracle 数据库的连接,并返回后续数据库调用使用的资源。

从完成所需时间来看,连接到 Oracle 服务器是一个相当昂贵的操作。oci_pconnect() 函数使用一个持久的连接缓存,可以在不同的脚本请求中重复使用。这意味着连接开销通常每个 PHP 进程(或 Apache 子进程)只发生一次。

如果应用程序使用不同的数据库凭据集为每个 Web 用户连接到 Oracle,则oci_pconnect() 使用的持久缓存随着并发用户数量的增加会变得不太有用,甚至可能由于维护过多的空闲连接而开始对 Oracle 服务器的整体性能产生不利影响。如果应用程序以此方式构建,建议使用 oci8.max_persistentoci8.persistent_timeout 配置设置来调整应用程序(这些将控制持久连接缓存的大小和生命周期),使用 Oracle 数据库驻留连接池(在 Oracle 数据库 11g 或更高版本中),或者改用 oci_connect()

oci_connect()oci_pconnect() 都使用连接缓存;如果在给定脚本中对 oci_connect() 的多次调用使用相同的参数,则第二次及后续调用将返回现有的连接句柄。 oci_connect() 使用的缓存在脚本运行结束时或显式关闭连接句柄时将被清除。oci_pconnect() 函数的行为类似,尽管它的缓存是单独维护的,并且在 HTTP 请求之间仍然存在。

此缓存功能意味着这两个句柄不是事务隔离的(实际上它们是同一个连接句柄,因此没有任何类型的隔离)。如果应用程序需要两个独立的事务隔离连接,则使用 oci_new_connect()

当 PHP 进程终止时,oci_pconnect() 缓存将被清除,任何数据库连接都将关闭,因此有效使用持久连接需要 PHP 是一个 Apache 模块或与 FPM 或类似的技术一起使用。当 PHP 与 CGI 一起使用或通过命令行使用时,持久连接不会比 oci_connect() 具有任何优势。

oci_new_connect() 函数始终创建一个到 Oracle 服务器的新连接,而不管可能已经存在哪些其他连接。高流量 Web 应用程序应避免使用 oci_new_connect(),尤其是在应用程序最繁忙的部分。

持久连接可以由用户关闭,从而可以更好地控制连接资源的使用。当没有 PHP 变量引用持久连接时(例如在 PHP 用户函数的作用域结束时),持久连接现在也将自动关闭。这将回滚任何未提交的事务。这些对持久连接的更改使其行为类似于非持久连接,简化了接口,提高了应用程序的一致性和可预测性。使用 oci8.old_oci_close_semantics 设置为 On 以保留历史行为。

在 Apache 或 FPM 进程重新生成后,PHP 持久连接的自动重新建立意味着 Oracle 数据库 LOGON 触发器仅推荐用于设置会话属性,而不推荐用于每个应用程序的用户连接请求。

DRCP 连接池

PHP 支持 Oracle 数据库驻留连接池 (DRCP)。DRCP 允许更有效地利用数据库机器内存并提供高可扩展性。使用 DRCP 无需或只需最少的应用程序更改。

DRCP 适用于使用少量数据库模式并将数据库连接保持打开很短时间的应用程序。其他应用程序应使用 Oracle 的默认 Dedicated 数据库服务器进程,或使用 Shared 服务器。

DRCP 有益于所有三种连接函数,但在使用 oci_pconnect() 创建连接时可扩展性最高。

要在 OCI8 中使用 DRCP,PHP 使用的 Oracle 客户端库和 Oracle 数据库的版本都必须是 11g 或更高版本。

有关 DRCP 的文档可在多份 Oracle 手册中找到。例如,请参阅 Oracle 文档中的 » 配置数据库驻留连接池 以获取使用信息。 » DRCP 白皮书 包含有关 DRCP 的背景信息。

要使用 DRCP,请安装 OCI8 扩展和 Oracle 11g(或更高版本)库,然后按照以下步骤操作

  • 作为特权数据库管理员,使用 SQL*Plus 等程序在数据库中启动连接池

        SQL> execute dbms_connection_pool.start_pool;
    

  • 可以选择使用 dbms_connection_pool.alter_param() 来配置 DRCP 设置。可以从 DBA_CPOOL_INFO 视图查询当前的池设置。

  • 更新使用的连接字符串。对于目前使用类似 MYDB 的网络连接名称连接的 PHP 应用程序

        $c = oci_pconnect("myuser", "mypassword", "MYDB");
    

    修改 tnsnames.ora 文件并添加 (SERVER=POOLED) 子句,例如

        MYDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=myhost.dom.com)
               (PORT=1521))(CONNECT_DATA=(SERVICE_NAME=sales)
               (SERVER=POOLED)))
    

    或者,修改 PHP 中的 Easy Connect 语法并在服务名称后添加 :POOLED

        $c = oci_pconnect("myuser", "mypassword", "myhost.dom.com:1521/sales:POOLED");
    

  • 编辑 php.ini 并选择连接类名称。此名称指示连接池的逻辑划分,可用于隔离不同应用程序的池化。具有相同用户名和连接类值的任何 PHP 应用程序都将能够共享池中的连接,从而提高可扩展性。

        oci8.connection_class = "MY_APPLICATION_NAME"
    

  • 运行应用程序,连接到 11g(或更高版本)数据库。

注意:

使用 Oracle 客户端库 10g 并需要持久连接性能的应用程序可以通过使用 Oracle Shared 服务器(以前称为多线程服务器)来减少所需的数据库服务器内存量。有关信息,请参阅 Oracle 文档。

注意:

通过 DRCP 连接更改密码将失败,并出现错误 ORA-56609: Usage not supported with DRCP。这是 Oracle 数据库 11g 的已记录限制。

添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top