When Asterisk 13.8.0 gets released, it will contain a large-scale change to the ODBC code. Those of you that use ODBC for your realtime configuration will either see no change or a performance improvement.
The big change is how Asterisk manages ODBC connections: it doesn’t do it anymore.
Why remove ODBC connection management?
Like most things, it started with identifying a specific problem. Some Asterisk servers seemed to be handling SIP traffic slower than we expected. When we inspected backtraces of the running system during those times, we noticed that many threads in the system were waiting attempting to perform database operations.
What were those threads waiting for? Asterisk, by default, set “share_connections = yes” in res_odbc.conf. This meant Asterisk opened a single connection to the database, then re-used it for all operations. Because databases are not cool with attempting simultaneous operations on a single connection, Asterisk had to hold a lock any time that an operation was performed on the database connection. In other words, all database queries were mutually exclusive.
Using a single database connection in a highly multi-threaded application was going to cause concurrency problems. The obvious solution to this was to use multiple connections. And look! Asterisk already had such an option. By setting “share_connections = no”, we maintained a connection pool. The problem was the code that maintained the connection pool was a bit of a mess.
- The algorithm to find a connection was overly complex.
- The reference counting being used was confusing.
- The mechanisms for determining that a stale connection was still valid were arcane.
- There were bugs.
How do we fix it?
With the flaws of the current connection pool, we faced a question: was it worth refactoring the code we already had? Or would we be better off using an external solution? After researching the options, we elected to let unixODBC do the work of maintaining the connection pool for us. This resulted in removing around 1000 lines of code from res_odbc.c
As a user, if you were to notice any change at all, you might see performance improve. The biggest user-facing changes are the “pooling,” “share_connections,” “limit,” and “idlecheck” options no longer have any effect since Asterisk is not maintaining the connection pool. If you have those options defined, you’ll see a warning message on startup letting you know that you don’t need to set those options any longer. Because of how Asterisk requests connections from unixODBC, it’s strongly recommended that you set up connection pooling in unixODBC.
What does this mean going forward? This code change helps on a few fronts:
- It curbs a performance bottleneck that was being observed on production systems.
- The ODBC code is less complex. This means fewer chances for bugs.
- Auditing ODBC code has helped to show areas that could use improvement.
This is the first time in a long while that the ODBC code has received this much attention. Expect this to be a jumping-off point for further improvements in the ODBC code. With the code simplified, we expect that will be easier for the core Asterisk team and the wider community to offer changes that will be accepted quickly.