主页 > Drupal | 其他 | 数据库技术 > 在Drupal的数据库层应用MySQL Master/Slave

在Drupal的数据库层应用MySQL Master/Slave

PDF版本

关于Drupal性能的优化,文章Drupal高性能经验漫谈中提及多种方法,但在数据库的架构方面,我们还没有讨论到MySQL的主从架构,即Master/Slave如何在Drupal中应用。

众所周知,MySQL的master/slave模式对于提高数据库访问层的性能是非常有效的,本文就在Drupal中如何应用mysql当master/slave做一下简单介绍。

默认情况下Drupal6并不支持master/slave结构,即使是Drupal的Pressflow版本,也是只提供相关函数,并不能把已有的db_query定向到slave数据库,因此有必要在drupal到query机制中加入router的功能。

根据Drupal.org上面这篇文章的讨论,笔者总结了一下,并作了相应的改良,http://drupal.org/node/469274

比如sql过滤中会出现过滤掉某些字段中含有update的字段,此外由于主从数据库的延迟问题,我们需要一个锁定到master数据库的机制,所以添加了一个函数用于锁定主数据库。

首先,修改settings.php,添加default和readonly数据库的设置。

2
3
$db_url['default'] = 'mysql://username:password@localhost/databasename';
$db_url['readonly'] = 'mysql://username:password@localhost/databasename';

其次,修改和添加如下代码在/includes/database.mysql-common.inc 中,

注意:
1. db_query是修改drupal核心。
2. db_lock_master是保持db一直锁定在master数据库上。(不同步的情况下使用,有时我们不能保证主从完全同步,就需要一直在master上操作,比如Drupal的核心函数user_save/node_save,在保存之后立即load一个对象,这种情况主从没有同步导致莫名其妙的数据bug,笔者以前在项目中经常遇到,大家多注意)。

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
function db_query($query) {
  $args = func_get_args();
  array_shift($args);
  $query = db_prefix_tables($query);
  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
    $args = $args[0];
  }
  _db_query_callback($args, TRUE);
  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
 
  /*
   * Integrating multiple read/write databases
   */
  if(!db_lock_master() && strpos(strtolower($query), "select") === 0 && strpos(strtolower($query), "last_insert_id") === FALSE){
    $commits   = array('alter', 'insert', 'update', 'delete', 'flush', 'lock','create');
    $is_commit = false;
    foreach($commits as $type) {
      if((strpos(strtolower($query), "$type "))){//[insert|update|create] xxxx, need a space, otherwise, some field which is like 'user_updated' will be filter as commits
        $is_commit = true;
      }
    }
 
    if($is_commit){
      db_set_active('default');
      //drupal_set_message('default');
    } else{
      db_set_active('readonly');
      //drupal_set_message('readonly');
    }
  }
  else {
    db_set_active('default');
  }
  /*
   * End read/write router
   */
 
  return _db_query($query);
}
 
function db_lock_master($lock = null) {
  static $lock_master = false;
  if (is_null($lock)) {
    return $lock_master;
  }
  else {
    $lock_master = $lock;
    return $lock_master;
  }
}

最后,该代码只能支持一个slave数据库,如果我们有多个slave db,那么有两个办法。
1. 修改上面到php代码,在应用slave db的代码中,再用一个函数分配slave数据库。
2. 用haproxy做一个mysql db代理。参考这篇文章 http://www.oschina.net/question/17_4131

参考文章
Using multiple slave MySQL databases as ‘read only’ DBs
How does Drupal.org split MySQL read/write queries to a master/slave


声明: 本站所有文章欢迎转载,所有文章未说明,均属于原创,转载均请注明出处。
本文有效链接: http://www.drupal001.com/2011/09/drupal-mysql-master-slave/
版权所有: Drupal与高性能网站架构 http://www.drupal001.com


, , ,

评论:7

发表评论
  1. avatar
    回复 小龙
    11/12/16

    在配置主从数据库的时候,使用了以上代码,还需要配置mysql吗?我按照以上方法进行了配置,但是用户就登不上了,只是为啥、、、、、

    • avatar
      回复 小龙
      11/12/16

      急求解答。。 坐等、、、、、

    • avatar
      回复 robbin
      11/12/16

      数据库需要配置的,首先你的MySQL要主从服务配置成功,这个只是Drupal如何使用MySQL的主从服务器,但是前提是主从服务器运行必须正常。
      你可以百度一下,MySQL的主从配置先 :P

      • avatar
        回复 小龙
        11/12/17

        原来是这样啊,那我先配置下先,能加你qq吗,有些问题还要请教你啊,qq781110641,谢谢了

      • avatar
        回复 小龙
        11/12/18

        非常感谢你的帮助啊,我找到原因了,就是你说的,谢谢你了,已经实现了

  2. avatar
    回复 小龙
    11/12/18

    [mysqld]
    port=3306
    server-id=2
    master-host=192.168.177.123
    master-user=root
    master-port=3306
    master-connect-retry=60
    master-password=123456
    在从数据库里加入此段代码,从数据库就不能启动了,这是怎么回事啊,

  3. avatar
    回复 Nicole
    11/12/28

    强大!

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注


7 − 一 =

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

引用:0

下面所列的是引用到本博客的链接
在Drupal的数据库层应用MySQL Master/Slave 来自 Drupal与高性能网站架构
顶部