Php Symfony/1.4:从一个数据库读取,写入另一个数据库
我们在Symfony 1.4/Propel 1.4中有一个现有项目(SNS网站+android/Iphone游戏) 我们在DB服务器上遇到了额外的负载(比如DB1)。我们正在进行数据库优化,但作为即时解决方案,我们决定再创建一个数据库服务器,就像DB2一直都是DB1的复制品一样。目前我们只有DB1,用于读写操作 现在我们需要将所有读操作移到DB2,并保持DB1上的写操作(通常在事务中)与现在一样 有哪些可能的方法来进行这些更改(在生产服务器上进行更改而不需要太多的停机时间),如果可能的话,只需最少的代码更改 第一次评论后编辑 基于J0k提供的链接和其他一些链接,我在本地开发环境中完成了以下工作Php Symfony/1.4:从一个数据库读取,写入另一个数据库,php,symfony1,symfony-1.4,propel,Php,Symfony1,Symfony 1.4,Propel,我们在Symfony 1.4/Propel 1.4中有一个现有项目(SNS网站+android/Iphone游戏) 我们在DB服务器上遇到了额外的负载(比如DB1)。我们正在进行数据库优化,但作为即时解决方案,我们决定再创建一个数据库服务器,就像DB2一直都是DB1的复制品一样。目前我们只有DB1,用于读写操作 现在我们需要将所有读操作移到DB2,并保持DB1上的写操作(通常在事务中)与现在一样 有哪些可能的方法来进行这些更改(在生产服务器上进行更改而不需要太多的停机时间),如果可能的话,只需最
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzo;'
username: root
password: mysql
encoding: utf8
persistent: true
pooling: true
slaves:
slave1:
dsn: 'mysql:host=localhost;dbname=wzoslv;'
username: root
password: mysql
encoding: utf8
其中数据库wzoslv
是数据库wzo
的精确副本,但一个测试条目中的更改除外。在表odd_play
第26行(主键)列result
中,条目分别为WON1
和WON
php symfony propel:build-schema
php symfony propel:build-model
php symfony cc
class wzoActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$con_write = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
$con_read = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_READ);
$oddPlay = OddPlayPeer::retrieveByPK(26,0,$con_write);
echo "on write connection, result=".$oddPlay->getResult();
$oddPlayRead = OddPlayPeer::retrieveByPK(26,0,$con_read);
echo "<br/>on Read connection, result=".$oddPlayRead->getResult();
exit;
$this->setLayout('layout');
}
}
其中,$slaveconfigs
为空,因此返回写连接。现在的问题是,为什么slaveconfigs是空的
我还尝试编辑中定义的sfDatabaseConfigHandler.class.php,但这样做时,在某个地方断开symfony,就不会在web上甚至日志中显示任何内容。根据(在github上)的规定,您应该为
从机添加一个新级别,外加一个连接
条目
我肯定我犯了一些错误,但无论是在Prope/symfony的官方文件上,甚至在stackoverflow这里,任何建议似乎都不适用于我。也许官方文档应该更好地照顾那些没有太多symfony经验的程序员
虽然我们不喜欢编辑任何框架/第三方库的核心文件,但这迫使我编辑核心文件,以便为我提供一个有效的解决方案。对我有效的解决方案如下:
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzo;'
username: testuserwzo
password:
encoding: utf8
persistent: true
pooling: true
slave:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzoslv;'
username: testuserwzoslv
password:
encoding: utf8
persistent: true
pooling: true
数据库.yml
我的database.yml文件如下:
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzo;'
username: testuserwzo
password:
encoding: utf8
persistent: true
pooling: true
slave:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzoslv;'
username: testuserwzoslv
password:
encoding: utf8
persistent: true
pooling: true
之后,我编辑了sprip.php文件,如下所示
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzo;'
username: root
password: mysql
encoding: utf8
persistent: true
pooling: true
slaves:
slave1:
dsn: 'mysql:host=localhost;dbname=wzoslv;'
username: root
password: mysql
encoding: utf8
用于推进1.4
文件:lib/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/prople/prople.php
换行542-543
// we've already ensured that the configuration exists, in previous if-statement
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
带(中间添加一行)
然后在同一个文件中,更改了第560行
$con = Propel::initConnection($conparams, $name);
$con = Propel::initConnection($conparams, $name);
到
对于propel 1.6(我们升级propel只是为了使其正常工作,但后来又恢复到propel 1.4,因为生产升级需要经过充分测试。)
文件:plugins/sfpropolormplugin/lib/vendor/spreep/runtime/lib/spreep.php
更改了第601行
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
至(之前添加了一行)
然后在同一个文件中,更改了第629行
到
然后,下面的测试文件给出了预期的结果
class kapsActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$con_write = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
$con_read = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_READ);
$oddPlay = OddPlayPeer::retrieveByPK(28,0,$con_write);
echo "on write connection, result=".$oddPlay->getResult().$oddPlay->getPlayscore();
$oddPlayRead = OddPlayPeer::retrieveByPK(27,0,$con_read);
echo "<br/>on Read connection, result=".$oddPlayRead->getResult().$oddPlayRead->getPlayscore();
exit;
//$this->setLayout('layout');
}
}
class kapsActions扩展了sfActions
{
公共函数executeIndex(sfWebRequest$request)
{
$con_write=spreep::getConnection(OddPlayPeer::DATABASE_NAME,spreep::CONNECTION_write);
$con_read=spreep::getConnection(OddPlayPeer::DATABASE_NAME,spreep::CONNECTION_read);
$oddPlay=OddPlayPeer::retrieveByPK(28,0,$con_write);
echo“在写入连接时,结果=”.$oddPlay->getResult().$oddPlay->getPlayscore();
$oddPlayRead=OddPlayPeer::retrieveByPK(27,0,$con_-read);
echo“
在读取连接时,result=“.$oddPlayRead->getResult()。$oddPlayRead->getPlayscore();
出口
//$this->setLayout('layout');
}
}
我仍然不建议编辑核心文件,但这个解决方案在紧急情况下对我们有效。如果需要,其他人可以在紧急情况下使用它。仍然在寻找完美的解决方案。您检查过了吗?您好@j0k,我查看了该URL,但不知道如何在symfony中使用该信息。我用代码/配置编辑了这个问题,我正在根据不同链接提供的示例进行尝试。你能告诉我我在哪里犯了这个错误吗?嗨@j0k,对我来说似乎什么都不管用。这迫使我使用核心框架文件来解决生产服务器上的紧急问题。我发布了我的解决方案。我知道这不是一个好的做法,但你能看看它,并想提出一些建议。这太疯狂了,医生的官方信息不起作用?您是否也尝试过propel 1.6(在本地)?顺便说一句,你在回答中描述的是我在网上找到的一个黑客解决方案,但它是一个旧的推进版本(我想是1.2)。是的@j0k its(官方信息…)是非常不可能的,我同意我一定是犯了一些错误,但最终结果是:它对我不起作用。后来我又回到了propel 1.4,但该解决方案首先在1.6上进行了测试,并在1.6上运行。我从问题中提到的链接中得到了这个想法,但它是针对推进1.2的。关于黑客行为,是的,这是真正的黑客行为&我提到我不建议在一般情况下使用我的解决方案,但我的情况不同。生产服务器停机,stackholder站在我身后等待解决方案,在这种情况下,黑客攻击是可以接受的,不是吗?现在正在寻找完美的解决方案。
self::$configuration['datasources'][$name]['slaves'] = isset(self::$configuration['datasources']['slave']) ? self::$configuration['datasources']['slave'] : null;
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
$con = Propel::initConnection($conparams, $name);
$con = Propel::initConnection($conparams, 'slave');
class kapsActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$con_write = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
$con_read = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_READ);
$oddPlay = OddPlayPeer::retrieveByPK(28,0,$con_write);
echo "on write connection, result=".$oddPlay->getResult().$oddPlay->getPlayscore();
$oddPlayRead = OddPlayPeer::retrieveByPK(27,0,$con_read);
echo "<br/>on Read connection, result=".$oddPlayRead->getResult().$oddPlayRead->getPlayscore();
exit;
//$this->setLayout('layout');
}
}