I know that PHP automatically closes open MySQL connections at the end of the script, and the only viable way to open a persistent connection is to use the appropriate PHP function; many questions have been asked and answered.
What I would like to know is the benefit - or the inconvenient - of keeping a temporary connection instead of a persistent connection
EDIT :
A persistent connection for each PHP user session.
For instance, statements such as the following:
session_start();
$connection = new mysqli($host, $user, $pass, $db);
$_SESSION['connection'] = $connection;
might set up a reference to a mysqli object useful for performing multiple queries across navigation in the website within the same session by the same user.
If the connection is supposed to be used soon after its activation, would not be the right choice to leave it just open for further queries? Maybe this approach would generate an inconvenient situation (and possible security risks) when multiple users are HTTP-requesting pages from a web site which keeps MySQL connections alive?
I would like to know more. Thank you.
There's overhead to connecting to MySQL or any database, although it isn't typically large. This overhead can be greater when the MySQL service is running on a different server, or depending on the authentication method and init commands needed.
More, MySQL connections may have associated caches. So reusing a connection may be able to reuse these caches.
But saving a resource in the session doesn't work. Session data is serialized, and stored in e.g. a file between requests. That's why the persistent connect methods have to be used.
The reason is that the connection is ultimately a resource, or a socket connection on an internal class, and this can't be "saved" without special handling. Try it, and you'll see that you get an error (with PDO and mysqli.)
mysqli::query(): Couldn't fetch mysqli
I don't think there's any way to get session-specific connection reuse without writing an extension to implement it. Theoretically it's possible, though, and you could theoretically implement a method to pull a connection from the pool by session id.
There are a lot of potential drawbacks and risks to persistent db connections, though:
If your application creates TEMPORARY TABLEs, those tables will still exist on the next run, since it's the same MySQL session.
If you set any variables (SET SESSION or etc.), they will be retained.
Depending on how transactions are handled, it's theoretically possible a persistent connection may have an in-progress transaction.
If the application issues any LOCK commands or uses user-locks, the locks could be held between requests and unknowingly held in new requests.
On a multi-tenant (shared) webserver, the risk of another process somehow obtaining database access it shouldn't have is higher.
This may leave large numbers of connections open for long periods of time, increasing resource usage on the database server.
You still have to expect that the connection might be lost between requests.
Related
This question has a wide area set, e.g. web servers, database servers, php application, etc and hence I doubt it belongs refers to stackoverflow, however since this question will help us on how to write the application code, I have decided to ask it here.
I have a confusion on how database sessions and web servers work together. If I am right, when a connection is made for a client, ONLY one session will be created for that connection, and that will last till the time either the connection is disconnected or it is reconnected due to long inactivity.
Now if we consider a web server, Apache 2.4 in particular running a PHP 7.2 application (in Virtual Host) with a database backed by MariaDB 10.3.10 (on Fedora 28 if that matters at all), I assume the following scenario (please correct me if I am wrong):
For each web application, right now we use Laravel, only one database connection will be made as soon as the first query is hit to the URLs it serves.
Subsequently, it will only have ONE database session for that. When the query is served, the connections is kept alive to be reused by other queries the application receives. That means most likely if the application receives web requests 24 x 7 continuously, the connection will be also kept alive and only will be disconnected when we restart either mysqld or httpd, that might not even happen in months.
Since all the users of the application, let us say something like 20 users at time, uses the same Apache servers and Laravel application files (I assume I can call that an application instance) all the 20 users will be served through the same database connection and database session.
If all the use cases mentioned above is right, then the concept of database locking seems very confusing. Since let's say we would issue an exclusive lock, e.g. lock tables t1 write;, it will block the reads and writes of the other sessions, to avoid dirty read and write operations for concurrent sessions. However, since all the 20 users uses the same session and connection concurrently, we will not get the required concurrency safety out of database locking mechanism.
Questions:
How database locking, explicitly exclusive lock work in terms of web applications?
Will each web request received at Laravel application create a new connection and session, or ONLY one connection and session is reused?
Will each database connection have only and only ONE session at a time?
Will this command shows the current active sessions or connections show status wherevariable_name= 'Threads_connected'? If it shows the current active connections, how we can get the current active database sessions?
Apache has nothing to do with sessions in this scenario (mostly). Database connections and sessions are handled by php itself.
Unless you have connection pooling enabled, database sessions will not be reused, each request will open its own connection and close it at the end.
With connection pooling enabled the thread serving the request will ask for a connection from the pool to the process manager (be it fpm or mod_php) and it will return an available connection from the pool, but there will still be at least as many sessions as concurrent requests (unless you hit any of the max_ limits). The general reference goes into more details, but as a highlight:
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.
Even having a connection pool available, the manager must run some cleanup operations before returning the conection to the client. One of those operations is table unlocking.
You can refer to the connections reference and persistent connections reference of the mysqli extension for more information.
However, the mode of operation you are describing where multiple client sessions share a connection is possible (and experimental) and has more drawbacks. It's known as session multiplexing.
I created a temporary table in one php file, and want to access it in another php file. the scripts run sequentially. I used mysqli and am prepending p: to hostname.
The problem is in my second php file, I cant access my temporary table. So I wanted to know if its possible to do this, or not? And if yes how? Am using WAMP server.
Not possible, directly. Temporary tables are destroyed when the connection used to establish them is closed. When your "create" script shuts down, its DB connection is closed, and mysql cleans - including destroying that temp table.
That means when your "use" script fires up, it gets a new connection, without any of the stuff that the first script did.
There are persistent connections available in PHP, but those connections exist in a pool, and there is no control over WHICH connection any particular scripts gets from that pool. You may get lucky and receive the same connection for two different scripts, but it's purely by chance.
You'd need some OTHER 3rd script that operates continously to hold open the mysql connection, leaving the temp table in place. And your other two scripts would communicate with this third one.
From http://php.net/manual/en/mysqli.persistconns.php
The persistent connection of the mysqli extension however provides built-in cleanup handling code. The cleanup carried out by mysqli includes:
(worth reading the other things too but the important bit is)
Close and drop temporary tables
In short, a temporary table is just that, temporary. It's not meant to be used for other purposes than to temporarily store some data for one specific operation. If you want a more permanent thing consider using a concrete table with a memory storage engine.
Are there any disadvantages to caching a MySQL connection?
For example,
$mysqli = new mysqli(params);
apc_store('mysqli', $mysqli);
This would save some time if there are lots of users on your site all requiring connections. Instead of opening a connection for every user, why not cache it?
I haven't found anything by googling, so just wondering if I've missed something.
Thanks for your time.
A mysqli object is not something you can cache. It's a resource, not a plain object.
Fetching it out of the cache would require it to reconnect to the database server, which means that the cached version would need to store a password in plaintext, which makes it a security flaw if you could cache it.
Also, there's no guarantee that the database server would still be available when you fetch it out of the cache.
And there's no way for multiple PHP requests to share the same cached resource. There's all sorts of problems with this plan.
What is a solution for your goal is persistent mysqli connections, so the PHP runtime environment maintains some number of connections and can reuse them from one PHP request to the next.
I'm implementing an application that will have a lot of clients querying lots of small data packages from my webserver. Now I'm unsure whether to use persistent data connections to the database or not. The database is currently on the same system as the webserver and could connect via the socket, but this may change in the near future.
As I know a few releases of PHP ago mysqli_pconnect was removed because it behaved suboptimally. In the meantime it seems to be back again.
Based on my scenario I suppose I won't have an other chance to handle thousands of queries per minute but with loads of persistent connections and a MySQL configuration that reserves only little resources per connection, right?
Thanks for your input!
What happened when you tested it?
With the nest will in the world, there's no practical way you can convey all the informaton required for people to provide a definitive answer in a SO response. However usually there is very little overhead in establishing a mysql connection, particularly if it resides on the same system as the database client (in this case the webserver). There's even less overhead if you use a filesystem rather than a network socket.
So I'd suggest abstracting all your database calls so you can easily switch between connection types, but write your system to use on-demand connections, and ensure you code explicitly releases the connection as soon as practical - then see how it behaves.
C.
Are PHP persistant connections evil?
The problem is there can be only so
many connections active between Host
“Apache” and Host “MySQL”
Persistant connections usually give problems in that you hit the maximum number of connections. Also, in your case it does not give a great benefit since your database server is on the same host. Keep it to normal connections for now.
As they say, your mileage may vary, but I've never had good experiences using persistent connections from PHP, including MySQL and Oracle (both ODBC and OCI8). Every time I've tested it, the system fails to reuse connections. With high load, I end up hitting the top limit while I have hundreds of idle connections.
So my advice is that you actually try it and find out whether your set-up is reusing connections properly. If it isn't working as expected, it won't be a big lose anyway: opening a MySQL connection is not particularly costly compared to other DBMS.
Also, don't forget to reset all relevant settings when appropriate (whatever session value you change, it'll be waiting for you next time to stablish a connection and happen to reuse that one).
Are there any tricks to transferring and/or sharing the Resource Links across multiple PHP pages? I do not want the server to continue connecting to the database just to obtain another link to the same user in the same database.
Remember that the link returned from mysql_connect() is automatically closed after the script it originated on completes executing. Is there anyway to close it manually at the end of each session instead?
PHP allows persistent mysql connections, but there are drawbacks. Most importantly, idle apache children end up sitting around, holding idle database connections open. Database connections take up a decent amount of memory, so you really only want them open when they're actually being used.
If your user opens one page every minute, it's far better to have the database connection closed for the 59 seconds out of every minute you're not using it, and re-open it when needed, than to hold it open continually.
Instead, you should probably look into connection pooling.
One of the advantages of Mysql over other heavier-weight database servers is that connections are cheap and quick to setup.
If you are concerned about large numbers of connections to retrieve the save information, you may like to look at such things as caching of information instead, or as well as getting the information from disk. As usual, profiling of the number, and type of calls to SQL that are being made, will tell you are great deal more than anyone here guessing at what you should really be doing next.