From 587f22b47cc561d1b2a19cd70e93ec59197cf01c Mon Sep 17 00:00:00 2001 From: yanhuqing Date: Sat, 9 Sep 2017 17:53:24 +0800 Subject: [PATCH] add ReadMe --- Develop_Note.md | 276 ------------ README.md | 50 ++- README_Chinese.md | 59 --- README_MyCat.md | 425 ------------------ Release_Note.md | 196 -------- docs/CONTRIBUTING.md | 178 ++++++++ docs/QUICKSTART.md | 93 ++++ docs/ROADMAP.md | 54 +++ docs/architecture.PNG | Bin 0 -> 57413 bytes .../com/actiontech/dble/config/ErrorCode.java | 2 +- .../com/actiontech/dble/config/Versions.java | 2 +- .../dble/config/loader/xml/XMLRuleLoader.java | 5 - .../config/loader/xml/XMLSchemaLoader.java | 15 - .../entity/rule/function/Function.java | 5 - .../actiontech/dble/memory/SeverMemory.java | 10 - .../unsafe/storage/DataNodeFileManager.java | 2 +- .../utils/sort/RecordPointerAndKeyPrefix.java | 3 +- .../dble/memory/unsafe/utils/sort/Sorter.java | 1 - .../dble/net/mysql/HandshakeV10Packet.java | 2 +- .../dble/net/mysql/HeartbeatPacket.java | 2 +- .../actiontech/dble/route/RouteService.java | 8 +- .../route/handler/HintMasterDBHandler.java | 4 +- .../parser/druid/impl/DruidInsertParser.java | 3 +- .../dble/server/parser/ServerParse.java | 2 +- .../dble/sqlengine/mpp/DataMergeService.java | 2 +- src/main/resources/cacheservice.properties | 2 +- src/main/resources/log4j2.xml | 4 - src/main/resources/rule_template.xml | 20 +- src/main/resources/schema_template.xml | 22 +- src/main/resources/server_template.xml | 1 + .../visitor/TestMySQLPlanNodeVisitor.java | 2 +- .../actiontech/dble/route/HintDBTypeTest.java | 6 +- .../actiontech/dble/sqlexecute/TestJdbc.java | 3 - .../dble/statistic/SQLStatisticsMain.java | 32 -- 34 files changed, 418 insertions(+), 1073 deletions(-) delete mode 100644 Develop_Note.md delete mode 100644 README_Chinese.md delete mode 100644 README_MyCat.md delete mode 100644 Release_Note.md create mode 100644 docs/CONTRIBUTING.md create mode 100644 docs/QUICKSTART.md create mode 100644 docs/ROADMAP.md create mode 100644 docs/architecture.PNG delete mode 100644 src/test/java/com/actiontech/dble/statistic/SQLStatisticsMain.java diff --git a/Develop_Note.md b/Develop_Note.md deleted file mode 100644 index f31eb74370..0000000000 --- a/Develop_Note.md +++ /dev/null @@ -1,276 +0,0 @@ -DATE:2017/04/20 -VERSION 2.17.04.0 -CONTENT: -### 1.fix bug -#### 1.1 #42,#51 -有关排序的,使用ares移植代码逻辑 -#### 1.2 #84 -目前仅仅记录了log -#### 1.3 #92 -防火墙失效问题 - -### 2.feature -#### 2.1 全局序列 -移除本地配置和数据库方式配置,默认单机部署采用时间戳方式 -#### 2.2 移除sqlInterceptor 和defaultSqlParser 配置 - ------- - -DATE:2017/04/13 -VERSION 0.3.5 -CONTENT: -### 1.fix bug -#### 1.1 #68 -fix可能建立连接会有NP异常 -#### 1.2 #86 -begin应当为commit当前并新开一个事物 -#### 1.3 #88 -性能相关,消耗较大的计算字节数只在开启统计时使用 -#### 1.4 #83 - 事务中复杂查询上下文未正确设置(上一版仍有问题) -#### 1.5 #59 -连接出现异常不会关闭前端连接 - -### 2.feature -#### 2.1 移除临时参数useExtensions -开原版聚合函数bug较多,直接弃用 -#### 2.2 移除不必要的依赖包 -mongo-java-driver-2.11.4.jar -mysql-binlog-connector-java-0.4.1.jar -sequoiadb-driver-1.12.jar(原本集成gson包,所以要添加gson-2.8.0.jar) - ------- - - -DATE:2017/04/07 -VERSION 0.3.4 -CONTENT: -注:0.3.3 有个临时版本,故跳过 -### 1. fix bug -#### 1.1 #62(0.3.3版已修正) -#### 1.2 #43 -原生mycat将多节点having移除,猜测是想留给客户端去做,另外group by ,having中有聚合函数也没有处理,在使用useExtensions前提下一并修正。 -#### 1.3 #73 -backlog默认值改为2048,也可以通过serverBacklog 设置 -#### 1.4 #78 -增加不支持提示 -#### 1.5 #81 -跨库join判断 schema -#### 1.6 #83 - 事务中复杂查询上下文未正确设置 -#### 1.7 #74 -可能引起原因:默认close不会关闭XA事务,导致连接僵死 ( 和#71 kill相关) -#### 1.8 load data 相关 #58,#61(优先级低) - -### 2. feature -#### 2.1 移除半成品参数 ProcessorBufferPoolType -#### 2.2 运维账号与普通账号隔离 #56 -使用方法: - - - 654321 - true - -或 - - - 654321 - true - MYCAT_TEST - - - -#### 2.3 #71 XA事务时候的kill -#### 2.4 create table 限制(优先级较低) #69 -#### 2.5 普通join 的Strategy策略(优先级较低) -默认不开,如需开启加参数useJoinStrategy - ------- - -DATE:2017/03/27 -VERSION 0.3.2 -CONTENT: -### fix bug -1.#64, #67 -略 -2.#59 -疑似JDK LinkedTransferQueue bug,未找到直接证据,修改为LinkedBlockingQueue,涉及代码一行,需要压力测试观察 -3.#57 -修改后台node close conn时候响应逻辑,设计代码较多,需要回归正常事务的冒烟以及单、多结点异常关闭时的表现。 -4.#62 修改XA 写log时候的死锁问题,代码只涉及到XA,需要压力观察是否修改正确 -5.#68 修改join时候其中一个表返回结果时提前释放handler,导致另一个表结果返回时报NP或者hang住(log有WARN),涉及代码一行,只影响JOIN - ------- - -DATE:2017/03/21 -VERSION 0.3.1 -CONTENT: -### 1.fix #32, #36, #37, #39 -### 2.new issue 33 -### 3 fix 46 -将连接登陆成功和关闭的日志改为debug级别,另外更新以下jar包,防止写日志时生产者过多导致disruptor内部环形队列越界死锁。 -disruptor-3.3.4.jar->disruptor-3.3.6.jar -log4j-1.2-api-2.5.jar->log4j-1.2-api-2.7.jar -log4j-api-2.5.jar->log4j-api-2.7.jar -log4j-core-2.5.jar->log4j-core-2.7.jar -log4j-slf4j-impl-2.5.jar->log4j-slf4j-impl-2.7.jar - -### 4.聚合函数相关bug: #50, #45, #44, #41, #31 -测试select 中包含聚合函数时请将```true``` 打开看是否解决,并回归其他聚合函数的case。 - - -### 5 join、union、子查询语句 #47 -测试时请将 -``` -true -``` - 打开看是否解决。 - ------- - -date:2017/03/11 -VERSION 0.2.6 -CONTENT: -### 1.fix 29 -select @@session.tx_isolation; 写死的问题 -### 2. set -无论是否支持,都返回OK--->不支持的返回错误提示 -### 3.fix 31 - 聚合函数min不正确 -### 4. 连接处理核心 -改成有界队列(防止大量短连接并发导致 开太多线程) -### 5.查询分析树 相关 (暂时无需测试,未暴露给用户) - 5.1 GLOBAL TABLE - 5.2 druid 更新 - 5.3 查询分析树一些bug - -### 6.将join时候mycat原有逻辑暴露出来。 -修正当sql带schema时候可能会找不到路由的bug - -### 7.druid-1.0.26.jar 升级到 druid-1.0.28.jar - ------- - - -date:2017/03/11 -VERSION 0.2.5 -CONTENT: -### 1.移除schema 的以下配置:checkSQLschema -即支持sql 在未使用use schema时,可以用schema.table 来作查询,增删改。 - -例如 :原来 -use db1; -insert into table1 values 。。。。 -现在: -insert into db1.table1 values 。。。。 - -### 2.将schema 下lowercase配置 移到全局。 - -方法: 在server.xml 的 -下配置 -``` - true -``` -和mysql内部处理方式相同,当大小写不敏感时,内存中全部用小写来做比较。 - -### 3. 对解析性能优化,对SQL的多次解析尽量 合在一起 -### 4. 将所有未经测试的改进/新功能都隐藏起来,如需测试可配置一个内部参数尝试新功能,等稳定后再放出。 -(本次主要是复杂SQL的查询,还未完全写完,本次测试暂不涉及)。 -启用方法,配:true,限于内部使用。 - - -升级: -从 0.2.4升级上来 需替换jar包,schema.dtd , 以及去掉schema.xml 配置中的checkSQLschema - ------- - -date:2017/02/08 -VERSION 0.2.4 -CONTENT: -### 1.fix bugs -issue 24,25,26,13 - -@maguoji: -when multi writing masters and a writing master that is not the last don't have a slave, master don't correspond to its slaves - -### 2.合并官方bug - 1126, 1125,1294,(1248,1251 and new $ bug//官方修复不完全正确 ) -参见 issue 27 - -### 3.不支持 MultiQueries,会提示警告。 -### 4.性能方面: -Reactor 改为非阻塞 -线程池增加cached -xa recover log 写入性能增强 - - -date:2017/01/16 -VERSION 0.2.3 -CONTENT: -### 1.fix bugs -issue 5. -isseu 6: 支持大小写敏感,粒度:schema。 -方法:schema.xml中 标签schema下 添加lowerCase 属性 0 或者 1 ,默认不添加为为1大小写不敏感。 -issue 7. -issue 8. -issue 10. -ISSUE 16. - -### 2.移除对其他后端异构数据库的支持,以及对应的配置中的无用项。 -### 3.不支持 between and 的枚举和 固定Hash 分区(string 类型)算法会提示警告。 -### 4.DML(I/U/D)以及DDL的描述和限制 -参见http://10.186.18.11/confluence/pages/viewpage.action?pageId=3671908 - - -date:2016/12/14 -VERSION 0.2.1 -CONTENT: -### 1.数据库写入 -#### 1.1 普通事务实现分布式事务 及日志 -#### 1.2 XA实现分布式(事务MySQL5.7以上) 及recover -#### 1.3 隐式分布式事务 及日志 - -分布式事务使用两阶段提交的方式, -具体设计 参见 http://10.186.18.11/confluence/pages/viewpage.action?pageId=3670789 - -### 2 meta 数据定时巡检 -参见 http://10.186.18.11/confluence/pages/viewpage.action?pageId=3670785 - -### 3增加可选配置项 -server.xml 文件中 system标签 下 - -``` -1000 -1000 -0 - 60000 -0 -``` - -也可见server_template.xml - - ------- ------- - -date:2016/11/28 -VERSION 0.1.1 -CONTENT: -### 1.拆分算法 - -保留 -- 枚举方式分区 -- 数字范围方式分区 -- 固定Hash 分区 -- 固定Hash 分区(string 类型) -- 按日期分区 - -以上修改部分 -固定Hash 分区: -sum((count[i]*length[i])) 不受乘积为1024的限制,改为不大于1024的都可以支持 -按日期分区: -可以设置default node - -其余配置见rule_template.xml - -### 2.支持insert 不带columns diff --git a/README.md b/README.md index aceb223d88..969a22da59 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,51 @@ -see README_MyCat.md +# DBLE + +## What is DBLE? + +DBLE is a high scalability middle-ware for MySQL sharding. + + +- __Sharding__ +As your business grows, you can use DBLE to replace the origin single MySQL instance. + +- __Compatible with MySQL protocol__ +Use DBLE as MySQL. You can replace MySQL with DBLE to power your application without changing a single line of code in most cases. + +- __High availability__ +DBLE server can used as clustered,business will not suffer with single node fail. + +- __SQL Support__ +Support(some in Roadmap) SQL 92 standard and MySQL dialect. We support complex SQL query like group by, order by, distinct ,join ,union, subquery(in Roadmap) and so on. + +- __Complex Query Optimize__ +Optimize the complex query, including, without limitation, Global-table join sharding-table,ER-relation tables,Subquerys,Simplifying select items,and the like. + +- __Distributed Transaction__ +Support Distributed Transaction using two-phase commit. You can choose normal mode for performance or XA mode for data safe,of cource,the XA mode dependent on MySQL5.7's XA Transaction, MySQL node's high availability and data reliability of disk. + + +## History +Firstly,hanks for [MyCat](https://github.com/MyCATApache/Mycat-Server)'s contribution in the open source community. +But for us, focusing more attention on support for MySQL is a better choise.So we removed the support for other heterogeneous database,deeply improved/optimized the compatible, complex query and distributed transaction. And of cource, fixed some bugs during testing. + +For more details, see[Roadmap](./docs/ROADMAP.md) or [Issues](https://github.com/actiontech/dble/issues) . + +## Roadmap + +Read the [Roadmap](./docs/ROADMAP.md). + +## Architecture + +![architecture](./docs/architecture.png) + +## Quick start +Read the [Quick Start](./docs/QUICKSTART.md). + + +## Contributing + +Contributions are welcomed and greatly appreciated. See [CONTRIBUTING.md](./docs/CONTRIBUTING.md) +for details on submitting patches and the contribution workflow. - diff --git a/README_Chinese.md b/README_Chinese.md deleted file mode 100644 index e2f8207d90..0000000000 --- a/README_Chinese.md +++ /dev/null @@ -1,59 +0,0 @@ -### Mycat介绍 - -### 官网:[http://www.mycat.org.cn](http://www.mycat.org.cn) - -### github:[https://github.com/MyCATApache](https://github.com/MyCATApache) -##### 入门: [zh-CN: https://github.com/MyCATApache/Mycat-doc/blob/master/MyCat_In_Action_%E4%B8%AD%E6%96%87%E7%89%88.doc] [English:https://github.com/MyCATApache/Mycat-doc/tree/master/en] - -什么是Mycat?简单的说,Mycat就是: - -* 一个彻底开源的,面向企业应用开发的“大数据库集群” -* 支持事务、ACID、可以替代MySQL的加强版数据库 -* 一个可以视为“MySQL”集群的企业级数据库,用来替代昂贵的Oracle集群 -* 一个融合内存缓存技术、Nosql技术、HDFS大数据的新型SQL Server -* 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品 -* 一个新颖的数据库中间件产品 - - - -##### Mycat的目标是: - -低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。 - - -##### Mycat的关键特性: - -* 支持 SQL 92标准 -* 支持MySQL集群,可以作为Proxy使用 -* 支持JDBC连接ORACLE、DB2、SQL Server,将其模拟为MySQL Server使用 -* 支持galera for MySQL集群,percona-cluster或者mariadb cluster,提供高可用性数据分片集群 -* 自动故障切换,高可用性 -* 支持读写分离,支持MySQL双主多从,以及一主多从的模式 -* 支持全局表,数据自动分片到多个节点,用于高效表关联查询 -* 支持独有的基于E-R 关系的分片策略,实现了高效的表关联查询 -* 多平台支持,部署和实施简单 - - -##### Mycat的优势: - -* 基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能,以及众多成熟的使用案例使得Mycat一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。 -* 广泛吸取业界优秀的开源项目和创新思路,将其融入到Mycat的基因中,使得Mycat在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。 -* Mycat背后有一只强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了Mycat的产品质量。 -* Mycat并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。 - - -##### Mycat的长期路线规划: - -* 在支持MySQL的基础上,后端增加更多的开源数据库和商业数据库的支持,包括原生支持PosteSQL、FireBird等开源数据库,以及通过JDBC等方式间接支持其他非开源的数据库如Oracle、DB2、SQL Server等 -* 实现更为智能的自我调节特性,如自动统计分析SQL,自动创建和调整索引,根据数据表的读写频率,自动优化缓存和备份策略等 -* 实现更全面的监控管理功能 -* 与HDFS集成,提供SQL命令,将数据库装入HDFS中并能够快速分析 -* 集成优秀的开源报表工具,使之具备一定的数据分析的能力 - -##### 下载: - -github上面的Mycat-download项目是编译好的二进制安装包 [https://github.com/MyCATApache/Mycat-download](https://github.com/MyCATApache/Mycat-download) - -##### 文档: - -github上面的Mycat-doc项目是相关文档 [https://github.com/MyCATApache/Mycat-doc](https://github.com/MyCATApache/Mycat-doc) \ No newline at end of file diff --git a/README_MyCat.md b/README_MyCat.md deleted file mode 100644 index e4fe272f2f..0000000000 --- a/README_MyCat.md +++ /dev/null @@ -1,425 +0,0 @@ - -# [MyCAT](http://mycat.io/) -[![GitHub issues](https://img.shields.io/github/issues/MyCATApache/Mycat-Server.svg)](https://github.com/MyCATApache/Mycat-Server/issues) -[![GitHub forks](https://img.shields.io/github/forks/MyCATApache/Mycat-Server.svg)](https://github.com/MyCATApache/Mycat-Server/network) -[![GitHub stars](https://img.shields.io/github/stars/MyCATApache/Mycat-Server.svg)](https://github.com/MyCATApache/Mycat-Server/stargazers) -[![MyCAT](https://img.shields.io/badge/MyCAT-%E2%9D%A4%EF%B8%8F-%23ff69b4.svg)](http://mycat.io/) - -MyCAT is an Open-Source software, “a large database cluster” oriented to enterprises. MyCAT is an enforced database which is a replacement for MySQL and supports transaction and ACID. Regarded as MySQL cluster of enterprise database, MyCAT can take the place of expensive Oracle cluster. MyCAT is also a new type of database, which seems like a SQL Server integrated with the memory cache technology, NoSQL technology and HDFS big data. And as a new modern enterprise database product, MyCAT is combined with the traditional database and new distributed data warehouse. In a word, MyCAT is a fresh new middleware of database. - -Mycat’s target is to smoothly migrate the current stand-alone database and applications to cloud side with low cost and to solve the bottleneck problem caused by the rapid growth of data storage and business scale. - -* [Getting Started](https://github.com/MyCATApache/Mycat-doc/tree/master/en) -* [尝试 MyCAT](https://github.com/MyCATApache/Mycat-doc/blob/master/MyCat_In_Action_%E4%B8%AD%E6%96%87%E7%89%88.doc) - -## Features - -* Supports SQL 92 standard -* Supports MySQL cluster, used as a Proxy -* Supports JDBC connection with ORACLE, DB2, SQL Server, simulated as normal MySQL Server connection -* Supports MySQL cluster, percona cluster or mariadb cluster, providing high availability of data fragmentation clusters -* Supports automatic failover and high availability -* Supports separation of read and write, dual-master with multi-slave, single-master with multi-master of MySQL model -* Supports global table, automatically fragment data into multiple nodes for efficient relational query -* Supports the unique fragmentation strategy based on ER-relation for efficient relational query -* Supports multiple platforms, easy deployment and implementation - -## Advantage - -* Based on Alibaba's open-source project [Cobar](https://github.com/alibaba/cobar), whose stability, reliability, excellent architecture and performance, as well as many mature use-cases make MyCAT have a good starting. Standing on the shoulders of giants, MyCAT feels confident enough to go farther. -* Extensively drawing on the best open-source projects and innovative ideas, which are integrated into the Mycat’s gene, make MyCAT be ahead of the other current similar open-source projects, even beyond some commercial products. -* MyCAT behind a strong technical team whose participants are experienced more than five years including some senior software engineer, architect, DBA, etc. Excellent technical team to ensure the product quality of Mycat. -* MyCAT does not rely on any commercial company. It’s unlike some open-source projects whose important features is enclosed in its commercial products and making open-source projects like a decoration. - -## Roadmap - -* On the basis of MySQL’s support, MyCAT add more support of commercial open-source database, including native support of PostgreSQL, FireBird and other open-source databases, as well as indirect support via JDBC of other non-open-source databases such as Oracle, DB2, SQL Server etc. -* More intelligent self-regulating properties, such as automatic statistical analysis of SQL, automatic creating and adjusting indexes. Based on the frequency of read and write, MyCAT automatically optimizes caching and backup strategies -* Achieve a more comprehensive monitoring and management -* Integrated with HDFS, provide SQL commands, load databases into HDFS for rapid analysis -* Integrated excellent open-source reporting tools to make MyCAT have data analysis capability - -## Download - -There are some compiled binary installation packages in Mycat-download project on github at [Mycat-download](https://github.com/MyCATApache/Mycat-download). - -## Document - -There are some documents in Mycat-doc project on github at [Mycat-doc](https://github.com/MyCATApache/Mycat-doc). - - -Mycat 简单demo,具体参考Mycat权威指南 - -官网 : mycat.io -qq官方群:106088787 -Mycat权威指南官方下载:http://songwie.com/attached/file/mycat_1.5.2.pdf -wiki: wiki - -# Mycat前世今生 - -2013年阿里的Cobar在社区使用过程中发现存在一些比较严重的问题,及其使用限制,经过Mycat发起人第一次改良,第一代改良版——Mycat诞生。 Mycat开源以后,一些Cobar的用户参与了Mycat的开发,最终Mycat发展成为一个由众多软件公司的实力派架构师和资深开发人员维护的社区型开源软件。 - -2014年Mycat首次在上海的《中华架构师》大会上对外宣讲,更多的人参与进来,随后越来越多的项目采用了Mycat。 - -2015年5月,由核心参与者们一起编写的第一本官方权威指南《Mycat权威指南》电子版发布,累计超过500本,成为开源项目中的首创。 - -2015年10月为止,Mycat项目总共有16个Committer。 - -截至2015年11月,超过300个项目采用Mycat,涵盖银行、电信、电子商务、物流、移动应用、O2O的众多领域和公司。 - -截至2015年12月,超过4000名用户加群或研究讨论或测试或使用Mycat。 - -Mycat是基于开源cobar演变而来,我们对cobar的代码进行了彻底的重构,使用NIO重构了网络模块,并且优化了Buffer内核,增强了聚合,Join等基本特性,同时兼容绝大多数数据库成为通用的数据库中间件。1.4 版本以后 完全的脱离基本cobar内核,结合Mycat集群管理、自动扩容、智能优化,成为高性能的中间件。我们致力于开发高性能数据库中间而努力。永不收费,永不闭源,持续推动开源社区的发展。 - -Mycat吸引和聚集了一大批业内大数据和云计算方面的资深工程师,Mycat的发展壮大基于开源社区志愿者的持续努力,感谢社区志愿者的努力让Mycat更加强大,同时我们也欢迎社区更多的志愿者,特别是公司能够参与进来,参与Mycat的开发,一起推动社区的发展,为社区提供更好的开源中间件。 - -Mycat还不够强大,Mycat还有很多不足,欢迎社区志愿者的持续优化改进。 - -# 关键特性 -支持SQL92标准 - -遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理。 - -基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群。 - -支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster - -基于Nio实现,有效管理线程,高并发问题。 - -支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数。 - -支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join。 - -支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。 - -支持多租户方案。 - -支持分布式事务(弱xa)。 - -支持全局序列号,解决分布式下的主键生成问题。 - -分片规则丰富,插件化开发,易于扩展。 - -强大的web,命令行监控。 - -支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。 - -支持密码加密 - -支持服务降级 - -支持IP白名单 - -支持SQL黑名单、sql注入攻击拦截 - -支持分表(1.6) - -集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。 - - -# Mycat安装与使用 - -## 下载: -[https://github.com/MyCATApache/Mycat-download](https://github.com/MyCATApache/Mycat-download) -具体下载哪个版本以发布为准,推荐1.4,1.5. - -## 安装: -下载的文件直接解压即可。 - -## 运行: -### linux: - ./mycat start 启动 - - ./mycat stop 停止 - - ./mycat console 前台运行 - - ./mycat install 添加到系统自动启动(暂未实现) - - ./mycat remove 取消随系统自动启动(暂未实现) - - ./mycat restart 重启服务 - - ./mycat pause 暂停 - - ./mycat status 查看启动状态 - -### win: -直接运行startup_nowrap.bat,如果出现闪退,在cmd 命令行运行,查看出错原因。 - -## 内存配置: -启动前,一般需要修改JVM配置参数,打开conf/wrapper.conf文件,如下行的内容为2G和2048,可根据本机配置情况修改为512M或其它值。 -以下配置跟jvm参数完全一致,可以根据自己的jvm参数调整。 - -Java Additional Parameters - -wrapper.java.additional.1= - -wrapper.java.additional.1=-DMYCAT_HOME=. - -wrapper.java.additional.2=-server - -wrapper.java.additional.3=-XX:MaxPermSize=64M - -wrapper.java.additional.4=-XX:+AggressiveOpts - -wrapper.java.additional.5=-XX:MaxDirectMemorySize=100m - -wrapper.java.additional.6=-Dcom.sun.management.jmxremote - -wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984 - -wrapper.java.additional.8=-Dcom.sun.management.jmxremote.authenticate=false - -wrapper.java.additional.9=-Dcom.sun.management.jmxremote.ssl=false - -wrapper.java.additional.10=-Xmx100m - -wrapper.java.additional.11=-Xms100m - -wrapper.java.additional.12=-XX:+UseParNewGC - -wrapper.java.additional.13=-XX:+UseConcMarkSweepGC - -wrapper.java.additional.14=-XX:+UseCMSCompactAtFullCollection - -wrapper.java.additional.15=-XX:CMSFullGCsBeforeCompaction=0 - -wrapper.java.additional.16=-XX:CMSInitiatingOccupancyFraction=70 - - -以下配置作废: - -wrapper.java.initmemory=3 - -wrapper.java.maxmemory=64 - -### Mycat连接测试: -测试mycat与测试mysql完全一致,mysql怎么连接,mycat就怎么连接。 - -推荐先采用命令行测试: - -mysql -uroot -proot -P8066 -h127.0.0.1 - -如果采用工具连接,1.4,1.3目前部分工具无法连接,会提示database not selected,建议采用高版本,navicat测试。1.5已经修复了部分工具连接。 - - -# Mycat配置入门 - -## 配置: ---bin 启动目录 - ---conf 配置文件存放配置文件: - - --server.xml:是Mycat服务器参数调整和用户授权的配置文件。 - - --schema.xml:是逻辑库定义和表以及分片定义的配置文件。 - - --rule.xml: 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改需要重启MyCAT。 - - --log4j.xml: 日志存放在logs/log中,每天一个文件,日志的配置是在conf/log4j.xml中,根据自己的需要可以调整输出级别为debug debug级别下,会输出更多的信息,方便排查问题。 - - --autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties, sequence_db_conf.properties 分片相关的id分片规则配置文件 - - --lib MyCAT自身的jar包或依赖的jar包的存放目录。 - - --logs MyCAT日志的存放目录。日志存放在logs/log中,每天一个文件 - -下面图片描述了Mycat最重要的3大配置文件: -

- -

- -## 逻辑库配置: -### 配置server.xml -添加两个mycat逻辑库:user,pay: -system 参数是所有的mycat参数配置,比如添加解析器:defaultSqlParser,其他类推 -user 是用户参数。 - - - - druidparser - - - - - - mycat - - user,pay - - - -### 编辑schema.xml -修改dataHost和schema对应的连接信息,user,pay 垂直切分后的配置如下所示: - -schema 是实际逻辑库的配置,user,pay分别对应两个逻辑库,多个schema代表多个逻辑库。 - -dataNode是逻辑库对应的分片,如果配置多个分片只需要多个dataNode即可。 - -dataHost是实际的物理库配置地址,可以配置多主主从等其他配置,多个dataHost代表分片对应的物理库地址,下面的writeHost、readHost代表该分片是否配置多写,主从,读写分离等高级特性。 - -以下例子配置了两个writeHost为主从。 - - - - - - - - - - - - select 1 - - - - - - - -# Mycat逻辑库、系统参数配置 - -## 配置Mycat环境参数 - - - - - druidparser - - - -如例子中配置的所有的Mycat参数变量都是配置在server.xml 文件中,system标签下配置所有的参数,如果需要配置某个变量添加相应的配置即可,例如添加启动端口8066,默认为8066: - - 8066 - -其他所有变量类似。 - -## 配置Mycat逻辑库与用户 - - - - - - mycat - TESTDB - - - - -如例子中配置的所有的Mycat连接的用户与逻辑库映射都是配置在server.xml 文件中,user标签下配置所有的参数,例如例子中配置了一个mycat用户供应用连接到mycat,同时mycat 在schema.xml中配置后了一个逻辑库TESTDB,配置好逻辑库与用户的映射关系。 - - -# 逻辑库、表分片配置 - -## 配置逻辑库(schema) - -Mycat作为一个中间件,实现mysql协议那么对前端应用连接来说就是一个数据库,也就有数据库的配置,mycat的数据库配置是在schema.xml中配置,配置好后映射到server.xml里面的用户就可以了。 - - - - - - -
-
- - - - - - show status like 'wsrep%' - - - - - -上面例子配置了一个逻辑库TESTDB,同时配置了t_user,ht_jy_login_log两个分片表。 - -### 逻辑表配置 -
- -table 标签 是逻辑表的配置 其中 - -name代表表名, - -dataNode代表表对应的分片, - -Mycat默认采用分库方式,也就是一个表映射到不同的库上, - -rule代表表要采用的数据切分方式,名称对应到rule.xml中的对应配置,如果要分片必须配置。 - - -## 配置分片(dataNode) - - - - -表切分后需要配置映射到哪几个数据库中,Mycat的分片实际上就是库的别名,例如上面例子配置了两个分片dn1,dn2 分别对应到物理机映射dataHost -localhost1 的两个库上。 - -## 配置物理库分片映射(dataHost) - - - show status like 'wsrep%' - - - - -Mycat作为数据库代理需要逻辑库,逻辑用户,表切分后需要配置分片,分片也就需要映射到真实的物理主机上,至于是映射到一台还是一台的多个实例上,Mycat并不关心,只需要配置好映射即可,例如例子中: - -配置了一个名为localhost1的物理主机(dataHost)映射。 - -heartbeat 标签代表Mycat需要对物理库心跳检测的语句,正常情况下生产案例可能配置主从,或者多写 或者单库,无论哪种情况Mycat都需要维持到数据库的数据源连接,因此需要定时检查后端连接可以性,心跳语句就是来作为心跳检测。 - -writeHost 此标签代表 一个逻辑主机(dataHost)对应的后端的物理主机映射,例如例子中写库hostM1 映射到127.0.0.1:3306。如果后端需要做读写分离或者多写 或者主从则通过配置 多个writeHost 或者readHost即可。 - -dataHost 标签中的 writeType balance 等标签则是不同的策略,具体参考指南。 - -# Mycat 表切分规则配置 - -## 表切分规则 - - - - - - - - createTime - sharding-by-hour - - - - - 24 - - - - -数据切分中作为表切分规则中最重要的配置,表的切分方式决定了数据切分后的性能好坏,因此也是最重要的配置。 - -如上面例子配置了一个切分规则,名为sharding-by-hour 对应的切分方式(function )是按日期切分,该配置中: - -### tableRule - -name 为schema.xml 中table 标签中对应的 rule="sharding-by-hour" ,也就是配置表的分片规则, - -columns 是表的切分字段: createTime 创建日期。 - -algorithm 是规则对应的切分规则:映射到function 的name。 - - -### function - -function 配置是分片规则的配置。 - -name 为切分规则的名称,名字人员取,但是需要与tableRule 中匹配。 - -class 是切分规则对应的切分类,写死,需要哪种规则则配置哪种,例如本例子是按小时分片:org.opencloudb.route.function.LatestMonthPartion - -property 标签是切分规则对应的不同属性,不同的切分规则配置不同。 - - diff --git a/Release_Note.md b/Release_Note.md deleted file mode 100644 index d2456eaa40..0000000000 --- a/Release_Note.md +++ /dev/null @@ -1,196 +0,0 @@ -DATE:2017/08/01 -VERSION 2.17.07.0 -CONTENT: -## 1.feature -1.dual支持 #172 -2.show full tables where table_type 语句支持 #181 -3.非拆分表的show语句支持,insert...select #187 -4.enum 算法的between...and 下发给所有节点 #194 -5.禁用select into file#196 -## 2.fix bugs -1.异常打印typo #182 -2.全局序列时使用insert table_name values (...),可能报错#185 -3.全局序列type=4 时,报NP异常 #186 -4.GLOBAL表:插入数据时,_mycat_op_time列未生成数据 #190 -5.禁止管理用户和普通用户混用 #195 -6.复杂查询(eg.聚合函数)where条件大于2个会导致下发sql丢失条件 #214 -7.当配置EnchachePooFactory缓存时,超时没有实现 -8.移除/修改部分无用/错误管理端命令 #197,#198,#212 -9.含有冗余datanode或datahost时,mycat启动/reload失败#201 - ------- - - - -DATE:2017/06/29 -VERSION 2.17.06.0 -CONTENT: -## 1.feature -1.移除writeType参数,等效于原来writeType =0 -2.conf/index_to_charset.properties的内容固化到代码 #77 -3.show @@binlog.status ,显示节点间事务一致的binlog线 #118 -4.增强explain执行计划#143 -5.show tables时,不显示未创建的表,show full tables 拆分表的type会显示为SHARDING TABLE,global表会显示为GLOBAL TABLE -6.ddl 执行前做一次心跳检查 -7.多表查询中using()结果未合并重复列 #103 -8.natural join #97 -## 2.fix bugs -1.配置为自循环不会去拉取meta信息 #146 -2.自增序列部分算法缺陷及改进 -3.单节点查询不加入主键缓存bug #160 -4.租户权限不不隔离的问题 #164 -5.show full tables from db,当db为不存在的db时,多发包导致乱序 #159 -6.数字范围算法(AutoPartitionByLong),有默认节点时,between...and...可能路由错误 #145 -## 3.不兼容项 -#### 3.1 全局序列配置 : -##### 3.1.1 sequence_conf.properties -库表名要用"\`"包起来,用"."连接 -##### 3.1.2 sequence_db_conf.properties -库表名要用"\`"包起来,用"."连接 -#### 3.2 缓存配置 -3.2.1 cacheservice.properties 库表名要用"\`"包起来,用"_"连接。 -#### 3.3 自增序列部分算法 -##### 3.3.1.本地时间戳方式 -ID= (30(毫秒时间戳前30位)+5(机器ID)+5(业务编码)+12(重复累加)+12(毫秒时间戳后12位) -##### 3.3.2.分布式ZK ID 生成器 -ID= 63位二进制 (9(线程ID) +5(实例ID)+4(机房ID)+6(重复累加) +39(毫秒求模,可用17年)) -#### 3.4 server.xml -3.4.1 mycatNodeId 改为serverNodeId - -## 4.ushard分支 #117 -如果不需要混淆成字母类(eg:A.class),maven编译增加参数: --Dneed.obfuscate=false ,默认为true -#### 4.1 客户端登录信息 -显示ushard相关字样 -#### 4.2 注解 -注解内部原本用mycat的改为ushard -#### 4.3 全局序列 -数据库方式全局序列需要的dbseq.sql 已经重新生成,mycat已经用ushard替换,表结构相关名称改变 -#### 4.4 配置 -##### 4.4.1 xml的使用规约 -mycat改为ushard ,例如:server的根节点写法是: - -``` - -``` - -``` - -``` - -##### 4.4.2 cacheservice.properties -此配置中需要指定类名用于反射加载缓存池类型,可使用简称 -ehcache -leveldb -mapdb -来指代原有类名(不区分大小写),mycat分支下兼容原有方式和简称方式。 -原有方式如下,按顺序与简称方式一一对应。 -EnchachePooFactory -LevelDBCachePooFactory -MapDBCachePooFactory -和简称方式。 -##### 4.4.3 rule.xml -rule.xml配置当中需要指定类名用于反射加载拆分算法,可使用简称 -Hash -StringHash -Enum -NumberRange -Date -PatternRange -来指代原有类名(不区分大小写),mycat分支下兼容原有方式和简称方式。 -原有方式如下,按顺序与简称方式一一对应。 -PartitionByLong(固定Hash 分区) -PartitionByString(String固定Hash 分区) -PartitionByFileMap(枚举方式) -AutoPartitionByLong(数字范围) -PartitionByDate(日期分区) -PartitionByPattern(取模范围约束) -#### 4.5 全局表检查 -启用全局表检查时候,列名由_mycat_op_time改为_ushard_op_time -#### 4.6 日志 -日志路径logs/ushard.log。 -里面涉及到的包名从io.mycat 改为com.actionsky.com - ------- - - - -DATE:2017/04/20 -VERSION 2.17.04.0 -CONTENT: -同开源1.6.1版本相比,做了如下更新 -## 1.fix bug(只列了重要的) -#### 1.1 拆分算法 -hash拆分算法中,如果使用between跨越了所有分区,计算时分区会不正确 -范围拆分算法中,没有超越范围的默认结点。 -#### 1.2 XA实现分布式事务不可用,客户端报错退出 -#### 1.3 不当的线程并发导致double free,服务崩溃,被守护进程重启 -#### 1.4 防火墙,相同的sql因为缓存,防火墙会失效 -#### 1.5 聚合函数,group by,order by ,复杂查询等多处bug -这部分移植了ares的代码,文档待补充 -#### 1.6 普通用户都具有管理权限 - -## 2.feature -#### 2.1 拆分算法 - -保留 -- 枚举方式分区 -- 数字范围方式分区 -- 固定Hash 分区 -- 固定Hash 分区(string 类型) -- 按日期分区 - -其余分区算法移除 - -固定Hash 分区: -特别的sum((count[i]*length[i])) 不受乘积为1024的限制,改为不大于1024的都可以支持,当然,2的次方性能会比较好 -按日期分区: -可以设置default node - -其余配置见rule_template.xml - -#### 2.2 支持insert 不带columns -启动时拉取db的meta数据,ddl也会修改内存中meta数据,集群部署时DDL需要轮询重启抱枕meta数据更新 - -#### 2.3 XA实现分布式(事务MySQL5.7以上) 及recover -具体逻辑:http://10.186.18.11/confluence/pages/viewpage.action?pageId=4327696 -目前不完整,待补充 - -#### 2.4 移除对其他后端异构数据库的支持,以及对应的配置中的无用项。 -#### 2.5 支持大小写敏感 -需要依赖于mysql结点大小写敏感性以及配置文件一致 -#### 2.6 移除server.xml里一些不必要的配置 -详见http://10.186.18.11/confluence/pages/viewpage.action?pageId=3673209 - -#### 2.7 全局表DML(I/U/D)以及DDL的描述和限制 -参见http://10.186.18.11/confluence/pages/viewpage.action?pageId=3671908 -#### 2.8 增加一些其他友好的用户提示 -#### 2.9 全局序列 -移除本地配置和数据库方式配置,默认单机部署采用时间戳方式 -#### 2.10 移除"第一个节点通过数字方式分表" -#### 2.11 其他性能方面的优化 - - -## 3.已知限制 -#### 3.1 用普通事务两步提交实现的分布式事务的固有问题 -第二步commit时有节点出现网络异常会尤为明显 -#### 3.2 多连接并发更新多节点的相同的数据可能引发死锁,并发连接会等待结点超时最终都超时 -并发更新global的同一行数据现象明显 -#### 3.3 由于mysql 不支持事务性ddl,下发时可能导致数据不一致并无法回滚 - -注: 以上3.1~3.3 暂无一个好的解决方案 -#### 3.4 其他sql的详细支持列表测试中 -http://10.186.18.11/confluence/pages/viewpage.action?pageId=3673100 -是一个支持列表的相对安全的子集 -#### 3.5 不支持 allowMultiQueries=true -#### 3.6 不支持view -#### 3.7 集群部署时,ddl之后需要轮询重启,否则会影响meta数据的正确性 - -## 4.已知的重要bug(修复中) -#### 4.1 多次改变autocommit值,事务hang住(偶发) -#### 4.2 多表查询,多次查询结果不一致 (偶发) -#### 4.3 set CHARACTER 系列.... - ------- - - \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000000..fe848ad808 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,178 @@ +# Contribution Guide +Dble is a community driven open source project and we welcome any contributor.This guide documents the best way to make various types of contribution to Dble, including what is required before submitting a code change. +Of couse, contributing doesn’t just mean writing code. Improving documentation and reporting bugs are also welcome. + +## Contributing Bug Reports +Ideally, bug reports are accompanied by a proposed code change to fix the bug. This isn’t always possible, as those who discover a bug may not have the experience to fix it. A bug may be reported but without creating a pull request (see below). + +Bug reports are only useful however if they include enough information to understand, isolate and ideally reproduce the bug.Unreproducible bugs, or simple error reports, may be closed. + +It is possible to propose new features as well. These are generally not helpful unless accompanied by detail, such as a design document and/or code change. Feature requests may be rejected, or closed after a long period of inactivity. + +## Contributing Documentation Changes +To propose a change to documentation, similarly, edit the Markdown file in the repository and open a pull request. + +## Contributing Code Changes +This part outlines some conventions about development workflow, commit message formatting, contact points and other resources to make it easier to get your contribution accepted. + +## Preparing to Contribute Code Changes +### Choosing What to Contribute + +Before you move on, please make sure what your issue and/or pull request is, a bug fix or an architecture change. + +You konw that review can take hours or days of committer time, so +everyone benefits if contributors focus on changes that are useful, clear, easy to evaluate, and already pass basic checks. + +Besides all above, each issue should be filed with template. + + +### Is this a bug fix? + +Bug fixes usually come with tests. With the help of continuous integration test, patches can be easy to review. Please update the unit tests so that they catch the bug! +Issue example will comming soon. + +### Is this an architecture improvement? + +Some examples of "Architecture" improvements: + +- Improving test coverage. +- Decoupling logic or creation of new utilities. +- Making code more resilient (sleeps, backoffs, reducing flakiness, etc). +- Improving performance. + + +If you are improving the quality of code, then justify/state exactly what you are 'cleaning up' in your Pull Request so as to save reviewers' time. An example will be comming soon. + +If you're making code more resilient, test it locally to demonstrate how exactly your patch changes things. + + +### Workflow + +### Step 1: Fork in the cloud + +1. Visit https://github.com/actiontech/dble +2. Click `Fork` button (top right) to establish a cloud-based fork. + +### Step 2: Clone fork to local storage + + +Create your clone: + + +``` +mkdir -p $working_dir +cd $working_dir +git clone git@github.com:$user/dble.git +# the following is recommended +# or: git clone https://github.com/$user/dble.git + +cd $working_dir/dble +git remote add upstream git@github.com:actiontech/dble.git +# or:git remote add upstream https://github.com/actiontech/dble.git + +# Never push to upstream master since you do not have write access +git remote set-url --push upstream no_push + +# Confirm that your remotes make sense: +# It should look like: +# origin git@github.com:$(user)/dble.git (fetch) +# origin git@github.com:$(user)/dble.git (push) +# upstream https://github.com/actiontech/dble (fetch) +# upstream no_push (push) +git remote -v +``` + + +### Step 3: Branch + +Get your local master up to date: + +```sh +cd $working_dir/dble +git fetch upstream +git checkout master +git rebase upstream/master +``` + +Branch from master: + +```sh +git checkout -b yours-issue +``` + +Then edit code on the `yours-issue` branch. + +#### Compile, Check, Test + +```sh +# Complie and run unit test to make sure all test passed +mvn clean install package +``` + +### Step 4: Keep your branch in sync + +```sh +# While on your yours-issue branch +git fetch upstream +git rebase upstream/master +``` + +### Step 5: Commit + +Commit your changes. + +```sh +git commit +``` + +Likely you'll go back and edit/build/test some more than `commit --amend` +in a few cycles. + +### Step 6: Push + +When ready to review (or just to establish an offsite backup or your work), +push your branch to your fork on `github.com`: + +```sh +git push -f origin yours-issue +``` + +### Step 7: Create a pull request + +1. Visit your fork at https://github.com/$user/dble (replace `$user` obviously). +2. Click the `Compare & pull request` button next to your `yours-issue` branch. + +#### Step 8: get a code review + +Once your pull request has been opened, it will be assigned to at least one +reviewers. Those reviewers will do a thorough code review, looking for +correctness, bugs, opportunities for improvement, documentation and comments, +and style. + +Commit changes made in response to review comments to the same branch on your +fork. + +Very small PRs are easy to review. Very large PRs are very difficult to +review. + +## Commit message style + +Please follow this style to make Dble easy to review, maintain and develop. + +``` + + + + +
(optional) +``` + +The first line is the subject and should be no longer than 70 characters, the +second line is always blank, and other lines should be wrapped at 80 characters. +This allows the message to be easier to read on GitHub as well as in various +git tools. + +For the why part, if no specific reason for the change, +you can use one of some generic reasons like "Improve documentation.", +"Improve performance.", "Improve robustness.", "Improve test coverage." + diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md new file mode 100644 index 0000000000..c6f2aeedc7 --- /dev/null +++ b/docs/QUICKSTART.md @@ -0,0 +1,93 @@ +# Quick Start +## 1.Download DBLE Release +Get packages from https://github.com/actiontech/DBLE/releases + +## 2.Pepare +### 2.1 MySQL +Make Sure there is at least one MySQL Instance with url $url(like:localhost:3306) ,$user(like:test) and $password(like:testPsw) in your machine. +Add 3 database ,the SQL as below: + +``` +create database db1; +create database db2; +create database db3; +create database db4; +``` + +### 2.2 JVM +Make sure JAVA version is 1.8 and JAVA_HOME has been set.The older version may occurs Exception. + +## 3.Install + +``` + +mkdir -p $working_dir +cd $working_dir +tar -xvf actiontech-dble-$version.tar.gz +cd $working_dir/dble/conf +cp rule_template.xml rule.xml +cp schema_template.xml schema.xml +cp server_template.xml server.xml + +``` + +## 4.Config +Edit the file schema.xml. +Find the dataHost element ,delete all the writeHost/readHost element below. +Create a new writeHost element like +``` +   +``` +(replace to your own MySQL information) +Save the schema.xml + + + +## 4.Start + +start cmd: + +``` +$working_dir/dble/bin/dble start + +``` + + +check log in $working_dir/logs + +``` +tail -f logs/wrapper.log +``` + +You should see "Server startup successfully. see logs in logs/dble.log". + +## 5.connect +As a distributed-database imitate mysql,you can use all Mysql classic connection. +In this case you can connect to the DBLE where commond: +``` +mysql -p -P8066 -h 127.0.0.1 -u root +``` +Enter the password 123456 to login in +``` +use testdb; + +create table travelrecord( +id int, +name char(255) , +PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +show full tables; +``` + + +## 4.Stop + +``` + +cd $working_dir/dble +./bin/dble stop + +``` + + diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000000..c6cd7fe546 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,54 @@ +# Roadmap + +This document defines the roadmap for DBLE development. +##### __SQL Layer__ +- [x] DDL +- [x] Query Plan +- [x] Distributed Transactions +- [ ] High Performance LIMIT +- [x] REPLACE Syntax +- [x] Join (LEFT JOIN / RIGHT JOIN / CROSS JOIN) +- [x] Union +- [x] Simple Subquery +- [ ] Correlated Subquery +- [x] Functions support + - [x] Type Conversion in Expression Evaluation + - [x] Operators + - [x] Control Flow Functions + - [x] String Functions + - [x] Numeric Functions and Operators + - [x] Date and Time Functions + - [x] Cast Functions and Operators + - [x] Bit Functions and Operators + - [x] Aggregate (GROUP BY) Functions +- [ ] VIEW +- [ ] allowMultiQueries +- [ ] Charset +- [ ] allowMultiQueries +- [ ] System Variables +- [ ] User Variables +- [ ] Kill statement +- [x] Show full tables +- [ ] MySQL5.7 Client/Server Protocol + +##### __Cluster__ +- [x] Zookeeper +- [ ] Consul + +##### __Backend Connection Pool__ +- [x] Correct Idle Conn Heartbeat +- [ ] Connection Version +- [ ] Smooth Offline + +##### __Optimization__ +- [x] Global tablle +- [x] ER table +- [x] Push down Where Filter +- [x] Simplify Where Filter +- [x] Simplify SELECT + +##### __Remove__ +- [x] Least frequently used algorithm +- [x] Heterogeneous database +- [x] Migrate Logic +- [x] Other unused Code \ No newline at end of file diff --git a/docs/architecture.PNG b/docs/architecture.PNG new file mode 100644 index 0000000000000000000000000000000000000000..038b172ea6247047ef8e0f5caa0786cc49e1c519 GIT binary patch literal 57413 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 kuLN*}{GS^zjkzzm;mJ5Q$Fy1RD(lhB$ - * yyyy-MM-dd - * 2015-01-01 - * * * @param root * @throws ClassNotFoundException diff --git a/src/main/java/com/actiontech/dble/config/loader/xml/XMLSchemaLoader.java b/src/main/java/com/actiontech/dble/config/loader/xml/XMLSchemaLoader.java index d67f90d40a..f98e57168f 100644 --- a/src/main/java/com/actiontech/dble/config/loader/xml/XMLSchemaLoader.java +++ b/src/main/java/com/actiontech/dble/config/loader/xml/XMLSchemaLoader.java @@ -407,21 +407,6 @@ private void checkDataNodeExists(Collection nodes) { } /** - *
- * eg::
- * {@code - *
- * } - *
- * algorithm:
- * {@code - * - * - * 3 - * - * } - *
* shard table datanode(2) < function count(3) and check failed */ private void checkRuleSuitTable(TableConfig tableConf) { diff --git a/src/main/java/com/actiontech/dble/config/loader/zkprocess/entity/rule/function/Function.java b/src/main/java/com/actiontech/dble/config/loader/zkprocess/entity/rule/function/Function.java index 6e612fbac6..9c3715261c 100644 --- a/src/main/java/com/actiontech/dble/config/loader/zkprocess/entity/rule/function/Function.java +++ b/src/main/java/com/actiontech/dble/config/loader/zkprocess/entity/rule/function/Function.java @@ -12,11 +12,6 @@ import java.util.List; /** - * - * * 3 - * - *

- *

* author:liujun * Created:2016/9/18 */ diff --git a/src/main/java/com/actiontech/dble/memory/SeverMemory.java b/src/main/java/com/actiontech/dble/memory/SeverMemory.java index bee84a3c72..244bd5ba23 100644 --- a/src/main/java/com/actiontech/dble/memory/SeverMemory.java +++ b/src/main/java/com/actiontech/dble/memory/SeverMemory.java @@ -47,11 +47,6 @@ public SeverMemory(SystemConfig system, long totalNetWorkBufferSize) assert resultSetBufferSize > 0; - /** - * mycat.merge.memory.offHeap.enabled mycat.buffer.pageSize - * mycat.memory.offHeap.size mycat.merge.file.buffer - * mycat.direct.output.result mycat.local.dir - */ if (system.getUseOffHeapForMerge() == 1) { conf.set("server.memory.offHeap.enabled", "true"); @@ -96,11 +91,6 @@ public SeverMemory() throws NoSuchFieldException, IllegalAccessException { resultSetBufferSize = (long) ((Platform.getMaxDirectMemory()) * DIRECT_SAFETY_FRACTION); assert resultSetBufferSize > 0; - /** - * mycat.memory.offHeap.enabled mycat.buffer.pageSize - * mycat.memory.offHeap.size mycat.testing.memory - * mycat.merge.file.buffer mycat.direct.output.result mycat.local.dir - */ conf.set("server.memory.offHeap.enabled", "true").set("server.pointer.array.len", "8K").set("server.buffer.pageSize", "1m").set("server.memory.offHeap.size", JavaUtils.bytesToString2(resultSetBufferSize)); LOGGER.info("resultSetBufferSize: " + JavaUtils.bytesToString2(resultSetBufferSize)); diff --git a/src/main/java/com/actiontech/dble/memory/unsafe/storage/DataNodeFileManager.java b/src/main/java/com/actiontech/dble/memory/unsafe/storage/DataNodeFileManager.java index b3730adcfd..aea92428e7 100644 --- a/src/main/java/com/actiontech/dble/memory/unsafe/storage/DataNodeFileManager.java +++ b/src/main/java/com/actiontech/dble/memory/unsafe/storage/DataNodeFileManager.java @@ -36,7 +36,7 @@ * Creates and maintains the logical mapping between logical blocks and physical on-disk * locations. One block is mapped to one file with a name given by its BlockId. *

- * Block files are hashed among the directories listed in mycat.local.dir + * Block files are hashed among the directories listed in local.dir */ public class DataNodeFileManager { private static final Logger LOG = LoggerFactory.getLogger(DataNodeFileManager.class); diff --git a/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/RecordPointerAndKeyPrefix.java b/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/RecordPointerAndKeyPrefix.java index 1a4369b0b2..6bee4d6969 100644 --- a/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/RecordPointerAndKeyPrefix.java +++ b/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/RecordPointerAndKeyPrefix.java @@ -23,8 +23,7 @@ public final class RecordPointerAndKeyPrefix { private long keyPrefix; /** - * A pointer to a record; see {@link io.mycat.memory.unsafe.memory} for a - * description of how these addresses are encoded. + * A pointer to a record; */ public long getRecordPointer() { return recordPointer; diff --git a/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/Sorter.java b/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/Sorter.java index bc9f12efa4..0612c4c725 100644 --- a/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/Sorter.java +++ b/src/main/java/com/actiontech/dble/memory/unsafe/utils/sort/Sorter.java @@ -23,7 +23,6 @@ * A simple wrapper over the Java implementation [[TimSort]]. *

* The Java implementation is package private, and hence it cannot be called outside package - * org.opencloudb.memory.unsafe.utils.sort. This is a simple wrapper of it that is available to mycat. */ public class Sorter { diff --git a/src/main/java/com/actiontech/dble/net/mysql/HandshakeV10Packet.java b/src/main/java/com/actiontech/dble/net/mysql/HandshakeV10Packet.java index 8b68024428..19586ac3b4 100644 --- a/src/main/java/com/actiontech/dble/net/mysql/HandshakeV10Packet.java +++ b/src/main/java/com/actiontech/dble/net/mysql/HandshakeV10Packet.java @@ -30,7 +30,7 @@ import java.nio.ByteBuffer; /** - * From mycat server to client during initial handshake. + * From server to client during initial handshake. *

*

  * Bytes                        Name
diff --git a/src/main/java/com/actiontech/dble/net/mysql/HeartbeatPacket.java b/src/main/java/com/actiontech/dble/net/mysql/HeartbeatPacket.java
index cae56096df..343305b829 100644
--- a/src/main/java/com/actiontech/dble/net/mysql/HeartbeatPacket.java
+++ b/src/main/java/com/actiontech/dble/net/mysql/HeartbeatPacket.java
@@ -30,7 +30,7 @@
 import java.nio.ByteBuffer;
 
 /**
- * From client to server when the client do heartbeat between mycat cluster.
+ * From client to server when the client do heartbeat between cluster.
  * 

*

  * Bytes         Name
diff --git a/src/main/java/com/actiontech/dble/route/RouteService.java b/src/main/java/com/actiontech/dble/route/RouteService.java
index 172558c626..a34d7b9666 100644
--- a/src/main/java/com/actiontech/dble/route/RouteService.java
+++ b/src/main/java/com/actiontech/dble/route/RouteService.java
@@ -75,13 +75,13 @@ public RouteResultset route(SchemaConfig schema,
             }
         }
 
-        /*!mycat: sql = select name from aa */
-        /*!mycat: schema = test */
+        /*!dble: sql = select name from aa */
+        /*!dble: schema = test */
         int hintLength = RouteService.isHintSql(stmt);
         if (hintLength != -1) {
             int endPos = stmt.indexOf("*/");
             if (endPos > 0) {
-                // router by hint of !mycat:
+                // router by hint of !dble:
                 String hint = stmt.substring(hintLength, endPos).trim();
 
                 String hintSplit = "=";
@@ -136,7 +136,7 @@ public static int isHintSql(String sql) {
         int len = sql.length();
         if (sql.charAt(j++) == '/' && sql.charAt(j++) == '*') {
             char c = sql.charAt(j);
-            // support: "/** !mycat: */" for mysql  and "/** #mycat: */"  for mybatis
+            // support: "/** !dble: */" for mysql  and "/** #dble: */"  for mybatis
             while (j < len && c != '!' && c != '#' && (c == ' ' || c == '*')) {
                 c = sql.charAt(++j);
             }
diff --git a/src/main/java/com/actiontech/dble/route/handler/HintMasterDBHandler.java b/src/main/java/com/actiontech/dble/route/handler/HintMasterDBHandler.java
index fea4b250f3..f89146f49a 100644
--- a/src/main/java/com/actiontech/dble/route/handler/HintMasterDBHandler.java
+++ b/src/main/java/com/actiontech/dble/route/handler/HintMasterDBHandler.java
@@ -14,8 +14,8 @@
 import java.util.Map;
 
 /**
- * sql hint: mycat:db_type=master/slave
- * maybe add mycat:db_type=slave_newest in feature + * sql hint: dble:db_type=master/slave
+ * maybe add dble:db_type=slave_newest in feature * * @author digdeep@126.com */ diff --git a/src/main/java/com/actiontech/dble/route/parser/druid/impl/DruidInsertParser.java b/src/main/java/com/actiontech/dble/route/parser/druid/impl/DruidInsertParser.java index 5a64d23992..3cb0cb846e 100644 --- a/src/main/java/com/actiontech/dble/route/parser/druid/impl/DruidInsertParser.java +++ b/src/main/java/com/actiontech/dble/route/parser/druid/impl/DruidInsertParser.java @@ -367,7 +367,6 @@ private String convertInsertSQL(SchemaInfo schemaInfo, MySqlInsertStatement inse boolean isAutoIncrement = tc.isAutoIncrement(); - String tableName = schemaInfo.getTable(); if (isGlobalCheck && !GlobalTableUtil.isInnerColExist(schemaInfo, orgTbMeta)) { if (!isAutoIncrement) { return originSql; @@ -382,7 +381,7 @@ private String convertInsertSQL(SchemaInfo schemaInfo, MySqlInsertStatement inse sb.append("ignore "); } sb.append("into "); - sb.append(tableName); + sb.append(schemaInfo.getTable()); List columns = insert.getColumns(); diff --git a/src/main/java/com/actiontech/dble/server/parser/ServerParse.java b/src/main/java/com/actiontech/dble/server/parser/ServerParse.java index d3e4049b16..7de328f574 100644 --- a/src/main/java/com/actiontech/dble/server/parser/ServerParse.java +++ b/src/main/java/com/actiontech/dble/server/parser/ServerParse.java @@ -663,7 +663,7 @@ static int seCheck(String stmt, int offset) { case 't': if (stmt.length() > ++offset) { //support QUERY like this - // /*!mycat: sql=SELECT * FROM test where id=99 */set @pin=1; + // /*!dble: sql=SELECT * FROM test where id=99 */set @pin=1; // call p_test(@pin,@pout); // select @pout; if (stmt.startsWith("/*!" + Versions.ANNOTATION_NAME) || stmt.startsWith("/*#" + Versions.ANNOTATION_NAME) || stmt.startsWith("/*" + Versions.ANNOTATION_NAME)) { diff --git a/src/main/java/com/actiontech/dble/sqlengine/mpp/DataMergeService.java b/src/main/java/com/actiontech/dble/sqlengine/mpp/DataMergeService.java index 9a0a4518d2..8bf0491ebd 100644 --- a/src/main/java/com/actiontech/dble/sqlengine/mpp/DataMergeService.java +++ b/src/main/java/com/actiontech/dble/sqlengine/mpp/DataMergeService.java @@ -45,7 +45,7 @@ * * @author wuzhih /modify by coder_czp/2015/11/2 *

- * Fixbug: mycat sql timeout and hang problem. + * Fixbug: sql timeout and hang problem. * @author Uncle-pan * @since 2016-03-23 */ diff --git a/src/main/resources/cacheservice.properties b/src/main/resources/cacheservice.properties index a0fe7dcf13..cfe2b36e36 100644 --- a/src/main/resources/cacheservice.properties +++ b/src/main/resources/cacheservice.properties @@ -1,4 +1,4 @@ -#used for mycat cache service conf +#used for cache service conf factory.encache=ehcache #key is pool name ,value is type,max size, expire seconds pool.SQLRouteCache=encache,10000,1800 diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 0e4d6d47b4..6795e49ea1 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -18,10 +18,6 @@ - - - - diff --git a/src/main/resources/rule_template.xml b/src/main/resources/rule_template.xml index 7ef740271c..7ff6801c69 100644 --- a/src/main/resources/rule_template.xml +++ b/src/main/resources/rule_template.xml @@ -30,6 +30,13 @@ + + + id + hashLong2 + + + id @@ -83,9 +90,18 @@ 4,5--> - + + + + 2 + 512 + + + + - 8 + 4 1 diff --git a/src/main/resources/schema_template.xml b/src/main/resources/schema_template.xml index dd6e1f2d5c..762a595c83 100644 --- a/src/main/resources/schema_template.xml +++ b/src/main/resources/schema_template.xml @@ -4,22 +4,17 @@ -

+
-
+
-
- -
+
+ rule="sharding-by-mod">
-
- + select user() diff --git a/src/main/resources/server_template.xml b/src/main/resources/server_template.xml index f6530c4dd1..265e295bc9 100644 --- a/src/main/resources/server_template.xml +++ b/src/main/resources/server_template.xml @@ -33,6 +33,7 @@ 0 2 + 512 diff --git a/src/test/java/com/actiontech/dble/plan/visitor/TestMySQLPlanNodeVisitor.java b/src/test/java/com/actiontech/dble/plan/visitor/TestMySQLPlanNodeVisitor.java index 9bc0841076..e709c975d2 100644 --- a/src/test/java/com/actiontech/dble/plan/visitor/TestMySQLPlanNodeVisitor.java +++ b/src/test/java/com/actiontech/dble/plan/visitor/TestMySQLPlanNodeVisitor.java @@ -9,7 +9,7 @@ import org.junit.Test; /** - * this test must setup mycat server, because TableNode need the metadata of tables. + * this test must start server, because TableNode need the metadata of tables. * Curent, we skip it. */ public class TestMySQLPlanNodeVisitor { diff --git a/src/test/java/com/actiontech/dble/route/HintDBTypeTest.java b/src/test/java/com/actiontech/dble/route/HintDBTypeTest.java index d7bd535d69..9665717542 100644 --- a/src/test/java/com/actiontech/dble/route/HintDBTypeTest.java +++ b/src/test/java/com/actiontech/dble/route/HintDBTypeTest.java @@ -36,19 +36,19 @@ public HintDBTypeTest() { @Test public void testHint() throws Exception { SchemaConfig schema = schemaMap.get("TESTDB"); - //(new hint,/*!mycat*/),runOnSlave=false force master + //(new hint,/*!dble*/),runOnSlave=false force master String sql = "/*!dble:db_type=master*/select * from employee where sharding_id=1"; CacheService cacheService = new CacheService(false); RouteService routerService = new RouteService(cacheService); RouteResultset rrs = routerService.route(schema, ServerParse.SELECT, sql, "UTF-8", null); Assert.assertTrue(!rrs.getRunOnSlave()); - //(new hint,/*#mycat*/),runOnSlave=false force master + //(new hint,/*#dble*/),runOnSlave=false force master sql = "/*#dble:db_type=master*/select * from employee where sharding_id=1"; rrs = routerService.route(schema, ServerParse.SELECT, sql, "UTF-8", null); Assert.assertTrue(!rrs.getRunOnSlave()); - //(new hint,/*mycat*/),runOnSlave=false force master + //(new hint,/*dble*/),runOnSlave=false force master sql = "/*dble:db_type=master*/select * from employee where sharding_id=1"; rrs = routerService.route(schema, ServerParse.SELECT, sql, "UTF-8", null); Assert.assertTrue(!rrs.getRunOnSlave()); diff --git a/src/test/java/com/actiontech/dble/sqlexecute/TestJdbc.java b/src/test/java/com/actiontech/dble/sqlexecute/TestJdbc.java index 74f6963cba..e0847123be 100644 --- a/src/test/java/com/actiontech/dble/sqlexecute/TestJdbc.java +++ b/src/test/java/com/actiontech/dble/sqlexecute/TestJdbc.java @@ -11,9 +11,6 @@ public static void main(String[] args) throws SQLException { e.printStackTrace(); } - // String url = "jdbc:mysql://192.168.56.101:3309/mycat"; - // String username = "root"; - // String password = "root123"; String url = "jdbc:mysql://127.0.0.1:8066/TESTDB"; String username = "test"; String password = "test"; diff --git a/src/test/java/com/actiontech/dble/statistic/SQLStatisticsMain.java b/src/test/java/com/actiontech/dble/statistic/SQLStatisticsMain.java deleted file mode 100644 index 1d343de551..0000000000 --- a/src/test/java/com/actiontech/dble/statistic/SQLStatisticsMain.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software;Designed and Developed mainly by many Chinese - * opensource volunteers. you can redistribute it and/or modify it under the - * terms of the GNU General Public License version 2 only, as published by the - * Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Any questions about this component can be directed to it's project Web address - * https://code.google.com/p/opencloudb/. - * - */ -package com.actiontech.dble.statistic; - -/** - * @author mycat - */ -public class SQLStatisticsMain { - - -} \ No newline at end of file