Php Symfony/1.4:从一个数据库读取,写入另一个数据库

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上的写操作(通常在事务中)与现在一样 有哪些可能的方法来进行这些更改(在生产服务器上进行更改而不需要太多的停机时间),如果可能的话,只需最

我们在Symfony 1.4/Propel 1.4中有一个现有项目(SNS网站+android/Iphone游戏)

我们在DB服务器上遇到了额外的负载(比如DB1)。我们正在进行数据库优化,但作为即时解决方案,我们决定再创建一个数据库服务器,就像DB2一直都是DB1的复制品一样。目前我们只有DB1,用于读写操作

现在我们需要将所有读操作移到DB2,并保持DB1上的写操作(通常在事务中)与现在一样

有哪些可能的方法来进行这些更改(在生产服务器上进行更改而不需要太多的停机时间),如果可能的话,只需最少的代码更改

第一次评论后编辑

基于J0k提供的链接和其他一些链接,我在本地开发环境中完成了以下工作

  • 创建了一个测试symfony 1.4项目
  • 更新database.yml如下

    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

  • 运行symfony任务

    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');
      }
    }