安静
PHP技术博客

131108 Discuz 主从配置原理

之前有提到 discuz x3 开启 db主从后 报bug导致无法 正常使用 后来通过修改

// source/class/db/db_driver_mysql_slave.php 参数设置为1

解决 。

原帖:131101 discuz x3 主从数据库配置

本周深入了解了下 原来是因为 二次开发的时候 某些不是很规范的写法引起的:

db查询的时候没有使用 discuz 提供的 DB::table 导致。

修正完毕后 就可以正常使用了。
在这里转一篇关于 discuz 主从原理的文章

/source/class/class_core.php
当配置了从库信息时,直接连接从库
discuz_core::_init_db()

function _init_db() {
                $class = 'db_mysql';
                if(count(getglobal('config/db/slave'))) {
                        require_once libfile('class/mysql_slave');
                        $class = 'db_mysql_slave';
                }
                $this->db = & DB::object($class);
                $this->db->set_config($this->config['db']);
                $this->db->connect();
        }

db_mysql::table_name
table_name方法,每次将数据库连接curlink重置了主库连接。
其中$this->map为对数据库分库的配置,哪些表适用哪一个数据库,然后建立连接。

function table_name($tablename) {
                if(!empty($this->map) && !empty($this->map[$tablename])) {
                        $id = $this->map[$tablename];
                        if(!$this->link[$id]) {
                                $this->connect($id);
                        }
                        $this->curlink = $this->link[$id];
                } else {
                        $this->curlink = $this->link[1];
                }
                return $this->tablepre.$tablename;
        }

DB::table
此方法调用db_mysql::table_name方法

function table($table) {
                return DB::_execute('table_name', $table);
        }

/source/class/class_mysql_slave.php
db_mysql_slave::table_name
slave的table方法,判断表是否在“slave_except_table”中,slave_except_table为配置的不使用从库连接的数据表

function table_name($tablename) {
                if($this->slaveid && !$this->slaveexcept && $this->excepttables) {
                        if(in_array($tablename, $this->excepttables)) {
                                $this->slaveexcept = true;
                        }
                }

db_mysql_slave::query
slave的query方法,判段没有配置不使用从库的表,且sql语句为select时,才将curlink指向从库,否则curlink仍执行主库。

function query($sql, $type = '') {
                if($this->slaveid && !$this->slaveexcept && strtoupper(substr($sql, 0 , 6)) == 'SELECT') {
                        $this->slave_connect();
                }
                $this->slaveexcept = false;
                return parent::query($sql, $type);
        }

总结:

1. 在扩展或做插件,使用数据库操作时,使用“DB::table($tablename)”来获取表名拼接sql就能兼容Discuz!X的主从库配置
2. 若仅使用主库连接,系统不会使用到db_mysql_save的类
3. 每次页面请求,只有一个db对象。 使用connect和设置curlink来实现主从连接

转载自:
http://discuzx.sinaapp.com/thread-12-1-1.html

赞(0) 打赏
未经允许不得转载:AJ's Blog » 131108 Discuz 主从配置原理
分享到: 更多 (0)

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #-49

    感谢楼主分享。

    外教8年前 (2013-11-14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏