Kingshard数据库中间件

miproxy就是基于kingshard进行开发的,该中间件是用Go语言写的,今天就简单看了一下代码。我主要是想看看它是怎么实现强制选择主库的。因为有了主从库,必然就有延时性的问题,一致性的问题。

看了代码感觉挺简单的,主要是下面的代码:

 

func (c *ClientConn) getBackendConn(n *backend.Node, fromSlave bool) (co *backend.BackendConn, err error) {
   if !c.isInTransaction() {
      if fromSlave {
         co, err = n.GetSlaveConn()
         if err != nil {
            co, err = n.GetMasterConn()
         }
      } else {
         co, err = n.GetMasterConn()
      }
      if err != nil {
         golog.Error("server", "getBackendConn", err.Error(), 0)
         return
      }
   } else {
      var ok bool
      co, ok = c.txConns[n]

      if !ok {
         if co, err = n.GetMasterConn(); err != nil {
            return
         }

         if !c.isAutoCommit() {
            if err = co.SetAutoCommit(0); err != nil {
               return
            }
         } else {
            if err = co.Begin(); err != nil {
               return
            }
         }

         c.txConns[n] = co
      }
   }

   if err = co.UseDB(c.db); err != nil {
      //reset the database to null
      c.db = ""
      return
   }

   if err = co.SetCharset(c.charset, c.collation); err != nil {
      return
   }

   return
}

 

如果是事务,直接建立Master连接;

对于非事务的:

如果fromslave=false,就选择主库,否则选择从库。那么这个fromslave从哪来呢?

往上找:

//处理select语句
func (c *ClientConn) handleSelect(stmt *sqlparser.Select, args []interface{}) error {
   var fromSlave bool = true
   plan, err := c.schema.rule.BuildPlan(c.db, stmt)
   if err != nil {
      return err
   }
   if 0 < len(stmt.Comments) {
      comment := string(stmt.Comments[0])
      if 0 < len(comment) && strings.ToLower(comment) == MasterComment {
         fromSlave = false
      }
   }
const (
   MasterComment    = "/*master*/"

如果在sql语句中,加入了上面的文本,就可以直接选择主库。

 

其实除了上述的方法,还可以根据账号来决定。

 

 

 

--------EOF---------
本文微信分享/扫码阅读