数据库锁和网络服务器如何就数据库会话进行协作?
How database locks and web server collaborate with respect to database sessions?
这个问题的范围很广,例如Web 服务器、数据库服务器、php 应用程序等,因此我怀疑它属于指的是 Whosebug,但是由于这个问题将帮助我们了解如何编写应用程序代码,所以我决定在这里提问。
我对数据库会话和 Web 服务器如何协同工作感到困惑。如果我是对的,当为客户端建立连接时,只会为该连接创建一个会话,并且该会话将持续到连接断开或由于长时间不活动而重新连接。
现在,如果我们考虑一个 Web 服务器,特别是 Apache 2.4 运行 一个 PHP 7.2 应用程序(在虚拟主机中),其数据库由 MariaDB 10.3.10 支持(如果是,则在 Fedora 28 上)根本不重要),我假设以下情况(如果我错了请纠正我):
- 对于每个 Web 应用程序,现在我们使用 Laravel,只要第一个查询命中它所服务的 URL,就会建立一个数据库连接。
- 随后,它将只有一个数据库会话。提供查询时,连接将保持活动状态,以供应用程序接收的其他查询重用。这意味着如果应用程序连续接收 24 x 7 的 Web 请求,连接也将保持活动状态,并且只有在我们重新启动 mysqld 或 httpd 时才会断开连接,这甚至可能在几个月内都不会发生。
- 由于应用程序的所有用户,让我们说一次大约 20 个用户,使用相同的 Apache 服务器和 Laravel 应用程序文件(我假设我可以称之为应用程序实例)所有 20将通过相同的数据库连接和数据库会话为用户提供服务。
如果上面提到的所有用例都是正确的,那么数据库锁定的概念似乎很混乱。因为假设我们会发出排他锁,例如lock tables t1 write;
,会阻塞其他会话的读写,避免并发会话的脏读写操作。 但是,由于所有 20 个用户同时使用相同的会话和连接,我们无法通过数据库锁定机制获得所需的并发安全性。
问题:
- 数据库锁定、显式独占锁定在 Web 应用程序方面如何工作?
- 在 Laravel 应用程序收到的每个 Web 请求是否会创建一个新的连接和会话,或者只有一个连接和会话被重用?
- 每个数据库连接是否一次只有一个会话?
- 这个命令会显示当前活动的会话或连接吗
show status where
variable_name= 'Threads_connected'
?如果它显示当前活动连接,我们如何获得当前活动数据库会话?
在这种情况下(大部分)Apache 与会话无关。数据库连接和会话由 php 本身处理。
除非您启用了连接池,否则数据库会话将不会被重用,每个请求都会打开自己的连接并在结束时关闭它。
启用连接池后,为请求提供服务的线程将请求从池到进程管理器的连接(fpm
或 mod_php
),并且它将 return来自池的可用 连接,但仍然至少有与并发请求一样多的会话(除非您达到任何max_
限制)。 general reference 进入更多细节,但作为亮点:
Persistent connections do not give you an ability to open 'user
sessions' on the same link, they do not give you an ability to build
up a transaction efficiently, and they don't do a whole lot of other
things. In fact, to be extremely clear about the subject, persistent
connections don't give you any functionality that wasn't possible with
their non-persistent brothers.
即使有可用的连接池,管理器也必须 运行 在 return 连接到客户端之前进行一些清理操作。其中一项操作是 table 解锁。
您可以参考 mysqli
扩展的 connections reference and persistent connections reference 了解更多信息。
但是,您所描述的多个客户端会话共享一个连接的操作模式是可能的(并且是实验性的)并且有更多缺点。它被称为 session multiplexing。
这个问题的范围很广,例如Web 服务器、数据库服务器、php 应用程序等,因此我怀疑它属于指的是 Whosebug,但是由于这个问题将帮助我们了解如何编写应用程序代码,所以我决定在这里提问。
我对数据库会话和 Web 服务器如何协同工作感到困惑。如果我是对的,当为客户端建立连接时,只会为该连接创建一个会话,并且该会话将持续到连接断开或由于长时间不活动而重新连接。
现在,如果我们考虑一个 Web 服务器,特别是 Apache 2.4 运行 一个 PHP 7.2 应用程序(在虚拟主机中),其数据库由 MariaDB 10.3.10 支持(如果是,则在 Fedora 28 上)根本不重要),我假设以下情况(如果我错了请纠正我):
- 对于每个 Web 应用程序,现在我们使用 Laravel,只要第一个查询命中它所服务的 URL,就会建立一个数据库连接。
- 随后,它将只有一个数据库会话。提供查询时,连接将保持活动状态,以供应用程序接收的其他查询重用。这意味着如果应用程序连续接收 24 x 7 的 Web 请求,连接也将保持活动状态,并且只有在我们重新启动 mysqld 或 httpd 时才会断开连接,这甚至可能在几个月内都不会发生。
- 由于应用程序的所有用户,让我们说一次大约 20 个用户,使用相同的 Apache 服务器和 Laravel 应用程序文件(我假设我可以称之为应用程序实例)所有 20将通过相同的数据库连接和数据库会话为用户提供服务。
如果上面提到的所有用例都是正确的,那么数据库锁定的概念似乎很混乱。因为假设我们会发出排他锁,例如lock tables t1 write;
,会阻塞其他会话的读写,避免并发会话的脏读写操作。 但是,由于所有 20 个用户同时使用相同的会话和连接,我们无法通过数据库锁定机制获得所需的并发安全性。
问题:
- 数据库锁定、显式独占锁定在 Web 应用程序方面如何工作?
- 在 Laravel 应用程序收到的每个 Web 请求是否会创建一个新的连接和会话,或者只有一个连接和会话被重用?
- 每个数据库连接是否一次只有一个会话?
- 这个命令会显示当前活动的会话或连接吗
show status where
variable_name= 'Threads_connected'
?如果它显示当前活动连接,我们如何获得当前活动数据库会话?
在这种情况下(大部分)Apache 与会话无关。数据库连接和会话由 php 本身处理。
除非您启用了连接池,否则数据库会话将不会被重用,每个请求都会打开自己的连接并在结束时关闭它。
启用连接池后,为请求提供服务的线程将请求从池到进程管理器的连接(fpm
或 mod_php
),并且它将 return来自池的可用 连接,但仍然至少有与并发请求一样多的会话(除非您达到任何max_
限制)。 general reference 进入更多细节,但作为亮点:
Persistent connections do not give you an ability to open 'user sessions' on the same link, they do not give you an ability to build up a transaction efficiently, and they don't do a whole lot of other things. In fact, to be extremely clear about the subject, persistent connections don't give you any functionality that wasn't possible with their non-persistent brothers.
即使有可用的连接池,管理器也必须 运行 在 return 连接到客户端之前进行一些清理操作。其中一项操作是 table 解锁。
您可以参考 mysqli
扩展的 connections reference and persistent connections reference 了解更多信息。
但是,您所描述的多个客户端会话共享一个连接的操作模式是可能的(并且是实验性的)并且有更多缺点。它被称为 session multiplexing。