Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - 数据库管理 » 启动并连接到数据库 » 运行数据库服务器 » 一些常见的选项 » SQL Anywhere 中的线程

 

设置数据库服务器的进程并发水平

数据库服务器的进程并发水平是指最多可以同时处于活动状态的任务数量,通过 -gn 服务器选项进行控制。活动任务是指数据库服务器中当前正由线程(或纤程)执行的任务。活动任务可能正在执行访问计划运算符,或执行某个其它有用的工作,但也可能因等待资源(如 I/O 操作或某行上的锁)而被阻塞。未调度任务是指可以执行但正在等待可用线程或纤程的任务。可以同时执行的活动任务数量取决于计算机上使用中的数据库服务器线程数量和逻辑处理器数量。

服务器执行期间进程并发水平保持不变,并应用于该服务器上的所有数据库。对于网络数据库服务器和个人数据库服务器,其缺省值均为 20 个活动任务,但在 Windows Mobile 上例外,在该平台上其缺省值为 3 个活动任务。

提高进程并发水平

确定何时提高或降低进程并发水平可能是件困难的工作。例如,如果数据库应用程序利用 Java 存储过程或启用了查询内并行机制,则为处理这些请求而额外创建的服务器任务可能会超过进程并发限制,要等到另一请求完成后再执行这些任务。在这种情况下,提高进程并发水平可能是适宜的做法。通常,提高进程并发水平会相应地提高数据库服务器的总吞吐量,因为这样做将允许并发执行更多任务(请求)。不过,应考虑到提高进程并发水平会产生的负面影响。这些负面影响包括:

  • 增加了争用   提高并发任务数量可能使活动请求之间发生争用的可能性增大。争用可能涉及模式或行锁等资源,或数据库服务器内部的数据结构和/或同步基元。此类状况实际上可能会降低服务器吞吐量。

  • 增加了服务器开销   每项活动任务都要求对线程(在 Windows 和 Linux 上是一种叫作纤程的轻量线程)进行分配和维护,并要求使用附加簿记结构来控制对它的调度。此外,每项活动任务都要求为其执行堆栈预分配地址空间。堆栈的大小因平台而异,但一般来说 32 位平台上为 1 MB,64 位平台上会更大。在 Windows 系统上,分配堆栈空间会影响服务器进程的地址空间,但堆栈内存是按需分配的。在 Unix 平台(包括 Linux)上,堆栈后备内存的分配是即时进行的。因此,设置较高的进程并发水平会增加服务器的内存占用并减少可以用作高速缓存的内存量,因为可用地址空间减少了。

  • 系统失效   数据库服务器可能会达到这样一种状态:将大量资源全部用于管理其执行开销,而不是为特定请求执行有用的工作。这种状态通常称为系统失效。举例来说,在以下情况下可能会出现系统失效的状况:为获取数据库高速缓存空间而竞争的活动请求数量过多,但高速缓存不足以容纳这组活动请求所使用的有效数据库页集。这种情况可能会导致页面挪用,其发生方式与操作系统中页面挪用的发生方式类似。

  • 对查询处理有影响   数据库服务器将选择可并发处理的最大数量的内存密集型请求。即便提高数据库服务器的进程并发水平,请求可能仍需要在内存可用之前一直等待。请参见内存调控器

  • 数据结构占用内存   数据库服务器需要使用资源来分析和优化语句。如果语句非常复杂或高速缓存过小,服务器数据结构所占用的内存可能超过可用内存量。内存调控器限制了每个任务的服务器数据结构所使用的内存量。每个任务都具有以下限制:
    (3/4 maximum cache size) / (number of currently active tasks)

    如果超过此限制,语句将失败并出现错误。

降低进程并发水平

通过减少并发执行的任务数量来降低数据库服务器的进程并发水平通常会减少服务器的吞吐量。不过,降低进程并发水平可能会缩短单个请求的响应时间,原因是为获得资源而竞争的请求数量减少了,发生锁争用的可能性也降低了。

在 SQL Anywhere 中,线程(纤程)以协作方式执行任务。完成任务后,线程(纤程)即可不受限制地拾取下一个等待执行的任务。不过,如果任务被阻塞(例如,等待行锁时),则线程(纤程)也会被阻塞。

当进程并发水平设置过低时,可能会发生线程死锁。假定数据库服务器有 n 个线程(纤程)。当 n-1 个线程被阻塞,并且最后一个线程也即将被阻塞时,就会发生线程死锁。数据库服务器的内核不会允许这最后一个线程被阻塞,因为这样会导致所有线程都被阻塞,服务器将因此而挂起。数据库服务器会执行 SQLSTATE 40W06 来结束即将阻塞最后一个线程的任务。

如果就负载而言进程并发水平处于一个合理的级别,那么发生线程死锁就是应用程序存在设计问题的征兆,这种问题会导致大量争用,并因此削弱可伸缩性。例如,每个应用程序在向数据库插入新数据时都必须修改的表就是一种典型情况。此技术常用作模式的一部分来生成主键。但结果是,它对应用程序的所有插入事务进行了有效序列化。当由于共享表上的序列化而使插入事务的速率超过服务器能够提供服务的能力时,通常会发生线程死锁。

选择进程并发水平

建议对应用程序的负载进行试验,以分析服务器的进程并发水平对服务器吞吐量和请求响应时间的影响。有各种性能计数器可供使用,它们要么以属性函数形式出现,要么通过 Windows 上的 Windows 性能监控器提供,这些性能计数器可以在测试应用程序时帮助您分析数据库服务器的行为。对这种分析而言,与活动请求和未调度请求有关的性能计数器十分重要。

如果活动请求的数量总是低于 -gn 数据库服务器选项的值,则可以考虑降低进程并发水平,但必须将查询内并行机制的影响考虑在内,该机制会在服务器的执行队列中添加额外任务。如果查询内并行机制的影响很小,就可以放心地降低进程并发水平而不会降低系统的总吞吐量。不过,如果总请求数量(活动请求与未调度请求数量之和)经常大于 -gn,则提高进程并发水平可能是有充分根据的,但会出现前文中概要介绍的负面影响。请注意,Unix 或 Linux 平台上未提供性能监控器。