目前DBProxy兼容绝大多数MySQL语法。但是对于特殊配置、环境下的某些MySQL语法有一定的限制,限制会在本节列出。
序号 | 不支持的语句 |
1 | lock table(s) |
2 | flush table with read lock |
3 | flush table for export |
4 | lock binlog for backup |
5 | lock table for backend |
6 | handleropen/read |
7 | DDL语句 |
8 | prepare语句 |
select for update 也可能会走从库,使用select for update 必须在显示事务中。
不支持没有where条件的update ,delete操作。
目前不支持load data。
connector/J 5.1.18之前的驱动会发送该类语句。
版本 | 限制 |
0.0.1 | 不支持set session级别的变量,因为后端的连接会重用,除set autocommit外 |
0.0.2 | 支持set session级别的变量,仍然有以下限制: |
0.1.0 之后 | 支持了set transaction isolation level |
对于found_rows、row_count以及show warning、select last_insert_id等获取上下文信息的语句,仅在产生该类信息的语句(比如SQL_CALC_FOUND_ROWS语句、insert auto increment等)正确执行后立即执行有效,否则结果无效。
temporary表的相关操作执行结果可能错误,temporary表在不同的session中查询结果不同。
不支持原生的cursor、prepare等功能。
对于prepare语句的处理机制主要有以下两种:
(1) prepare时不向server端发送prepare命令,而是在execute时生成完成的SQL,直接发往server执行。
(2) prepare时向server端发送prepare命令,execute时发送execute命令。
各个驱动中的具体处理机制如下:
- PHP(PDO):默认为第一种方式,在PDO_ATTR_EMULATE_PREPARES和PDO_MYSQL_ATTR_DIRECT_QUERY都设置为0时,采用第二种方式
- PHP(mysqli):采用第二种方式
- JDBC:useServerPrepStmts=false时(默认值),采用第一种方式。
序号 | 限制 |
1 | 不支持客户端驱动(jdbc、pdo等)直接发送use dbname语句,可通过相应的更改db接口修改(比如Connection.setCatalog()) |
2 | 不支持客户端驱动执行COM_CHANGE_USER和COM_SET_OPTION命令 |
版本 | 限制 |
0.0.1 | 不支持连接串中设置属性,其中useAffectedRows默认为FALSE |
0.0.2 | 支持连接串中的参数设置,但仍然有以下限制: |
0.0.2之后 | 仍旧继承0.0.2的限制 |
序号 | 限制 |
1 | 不能设置多个主库,或者在已有主库再增加主库 |
2 | 所有的后端db节点,都需要有相同的用户名及密码 |
3 | 配置mysql的IP权限时,必须保证所有用户在DBProxy所在的机器具有权限 |
序号 | 限制 |
1 | where 条件: |
2 | 不支持range查询 |
3 | Insert操作,如果没有显式的指定列名,则会按照value list的第一个值来计算。比如Insert values(c1,c2,c3),则按照c1来计算分表。如果是多行插入,则只根据第一组数据来选择分表。分表值不能是表达式、函数等 |
4 | InsertBatch操作时,只会根据第一个value进行计算属于哪一张分表,然后把整条SQL直接发到这分表中,不管其余的value是否也属于这个分表 |
5 | update修改分表字段的值时,只会修改值,不会根据修改后的值再对数据进行迁移 |
6 | 不支持跨子表查询的Limit、Sort、Group by和Union操作。目前DBProxy只是简单合并转发后台的结果集 |
7 | 不支持分表中含有自增列(使用自增列不会报错,但要考虑到各个分表间自增列值重复的问题,例如:自增列不能作为分表键) |
8 | 不支持JOIN语句中含有多个分表 |
9 | 如果更新语句涉及到多个子表,则中间某个子表的更新出错,则只回滚当前子表的更新,已成功的子表则不会回滚 |