I have a PHP/MySQL website and it is hosted on Shared hosting. This website is not a huge traffic site. But I got an error (Too Many Connections Error) frequently. The hosting provider said that 25 MySQL connections at a time
I am using two functions for database connections, initDB() and closeDB()
function initDB()
{
$connection = mysql_connect($DatabaseURL,$DatabaseUName,$DatabasePWord);
if($connection)
{
$db = mysql_select_db($DatabaseName,$connection);
}
return $connection;
}
function closeDB($connection)
{
mysql_close($connection);
}
gettings data from database
$connection = initDB();
//executing MySQL query
closeDB($connection);
This is working fine, but sometime got Too Many Connections Error.
In my website, initDB() and closeDB() functions are called 76 times.
I am sure the opened connections are closed after execution
If any problem in the above code
How can i solve the Too Many Connections Error
You can use fast-hack of your code using static.
function initDB()
{
static $connection;
if (!$connection) //establish connection only once
{
$connection = mysql_connect($DatabaseURL,$DatabaseUName,$DatabasePWord);
if($connection)
{
$db = mysql_select_db($DatabaseName,$connection);
}
}
return $connection;
}
function closeDB($connection)
{
//no need to close.
}
Related
I am using PHP 7.2 on a website hosted on Amazon. I have a code similar to this one that writes a record in the MongoDB:
Database connection class:
class Database {
private static $instance;
private $managerMongoDB;
private function __construct() {
#Singleton private constructor
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new Database();
}
return self::$instance;
}
function writeMongo($collection, $record) {
if (empty($this->managerMongoDB)) {
$this->managerMongoDB = new MongoDB\Driver\Manager(DB_MONGO_HOST ? DB_MONGO_HOST : null);
}
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert($record);
try {
$result = $this->managerMongoDB->executeBulkWrite(
DB_MONGO_NAME . '.' . $collection, $bulk, $writeConcern
);
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
// Not important
} catch (MongoDB\Driver\Exception\Exception $e) {
// Not important
}
return $result->getInsertedCount() > 0;
}
}
Execution:
Database::getInstance()->writeMongo($tableName, $dataForMongo);
The script is working as intended and the records are added in MongoDB.
The problem is that connections are not being closed at all and once there are 500 inserts (500 is the limit of connections in MongoDB on our server) it stops working. If we restart php-fpm the connections are also reset and we can insert 500 more records.
The connection is reused during the request, but we have requests coming from 100s of actual customers.
As far as I can see there is no way to manually close the connections. Is there something I'm doing wrong? Is there some configuration that needs to be done on the driver? I tried setting socketTimeoutMS=1000&wTimeoutMS=1000&connectTimeoutMS=1000 in the connection string but the connections keep staying alive.
You are creating a client instance every time the function is invoked, and never closing it, which would produce the behavior you are seeing.
If you want to create the client instance in the function, close it in the same function.
Alternatively create the client instance once for the entire script and use the same instance in all of the operations done by that script.
I've been struggling with this for quite a while, and it's to the point where I need to ask for help because even with all the research I've done I can't get a handle on why this is happening.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1040] Too many connections'
This happens upon loading a single page (index.php), and I am the only user (dev). As you can see here, the MySQL connection limit is set # 50 but I am narrowly surpassing that. This is an improvement over the 100~ connections that were being created before I refactored the code.
Here are the stats after the page has loaded once.
I've narrowed the issue down to several causes:
I don't fully understand how PDO/MySQL connections work.
I am creating too many connections in my code even though I am trying to only create one that I can share.
I need to increase the connection limit (seems unlikely).
Most of the SO questions I've found, tell the OP to increase the connection limit without truly knowing if that's the best solution so I'm trying to avoid that here if it's not needed. 50 connections for one page load seems like way too many.
These are the classes I am instantiating on the page in question.
$DataAccess = new \App\Utility\DataAccess();
$DataCopyController = new App\Controllers\DataCopyController($DataAccess);
$DriveController = new App\Controllers\DriveController($DataAccess);
$Helper = new App\Utility\Helper();
$View = new App\Views\View();
I am creating the DAL object then injecting it into the classes that need it. By doing it this way I was hoping to only create one object and one connection, however this is not what's happening obviously. Inside the DAL class I've also added $this->DbConnect->close() to each and every query method.
Here is the constructor for the DataAccess() class.
public function __construct() {
$this->DbConnect = new \App\Services\DbConnect();
$this->db = $this->DbConnect->connect("read");
$this->dbmod = $this->DbConnect->connect("write");
$this->Helper = new Helper();
}
Here is the DbConnect() class.
class DbConnect {
private $db;
private $dbmod;
private function isConnected($connection) {
return ($connection) ? TRUE : FALSE;
}
public function connect($access) {
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
];
if ($access == "read") {
if ($this->isConnected($this->db)) {
return $this->db;
} else {
if (strpos($_SERVER['SERVER_NAME'], DBNAME_DEV) === false) {
$this->db = new PDO("mysql:host=127.0.0.1; dbname=".DBNAME,
DBUSER,
DBPASS,
$options
);
} else {
$this->db = new PDO("mysql:host=" . DBHOST_DEV ."; dbname=".DBNAME_DEV,
DBUSER,
DBPASS,
$options
);
}
return $this->db;
}
} elseif ($access == "write") {
if ($this->isConnected($this->dbmod)) {
return $this->dbmod;
} else {
if (strpos($_SERVER['SERVER_NAME'], DBNAME_DEV) === false) {
$this->dbmod = new PDO("mysql:host=127.0.0.1; dbname=".DBNAME,
DBUSER_MOD,
DBPASS,
$options
);
} else {
$this->dbmod = new PDO("mysql:host=" . DBHOST_DEV . "; dbname=".DBNAME_DEV,
DBUSER_MOD,
DBPASS,
$options
);
}
}
return $this->dbmod;
}
}
public function close() {
$this->db = null;
$this->dbmod = null;
}
}
I've also tried instantiating the DbConnect() class on index.php and injecting that rather than DataAccess() but the result was the same.
EDIT:
I also want to add that this MySQL server has two databases, prod and dev. I suppose the connection limit is shared between both. However, the prod database gets very little traffic and I am not seeing this error there. When I refreshed the stats, there were no connections to the prod database.
From the PHP manual ~ http://php.net/manual/en/pdo.connections.php
Many web applications will benefit from making persistent connections to database servers. Persistent connections are not closed at the end of the script, but are cached and re-used when another script requests a connection using the same credentials.
So I would advise removing the DbConnection#close() method as you would not want to ever call this.
Also from the manual...
Note:
If you wish to use persistent connections, you must set PDO::ATTR_PERSISTENT in the array of driver options passed to the PDO constructor. If setting this attribute with PDO::setAttribute() after instantiation of the object, the driver will not use persistent connections.
So you'll want (at least)
new \PDO("mysql:host=127.0.0.1;dbname=" . DBNAME, DBUSER, DBPASS, [
PDO::ATTR_PERSISTENT => true
]);
You can also set your other connection attributes in the constructor.
I have a project which has been developed in php 4 now it has to be upgraded to php 7.
The database is connected via odbc connection. When i try to connect to the database and run the index file nothing seems to pop up.
What i have done is i have converted my database into mysql and tried to connect to the database and it is connecting .
How do i change the complete odbc to mysql?
Please find below the odbc dataconnection file and let me know how to i connect it with mysqli.
<?php
//##################### ODBC CONNECT #######################
class DBConnectionManager{
var $DB;
function DBConnectionManager(){
$this->DB=$this->DBConnect();
}
function DBConnect()
{
//connection to database
// $dbconnect = odbc_connect(DB_SOURCE_NAME,DB_USERNAME,DB_PASSWORD)
$dbconnect = new mysqli("localhost",DB_USERNAME,DB_PASSWORD);
or die("Unable to Connect to SQL SERVER on ".DB_SOURCE_NAME);
return $dbconnect;
}
function DBexecute($query='')
{
$result = odbc_exec($this->DB,$query);
return $result;
}
function DBRows($query='')
{
$result=$this->DBexecute($query);
$num_row = 0;
while ($row = odbc_fetch_array($result))
{
$num_row++;
}
odbc_free_result($result);
return $num_row;
}
function mysqlFetchArray($arry){
return odbc_fetch_array($arry);
}
function closeConnection(){
if(isset($this->DB)){
odbc_close($this->DB);
unset($this->DB);
}
}
}
?>
What are the other changes i have to make?
Thanks in advance,
Renu
I've got a class that is pulling and aggregating data from a Mongo DB. This is all working fine...I have multiple queries being run for a connection under the same connection (in the same class). However, every time I refresh the page, a new connection is opened...I can see this in my mongod output:
[initandlisten] connection accepted from 127.0.0.1:46770 #12 (6 connections now open)
I see this count up and up with every page refresh. This should be fine, I think; however, the connections never seem to close.
After a while, the connections / locks take up too much memory in Mongo, and I can no longer run the queries.
This dev environment is on a 32-bit version of Mongo, so I don't know if this is only happening because of that. (Our prod env is 64-bit, and I cannot change the dev env right now.)
My question is: Should I be closing the connection after all the queries have been made for a particular user? How should I be handling the connection pool?
The service class:
class MongoService{
protected $mongoServer;
public function setSpokenlayerMongoServer($mongoServer)
{ $this->mongoServer = $mongoServer; }
protected $mongoUser;
public function setSpokenlayerMongoUser($mongoUser)
{ $this->mongoUser = $mongoUser; }
protected $mongoPassword;
public function setSpokenlayerMongoPassword($mongoPassword)
{ $this->mongoPassword = $mongoPassword; }
protected $conn;
public function setServiceConnection($conn)
{ $this->conn = $conn; }
public function connect(){
try {
$this->conn = $this->getMongoClient();
} catch(Exception $e) {
/* Can't connect to MongoDB! */
// logException($e);
die("Can't do anything :(");
}
}
public function getDatabase($name){
if(!isset($this->conn)){
$this->connect();
}
return $this->conn->$name;
}
protected function getMongoClient($retry = 3) {
$connectString= "mongodb://".$this->mongoUser.":".$this->mongoPassword."#". $this->mongoServer."";
try {
return new MongoClient($connectString);
} catch(Exception $e) {
/* Log the exception so we can look into why mongod failed later */
// logException($e);
}
if ($retry > 0) {
return $this->getMongoClient(--$retry);
}
throw new Exception("I've tried several times getting MongoClient.. Is mongod really running?");
}
}
And in the service class where the queries are:
protected function collection(){
if(!isset($this->collection)){
$this->collection = $this->db()->selectCollection($this->collectionName);
}
return $this->collection;
}
And then a query is done like so:
$results = $this->collection()->aggregate($ops);
Is this correct behavior?
Known issue if you're using Azure IaaS, possible issue on other platforms.
One option would be to change the Mongo configuration:
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(5);
This would kill all idle connections after 5 minutes.
I have just changed the connection driver (extension) from mssql_connect to work with sqlsrv_connect. Unfortunately things do not seem to work as I wanted. I'd appreciate if someone can tell me what’s wrong and how can I fix it.
Code excerpt:
//a oracle DB moudle with a generic functions such as
//db_connect() db_query()
/// turn on verbose error reporting (15) to see all warnings and errors
error_reporting(15);
//generic DB operations
// Global record . for using in
$curr_rec = NULL;
function dbok($res)
{
if($res==false){
echo "DB error: "."FIXME need error mesg"."\n";
exit;
}
return $res;
}
function db_now_expr()
{
return "getdate()";
}
function db_is_connected($dbh)
{
return $dbh>0;
}
function ensure_connected($dbh)
{
if(!db_is_connected($dbh)) die("DB is not connected, operation failed");
//echo "DEBUG: hdb=$dbh";
}
//connect to given database
//return handler to DB
function dbo_logon($dbserver,$dbname)
{
$tsql = ??????? ====>>> what should i put here????
$dbserver = "computername\SQLEXPRESS";
$dbname = MY_Database_name;
$connectionOptions = array("Database"=>"BULL");
$dbh=dbok(sqlsrv_connect($dbserver, $connectionOptions));
dbok(sqlsrv_query($dbname,$dbh));
$stmt = sqlsrv_query( $connectionOptions, $tsql );
return $dbh;
}
//close DB
function dbo_logoff($dbh)
{
if(!db_is_connected($dbh)) echo("DB disconnect error");
sqlsrv_close($dbh);
}
Here is the original code using mssql_connect:
//a oracle DB module with a generic function such as
//db_connect() db_query()
/// turn on verbose error reporting (15) to see all warnings and errors
error_reporting(15);
//generic DB operations
// Global record . for using in
$curr_rec = NULL;
function dbok($res)
{
if($res==false){
echo "DB error: "."FIXME need error mesg"."\n";
exit;
}
return $res;
}
function db_now_expr()
{
return "getdate()";
}
function db_is_connected($dbh)
{
return $dbh>0;
}
function ensure_connected($dbh)
{
if(!db_is_connected($dbh)) die("DB is not connected, operation failed");
//echo "DEBUG: hdb=$dbh";
}
//connect to given database
//return handler to DB
function dbo_logon($dbserver,$dbuser,$dbpass,$dbname)
{
// $dbh=dbok(mssql_pconnect($dbserver,$dbuser,$dbpass));
$dbh=dbok(mssql_connect($dbserver,$dbuser,$dbpass));
//error_log("connect to [$dbname]".date("His")." \r\n",3,"/tmpbull.log"); //DBEUG DELME
dbok(mssql_select_db($dbname,$dbh));
//dbo_exec($dbh,"alter session set NLS_DATE_FORMAT='dd-mm-yyyy //hh24:mi:ss'");
return $dbh;
}
//close DB
function dbo_logoff($dbh)
{
if(!db_is_connected($dbh)) echo("DB disconnect error");
mssql_close($dbh);
}
Note that I had to change the authentication method from SQL authentication to Windows authentication because sqlsrv_connect uses Windows authentication instead of SQL authentication. Is that right?
I think these two links will help to understand Difference between mssql and sqlsrv
http://blogs.msdn.com/b/brian_swan/archive/2010/03/08/mssql-vs-sqlsrv-what-s-the-difference-part-1.aspx
http://blogs.msdn.com/b/brian_swan/archive/2010/03/10/mssql-vs-sqlsrv-what-s-the-difference-part-2.aspx
Though in short, to quote one of the articles:
The sqlsrv driver is built, maintained, and supported by Microsoft`
and
The mssql driver is a community-built driver.
I’m not sure how recently this driver was updated or maintained as an official PHP extension, but as of the release of PHP 5.3, it is no longer available with PECL. A quick internet search turns up a few places to download the mssql driver, but none of them that I’ve found indicate that the driver is being actively maintained.
Source: http://blogs.msdn.com/b/brian_swan/archive/2010/03/08/mssql-vs-sqlsrv-what-s-the-difference-part-1.aspx
As for your code sample, see below:
$dbserver = "computername\SQLEXPRESS";
$dbname = "BULL";
$connetion = dbo_logon($dbserver,$dbname);
function dbo_logon($dbserver,$dbname) {
$connectionOptions = array("Database"=>$dbname);
$dbh=sqlsrv_connect($dbserver, $connectionOptions);
if(!$dbh){
die("Error in Database connection");
return false;
}
return $dbh;
}
I think this will work for the connection.please note the code is not tested.
"The sqlsrv driver is built, maintained, and supported by Microsoft`" well right now Sep 2014, there is no official release to support php 5.6 last official release is from april 2012. MS style...