今天一起来研究下MySQL Capabilities,这个非常重要,如果大家有想法自己动手实现一个MySQL客户端或者Proxy工具,那么就得先了解一下这块,正好PHP 5.3以上版本由于官方为了规避许可协议和版权的问题而开发mysqlnd驱动(mysql native driver),而且据资料显示其性能比libmysql驱动要高不少,直接步入正题,在开始前,说明一下,以下的源码部分是来源于php 5.5.10版本。

假如有这么一个场景:

运维A:老大,最近调研发现php 5.5版本性能提升了不少,咱们的游戏web后台php版本要不要来一下?

老大:新版本有啥优势啊?

运维A:新增了mysqlnd这个牛逼的驱动,咱们编译代码再也不用记着打开libmysql选项了,减少工作量之余,关键是这个驱动比libmysql牛逼多了。

老大:但是咱们中间有一层自制的mysql proxy,这个驱动对他的支持是否友好?

运维A:这个...,得测试一下哈

….

baba,编译php 5.5版本几个小时过去了,终于搞定了,写个小程序连接一下mysql proxy…

事情发生了,怎么回事?怎么连不上了?发生什么事了?马上打电话给mysql proxy开发小组咨询一下为啥php 5.5版本连接不上mysql proxy?于是mysql proxy开发小组开始深入调研一下,原来proxy的Capabilities没设置好,顺手还研究了一下php mysqlnd的源码,发现原来真相在ext/mysqlnd/mysqlnd_enum_n_def.h的第105行的MYSQLND_CAPABILITIES宏,原来mysqlnd默认开启的标志还真不少,而咱的proxy实现还没支持这么多标志,所以只能断开链接了

 #define MYSQLND_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | \

                 CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | \

                 CLIENT_MULTI_RESULTS | CLIENT_PS_MULTI_RESULTS | CLIENT_LOCAL_FILES | CLIENT_PLUGIN_AUTH)

接下来再看看这个标志是在哪里调用,发现原来隐藏在ext/mysqlnd/mysqlnd.c的第713行

 /* {{{ mysqlnd_conn_data::get_updated_connect_flags */

  static unsigned int                                                                                                                                              

  MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags TSRMLS_DC)

  {                                

      MYSQLND_NET * net = conn->net;

      DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags");

      /* we allow load data local infile by default */

      mysql_flags |= MYSQLND_CAPABILITIES;

      mysql_flags |= conn->options->flags; /* use the flags from set_client_option() */

      if (PG(open_basedir) && strlen(PG(open_basedir))) {

          mysql_flags ^= CLIENT_LOCAL_FILES;

      }                           

  #ifndef MYSQLND_COMPRESSION_ENABLED

      if (mysql_flags & CLIENT_COMPRESS) {

          mysql_flags &= ~CLIENT_COMPRESS;

      }                           

  #else             

      if (net && net->data->options.flags & MYSQLND_NET_FLAG_USE_COMPRESSION) {

          mysql_flags |= CLIENT_COMPRESS;

      }                           

  #endif            

  #ifndef MYSQLND_SSL_SUPPORTED    

      if (mysql_flags & CLIENT_SSL) {

          mysql_flags &= ~CLIENT_SSL;

      }             

  #else             

      if (net && (net->data->options.ssl_key || net->data->options.ssl_cert ||

          net->data->options.ssl_ca || net->data->options.ssl_capath || net->data->options.ssl_cipher))

      {                      

          mysql_flags |= CLIENT_SSL;

      }                      

  #endif                     

      DBG_RETURN(mysql_flags);                                                                                                                                     

  }                          

  /* }}} */

而get_updated_connect_flags又是在哪里调用呢?再调研一下,发现是在ext/mysqlnd/mysqlnd.c的第956行

 /* {{{ mysqlnd_conn_data::connect */

  static enum_func_status   

  MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,

                           const char *host, const char *user,

                           const char *passwd, unsigned int passwd_len,

                           const char *db, unsigned int db_len,

                           unsigned int port,

                           const char *socket_or_pipe,

                           unsigned int mysql_flags

                           TSRMLS_DC)

  {

… ...

      mysql_flags = conn->m->get_updated_connect_flags(conn, mysql_flags TSRMLS_CC);

      if (FAIL == conn->m->connect_handshake(conn, host, user, passwd, passwd_len, db, db_len, mysql_flags TSRMLS_CC)) {

          goto err;

      }

而再找找connect,发生是在ext/mysqlnd/mysqlnd.c 的第1131行里调用,mysqlnd_connect看起来有点熟悉,没错这个就是官方开发的mysqlnd驱动,而大名顶顶的PDO正是调用这个来连接mysql,具体编译方式大家再google一下,这里就不展开了。

 /* {{{ mysqlnd_connect */                                                                                                                                        

 PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle,

                          const char * host, const char * user,

                          const char * passwd, unsigned int passwd_len,

                          const char * db, unsigned int db_len,

                          unsigned int port,

                          const char * socket_or_pipe,

                          unsigned int mysql_flags

                          TSRMLS_DC)

 {                        

     enum_func_status ret = FAIL;

     zend_bool self_alloced = FALSE;

     DBG_ENTER("mysqlnd_connect");

     DBG_INF_FMT("host=%s user=%s db=%s port=%u flags=%u", host?host:"", user?user:"", db?db:"", port, mysql_flags);

     if (!conn_handle) { 

         self_alloced = TRUE;

         if (!(conn_handle = mysqlnd_init(FALSE))) {

             /* OOM */   

             DBG_RETURN(NULL);

         }               

     }                   

     ret = conn_handle->m->connect(conn_handle, host, user, passwd, passwd_len, db, db_len, port, socket_or_pipe, mysql_flags TSRMLS_CC);

总结:

从php mysqlnd驱动源码可以学习到如何设计一个mysql客户端,并且在设计过程中如何设计MySQL Capabilities

具体的MySQL Capabilities说明可详细阅读http://dev.mysql.com/doc/internals/en/capability-flags.html

以上就是今天要分享的小细节,希望对大家理解MySQL Capabilities方面的相关细节有所帮助,祝玩得开心!

浅谈MySQL Capabilities --从调研PHP mysqlnd源码细节角度认识的更多相关文章

  1. 浅谈 qmake 之 shadow build(将源码路径和构建路径分开,一套源码要分别用msvc2008、msvc2008、mingw分别编译又不互相干扰)

    shadow build shadow build 是什么东西?就是将源码路径和构建路径分开(也就是生成的makefile文件和其他产物都不放到源码路径),以此来保证源码路径的清洁. 这不是qmake ...

  2. 浅谈mysql主从复制的高可用解决方案

    1.熟悉几个组件(部分摘自网络)1.1.drbd     —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...

  3. 浅谈mysql innodb缓存策略

    浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...

  4. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  5. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  6. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  7. MySQL多版本并发控制机制(MVCC)-源码浅析

    MySQL多版本并发控制机制(MVCC)-源码浅析 前言 作为一个数据库爱好者,自己动手写过简单的SQL解析器以及存储引擎,但感觉还是不够过瘾.<<事务处理-概念与技术>>诚然 ...

  8. Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码)

    Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码) 备注: 之前在Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合中 ...

  9. MySQL数据库的二进制安装、源码编译和基础入门操作

    一.MySQL安装 (1)安装方式: 1 .程序包yum安装 优点:安装快,简单 缺点:定死了各个文件的地方,需要修改里边的相关配置文件,很麻烦 2 .二进制格式的程序包:展开至特定路径,并经过简单配 ...

随机推荐

  1. BEGIN - 开始一个事务块

    SYNOPSIS BEGIN [ WORK | TRANSACTION ] DESCRIPTION 描述 BEGIN 初始化一个事务块, 也就是说所有 BEGIN 命令后的用户语句都将在一个事务里面执 ...

  2. vue之Render函数

    (1)什么是Render函数 先来看一个场景,在博客网中,一般有一级标题.二级标题.三级标题...,为了方便分享url,它们都做成了锚点,点击后,会将内容加载网址后面,以#分隔. 例如‘特性’是一个& ...

  3. pytorch记录:seq2seq例子看看这torch怎么玩的

    先看看简单例子: import torch import torch.autograd as autograd import torch.nn as nn import torch.nn.functi ...

  4. 小程序input自动聚焦拉起键盘

    微信官方提供了两种自动聚焦的方法 1,auto-focus 接受boolean值:默认为false:只需设置为true即可 自动聚焦,拉起键盘:不过官方的提示即将废弃,所以能不用还是不要用 2,foc ...

  5. margin负值应用

    我理解的最关键的一点是: 在文档流中,只能是后面的流向前面的,即文档流只能向左或向上流动,不能向下或向右移动.第二个元素的基准线是第一个元素的右边界,第三个元素的基准线是第一.二个元素排好后最右边的边 ...

  6. 中南大学2019年ACM寒假集训前期训练题集(入门题)

    A: 漫无止境的八月 Description 又双叒叕开始漫无止境的八月了,阿虚突然问起长门在这些循环中团长哪几次扎起了马尾,他有多少次抓住了蝉等等问题,长门一共回复n个自然数,每个数均不超过1500 ...

  7. 1 SQL 数据库和SQL

    1 数据库和SQL 1-1 数据库是什么 将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合称为数据库(Database, DB). 法则 用来管理数据库的计算机系统称为数据库管理系统 ...

  8. pop(),del A[:], a[:] = b[:]/'str'/可迭代的

    s = ['a','ma','shi','ge'] s0 = s.pop(0) #---> 有返回值 print(s,s0) s1 = s.remove('shi') #---> 无返回值 ...

  9. LeetCode(54)Spiral Matrix

    题目 Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral ...

  10. matplotlib的使用--折线图--入门

    目录 matplotlib应用介绍 一天天气变化图 两小时随机温度图 中文显示问题 个人交往统计图 多人交往统计图 总结 介绍: 举个例子(一天天气变化图): 假设一天中每隔两个小时(range(2, ...