Network Config   «Prev  Next»

Lesson 3Configuring the Dispatchers for Oracle Shared Server (part 2)
ObjectiveExplain the function of Dispatchers.

Configuring Oracle Dispatchers for Shared Server

Lesson 2 covered the DISPATCHERS parameter's syntax, its attributes, and how to size the number of dispatchers you need for a given workload. This lesson steps back from syntax and asks a simpler question: what does a dispatcher actually do, and why does the parameter that controls it carry a name that, in older material, you may not immediately recognize. Understanding both of those things makes the syntax in Lesson 2 much easier to reason about rather than just memorize.

What a Dispatcher Does

Recall from Lesson 1 that under Shared Server, a client does not connect directly to a server process the way it does with a dedicated server. Instead, it connects to a dispatcher, and the dispatcher places that client's request on a common queue that any idle shared server process can pick up. A dispatcher, in other words, is not doing the database work itself; it is managing the traffic between clients and the pool of shared servers that do.

A dispatcher's role does not end once a request is queued. Each client connection to a dispatcher is bound to its own virtual circuit, a small piece of shared memory that carries that connection's traffic back and forth. When a shared server finishes processing a request, it does not send the response straight back to the client; it places the completed response on the dispatcher's own response queue. Each dispatcher has its own response queue in the SGA, separate from every other dispatcher's, and it is the dispatcher, not the shared server, that delivers the finished response back over the client's virtual circuit. A single dispatcher process is therefore juggling many clients' worth of virtual circuits and responses at once, which is exactly what lets a small number of dispatchers stand in front of a much larger number of shared servers and client connections.

This is why the number of dispatchers you configure matters so much. Too few dispatchers for a given protocol, and clients start queuing up waiting for a dispatcher to even accept their connection, long before they ever reach a shared server. Too many, and you are running processes that spend most of their time idle, which works against the whole point of Shared Server: using fewer processes to serve more clients. Lesson 2's sizing formula, based on your expected concurrent sessions and how many connections a single dispatcher process can handle on your operating system, exists to find the point between those two extremes; it is not repeated here, but everything below assumes you already have a working sense of it.

It is also worth being clear about what configuring dispatchers does not do. It does not force every client through Shared Server. A given connection can still end up on a dedicated server or a dispatcher depending on how that client connects, a point this lesson returns to at the end.

Monitoring a Dispatcher's Load

Sizing dispatchers correctly at startup is only half the job; the other half is noticing when reality has drifted away from your original estimate. Recall from Lesson 1 that when more than one dispatcher is registered for a protocol, the listener routes each new connection to whichever one is currently least loaded, using load information the LREG background process keeps registered on the dispatcher's behalf. That load balancing only helps if there are enough dispatchers in the first place to actually spread the load across; it cannot manufacture capacity that was never configured. V$DISPATCHER_RATE reports rate statistics for each dispatcher process, letting you see trends rather than just a single snapshot, while V$QUEUE shows how long requests are actually waiting in the common request queue before a shared server picks them up. Steadily rising wait times in V$QUEUE are the clearest signal that a protocol is short on dispatchers; a dispatcher that is consistently idle, by contrast, is a candidate for having its count reduced. Neither view tells you what to do on its own, but watched together over time they turn dispatcher sizing from a one time calculation at startup into something you can keep tuned as the workload changes.

From MTS_DISPATCHERS to DISPATCHERS

If you search the web for Oracle dispatcher configuration, or open a parameter file inherited from a much older system, you may run across a name for this parameter that does not exist in current documentation at all: mts_dispatchers. This is not a typo or a different feature; it is the exact same parameter under its pre-Oracle9i name.

Oracle9i renamed the entire Multi-Threaded Server architecture to Shared Server, the same rename covered in Lesson 1, and every parameter belonging to that architecture was renamed along with it:
Pre-9i nameCurrent name
MTS_DISPATCHERSDISPATCHERS
MTS_MAX_DISPATCHERSMAX_DISPATCHERS
MTS_SERVERSSHARED_SERVERS
MTS_MAX_SERVERSMAX_SHARED_SERVERS
MTS_CIRCUITSCIRCUITS
MTS_SESSIONSSHARED_SERVER_SESSIONS

The old MTS_* names were kept for a while afterward purely for backward compatibility, so that an existing parameter file did not break overnight, and were eventually removed entirely. None of them appear anywhere in current Oracle AI Database 26ai documentation, so a parameter file still using them needs updating before it will work on a current release. What has not changed at all across this rename is the dispatcher's actual job: accept a connection, queue the work, hand it to a shared server.

It is worth recognizing these old names for a practical reason, not just a historical one. Forum answers, older blog posts, and even some third-party tooling still reference mts_dispatchers and its relatives, and it helps to immediately recognize that advice as describing today's DISPATCHERS, SHARED_SERVERS, and so on, rather than something unfamiliar or unsupported. The rename itself was not cosmetic. Oracle used the Oracle9i release to position this architecture as something broader than the original "multi-threaded" framing suggested, adding capabilities over the following releases, connection pooling among them, that had nothing to do with threading as such; "Shared Server" describes what the architecture actually does far better than "Multi-Threaded Server" ever did.

A small number of very old dispatcher attributes did genuinely disappear along the way, TICK and POOL among them. It is easy to lump these in with the parameter renames above and assume everything from that era is gone, but that is not quite right: the attributes you are actually most likely to use today, CONNECTIONS, SESSIONS, LISTENER, MULTIPLEX, and SERVICE, are all still current, still documented, and work exactly as covered in Lesson 2.

Changing the Dispatcher Count Today

The dispatcher count for a protocol is set in the initialization parameter file, but changing it does not require restarting the instance. Using the current parameter name and syntax, not the old mts_dispatchers form:

ALTER SYSTEM SET DISPATCHERS='(PROTOCOL=tcp)(DISPATCHERS=4)' SCOPE=BOTH;
SCOPE=BOTH here does two things at once: it changes the running instance immediately, and it writes the new value to the server parameter file (SPFILE) so the change survives a future restart. That second part only works if the instance is actually using an SPFILE rather than a traditional text based PFILE (the classic init.ora file). A PFILE is still fully supported; it simply cannot be written to by ALTER SYSTEM, so a PFILE based instance would use SCOPE=MEMORY instead and then edit the text file by hand to make the change persistent. This distinction, and how to work with either kind of parameter file day to day, is covered in more depth on the initialization parameters page in the database architecture course.

See Lesson 2 for the full ALTER SYSTEM syntax, including how to target one specific dispatcher configuration with INDEX when more than one exists, and how to confirm the change actually took effect using V$DISPATCHER and V$DISPATCHER_CONFIG.

Putting the last two sections together, a realistic sequence looks like this. You notice, via V$QUEUE, that TCP request wait times have been climbing steadily over the past week. You check V$DISPATCHER_RATE and confirm the existing TCP dispatchers are consistently busy rather than idle, which rules out some unrelated cause. You raise the TCP dispatcher count with ALTER SYSTEM SET DISPATCHERS='(PROTOCOL=tcp)(DISPATCHERS=4)' SCOPE=BOTH;, and a few minutes later query V$DISPATCHER to confirm the new dispatcher actually started. Then you go back to watching V$QUEUE to see whether wait times actually improved, rather than assuming the change worked just because the statement succeeded. None of the individual steps here are new; what matters is treating dispatcher sizing as this kind of ongoing loop rather than a value you set once at instance creation and never revisit.

Dedicated or Shared, Per Connection

Configuring dispatchers, however many you have and however well sized, does not mean every client connection ends up going through one. Shared Server and dedicated server connections coexist on the same instance, and which one a particular client uses depends on that client's own connect descriptor, not on the dispatcher configuration itself. A connect descriptor that includes (SERVER=DEDICATED) in its CONNECT_DATA gets a dedicated server regardless of how many dispatchers exist, while one that omits the SERVER attribute entirely defaults to Shared Server when it is available:

(DESCRIPTION=
  (ADDRESS=(PROTOCOL=tcp)(HOST=dbhost)(PORT=1521))
  (CONNECT_DATA=
    (SERVICE_NAME=orcl)
    (SERVER=DEDICATED)))
Drop the (SERVER=DEDICATED) line from that same descriptor and, on an instance with Shared Server configured, the connection goes through a dispatcher instead, using whichever dispatchers this lesson and Lesson 2 have covered.

This is worth keeping in mind as client connection methods themselves continue to evolve. Older material describing how a client locates and connects to a database, sometimes still labeled SQL*Net after a naming convention Oracle retired decades ago, predates connection approaches such as Easy Connect Plus and OCI-native service connection methods that are current for Oracle AI Database 26ai; the network topology course covers those modern connection methods in detail. Whichever way a client connects, though, the choice of dedicated versus shared service handler on the server side works the same way described above.

Bringing Lessons 1 Through 3 Together

Across these three lessons, Lesson 1 laid out the architecture: dispatchers, a common request queue, and a pool of shared servers, along with how that architecture has evolved from Oracle Database 19c through Oracle AI Database 26ai. Lesson 2 turned that architecture into concrete configuration: the DISPATCHERS parameter's full attribute syntax, the related parameters that cap and reserve resources around it, and how to size and change dispatchers without an instance restart. This lesson filled in the piece those two leave out: what a dispatcher is actually doing moment to moment, why its count has real consequences in either direction, and why you may see it called something else entirely in material written before Oracle9i. With all three in view, the remaining dispatch parameters in the next lesson should read as refinements to a picture you already have, rather than an entirely new set of facts to memorize.

The next lesson examines the remaining dispatch parameters.

SEMrush Software 3 SEMrush Banner 3