php - MySQL with ND connection failover with PhalconPHP/PDO -
in this part of mysql-nd manual described how implement recommended way of failing on when loosing connection slave mysql server.
i'am willing implement in phalconphp. have couple of important projects using phalcon , mysql-nd, important me in right place.
trying find documentation, can't find example start with. trying find eventmanager approach, looking phalcon documentation here , here can't find way transparently.
most attractive way use event manager capture error event , query same again if connection error.
1 update
after reading phalcon sources found, there may no way run same query second time in standard way - mean here via kind of pdo parameter or using phalcons' eventmanager
attached db
service. 1 possible attempt found run query after db:afterconnection
event, not solution.
2 update
db:afterconnection
hardly reachable, instead possible gather during db:beforequery
. problem is, pdo run phalcon pdo::attr_errmode => pdo::errmode_exception
, when connection slave dies can't reach db:afterconnection
event. possible obtain pdo instance during db:beforequery
, change attribute via eventmanager
, gives nothing, because if able send same query second time, can't find way return in proper place (cannot override query result during db:afterquery
) because obtained statement not part of event send, , eventmanager result not being used @ all:
if typeof statement == "object" { if typeof eventsmanager == "object" { eventsmanager->fire("db:afterquery", this, bindparams); } return new resultpdo(this, statement, sqlstatement, bindparams, bindtypes); }
for seems fixed configuration:
{ "db-cluster": { "master": { "master": { "host": "master.local", "port": 3306 } }, "slave": { "slave-1": { "host": "slave-1.local", "port": 3306 }, "slave-2": { "host": "slave-2.local", "port": 3306 }, "slave-3": { "host": "slave-3.local", "port": 3306 } }, "filters": { "roundrobin": [] }, "failover": { "strategy": "loop_before_master", "remember_failed": true, "max_retries": 1 }, "server_charset": "utf8" } }
if server unreachable fallbacks other, problem was trying connect unreachable server @ least 3 seconds. walkaround be:
$eventsmanager = new eventsmanager(); $connection->seteventsmanager($eventsmanager); $eventsmanager->attach('db:beforequery', function($event, $connection) { // fix: if slave not respond, without goes on 3 seconds before trying next 1 !defined('dst') && define('dst', ini_get('default_socket_timeout')); ini_set("default_socket_timeout", 1); }); $eventsmanager->attach('db:afterquery', function($event, $connection) { ini_set('default_socket_timeout', defined('dst') ? dst : 60); });
even if works (when slave unreachable hangs on @ 1 second - , still lot of time), still not allow me put hands on connection php source write recommended solution.
update
it possible override executeprepared
method phalcon\db\adapter\pdo
class via extending phalcon\db\adapter\pdo\mysql
class:
namespace application; use \pdoexception; class mysql extends \phalcon\db\adapter\pdo\mysql { public function executeprepared(statement, placeholders, datatypes) { try { !defined('dst') && define('dst', ini_set('default_socket_timeout', 1)); $stmt = parent::executeprepared(statement, placeholders, datatypes); ini_set('default_socket_timeout', dst ?: 60); return $stmt; } catch(pdoexception $e) { if(/* logic find [2002, 2003, 2005] sql errors */) { return $this->executeprepared(statement, placeholders, datatypes); } throw $e; } } }
and build db
service it.
Comments
Post a Comment