Hey, I am struggling a bit to determine the exact cause of an error that has been popping up in our release environment. There does not seem to be much dealing with this particular error on Google.
This is the error message we are getting:
SQLSTATE[34000]: Invalid cursor name:
7 ERROR: portal "" does not exist
The error only pops up when we are using PDO prepared statements.
This is the setup for our release environment:
pgpool 3.0.1 (The postgresql backend is in Streaming Replication mode!)
PHP 5.3.5
PostgreSQL 9.0
Edit: Architecture is 64bit.
The same error does not manifest in our test environment (Edit: forgot to mention, the standard test environment uses Postgresql 9.0 without pgpool). Thus, I am led to suspect that pgpool is at least partly suspect.
Does anyone know what the probable causes for this error are?
Edit: ok, here is an example of the kind of code that causes the error.
$sql = 'SELECT * ';
$sql .= 'FROM "myTable" as "myStuff" ';
$sql .= 'WHERE "myTable"."status" = 1 ';
$sql .= 'AND "myTable"."myTableId" = :tableId ';
$sth = $this->_db->prepare($sql);
$sth->bindParam(':tableId', $tableId, PDO::PARAM_INT);
$sth->execute();
Edit: Some log file output;
Postgresql:
postgresql-Sun.log-129- ORDER BY "id"
postgresql-Sun.log:130:ERROR: portal "" does not exist
postgresql-Sun.log-131-ERROR: prepared statement "pdo_stmt_00000011" does not exist
postgresql-Sun.log-132-STATEMENT: DEALLOCATE pdo_stmt_00000011
postgresql-Mon.log-82- where "id" = 32024
postgresql-Mon.log:83:ERROR: portal "" does not exist
postgresql-Mon.log-84-ERROR: prepared statement "pdo_stmt_00000002" does not exist
postgresql-Mon.log-85-STATEMENT: DEALLOCATE pdo_stmt_00000002
pgpool:
LOG: pid 22071: Replication of node:1 is behind 2080 bytes from the primary server (node:0)
LOG: pid 22071: Replication of node:2 is behind 2080 bytes from the primary server (node:0)
LOG: pid 13499: pool_send_and_wait: Error or notice message from backend: : DB node id: 0 backend pid: 8470 statement: message: portal "" does not exist
LOG: pid 13499: pool_send_and_wait: Error or notice message from backend: : DB node id: 0 backend pid: 8470 statement: DEALLOCATE pdo_stmt_00000003 message: prepared statement "pdo_stmt_00000003" does not exist
I've found a solution. Turns out this bug we are experiencing does not exists in Pgpool-II 3.1 alpha2. It looks like this bug was fixed in March after the 3.0.3 release. The solution is to download the release and build/install manually. Some of the paths are different, for instance the config path is /usr/local/etc/
Pgpool-II 3.1 alpha2 is available here:
http://pgfoundry.org/frs/?group_id=1000055
It's possible that the latest 3.0-Stable tree also has a fix for this issue. I am hoping to test an export from the CVS later tonight.
If you could duplicate the problem in your test environment, I wouldn't hesitate to recommend running the server with the -d (debug) option.
Since that's not the case, I'll just remind you that it's an option.
PostgreSQL command line options
On that page, there are a couple of "Semi-internal Options" that might help isolate the problem. Might not.
I believe I have a temporary work around, and am invested in finding a permanent solution. I am working on a high-availability PG cluster on Amazon EC2, and have also ran into this exact issue.
It occurs randomly for queries executed using DBI's prepare/execute blocks when DBI is routed through PGPool2 (3.0.3). The portal errors do not occur when PGPool2 is removed and we use Postgres 9 directly.
We run Perl, using DBI and DBD::PG. The common factor seems to be PGPool2.
One possible solution we have found is to set 'ignore_leading_white_space' = false in the pgpool.conf. The errors completely disappear for us with this option set. Unfortunately this does have the downside of potentially routing selects to the master that should be load balanced, as such I do not consider it a final solution.
Example of code that randomly generates this issue:
$sth = $dbh->prepare("SELECT * FROM TABLEX WHERE ID = ?" )
|| die "Can't prepare statement: " . $dbh->errstr;
$sth->execute($self->id) || die "Can't get inventory " . $dbh->errstr;
Related
I am currently building a small application that uses the message queue built in PHP.
I have 1 "server" process and 1 "client" process. Messages flow from server to client.
They are simple JSON objects, that are serialised, then send.
This code is used
<?php
$send = msg_send($q, MESSAGE_TYPE_EXECUTION, $update, true, false, $error);
if (isset($error) && $error != 0) {
echo 'Execution error: ' . $error . PHP_EOL;
}
// $q is the message queue integer
// MESSAGE_TYPE_EXECUTION is integer 1
// $update is the JSON string
// true is that the JSON string is serialised
// false is that it is blocking (which it is not)
// $error get's filled when an error occurs (see below)
This works without issue, until it does not.
Sometimes after a couple of minutes, sometimes after a couple of hours the following error appears:
PHP Warning: msg_send(): msgsnd failed: Resource temporarily unavailable in
/var/www/server.php on line 57
The value of the $error variable is the integer 11.
All messages that follow this error will have error 11, until I restart the process and all is working again (for a while, until the same error appears again)
I have been searching but cannot find any explanation what error 11 is, how this can be managed and fixed without restarting the process.
Any clue, information, example etc is welcome. I would really like for server.php to be reliable.
-- edit --
client.php is the process that fetches the messages (which are all more or less the same, but with other values)
it uses this fetch the messages from the queue (filled in server.php)
<?php
$update = msg_receive($q, 0, $messagetype, 1024, $message, true, MSG_IPC_NOWAIT && MSG_NOERROR, $error);
if ($update) {
// Do stuff
}
usleep(1000000);
I have not yet checked memory usage, will look into that
Platform used
PHP 7.1.3
Centos 7
So, Solution was found after some information and leads (read the comments on my original question), brought up by #ChrisHaas (Thanks again!). After some tinkering all is running smoothly now, without error 11 for msg_send().
PHP msg_send() call is basically a wrapper of msgsnd
So a lot of information can be found there, also about errors you might encounter (in combination with flags used when reading messages with msg_receive() )
The queue is limited in total size and total messages it can hold (I, however, have not found a way to increase the total size of the queue).
The reason I was getting error 11 was due to a couple of things:
The client I created was too slow fetching messages from the queue, causing it to run into the max limit and crapping out. I did not find a solution for fixing this situation, other than restarting all processes involved. To repeat the same over and over again.
I also increased the size of reading messages in msg_receive() as sometimes the messages where big (most where small). But when you declare a too small size the big messages will remain in queue and clog it up until it craps out. Increasing the max_size helped with fetching the bigger messages too.
Long story short: error 11 is related to a full message queue in my perspective (I still do not have a 100% clear documented answer though).
Pointers to fix the issue:
Be sure you fetch all messages that are big.
Be sure to read out at least as fast as you send the messages in the queue.
Check your queue(s) with the command ipcs -q in the terminal. It allows you to see the queues currently active. Keeping an eye on that allows you to see it slowly filling up on problems.
Wish the documentation on php.net was better in this case...
I am trying to talk to a remote MongoDB server from my system. The code i use is like this
$con_string='mongodb://server_ip:27017';
$m = new Mongo($con_string);
$temp=$m->selectDB("DBName");
try {
$mc=$temp->collection_name->find()->limit(5);
var_dump($mc->info());
var_dump(iterator_to_array($mc));
}
catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."</br>";
echo "error code: ".$e->getCode();
}
Now i get the following message from Xdebug
MongoCursorException: couldn't send query: ët§ôï9·H'ﯤ7·ø?u§Ht§ ö·Ìu§®u§Ì½u§4e
Why is this exception raised and why is there junk at the end of exception. I dont get this exception every time but 5 out of 6 times.
Also the message i got from catch block is
error message: couldn't send query: QY¥ôï9·H§ï³¤7·DCY¥h §
error code: 14
The error code 14 means "C socket error on send." says the PHP manual.
What does this error mean?
A guy in chat suggested that the junk is indicator that the data might not be utf8_encoded but i am doing a simple find() with no criteria so what do i need to encode?
EDIT:
To get around this scenario i wrote this
function getCursor($conn,$db_name,$coll_name,$query_options=array(),$fields=array(),$cursor_options=array(),$max_tries=0) {
$counter=0;
while(1) {
try {
$cursor=new MongoCursor($conn,$db_name.'.'.$coll_name,$query_options,$fields);
if (array_key_exists('count',$cursor_options))
return $cursor->count();
if (array_key_exists('limit',$cursor_options))
$cursor=$cursor->limit($cursor_options['limit']);
if (array_key_exists('skip',$cursor_options))
$cursor=$cursor->skip($cursor_options['skip']);
if (array_key_exists('sort',$cursor_options))
$cursor=$cursor->sort($cursor_options['sort']);
return $cursor;
}
catch (MongoCursorException $e) {
$counter+=1;
if ($max_tries>0) {
if ($counter>$max_tries)
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
return false;
}
}
}
}
The functions takes the query parameters and then send the query to the server and if the MongoCursorException is raised it sends the query again. It does this $max_tries times. If $max_tries is set to 0 it will keep on sending this query to the server until the query succeeds. Maybe this is stupid, i should have set this to some fixed value like 50. On success the function returns the cursor except when your looking for the count and in that case it returns the count
Your string looks like that if:
You have a charset encoding issue
Memory is broken
As in your code not much strings are involved, the chances that this is an encoding issue are not very high.
But as Xdebug is a PHP extension that deals a lot with internals, breaking memory can be one thing.
An easy way to find out is to disable the extension you suspect that is causing the issue, e.g. xdebug.
It is also useful for documentation purposes tp write down which PHP and extension versions you are using as well as on which operating system. I asked for that in comments, it's a list like:
PHP 5.3.10
Mongodb Extension 1.2.10
Mongodb Server 2.0.6
Xdebug 2.2.0
Centos 6.2 64-bit
Checking the website for xdebug shows that there is a new version available. As you have found out earlier by disabling xdebug that it influences the result, try with updating the xdebug extension and see if it helps.
Even if it does, keep your version list for further reference (as well with a short description of the problem), because in case the problem is not fully solved with the upgrade, this information can be very useful at a later time to do a useful bug-report. Those internal problems in the software are sometimes hard to spot, so the information can help to reproduce easier then or to identify the areas involved.
This is fixed in Mongo driver v1.3+
ref: https://groups.google.com/forum/?fromgroups=#!topic/mongodb-user/IJ1n_Xt_al8
Downloads: http://docs.mongodb.org/ecosystem/drivers/
I am currently connecting sucessfully to an SQL database sat on a Windows 2008 using the following query;
$result = mssql_query("EXEC dbo.stored_procedure_name #param_level = 2");
I am basing my queries on existing code written in VB / ADO which looks like;
If level = "" Then level = 1
cmdTT.ActiveConnection = connStrTest1
set objParam=cmdTT.CreateParameter("#param_level", adInteger, adParamInput, 4, level)
cmdTT.Parameters.Append objParam
set rsTT = cmdTT.Execute
So what I attempted was the following;
$f = 2;
$stmt = mssql_init('dbo.stored_procedure_name', $mssql_link);
mssql_bind($stmt, "#param_level", $f, SQLINT4, false);
mssql_execute($stmt);
But no matter what the variation it always seems to print the print the screen the warning, "Warning: mssql_execute() [function.mssql-execute]: stored procedure execution failed in ...".
Whats the best way for me to debug the issue here? Can anyone see a clear fix to my problem?
I'm currently connecting remotely to the database from a LAMP stack.
Many Thanks
Ian
Is this from a linux server using FreeTDS? If so, I wonder if this is related to TDS Version. Try tds version = 8.0 in you /etc/freetds.conf
Run the contents of the stored procedure from w/in a sql editor with the parameters hard coded in. You'll get more verbose error messages that way.
I know it's an old post but am sure it will help someone.
You have to add mssql_free_statement($stmt) after executing.
How do i get a detailed error description during a php-mysql script run?
I have the following statements where the script fails and displays the custom error message - the contents of the "or die".
I want to get the actual error from MySQL (instead of the custom error i have mentioned), which would give better idea about the scenario - whether its a database issue or server connectivity issue etc..
this is the code i have where i need to enhance the error reporting
$query = "SELECT * FROM table_name";
$result = mysqli_query($db_conn, $query)
or die('Connected to database, but querying failed');
thanks!
Check out mysql_error function.
Have a look at the manual page for mysqli_error. In the section "Procedural style" you'll find a complete example that shows how to set up the database connection and querying the database, both steps with error handling.
If you want detailed error information from your scripts you can put the lines
error_reporting( E_ALL );
ini_set('log_errors', true);
ini_set('error_log', '/tmp/php-errors.log');
at the start of your code. That way all errors coming from PHP will be written into the log file. Make sure that the path to the log file exists (/tmp is only an example) and is writable by the web server, otherwise the errors will be silently discarded.
As a side note: While the "or die()" pattern is good for small examples, you should not use it in production code.
I prefer using PDO, and having PDO throw an exception.
you could insert the query into the query page on phpmyadmin that is if you are using it. But this wont tell you if the errors are with the variables
I wrote a utility for updating the DB from a list of numbered .sql update files. The utility stores inside the DB the index of the lastAppliedUpdate. When run, it reads lastAppliedUpdate and applies to the db, by order, all the updates folowing lastAppliedUpdate, and then updates the value of lastAppliedUpdate in the db. Basically simple.
The issue: the utility successfully applies the needed updates, but then when trying to store the value of lastAppliedUpdate, an error is encountered:
General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
Any ideas, what does it mean, and how can be resolved?
Below is the essence of the code. It's a php code within the Yii framework.
foreach ($numericlyIndexedUpdateFiles as $index => $filename)
{
$command = new CDbCommand (Yii::app()->db, file_get_contents ($filename));
$command->execute();
}
$metaData = MDbMetaData::model()->find();
$metaData->lastAppliedUpdate = $index;
if (!$metaData->save()) throw new CException ("Failed to save metadata lastAppliedUpdate.");
// on this line, instead of throwing the exception that my code throws, if any,
// I receive the described above error
mysql version is: 5.1.50, php version is: 5.3
edit: the above code is done inside a transaction, and I want it to.
Check it out
PDO Unbuffered queries
You can also look at the to set PDO:MYSQL_ATTR_USE_BUFFERED_QUERY
http://php.net/manual/en/ref.pdo-mysql.php
The general answer is that you have to retrieve all the results of the previous query before you run another, or find out how to turn off buffered queries in your database abstraction layer.
Since I don't know the syntax to give you with these mysterious classes you're using (not a Yii person), the easy fix solution is to close the connection and reopen it between those two actions.