Abstract:
A system optimizes a number of shared server processes executing on a processor. The system creates, in a memory, a data array for storing a plurality of performance metric values, each associated with a number of shared server processes. The system selects a value for an optimized number of shared server processes according to a first procedure based on the performance metric, observes a performance metric associated with the selected optimized number, and stores, in the data array, the observed performance metric. The system repeats the selecting, observing and storing until at least a predetermined number of contiguous data values are stored in the data array. The system selects the value for the optimized number according to a second procedure based on a slope of the performance metric. The system observes the performance metric associated with the selected optimized number, and stores, in the data array, the observed performance metric.

Description:
TECHNICAL FIELD 
       [0001]    One embodiment is directed generally to a computer system, and, in particular, to a computer system that optimizes the number of shared processes executing thereon. 
       BACKGROUND 
       [0002]    A computer system typically executes many different processes at the same time, including operating system (OS) processes, utility processes, resource processes, communications processes, application processes, etc. The computer system may include multiple processors, and a multitasking OS allows multiple processes to share processors and other system resources. Each process may include multiple threads of execution, which may concurrently execute on one or more processors. Generally, it may be desired to manage the number of processes executing on the computer system in order to optimize system performance. 
         [0003]    Certain server-based applications service data requests that are received over a network from one or more client computers. In a database application, these requests may be serviced using a dedicated server connection model or a shared server connection model. In the dedicated model, a dedicated server process is created for each client connection, and services the requests that are received from that client until the connection is terminated. The dedicated model increases the use of computer system resources, such as memory, processor time, etc., and may not be optimal for database applications that have high connection rates. In the shared model, a pool of shared server processes is managed by a supervisory process, such as a dispatcher, which assigns shared processes to service client connection requests that are received and stored in a request queue. The shared model reduces the number of concurrently executing server processes, as well as the amount of memory consumed, as compared to the dedicated model. 
       SUMMARY 
       [0004]    One embodiment is a system that optimizes a number of shared server processes executing on a processor. The system creates, in a memory, a data array for storing a plurality of performance metric values, each performance metric value being associated with a number of shared server processes. The system selects a value for an optimized number of shared server processes according to a first procedure based on the performance metric. The system observes a performance metric associated with the optimized number of shared server processes selected according to the first procedure. The system stores, in the data array, the performance metric associated with the optimized number of shared server processes selected according to the first procedure. The system repeats the selecting, observing and storing until at least a predetermined number of contiguous data values are stored in the data array. The system selects the value for the optimized number of shared server processes according to a second procedure based on a slope of the performance metric. The system observes the performance metric associated with the optimized number of shared server processes selected according to the second procedure. The system stores, in the data array, the performance metric associated with the optimized number of shared server processes selected according to the second procedure. 
     
    
     
       BRIEF DESCRIPTION OF THE DRAWINGS 
         [0005]      FIG. 1  is a block diagram of a computer server/system, in accordance with an embodiment of the present invention. 
           [0006]      FIG. 2  is a flow diagram of the functionality of a shared process optimizer module of  FIG. 1 , in accordance with an embodiment of the present invention. 
           [0007]      FIG. 3  is a table of values depicting the optimization of the number of shared server processes for a database application, in accordance with an embodiment of the present invention. 
       
    
    
     DETAILED DESCRIPTION 
       [0008]    Embodiments of the present invention will now be described with reference to the drawing figures, in which like reference numerals refer to like parts throughout. 
         [0009]    Embodiments of the present invention advantageously increase the throughput of a computer system by optimizing the number of shared processes in a pool, such as, for example, a shared server process pool for a database application. Other embodiments of the present invention may advantageously increase the throughput of a computer system by optimizing the number of servers allocated from a shared server pool, such as, for example, an authentication server pool, a slave server pool, etc., by optimizing the number of worker/thread pools in web-based applications, etc. 
         [0010]    One known way to optimize the number of shared processes executing in a computer system is to determine an integer value n, which represents the number of shared processes, that effectively maximizes an unknown noisy function f(n) defined on the integer domain, which represents the computer system behavior to be optimized. For a database system using a shared server connection model, n is the number of shared server processes and f(n) may be related to database throughput, such as, for example, the number of database requests served. One known method attempts to optimize the number of shared server processes as follows: 
         [0000]                                            new_shared_server_processes             = old_shared_server_processes             * existing_server_utilization             * ( current_requests_served + queued_requests ) /             current_requests_served                        
While this method is not likely to waste resources because the number of shared server processes is reduced when existing server utilization drops below 100%, the resulting database throughput can be very poor in certain circumstances.
 
         [0011]    For example, in one test, 20,000 requests from 200 constantly-active connections were processed using 20 shared server processes, and it was determined that 180 requests always remained in the queue. The number of shared server processes was initialized to 20, which remained essentially constant during the processing of the requests. This method did not increase the number of shared server processes to improve processing throughput and to reduce or eliminate the constantly-queued requests. In other words, an incoming request had to wait until the 180 queued requests were completed by the 20 shared server processes, which produced a 9× increase of the average request processing time. 
         [0012]    In order to improve the average request processing time and overall throughput, the number of shared server processes could be increased to 200, so that each of the 200 constantly-active connections is served by a dedicated server process. The dedicated server connection model eliminates queuing time, but may be inefficient and result in overloading, contention, etc., as noted above. Accordingly, an improved method for optimizing the number of shared server processes in a computer system has been developed. 
         [0013]      FIG. 1  is a block diagram of a computer server/system  10  in accordance with an embodiment of the present invention. Although shown as a single system, the functionality of system  10  can be implemented as a distributed system. Further, the functionality disclosed herein can be implemented on separate servers or devices that may be coupled together over a network. Further, one or more components of system  10  may not be included. For example, for functionality of a user client, system  10  may be a smartphone that includes a processor, memory and a display, but may not include one or more of the other components shown in  FIG. 1 . 
         [0014]    System  10  includes a bus  12  or other communication mechanism for communicating information, and a processor  22  coupled to bus  12  for processing information. Processor  22  may be any type of general or specific purpose processor. System  10  further includes a memory  14  for storing information and instructions to be executed by processor  22 . Memory  14  can be comprised of any combination of storage devices, such as, for example, random access memory (“RAM”), read only memory (“ROM”), static storage devices such as a magnetic or optical disk, or any other type of computer readable media. System  10  further includes a communication device  20 , such as a network interface card, to provide access to a network. Therefore, a user may interface with system  10  directly, or remotely through a network, or any other method. 
         [0015]    Computer readable media may be any available media that can be accessed by processor  22  and includes both volatile and nonvolatile media, removable and non-removable media, and communication media. Communication media may include computer readable instructions, data structures, program modules, or other data in a modulated data signal such as a carrier wave or other transport mechanism, and includes any information delivery media. 
         [0016]    Processor  22  is further coupled via bus  12  to a display  24 , such as a Liquid Crystal Display (“LCD”). A keyboard  26  and a cursor control device  28 , such as a computer mouse, are further coupled to bus  12  to enable a user to interface with system  10 . 
         [0017]    In one embodiment, memory  14  stores software modules that provide functionality when executed by processor  22 . The modules include an operating system  15  that provides operating system functionality for system  10 . The modules further include a shared process optimizer module  16  for optimizing shared processes, and all other functionality disclosed herein. System  10  can include one or more additional functional modules  18 , such as, for example, Oracle Database  12   c  Enterprise Edition or other type of database management system. Alternatively, shared process optimizer module  16  may be included within functional module  18 . A database  17  is coupled to bus  12  to provide, inter alia, centralized storage for shared process optimizer module  16  and functional modules  18 . System  10  can be part of a larger system, and one or more clients  30  may connect to the communication device  20  through one or more intervening networks (not shown), such as, for example, a Local Area Network (LAN), a Wide Area Network (WAN), a wireless network (WiFi), the Internet, etc. 
         [0018]    For a database application using a shared server connection model, shared process optimizer module  16  sets the number of shared server processes n to an initial value, and then increases or decreases the number of shared server processes n until a performance metric related to database throughput is maximized. In one embodiment, the performance metric is database throughput, such as, for example, the number of completed client requests processed by the shared server processes. Computer system resource contention may be quite high when the number of shared server processes is optimized using this performance metric. In another embodiment, the performance metric is database throughput squared per process, such as, for example, the square of the number of completed client requests divided by the number of shared server processes n. This performance metric tends to peak before database throughput is maximized, which keeps the level of computer system resource contention lower. Other performance metrics are also contemplated by embodiments of the present invention, including, for example, any performance metric that may be represented by a hump-shaped function with at least one local maximum. 
         [0019]      FIG. 2  is a flow diagram  100  of the functionality of shared process optimizer module  16  of  FIG. 1 , in accordance with an embodiment of the present invention. In some embodiments, the functionality of the flow diagram  100  may be implemented by software stored in memory or other computer readable, tangible non-transitory medium, and executed by one or more processors. In other embodiments, the functionality may be performed by hardware, such as, for example, an application specific integrated circuit (ASIC), a programmable gate array (PGA), a field programmable gate array (FPGA), etc., or through any combination of hardware and software. 
         [0020]    Generally, flow diagram  100  may be divided into two algorithm sections or procedures, a local algorithm section (procedure) and a utility algorithm section (procedure). After initialization and at regular time intervals thereafter, the local algorithm is used to determine whether the current value for n, the number of shared server processes, should be changed based on the observation of f(n), the performance metric, which is then stored in a data array u[n] of the values of f(n). Data array u[n] may be created in memory  14 , for example, and initialized to zero prior to observing f(n). Once there are a sufficient number of contiguous entries in u[n] and at regular time intervals thereafter, the utility algorithm is used to determine whether the current value for n should be changed based on the slope of f(n), which is calculated using the values stored in the utility array u[n]. The observation of f(n) is stored in u[n], and, if the current observation of f(n) differs from the previous value stored in u[n] by a certain percentage, which suggests that the load may have changed, then u[n] is reset and the local algorithm is used again to determine n, as before. This functionality is described in more detail below. 
         [0021]    At  110 , a new value of n, the number of shared server processes, is selected. For the initial pass through the local algorithm section, n may be initialized to any number between a minimum number of shared server processes (e.g., 1) and a maximum number of shared server processes (e.g., 100), such as, for example, 10, 50, etc. For example, at t=0, the initial value for n is 10, and the number of shared server processes executing on processor  22  is set to n. 
         [0022]      FIG. 3  presents a summary of example data discussed with respect to the details of the flow diagram  100  in accordance with one embodiment. 
         [0023]    After a period of time, during which the n shared server processes are executing on processor  22 , f(n) is observed and array u[n] is updated at  120 . For example, at t=100, the number of completed client requests may be 126, and the performance metric is calculated to be 1587.6 (i.e., 126 2 /10). Using n=10 as the array index, u[10] is then set to 1587.6. In one embodiment, an exponential moving average may be stored in u[n], such as, for example, u[n]=0.75*u[n]+0.25*f(n). For t=100, u[10] may be set to 1587.6, since no other value has yet been stored in u[10]. 
         [0024]    At  130 , the array u[n] is inspected to determine whether there are a sufficient number of contiguous values N in the array u[n]. In one embodiment, the minimum number of contiguous values K=5, so there must be a total of four other points to the left and/or right of u[10] to satisfy the condition. For example, values for f(n) may be stored in u[6], u[7], u[8], u[9] and u[10] in order to satisfy the condition, or, values for f(n) may be stored in u[10], u[11], u[12], u[13] and u[14] in order to satisfy the condition, or, values for f(n) may be stored in u[8], u[9], u[10], u[11] and u[12] in order to satisfy the condition, etc. At t=100, only one value is stored in u[n], i.e., u[10]=1587.6, and the local algorithm section loops back to  110 . 
         [0025]    At  110 , a new value of n, the number of shared server processes, is selected. At t=100, only one pass has been made through the local algorithm section, so n is simply incremented by the value of the minimum step size, e.g., n new =n+1 or 11. 
         [0026]    After a period of time, during which the n shared server processes are executing on processor  22 , f(n) is observed and array u[n] is updated at  120 . For example, at t=200, the number of completed client requests may be 139, and the performance metric is calculated to be 1756.4 (i.e., 139 2 /11). Using n=11 as the array index, u[11] is then set to 1756.4. In one embodiment, an exponential moving average may be stored in u[n]. For t=200, u[11] may be set to 1756.4, since no other value has yet been stored in u[11]. 
         [0027]    At  130 , the array u[n] is inspected to determine whether there are a sufficient number of contiguous values N in the array u[n]. At t=100, only two values are stored in u[n], i.e., u[10] and u[11], so the local algorithm section loops back to  110 . 
         [0028]    At  110 , a new value of n, the number of shared server processes, is selected. At t=200, only two passes have been made through the local algorithm section, so the values for u[10] and u[11] are compared and n is changed accordingly. For example, if u[11]&gt;u[10] then n=n+1, or if u[11]&lt;u[10] then n=n−1, or if u[11]=u[10] then n=n. In this case, u[11]&gt;u[10], so n new =n+1 or 12. 
         [0029]    After a period of time, during which the n shared server processes are executing on processor  22 , f(n) is observed and array u[n] is updated at  120 . For example, at t=300, the number of completed client requests may be 152, and the performance metric is calculated to be 1925.3 (i.e., 152 2 /12). Using n=12 as the array index, u[12] is then set to 1925.3. In one embodiment, an exponential moving average may be stored in u[n]. For t=300, u[12] may be set to 1925.3, since no other value has yet been stored in u[12]. 
         [0030]    At  130 , the array u[n] is inspected to determine whether there are a sufficient number of contiguous values N in the array u[n]. At t=100, only three values are stored in u[n], i.e., u[10], u[11] and u[12], so the local algorithm section loops back to  110 . 
         [0031]    At  110 , a new value of n, the number of shared server processes, is selected. After three passes through the local algorithm section, n may be determined using at least two different methods. In a two point embodiment, n new  may be determined based on the current and previous values of n and u[n], i.e., n and n 1 , u[n] and u[n 1 ]. In a three point embodiment, n new  may be determined based on the current and previous two values of n and u[n], i.e., n, n 1  and n 2 , u[n], u[n 1 ] and u[n 2 ]. Other methods are also contemplated by embodiments of the present invention. 
         [0032]    In the two-point embodiment, the values of n and n 1  are compared to determine whether the number of shared processes is increasing, decreasing or staying the same, u[n] and u[n 1 ] are compared to determine whether the value of the performance metric is increasing or decreasing, and n is selected accordingly. If n is increasing (i.e., n&gt;n 1 ) and the performance metric is increasing (i.e., u[n]&gt;u[n 1 ]), then n is incremented by 1. To the contrary, if n is increasing (i.e., n&gt;n 1 ) and the performance metric is decreasing (i.e., u[n]&lt;u[n 1 ]), then n is decremented by 1. Similarly, if n is decreasing (i.e., n&lt;n 1 ) and the performance metric is increasing (i.e., u[n]&gt;u[n 1 ]), then n is decremented by 1. And, if n is decreasing (i.e., n&lt;n 1 ) and the performance metric is decreasing (i.e., u[n]&lt;u[n 1 ]), then n is incremented by 1. If n=n 1 , then a random change in either direction may be taken. 
         [0033]    For the two point embodiment, at t=300, n&gt;n 1  and u[n]&gt;u[n 1 ], so n new =n+1 or 13. 
         [0034]    In the three point embodiment, similar comparisons between n, n 1  and n 2  and u[n], u[n 1 ] and u[n 2 ] are made in order to select the new value for n. For example, there may be nine test conditions for n, n 1  and n 2 , with several expressions for selecting the new value for n for each test condition: 
         [0000]    
       
         
               
             
               
               
               
             
           
               
                 TABLE 1 
               
             
             
               
                   
               
               
                 Three Point Algorithm Test Conditions and Expressions 
               
             
          
           
               
                 Case 
                 Test Condition 
                 Expression for n 
               
               
                   
               
               
                 1 
                 n2 &lt; n1 &lt; n 
                 if u[n] &lt; u[n1] then n new  = n1 
               
               
                   
                 or 
                 otherwise 
               
               
                   
                 n2 &gt; n1 &gt; n 
                 if n &gt; n1 then n new  = n + 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n − 1 
               
               
                 2 
                 n2 &gt; n1 = n 
                 if u[n] = u[n1] = u[n2] then n new  = n 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if (u[n] + u[n1])/2 &gt; u[n2] then n new  = n − 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n2 + 1 
               
               
                 3 
                 n2 &lt; n1 = n 
                 if u[n] = u[n1] = u[n2] then n new  = n 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if (u[n] + u[n1])/2 &gt; u[n2] then n new  = n + 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n2 − 1 
               
               
                 4 
                 n2 = n1 &lt; n 
                 if u[n] = u[n1] = u[n2] then n new  = n ± 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if (u[n2] + u[n1])/2 &gt; u[n] then n new  = n2 − 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n + 1 
               
               
                 5 
                 n2 = n1 &gt; n 
                 if u[n] = u[n1] = u[n2] then n new  = n ± 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if (u[n2] + u[n1])/2 &gt; u[n] then n new  = n2 + 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n − 1 
               
               
                 6 
                 n2 ≦ n &lt; n1 and 
                 if u[n] &lt; u[n1] &amp;&amp; n != 2 
               
               
                   
                 n2 ≦ n1 
                 or 
               
               
                   
                 or 
                 if (u[n] + u[n2])/2 &lt; u[n1 &amp;&amp; n = n2 
               
               
                   
                 n2 ≧ n &gt; n1 and 
                 then 
               
               
                   
                 n2 ≧ n1 
                 n new  = n1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if u[n] = u[n1] then n new  = n 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if n &gt; n1 then n new  = n + 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 if n &lt; n1 then n new  = n − 1 
               
               
                 7 
                 n &lt; n2 &lt; n1 
                 if u[n] &gt; u[n1] then n new  = n2 − 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n1 
               
               
                 8 
                 n &gt; n2 &gt; n1 
                 if u[n] &gt; u[n1] then n new  = n2 + 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n1 
               
               
                 9 
                 n2 = n1 = n 
                 if u[n] = u[n1] = u[n2] then n new  = n ± 1 
               
               
                   
                   
                 otherwise 
               
               
                   
                   
                 n new  = n ± 1 
               
               
                   
               
             
          
         
       
     
         [0035]    At t=300, n&gt;n 1 &gt;n 2 , u[n]&gt;u[n 1 ] and n&gt;n 1 , so n new =n+1 or 13 (Case 1). 
         [0036]    The local algorithm section of flow diagram  100  is executed until the array u[n] has sufficient number of contiguous values N. At t=1500, five values are stored in u[n], i.e., u[10], u[11], u[12], u[13] and u[14], so N=K and the utility algorithm section is then entered from  130 . 
         [0037]    At  140 , a new value of n, the number of shared server processes, is selected. In one embodiment, the slope of the performance metric is calculated based on the N contiguous values stored in u[n], and then n is determined based on the slope. For example, the slope may be calculated by fitting a linear function to the N contiguous values stored in u[n] as follows:
       Determine the average number of shared server processes, n avg      Determine the average performance metric, u avg      Determine the sum of the squares of the normalized number of shared processors, n norm   2      Determine the products of the normalized number of shared processes and the normalized performance metric, n norm *u norm      Calculate the slope as n norm *u norm /n norm   2          
 
         [0043]    At t=1500, the slope is calculated to be 78.2. 
         [0044]    In one embodiment, the new value for n is determined by comparing the calculated slope to the value stored in u[n]. For example, if the slope is greater than 3% of u[n], then n is incremented by 3, i.e., a number large than 1, the minimum step size. If the slope is between 2% and 3% of u[n], then n is incremented by 2, i.e., a number large than 1, the minimum step size. If the slope is between 0.2% and 1% of u[n], then n is incremented by 1, i.e., the minimum step size. If the slope is between −2% and 0.2% of u[n], then n is decremented by 1, so as to conserve system resources, for example. If the slope is between −3% and −2% of u[n], then n is decremented by 2, i.e., a number large than 1, the minimum step size. If the slope is less than −3% of the observed utility, n is decremented by 3, i.e., a number large than 1, the minimum step size. This schedule advantageously speeds up convergence for n to the optimal number. In another embodiment, n may be incremented by 1 if the slope is positive and decremented it by 1 if the slope is negative. 
         [0045]    At t=1500, the slope (78.2) is greater than 3% of the value of u[14] (1921.1), so n is incremented by 3, from 14 to 17. 
         [0046]    After a period of time, during which the n shared server processes are executing on processor  22 , f(n) is observed at  150 . 
         [0047]    At  160 , f(n) is compared to u[n] to determine whether a large change in the performance metric has occurred. If the difference is greater than 50%, for example, then u[n] is reset at  180  and the local algorithm section is entered at  110 . The array u[n] may be reset to zero, or some other number indicating an initialized state, such as −1. 
         [0048]    At  170 , the array u[n] is updated. For example, at t=1600, the number of completed client requests is 194, and the performance metric is 2213.8 (i.e., 194 2 /17). Using n=17 as the array index, u[17] is then set to 2213.8. In one embodiment, an exponential moving average may be stored in u[n]. For t=1600, u[17] may be set to 2213.8, since no other value has yet been stored in u[17], and the utility algorithm section loops back to  140 . 
         [0049]    In a further embodiment, upper and lower boundaries may be specified for n. The upper boundary avoids the situation when the utility algorithm increases n many times in a row because a positive slope has always been computed, and then an unusually low performance metric is observed at n=n upper , which changes the slope from positive to negative and forces n to be decreased many times in a row, until the window was shifted far enough to the left so as to stop considering n upper . At that point, a positive slope would be computed, n would be increased, then a negative slope would be computed since n upper  would become a part of the window, n would be decreased, etc. This situation can be avoided by marking n upper  as the upper boundary and then not considering it during the next utility slope computation step, which advantageously allows the utility algorithm to once again increase n, get another performance metric observation at n upper , average them together and get a more faithful estimate of the true performance metric at n upper . Eventually, the true performance metric might be such that the utility algorithm proceeds with increasing n for a while longer, assuming that the optimum value of n has not yet been reached. 
         [0050]    The lower boundary serves a similar purpose and allows the utility algorithm to avoid oscillations when n was decreased many times in a row because a negative utility slope has always been computed, and then an unusually high utility value has been observed at n lower . 
         [0051]    Also, in order to make it easier for the algorithm to pass through the boundary, the window would be extended by one point to the left if n=n upper , so as to give the utility algorithm a more complete picture of the utility slope in the neighborhood of n upper , similar to the one that the algorithm had at n upper −1. Similarly, the window would be extended by one point to the right if n=n lower , so as to give the utility algorithm a more complete picture of the slope in the neighborhood of n lower , similar to the one that the algorithm had at n upper +1. 
         [0052]    For example, at t=2000, the utility algorithm does not include the upper boundary of 26 into the window used for computing the slope. This allows the utility algorithm to compute a positive slope at t=2000 and make another attempt at increasing the number of processes to 26, thus getting a chance to make another observation of f(26). Then, at t=2100, when n=26, f(26) is observed to be 3190, which is much larger than the previously observed 2680 at t=1900. When these two values are combined using the previously described exponential smoothing procedure, the result is u[n]=2808.0, which is large enough to make the slope positive. 
         [0053]    Another factor that helped to make the slope positive was the fact that during the second “assault” at the boundary, the utility algorithm used a larger window for fitting the linear function, going all the way back to n=19, when a relatively low utility was observed. As a result, at t=2100, the utility algorithm recommends further increasing n to 27, getting “through” the previously set boundary. When that happens, the upper boundary is set to −1, as shown at t=2200. 
         [0054]    For a database application using a shared server connection model, the number of shared server processes may be optimized by setting the number of shared server processes n to an initial value, and then increasing or decreasing the number of shared server processes n until a performance metric related to database throughput is maximized. In one embodiment, the performance metric is database throughput, such as, for example, the number of completed client requests processed by the shared server processes, while in another embodiment, the performance metric is database throughput squared per process, such as, for example, the square of the number of completed client requests divided by the number of shared server processes n. The number of shared server processes may be set based on the value of the performance metric, as well as the slope of the value of the performance metric. 
         [0055]    The many features and advantages of the invention are apparent from the detailed specification, and, thus, it is intended by the appended claims to cover all such features and advantages of the invention which fall within the true spirit and scope of the invention. Further, since numerous modifications and variations will readily occur to those skilled in the art, it is not desired to limit the invention to the exact construction and operation illustrated and described, and, accordingly, all suitable modifications and equivalents may be resorted to that fall within the scope of the invention.