├── candidate-commiter └── readme.md ├── Mycat-Core ├── src │ ├── main │ │ ├── resources │ │ │ ├── readme.txt │ │ │ ├── sharding-rule.xml │ │ │ ├── schema.xml │ │ │ ├── datasource.xml │ │ │ └── log4j2.xml │ │ └── java │ │ │ └── io │ │ │ └── mycat │ │ │ ├── backend │ │ │ ├── WriteCompleteListener.java │ │ │ ├── callback │ │ │ │ ├── ResponseCallbackAdapter.java │ │ │ │ └── DummyCallBack.java │ │ │ ├── BackConnectionCallback.java │ │ │ ├── ConQueue.java │ │ │ ├── MySQLBackendConnectionFactory.java │ │ │ └── ConnectionMeta.java │ │ │ ├── sqlcache │ │ │ ├── HintHandler.java │ │ │ ├── HintSQLRemoveKeyListener.java │ │ │ ├── LocatePolicy.java │ │ │ ├── HintSQLDataLoader.java │ │ │ ├── HintSQLInfo.java │ │ │ └── HintSQLParser.java │ │ │ ├── common │ │ │ ├── NameableExecutorService.java │ │ │ ├── State.java │ │ │ ├── NamebleScheduledExecutor.java │ │ │ ├── NameableExecutor.java │ │ │ ├── ExecutorUtil.java │ │ │ ├── StateMachine.java │ │ │ ├── NameableThreadFactory.java │ │ │ └── SimpleStateMachine.java │ │ │ ├── engine │ │ │ ├── dataChannel │ │ │ │ ├── TransferMode.java │ │ │ │ ├── DataHandler.java │ │ │ │ ├── DataChannel.java │ │ │ │ ├── DefaultDataTransferChannel.java │ │ │ │ └── impl │ │ │ │ │ └── PassThrouthtoBackendDataHandler.java │ │ │ ├── SQLRouter.java │ │ │ ├── Util.java │ │ │ ├── BatchSQLCmd.java │ │ │ ├── NoneBlockTask.java │ │ │ ├── SQLCmdRespCallback.java │ │ │ ├── SQLCommandHandler2.java │ │ │ ├── sqlparser │ │ │ │ └── SQLInfo.java │ │ │ ├── SQLCommandHandler.java │ │ │ ├── impl │ │ │ │ ├── AbstractComQueryCommandHandler.java │ │ │ │ ├── NormalSchemaSQLCommandHandler.java │ │ │ │ ├── PartionSchemaSQLCommandHandler.java │ │ │ │ └── FrontendComQueryCommandHandler.java │ │ │ └── UserSession.java │ │ │ ├── net2 │ │ │ ├── TimeUtil.java │ │ │ ├── states │ │ │ │ ├── network │ │ │ │ │ ├── TRY_READ_RESULT.java │ │ │ │ │ └── TRANSMIT_RESULT.java │ │ │ │ ├── ClosedState.java │ │ │ │ ├── ClosingState.java │ │ │ │ ├── ListeningState.java │ │ │ │ ├── ParseCmdState.java │ │ │ │ ├── NoReadState.java │ │ │ │ ├── NoWriteState.java │ │ │ │ ├── NewCmdState.java │ │ │ │ ├── NoReadAndWriteState.java │ │ │ │ ├── ReadWaitingState.java │ │ │ │ ├── WriteWaitingState.java │ │ │ │ ├── ReadState.java │ │ │ │ └── WriteState.java │ │ │ ├── ConnectIdGenerator.java │ │ │ ├── ConnectionException.java │ │ │ ├── ConnectionFactory.java │ │ │ ├── NIOHandler.java │ │ │ ├── NIOReactorPool.java │ │ │ ├── ClosableConnection.java │ │ │ └── NIOAcceptor.java │ │ │ ├── mysql │ │ │ ├── state │ │ │ │ ├── backend │ │ │ │ │ ├── BackendCloseState.java │ │ │ │ │ ├── BackendInitialState.java │ │ │ │ │ ├── BackendConnectingState.java │ │ │ │ │ ├── BackendIdleState.java │ │ │ │ │ ├── BackendComQueryState.java │ │ │ │ │ ├── BackendComQueryResponseState.java │ │ │ │ │ ├── BackendAuthenticatingState.java │ │ │ │ │ ├── BackendComQueryColumnDefState.java │ │ │ │ │ ├── BackendComQueryRowState.java │ │ │ │ │ └── BackendHandshakeState.java │ │ │ │ ├── frontend │ │ │ │ │ ├── FrontendCloseState.java │ │ │ │ │ ├── FrontendInitialState.java │ │ │ │ │ ├── FrontendHandshakeState.java │ │ │ │ │ ├── FrontendConnectingState.java │ │ │ │ │ ├── FrontendIdleState.java │ │ │ │ │ ├── FrontendComQueryState.java │ │ │ │ │ └── FrontendComLoadState.java │ │ │ │ ├── AbstractMysqlConnectionState.java │ │ │ │ └── PacketProcessStateTemplete.java │ │ │ ├── ServerStatus.java │ │ │ ├── Versions.java │ │ │ ├── Isolations.java │ │ │ ├── packet │ │ │ │ ├── EmptyPacket.java │ │ │ │ ├── Reply323Packet.java │ │ │ │ ├── EOFPacket.java │ │ │ │ └── ResultSetHeaderPacket.java │ │ │ ├── Alarms.java │ │ │ └── Fields.java │ │ │ ├── buffer │ │ │ ├── MycatByteBufferAllocator.java │ │ │ ├── IterableBuffer.java │ │ │ ├── DirectFixBufferAllocator.java │ │ │ ├── PacketIterator.java │ │ │ └── PacketDescriptor.java │ │ │ ├── util │ │ │ ├── UnsafeMemory.java │ │ │ ├── GenelUtil.java │ │ │ ├── Utils.java │ │ │ ├── RandomUtil.java │ │ │ ├── CharTypes.java │ │ │ └── PacketUtil.java │ │ │ ├── front │ │ │ └── MySQLFrontendConnectionFactory.java │ │ │ └── beans │ │ │ ├── ShardingRuleBean.java │ │ │ ├── MySQLRepBean.java │ │ │ ├── TableDefBean.java │ │ │ ├── SchemaBean.java │ │ │ ├── DNBean.java │ │ │ └── MySQLBean.java │ └── test │ │ ├── resources │ │ ├── readme.txt │ │ ├── schema.xml │ │ ├── sharding-rule.xml │ │ └── datasource.xml │ │ └── java │ │ └── io │ │ └── mycat │ │ ├── sqlcache │ │ └── TestHintSqlParser.java │ │ ├── net2 │ │ ├── TestParseDatasource.java │ │ └── TestReactorBufferPool.java │ │ └── memalloc │ │ └── TestMycatMemoryAlloctor.java ├── .gitignore └── README.md ├── template ├── images │ ├── Eclipse-1.png │ ├── Eclipse-2.png │ ├── Eclipse-3.png │ ├── Eclipse-4.png │ ├── Intellij-1.png │ ├── Intellij-2.png │ ├── Intellij-3.png │ ├── Intellij-4.png │ ├── Intellij-5.png │ ├── Intellij-6.png │ └── Intellij-7.png └── README.md ├── README.md └── bin ├── startup_nowrap.bat ├── startup_nowrap.sh └── startup_nowrap.sh.bak /candidate-commiter/readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/resources/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/resources/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Mycat-Core/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | *.rtmp 3 | *.wtmp 4 | *.iml 5 | .idea 6 | /logs 7 | -------------------------------------------------------------------------------- /template/images/Eclipse-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Eclipse-1.png -------------------------------------------------------------------------------- /template/images/Eclipse-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Eclipse-2.png -------------------------------------------------------------------------------- /template/images/Eclipse-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Eclipse-3.png -------------------------------------------------------------------------------- /template/images/Eclipse-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Eclipse-4.png -------------------------------------------------------------------------------- /template/images/Intellij-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-1.png -------------------------------------------------------------------------------- /template/images/Intellij-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-2.png -------------------------------------------------------------------------------- /template/images/Intellij-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-3.png -------------------------------------------------------------------------------- /template/images/Intellij-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-4.png -------------------------------------------------------------------------------- /template/images/Intellij-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-5.png -------------------------------------------------------------------------------- /template/images/Intellij-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-6.png -------------------------------------------------------------------------------- /template/images/Intellij-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MyCATApache/abandomed/HEAD/template/images/Intellij-7.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mycat 2.0 已经转移到 https://github.com/MyCATApache/tcp-proxy 2 | 3 | mycat2.0 最新代码,及后续的更新都会在 https://github.com/MyCATApache/tcp-proxy 项目进行。 4 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/WriteCompleteListener.java: -------------------------------------------------------------------------------- 1 | package io.mycat.backend; 2 | 3 | import java.io.IOException; 4 | 5 | @FunctionalInterface 6 | public interface WriteCompleteListener { 7 | void wirteComplete() throws IOException; 8 | } 9 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/resources/sharding-rule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | sharding-by-enum.txt 4 | 5 | 6 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/sqlcache/HintHandler.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | /** 4 | * Hint处理Handler 5 | * 6 | * @author zagnix 7 | * @create 2017-01-17 14:07 8 | */ 9 | 10 | public interface HintHandler { 11 | public boolean handle(String sql); 12 | } 13 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/NameableExecutorService.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | 5 | /** 6 | * @author wuzh 7 | */ 8 | public interface NameableExecutorService extends ExecutorService { 9 | 10 | public String getName(); 11 | } 12 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/resources/schema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/resources/sharding-rule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | sharding-by-enum.txt 4 | 2222 5 | 6 | 7 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/resources/schema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/State.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.net2.Connection; 6 | 7 | /** 8 | * 状态机状态接口 9 | * 10 | * @author ynfeng 11 | */ 12 | public interface State { 13 | boolean handle(StateMachine context, Connection connection, Object attachment) throws IOException; 14 | } 15 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/resources/datasource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/dataChannel/TransferMode.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.dataChannel; 2 | 3 | /** 4 | * 透传模式 5 | * @author yanjunli 6 | * 7 | */ 8 | public enum TransferMode { 9 | SHORT_HALF_PACKET, //短半包透传, 当前包长度不能够解析出报文头 10 | LONG_HALF_PACKET, //半包透传状态 当前包长度可以解析出报文头,但是不够完整的一个包的长度 11 | COMPLETE_PACKET, //全包透传状态 12 | NONE //当前不处于透传模式 13 | } 14 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | /** 4 | * 弱精度的计时器,考虑性能不使用同步策略。 5 | **/ 6 | public class TimeUtil { 7 | private static long CURRENT_TIME = System.currentTimeMillis(); 8 | 9 | public static final long currentTimeMillis() { 10 | return CURRENT_TIME; 11 | } 12 | 13 | public static final void update() { 14 | CURRENT_TIME = System.currentTimeMillis(); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/network/TRY_READ_RESULT.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states.network; 2 | 3 | public enum TRY_READ_RESULT { 4 | /** 数据接收完毕 */ 5 | READ_DATA_RECEIVED, 6 | /** 没有接收到数据 */ 7 | READ_NO_DATA_RECEIVED, 8 | /** an error occurred (on the socket) (or client closed connection) */ 9 | READ_ERROR, 10 | /** failed to allocate more memory */ 11 | READ_MEMORY_ERROR, 12 | } 13 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/network/TRANSMIT_RESULT.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states.network; 2 | 3 | /** 4 | * 向socket write 状态 5 | * @author yanjunli 6 | * 7 | */ 8 | public enum TRANSMIT_RESULT { 9 | TRANSMIT_COMPLETE, /** All done writing. */ 10 | TRANSMIT_INCOMPLETE, /** More data readableBytes to write. */ 11 | TRANSMIT_SOFT_ERROR, /** Can't write any more right now. */ 12 | TRANSMIT_HARD_ERROR /** Can't write (c->state is set to conn_closing) */ 13 | } 14 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/java/io/mycat/sqlcache/TestHintSqlParser.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * @author zagnix 7 | * @create 2017-01-16 18:03 8 | */ 9 | 10 | public class TestHintSqlParser { 11 | //TODO 测试case待完善 12 | @Test 13 | public void testHintSqlParser(){ 14 | String hintSql = "/*!mycat:cacheable=true cache-time=5000 auto-refresh=true access-count=5000*/select * from table"; 15 | System.out.println(HintSQLParser.parserHintSQL(hintSql).toString()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/NamebleScheduledExecutor.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.util.concurrent.ScheduledThreadPoolExecutor; 4 | import java.util.concurrent.ThreadFactory; 5 | 6 | public class NamebleScheduledExecutor extends ScheduledThreadPoolExecutor 7 | implements NameableExecutorService { 8 | private final String name; 9 | 10 | public NamebleScheduledExecutor(String name, int corePoolSize, 11 | ThreadFactory threadFactory) { 12 | super(corePoolSize, threadFactory); 13 | this.name = name; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/ClosedState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.State; 6 | import io.mycat.common.StateMachine; 7 | 8 | import io.mycat.net2.Connection; 9 | 10 | public class ClosedState implements State { 11 | public static final ClosedState INSTANCE = new ClosedState(); 12 | 13 | 14 | private ClosedState() { 15 | } 16 | 17 | @Override 18 | public boolean handle(StateMachine context, Connection conn, Object attachment) 19 | throws IOException { 20 | return false; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/resources/datasource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/ConnectIdGenerator.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | /** 4 | * 连接ID生成器 5 | * 6 | * @author mycat 7 | */ 8 | public class ConnectIdGenerator { 9 | 10 | private static final long MAX_VALUE = Long.MAX_VALUE; 11 | private static ConnectIdGenerator instance=new ConnectIdGenerator(); 12 | public static ConnectIdGenerator getINSTNCE() 13 | { 14 | return instance; 15 | } 16 | private long connectId = 0L; 17 | private final Object lock = new Object(); 18 | 19 | public long getId() { 20 | synchronized (lock) { 21 | if (connectId >= MAX_VALUE) { 22 | connectId = 0L; 23 | } 24 | return ++connectId; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/ConnectionException.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | public class ConnectionException extends RuntimeException { 4 | /** 5 | * 6 | */ 7 | private static final long serialVersionUID = 1L; 8 | private final int code; 9 | private final String msg; 10 | 11 | public ConnectionException(int code, String msg) { 12 | super(); 13 | this.code = code; 14 | this.msg = msg; 15 | } 16 | 17 | public int getCode() { 18 | return code; 19 | } 20 | 21 | public String getMsg() { 22 | return msg; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "ConnectionException [code=" + code + ", msg=" + msg + "]"; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/sqlcache/HintSQLRemoveKeyListener.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | import io.mycat.bigmem.sqlcache.BigSQLResult; 4 | import io.mycat.bigmem.sqlcache.IRemoveKeyListener; 5 | 6 | /** 7 | * HintSQL 结果集被移除时回调类 8 | * 9 | * @author zagnix 10 | * @create 2017-01-20 15:14 11 | */ 12 | 13 | public class HintSQLRemoveKeyListener implements IRemoveKeyListener { 14 | /** 15 | * key 失效,做清理工作 16 | * 17 | * @param key 18 | * @param value 19 | */ 20 | @Override 21 | public void removeNotify(K key, V value) { 22 | if (value !=null){ 23 | value.removeAll(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/ClosingState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.State; 6 | import io.mycat.common.StateMachine; 7 | 8 | import io.mycat.net2.Connection; 9 | 10 | public class ClosingState implements State { 11 | public static final ClosingState INSTANCE = new ClosingState(); 12 | 13 | 14 | private ClosingState() { 15 | } 16 | 17 | @Override 18 | public boolean handle(StateMachine context, Connection conn, Object attachment) 19 | throws IOException { 20 | conn.close(" close connection!"); 21 | return false; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /bin/startup_nowrap.bat: -------------------------------------------------------------------------------- 1 | 2 | REM check JAVA_HOME & java 3 | set "JAVA_CMD=%JAVA_HOME%/bin/java" 4 | if "%JAVA_HOME%" == "" goto noJavaHome 5 | if exist "%JAVA_HOME%\bin\java.exe" goto mainEntry 6 | :noJavaHome 7 | echo --------------------------------------------------- 8 | echo WARN: JAVA_HOME environment variable is not set. 9 | echo --------------------------------------------------- 10 | set "JAVA_CMD=java" 11 | :mainEntry 12 | REM set HOME_DIR 13 | set "CURR_DIR=%cd%" 14 | cd .. 15 | set "MYCAT_HOME=%cd%" 16 | cd %CURR_DIR% 17 | "%JAVA_CMD%" -server -Xms1G -Xmx2G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=1G -DMYCAT_HOME=%MYCAT_HOME% -cp "..\conf;..\lib\*" org.opencloudb.MycatStartup -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/dataChannel/DataHandler.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.dataChannel; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.mysql.MySQLConnection; 6 | 7 | /** 8 | * 数据处理接口 9 | * @author yanjunli 10 | * 11 | */ 12 | public interface DataHandler { 13 | 14 | /** 15 | * 传输处理 16 | * @param in 17 | * @param isTransferLastPacket 是否传输最后一个报文 18 | * @param transferFinish 当前透传方向是否完成 19 | * @param isAllFinish 整个命令交互,是否全部透传完成, 命令可能经过多次交互后,才完成,例如:load data local 命令,分两个阶段完成 20 | * @throws IOException 21 | */ 22 | public void transfer(MySQLConnection in,boolean isTransferLastPacket,boolean transferFinish,boolean isAllFinish)throws IOException; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/NameableExecutor.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.util.concurrent.BlockingQueue; 4 | import java.util.concurrent.ThreadFactory; 5 | import java.util.concurrent.ThreadPoolExecutor; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * @author wuzh 10 | */ 11 | public class NameableExecutor extends ThreadPoolExecutor implements NameableExecutorService { 12 | protected final String name; 13 | 14 | public NameableExecutor(String name, int size, BlockingQueue queue, ThreadFactory factory) { 15 | super(size, size, Long.MAX_VALUE, TimeUnit.NANOSECONDS, queue, factory); 16 | this.name = name; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/ExecutorUtil.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.util.concurrent.LinkedTransferQueue; 4 | 5 | /** 6 | * 生成一个有名字的(Nameable)Executor,容易进行跟踪和监控 7 | * 8 | * @author wuzh 9 | */ 10 | public class ExecutorUtil { 11 | 12 | public static final NameableExecutor create(String name, int size) { 13 | NameableThreadFactory factory = new NameableThreadFactory(name, true); 14 | return new NameableExecutor(name, size, 15 | new LinkedTransferQueue(), factory); 16 | } 17 | 18 | public static final NamebleScheduledExecutor createSheduledExecute( 19 | String name, int size) { 20 | NameableThreadFactory factory = new NameableThreadFactory(name, true); 21 | return new NamebleScheduledExecutor(name, size, factory); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/ListeningState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.State; 6 | import io.mycat.common.StateMachine; 7 | 8 | import io.mycat.net2.Connection; 9 | import io.mycat.net2.NetSystem; 10 | 11 | public class ListeningState implements State { 12 | 13 | public static final ListeningState INSTANCE = new ListeningState(); 14 | 15 | 16 | private ListeningState() { 17 | } 18 | 19 | @Override 20 | public boolean handle(StateMachine context, Connection conn, Object attachment) throws IOException { 21 | NetSystem.getInstance().addConnection(conn); 22 | conn.setDataBuffer(conn.getMycatByteBufferAllocator().allocate()); 23 | return conn.init(); 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/StateMachine.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * 状态操作接口 7 | * 8 | * @author ynfeng 9 | */ 10 | public interface StateMachine { 11 | /** 12 | * 设置下一个状态 13 | * 14 | * @param state 15 | */ 16 | StateMachine setNextState(State state); 17 | 18 | /** 19 | * 获取下一个状态 用于同步 20 | * 21 | * @return 22 | */ 23 | State getNextState(); 24 | 25 | /** 26 | * 获取当前状态 27 | * 28 | * @return 29 | */ 30 | State getCurrentState(); 31 | 32 | /** 33 | * 驱动状态 34 | * 35 | * @param attachment 附加参数 36 | */ 37 | void driveState(Object attachment) throws IOException; 38 | 39 | /** 40 | * 驱动状态 41 | */ 42 | void driveState() throws IOException; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/ConnectionFactory.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | import java.io.IOException; 4 | import java.net.StandardSocketOptions; 5 | import java.nio.channels.SocketChannel; 6 | 7 | /** 8 | * @author wuzh 9 | */ 10 | public abstract class ConnectionFactory { 11 | 12 | /** 13 | * 创建一个具体的连接 14 | * 15 | * @param channel 16 | * @return Connection 17 | * @throws IOException 18 | */ 19 | protected abstract Connection makeConnection(SocketChannel channel) 20 | throws IOException; 21 | 22 | 23 | public Connection make(SocketChannel channel) throws IOException { 24 | channel.setOption(StandardSocketOptions.SO_REUSEADDR, true); 25 | // 子类完成具体连接创建工作 26 | Connection c = makeConnection(channel); 27 | // 设置连接的参数 28 | NetSystem.getInstance().setSocketParams(c,true); 29 | return c; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendCloseState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 6 | import io.mycat.net2.Connection; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | 11 | /** 12 | * 关闭状态 13 | * 14 | * @author ynfeng 15 | */ 16 | public class BackendCloseState extends AbstractMysqlConnectionState { 17 | private static final Logger LOGGER = LoggerFactory.getLogger(BackendCloseState.class); 18 | 19 | public static final BackendCloseState INSTANCE = new BackendCloseState(); 20 | 21 | private BackendCloseState() { 22 | } 23 | 24 | 25 | @Override 26 | public boolean handle(StateMachine context, Connection connection, Object attachment) { 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/callback/ResponseCallbackAdapter.java: -------------------------------------------------------------------------------- 1 | package io.mycat.backend.callback; 2 | 3 | import io.mycat.backend.BackConnectionCallback; 4 | import io.mycat.backend.MySQLBackendConnection; 5 | import io.mycat.net2.ConnectionException; 6 | 7 | /** 8 | * 只处理响应的适配器 9 | * 10 | * @author ynfeng 11 | */ 12 | public abstract class ResponseCallbackAdapter implements BackConnectionCallback { 13 | @Override 14 | public void connectionError(ConnectionException e, MySQLBackendConnection conn) { 15 | 16 | } 17 | 18 | @Override 19 | public void connectionAcquired(MySQLBackendConnection conn) { 20 | 21 | } 22 | 23 | @Override 24 | public void connectionClose(MySQLBackendConnection conn, String reason) { 25 | 26 | } 27 | 28 | @Override 29 | public void handlerError(Exception e, MySQLBackendConnection conn) { 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Mycat-Core/README.md: -------------------------------------------------------------------------------- 1 | # Mycat-Core 2 | Mycat 2.0的核心组件之一,正在重新设计和演化 3 | 目前参与的人为 4 | Leader.us以及Java高端培训一期和二期培训同学,希望更多高手参与 5 | 6 | 入口类:[io.mycat.net2.mysql.MockMySQLServer] 7 | 8 | 入口类中的静态方法快配置了一个DB node,目前大部分报文会直接转发到这个node上进行查询,返回的报文直接传给client 9 | DBHostConfig config = new DBHostConfig("host1", "127.0.0.1", 3306, "mysql", "root", "123456"); 10 | config.setMaxCon(10); 11 | PhysicalDatasource dbSource = new MySQLDataSource(config, false); 12 | PhysicalDBPool dbPool = new PhysicalDBPool("host1", new PhysicalDatasource[] { dbSource }, new HashMap<>()); 13 | PhysicalDBNode dbNode = new PhysicalDBNode("host1", "mysql", dbPool); 14 | 15 | 本机要启动一个MySQL Server,用户名root,密码 123456 ,如上面代码所示,即可连接和学习测试 16 | 监听端口:8066 17 | 18 | 目前MockServer只支持登录认证、大部分CRUD语句、exit 19 | 20 | ##### 登录:mysql -uroot -proot -P 8066 (是判断用户名是否为root) 21 | 22 | ##### 查询 23 | 24 | ##### exit 释放连接 -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/sqlcache/LocatePolicy.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | /** 4 | * 策略信息 5 | * 源文件名:LocatePolicy.java 6 | * 文件版本:1.0.0 7 | * 创建作者:Think 8 | * 创建日期:2016年12月27日 9 | * 修改作者:Think 10 | * 修改日期:2016年12月27日 11 | * 文件描述:TODO 12 | * 版权所有:Copyright 2016 zjhz, Inc. All Rights Reserved. 13 | */ 14 | public enum LocatePolicy { 15 | 16 | /** 17 | * 使用本地的内存进行缓存的策略 18 | * @字段说明 Core 19 | */ 20 | Core(1), 21 | 22 | /** 23 | * 使用文件进行映射的缓存的策略信息 24 | * @字段说明 Normal 25 | */ 26 | Normal(2); 27 | 28 | /** 29 | * 策略信息 30 | * @字段说明 policy 31 | */ 32 | private int policy; 33 | 34 | public int getPolicy() { 35 | return policy; 36 | } 37 | 38 | public void setPolicy(int policy) { 39 | this.policy = policy; 40 | } 41 | 42 | private LocatePolicy(int policy) { 43 | this.policy = policy; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/ParseCmdState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.State; 6 | import io.mycat.common.StateMachine; 7 | import io.mycat.mysql.MySQLConnection; 8 | 9 | import io.mycat.net2.Connection; 10 | 11 | public class ParseCmdState implements State { 12 | public static final ParseCmdState INSTANCE = new ParseCmdState(); 13 | 14 | private ParseCmdState() { 15 | } 16 | 17 | @Override 18 | public boolean handle(StateMachine context, Connection conn, Object object) 19 | throws IOException { 20 | ((MySQLConnection) conn).getProtocolStateMachine().driveState(null); 21 | if (conn.getNetworkStateMachine().getWriteRemaining() == 0) { 22 | conn.getNetworkStateMachine().setNextState(ReadWaitingState.INSTANCE); 23 | } 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/NameableThreadFactory.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | public class NameableThreadFactory implements ThreadFactory { 7 | private final ThreadGroup group; 8 | private final String namePrefix; 9 | private final AtomicInteger threadId; 10 | private final boolean isDaemon; 11 | 12 | public NameableThreadFactory(String name, boolean isDaemon) { 13 | SecurityManager s = System.getSecurityManager(); 14 | this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread() 15 | .getThreadGroup(); 16 | this.namePrefix = name; 17 | this.threadId = new AtomicInteger(0); 18 | this.isDaemon = isDaemon; 19 | } 20 | 21 | public Thread newThread(Runnable r) { 22 | Thread t = new Thread(group, r, namePrefix + threadId.getAndIncrement()); 23 | t.setDaemon(isDaemon); 24 | return t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendCloseState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 6 | import io.mycat.net2.Connection; 7 | import io.mycat.net2.states.ClosingState; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | /** 12 | * 关闭状态 13 | * 14 | * @author ynfeng 15 | */ 16 | public class FrontendCloseState extends AbstractMysqlConnectionState { 17 | private static final Logger LOGGER = LoggerFactory.getLogger(FrontendCloseState.class); 18 | 19 | public static final FrontendCloseState INSTANCE = new FrontendCloseState(); 20 | 21 | private FrontendCloseState() { 22 | } 23 | 24 | @Override 25 | public boolean handle(StateMachine stateMachine, Connection connection, Object attachment) { 26 | connection.getNetworkStateMachine().setNextState(ClosingState.INSTANCE); 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendInitialState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | import io.mycat.front.MySQLFrontConnection; 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 6 | import io.mycat.net2.Connection; 7 | 8 | /** 9 | * 初始状态 10 | * 11 | * @author ynfeng 12 | */ 13 | public class FrontendInitialState extends AbstractMysqlConnectionState { 14 | public static final FrontendInitialState INSTANCE = new FrontendInitialState(); 15 | 16 | private FrontendInitialState() { 17 | } 18 | 19 | /** 20 | * 前端连接在初始状态下不做任何动作,转到至连接中状态 21 | */ 22 | @Override 23 | public boolean handle(StateMachine stateMachine, Connection connection, Object attachment) { 24 | MySQLFrontConnection mySQLFrontConnection = (MySQLFrontConnection) connection; 25 | mySQLFrontConnection.getProtocolStateMachine().setNextState(FrontendConnectingState.INSTANCE); 26 | return true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/ServerStatus.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql; 2 | 3 | public class ServerStatus { 4 | public static short SERVER_STATUS_IN_TRANS = 0x0001; 5 | public static short SERVER_STATUS_AUTOCOMMIT = 0x0002; 6 | public static short SERVER_MORE_RESULTS_EXISTS = 0x0008; 7 | public static short SERVER_STATUS_NO_GOOD_INDEX_USED = 0x0010; 8 | public static short SERVER_STATUS_NO_INDEX_USED = 0x0020; 9 | public static short SERVER_STATUS_CURSOR_EXISTS = 0x0040; 10 | public static short SERVER_STATUS_LAST_ROW_SENT = 0x0080; 11 | public static short SERVER_STATUS_DB_DROPPED = 0x0100; 12 | public static short SERVER_STATUS_NO_BACKSLASH_ESCAPES = 0x0200; 13 | public static short SERVER_STATUS_METADATA_CHANGED = 0x0400; 14 | public static short SERVER_QUERY_WAS_SLOW = 0x0800; 15 | public static short SERVER_PS_OUT_PARAMS = 0x1000; 16 | public static short SERVER_STATUS_IN_TRANS_READONLY = 0x2000; 17 | public static short SERVER_SESSION_STATE_CHANGED = 0x4000; 18 | } 19 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendHandshakeState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | 4 | import io.mycat.front.MySQLFrontConnection; 5 | import io.mycat.common.StateMachine; 6 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 7 | import io.mycat.net2.Connection; 8 | 9 | /** 10 | * 握手状态 11 | * 12 | * @author ynfeng 13 | */ 14 | public class FrontendHandshakeState extends AbstractMysqlConnectionState { 15 | public static final FrontendHandshakeState INSTANCE = new FrontendHandshakeState(); 16 | 17 | private FrontendHandshakeState() { 18 | } 19 | 20 | /** 21 | * 接收客户端的握手响应包,转至认证状态 22 | */ 23 | @Override 24 | public boolean handle(StateMachine context, Connection connection, Object attachment) { 25 | MySQLFrontConnection mySQLFrontConnection = (MySQLFrontConnection) connection; 26 | mySQLFrontConnection.getProtocolStateMachine().setNextState(FrontendAuthenticatingState.INSTANCE); 27 | return true; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendInitialState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import io.mycat.backend.MySQLBackendConnection; 5 | import io.mycat.common.StateMachine; 6 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 7 | import io.mycat.net2.Connection; 8 | 9 | 10 | /** 11 | * 初始状态 12 | * 13 | * @author ynfeng 14 | */ 15 | public class BackendInitialState extends AbstractMysqlConnectionState { 16 | 17 | public static final BackendInitialState INSTANCE = new BackendInitialState(); 18 | 19 | private BackendInitialState() { 20 | } 21 | 22 | 23 | /** 24 | * 后端连接在初始状态下不做任何动作,转到至连接中状态 25 | */ 26 | @Override 27 | public boolean handle(StateMachine stateMachine, Connection connection, Object attachment) { 28 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 29 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendConnectingState.INSTANCE); 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/NIOHandler.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | import java.io.IOException; 4 | /** 5 | * NIOHandler是无状态的,多个连接共享一个,用于处理连接的事件,每个方法需要不阻塞,尽快返回结果 6 | * 7 | * @author wuzh 8 | */ 9 | public interface NIOHandler { 10 | 11 | /** 12 | * 连接建立成功的通知事件 13 | * 14 | * @param con 15 | * 当前连接 16 | */ 17 | public void onConnected(T con) throws IOException; 18 | 19 | /** 20 | * 连接失败 21 | * 22 | * @param con 23 | * 失败的连接 24 | * @param e 25 | * 连接异常 26 | */ 27 | public void onConnectFailed(T con, ConnectionException e); 28 | 29 | /** 30 | * 连接关闭通知 31 | * @param con 32 | * @throws IOException 33 | */ 34 | public void onClosed(T con,String reason); 35 | 36 | /** 37 | * 收到数据需要处理 38 | * 39 | * @param con 40 | * 当前连接 41 | */ 42 | void handleReadEvent(T con) throws IOException; 43 | 44 | /** 45 | * 数据处理过程中发生意外错误 46 | * @param con 47 | * @param e 48 | */ 49 | void onHandlerError(T con,Exception e); 50 | 51 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{36}.%M:%L - %m%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/NoReadState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import io.mycat.common.State; 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.net2.Connection; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.nio.channels.SelectionKey; 11 | 12 | /** 13 | * Created by ynfeng on 2017/8/4. 14 | */ 15 | public class NoReadState implements State { 16 | private static final Logger LOGGER = LoggerFactory.getLogger(NoReadAndWriteState.class); 17 | public static final NoReadState INSTANCE = new NoReadState(); 18 | 19 | private NoReadState() { 20 | } 21 | 22 | @Override 23 | public boolean handle(StateMachine context, Connection connection, Object attachment) throws IOException { 24 | SelectionKey processKey = connection.getProcessKey(); 25 | try { 26 | processKey.interestOps(processKey.interestOps() & Connection.OP_NOT_READ); 27 | return false; 28 | } catch (Exception e) { 29 | LOGGER.warn("disable read fail " + e); 30 | } 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/NoWriteState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import io.mycat.common.State; 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.net2.Connection; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | import java.nio.channels.SelectionKey; 11 | 12 | /** 13 | * Created by ynfeng on 2017/8/4. 14 | */ 15 | public class NoWriteState implements State { 16 | private static final Logger LOGGER = LoggerFactory.getLogger(NoReadAndWriteState.class); 17 | public static final NoWriteState INSTANCE = new NoWriteState(); 18 | 19 | private NoWriteState() { 20 | } 21 | 22 | @Override 23 | public boolean handle(StateMachine context, Connection connection, Object attachment) throws IOException { 24 | SelectionKey processKey = connection.getProcessKey(); 25 | try { 26 | processKey.interestOps(processKey.interestOps() & Connection.OP_NOT_WRITE); 27 | return false; 28 | } catch (Exception e) { 29 | LOGGER.warn("disable write fail " + e); 30 | } 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendConnectingState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | import io.mycat.backend.MySQLBackendConnection; 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 6 | import io.mycat.net2.Connection; 7 | import io.mycat.net2.NetSystem; 8 | 9 | import java.io.IOException; 10 | 11 | 12 | /** 13 | * 连接中状态 14 | * 15 | * @author ynfeng 16 | */ 17 | public class BackendConnectingState extends AbstractMysqlConnectionState { 18 | public static final BackendConnectingState INSTANCE = new BackendConnectingState(); 19 | 20 | private BackendConnectingState() { 21 | } 22 | 23 | /** 24 | * 连接后端服务器 25 | */ 26 | @Override 27 | public boolean handle(StateMachine stateMachine, Connection connection, Object attachment) throws IOException { 28 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 29 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendHandshakeState.INSTANCE); 30 | NetSystem.getInstance().getConnector().postConnect(mySQLBackendConnection); 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/NewCmdState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.State; 6 | import io.mycat.common.StateMachine; 7 | 8 | import io.mycat.net2.Connection; 9 | 10 | /** 11 | * @author yanjunli 12 | */ 13 | public class NewCmdState implements State { 14 | 15 | public static final NewCmdState INSTANCE = new NewCmdState(); 16 | 17 | 18 | private NewCmdState() { 19 | } 20 | 21 | @Override 22 | public boolean handle(StateMachine context, Connection connection, Object attachment) throws IOException { 23 | Connection.NetworkStateMachine networkStateMachine = ((Connection.NetworkStateMachine) context); 24 | if (networkStateMachine.getBuffer().writableBytes() < (networkStateMachine.getBuffer().capacity() / 2)) { 25 | networkStateMachine.getBuffer().compact(); 26 | } 27 | networkStateMachine.setNextState(ReadWaitingState.INSTANCE); 28 | if (networkStateMachine.getDest() != connection) { 29 | networkStateMachine.getDest().getNetworkStateMachine().setNextState(ReadWaitingState.INSTANCE); 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to Mycat 2 | ## 初次使用指南 3 | ### 一、 模版导入 4 | mycat使用模版在项目包的template目录下,使用的模版文件名为mycat-style.xml。 5 | 6 | 具体配置参考: 7 | #### Intellij IDEA 8 | 1. 打开IDEA的 Preferences->Editor->Code Style_Java 9 | ![本地图片](images/Intellij-1.png) 10 | 2. 点击右侧区域的Manage,在弹出的选项中选择Import 11 | ![本地图片](images/Intellij-2.png) 12 | 3. 在弹出的选项中选择Eclipse XML Profile 13 | ![本地图片](images/Intellij-3.png) 14 | 4. 选择mycat-style.xml文件,并点击ok 15 | ![本地图片](images/Intellij-4.png) 16 | 5. 添加完后在Schema中选择MyCATStyle,并点击右下角的ok 17 | ![本地图片](images/Intellij-5.png) 18 | 19 | #### Eclipse 20 | 1. 打开Eclipse的 Preferences->Java->Code Style->Formatter 21 | ![本地图片](images/Eclipse-1.png) 22 | 2. 点击Import将mycat-style.xml加入进profile中 23 | ![本地图片](images/Eclipse-2.png) 24 | 3. 在Active profile的下拉列表中选择MyCATStyle 25 | ![本地图片](images/Eclipse-3.png) 26 | 27 | ### 二、 保存自动格式化(可选) 28 | #### Intellij IDEA 29 | 1. IDEA的自动保存格式化需要添加plugin,在 Preferences->Plugins 中输入 Save Actions,在右侧框框中点击安装 30 | ![本地图片](images/Intellij-6.png) 31 | 2. 在 Preferences->Other Settings 中选择 Save Actions 配置自动保存时的操作 32 | ![本地图片](images/Intellij-7.png) 33 | 34 | #### Eclipse 35 | 在Eclipse的 Preferences->Java->Editor->Save Action 中勾选自动保存时的行为,如下所示,并点击Apply、OK 36 | ![本地图片](images/Eclipse-4.png) 37 | 38 | 至此配置完毕,在写完代码保存之后即可完成格式化。 -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/NoReadAndWriteState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | import java.nio.channels.SelectionKey; 5 | 6 | import io.mycat.common.State; 7 | import io.mycat.common.StateMachine; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import io.mycat.net2.Connection; 12 | 13 | public class NoReadAndWriteState implements State { 14 | 15 | private static final Logger LOGGER = LoggerFactory.getLogger(NoReadAndWriteState.class); 16 | public static final NoReadAndWriteState INSTANCE = new NoReadAndWriteState(); 17 | 18 | private NoReadAndWriteState() { 19 | } 20 | 21 | @Override 22 | public boolean handle(StateMachine context, Connection conn, Object attachment) 23 | throws IOException { 24 | SelectionKey processKey = conn.getProcessKey(); 25 | try { 26 | processKey.interestOps(processKey.interestOps() & Connection.OP_NOT_READ); 27 | processKey.interestOps(processKey.interestOps() & Connection.OP_NOT_WRITE); 28 | return true; 29 | } catch (Exception e) { 30 | LOGGER.warn("enable read fail " + e); 31 | } 32 | return false; 33 | } 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/buffer/MycatByteBufferAllocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, MyCAT and/or its affiliates. All rights reserved. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *

16 | */ 17 | package io.mycat.buffer; 18 | 19 | /** 20 | * 缓冲分配器,该分配器只分配固定大小的缓冲区 21 | * 22 | * Created by ynfeng on 2017/7/7. 23 | */ 24 | public interface MycatByteBufferAllocator { 25 | /** 26 | * 分配一个缓冲 27 | * 28 | * @return 缓冲区 29 | */ 30 | MycatByteBuffer allocate(); 31 | 32 | /** 33 | * 回收缓冲 34 | * 35 | * @param buffer 待回收的缓冲 36 | */ 37 | void recyle(MycatByteBuffer buffer); 38 | 39 | /** 40 | * 获取分配器每次分配的缓冲区大小 41 | * 42 | * @return 缓冲区大小 43 | */ 44 | int getChunkSize(); 45 | } 46 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/SQLRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | 26 | public interface SQLRouter { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | /** 26 | * 27 | * @author wuzhihui 28 | * 29 | */ 30 | public class Util { 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/NIOReactorPool.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class NIOReactorPool { 8 | private final NIOReactor[] reactors; 9 | private volatile int nextReactor; 10 | 11 | public NIOReactorPool(String name, int poolSize) throws IOException { 12 | reactors = new NIOReactor[poolSize]; 13 | Map reactorMap = new HashMap(); 14 | for (int i = 0; i < poolSize; i++) { 15 | NIOReactor reactor = new NIOReactor(name + "-" + i); 16 | reactors[i] = reactor; 17 | reactor.startup(); 18 | reactorMap.put(reactor.getName(), reactor); 19 | 20 | } 21 | 22 | } 23 | 24 | public NIOReactor[] getAllReactors() { 25 | return reactors; 26 | } 27 | 28 | public NIOReactor getSpecialActor(String name) { 29 | for (NIOReactor reactor : reactors) { 30 | if (reactor.getName().equals(name)) { 31 | return reactor; 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | public NIOReactor getNextReactor() { 38 | int i = ++nextReactor; 39 | if (i >= reactors.length) { 40 | i = nextReactor = 0; 41 | } 42 | return reactors[i]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/dataChannel/DataChannel.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.dataChannel; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.mysql.MySQLConnection; 6 | 7 | /** 8 | * 数据传输通道 9 | * @author yanjunli 10 | * 11 | */ 12 | public interface DataChannel { 13 | 14 | public void addToFrontHandler(DataHandler handler); 15 | 16 | public void addToBackendHandler(DataHandler handler); 17 | 18 | public void removeToFrontHandler(DataHandler handler); 19 | 20 | public void removeToBackendHandler(DataHandler handler); 21 | 22 | /** 23 | * 透传处理 24 | * @param in 透传数据输入连接 25 | * @param out 透传数据输出连接 26 | * @param shareDataBuffer 共享buffer 27 | * @param mode 传输模式 28 | * @param isTransferLastPacket 最后一个包是否传输 29 | * @param isAllFinish 是否全部透传完成 30 | */ 31 | public void transferToFront(MySQLConnection in,boolean isTransferLastPacket,boolean transferFinish,boolean isAllFinish)throws IOException; 32 | 33 | /** 34 | * 透传处理 35 | * @param in 透传数据输入连接 36 | * @param out 透传数据输出连接 37 | * @param shareDataBuffer 共享buffer 38 | * @param mode 传输模式 39 | * @param isTransferLastPacket 最后一个包是否传输 40 | * @param isAllFinish 是否全部透传完成 41 | */ 42 | public void transferToBackend(MySQLConnection in,boolean isTransferLastPacket,boolean transferFinish,boolean isAllFinish)throws IOException; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/BatchSQLCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */package io.mycat.engine; 24 | /** 25 | * 批量SQL命令,多条命令批量执行并返回结果 26 | * @author wuzhihui 27 | * 28 | */ 29 | public interface BatchSQLCmd { 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/buffer/IterableBuffer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, MyCAT and/or its affiliates. All rights reserved. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *

16 | */ 17 | package io.mycat.buffer; 18 | 19 | /** 20 | * Created by ynfeng on 2017/7/27. 21 | *

22 | * The class that implements this interface can create multiple iterators, 23 | * Each of which keeps its internal state until the {@link PacketIterator#reset()} method calls. 24 | * Note:For performance reasons, try to create only one iterator. 25 | */ 26 | public interface IterableBuffer { 27 | 28 | /** 29 | * Gets an iterator named 'default' 30 | */ 31 | PacketIterator packetIterator(); 32 | 33 | /** 34 | * Gets an iterator named {@code name} 35 | * 36 | * @param name The name of iterator 37 | */ 38 | PacketIterator packetIterator(String name); 39 | } 40 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/NoneBlockTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | /** 26 | * used for asynchronized execute ,MUST be noneblock and fatest !!! 27 | * @author wuzhihui 28 | * 29 | */ 30 | public interface NoneBlockTask { 31 | 32 | public void execute() throws Exception; 33 | } 34 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/Versions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql; 25 | 26 | /** 27 | * @author mycat 28 | */ 29 | public interface Versions { 30 | 31 | /**协议版本**/ 32 | public static final byte PROTOCOL_VERSION = 10; 33 | 34 | /**服务器版**/ 35 | public static final byte[] SERVER_VERSION = "Fake MySQL server".getBytes(); 36 | 37 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/util/UnsafeMemory.java: -------------------------------------------------------------------------------- 1 | package io.mycat.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import sun.misc.Unsafe; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | 10 | /** 11 | * Unsafe 工具类 12 | * 13 | * @author zagnix 14 | * @create 2016-11-18 14:17 15 | */ 16 | public final class UnsafeMemory { 17 | private final static Logger logger = LoggerFactory.getLogger(UnsafeMemory.class); 18 | private static final Unsafe _UNSAFE; 19 | public static final int BYTE_ARRAY_OFFSET; 20 | static { 21 | Unsafe unsafe; 22 | try { 23 | Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 24 | theUnsafeField.setAccessible(true); 25 | unsafe = (Unsafe) theUnsafeField.get(null); 26 | } catch (Exception e) { 27 | logger.error(e.getMessage()); 28 | unsafe = null; 29 | } 30 | _UNSAFE = unsafe; 31 | if (_UNSAFE != null) { 32 | BYTE_ARRAY_OFFSET = _UNSAFE.arrayBaseOffset(byte[].class); 33 | } else { 34 | BYTE_ARRAY_OFFSET = 0; 35 | } 36 | } 37 | public static Unsafe getUnsafe() { 38 | return _UNSAFE; 39 | } 40 | 41 | /** 42 | * 将size规整化为pagesize的倍数 43 | * @param size 44 | * @return 45 | */ 46 | public static long roundToOsPageSzie(long size) { 47 | long pagesize = _UNSAFE.pageSize(); 48 | return (size + (pagesize-1)) & ~(pagesize-1); 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/util/GenelUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.util; 25 | /** 26 | * 27 | * @author wuzhihui 28 | * 29 | */ 30 | public class GenelUtil { 31 | 32 | public static boolean isLinuxSystem() 33 | { 34 | //return false; 35 | return System.getProperty("os.name").toUpperCase().startsWith("LINUX"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/Isolations.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql; 25 | 26 | /** 27 | * 事务隔离级别定义 28 | * 29 | * @author mycat 30 | */ 31 | public interface Isolations { 32 | 33 | public static final int READ_UNCOMMITTED = 1; 34 | public static final int READ_COMMITTED = 2; 35 | public static final int REPEATED_READ = 3; 36 | public static final int SERIALIZABLE = 4; 37 | 38 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendConnectingState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | import io.mycat.front.MySQLFrontConnection; 4 | import io.mycat.common.StateMachine; 5 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 6 | import io.mycat.net2.Connection; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | 11 | /** 12 | * 连接中状态 13 | * 14 | * @author ynfeng 15 | */ 16 | public class FrontendConnectingState extends AbstractMysqlConnectionState { 17 | private static final Logger LOGGER = LoggerFactory.getLogger(FrontendConnectingState.class); 18 | public static final FrontendConnectingState INSTANCE = new FrontendConnectingState(); 19 | 20 | private FrontendConnectingState() { 21 | } 22 | 23 | /** 24 | * 向客户端响应握手包 25 | */ 26 | @Override 27 | public boolean handle(StateMachine context, Connection connection, Object attachment) { 28 | LOGGER.debug(connection.getClass().getSimpleName() + " in " + this.getClass().getSimpleName()); 29 | MySQLFrontConnection mySQLFrontConnection = (MySQLFrontConnection) connection; 30 | try { 31 | mySQLFrontConnection.sendAuthPackge(); 32 | mySQLFrontConnection.getProtocolStateMachine().setNextState(FrontendHandshakeState.INSTANCE); 33 | return false; 34 | } catch (Throwable e) { 35 | LOGGER.warn("frontend FrontendInitialState error", e); 36 | mySQLFrontConnection.getProtocolStateMachine().setNextState(FrontendCloseState.INSTANCE); 37 | return true; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/ClosableConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.net2; 25 | 26 | public interface ClosableConnection { 27 | 28 | /** 29 | * 关闭连接 30 | */ 31 | void close(String reason); 32 | 33 | boolean isClosed(); 34 | 35 | public void idleCheck(); 36 | 37 | long getStartupTime(); 38 | 39 | String getHost(); 40 | 41 | int getPort(); 42 | 43 | int getLocalPort(); 44 | 45 | long getNetInBytes(); 46 | 47 | long getNetOutBytes(); 48 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/SQLCmdRespCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | 26 | import java.io.IOException; 27 | 28 | /** 29 | * 异步收到SQL命令返回信息时候的回调方法 30 | * @author wuzhihui 31 | * 32 | */ 33 | public interface SQLCmdRespCallback { 34 | 35 | /** 36 | * 处理命令返回的结果,返回true表示data已经被消费,可以回收data底层数据了 37 | * @param data 38 | * @return 39 | * @throws IOException 40 | */ 41 | public boolean onResponse(S data) throws IOException; 42 | } 43 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/packet/EmptyPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql.packet; 25 | 26 | /** 27 | * @author mycat暂时只发现在load data infile时用到 28 | */ 29 | public class EmptyPacket extends MySQLPacket { 30 | public static final byte[] EMPTY = new byte[] { 0, 0, 0,3 }; 31 | 32 | @Override 33 | public int calcPacketSize() { 34 | return 0; 35 | } 36 | 37 | @Override 38 | protected String getPacketInfo() { 39 | return "MySQL Empty Packet"; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/SQLCommandHandler2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | 26 | import java.io.IOException; 27 | 28 | import io.mycat.mysql.MySQLConnection; 29 | 30 | /** 31 | * internal used for process sql command 32 | * @author wuzhihui 33 | * 34 | */ 35 | public interface SQLCommandHandler2 { 36 | /** 37 | * response received data 38 | * @param frontCon 39 | * @throws IOException 40 | */ 41 | public void processCmd(MySQLConnection conn) throws IOException; 42 | } 43 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/java/io/mycat/net2/TestParseDatasource.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | import java.net.URL; 4 | import java.util.List; 5 | 6 | import org.junit.Test; 7 | 8 | import io.mycat.ConfigLoader; 9 | import io.mycat.beans.MySQLRepBean; 10 | import io.mycat.beans.SchemaBean; 11 | import io.mycat.beans.ShardingRuleBean; 12 | import junit.framework.Assert; 13 | 14 | public class TestParseDatasource { 15 | 16 | @Test 17 | public void TestDatasource() { 18 | URL datasourceURL=ConfigLoader.class.getResource("/datasource.xml"); 19 | List allReps=ConfigLoader.loadMySQLRepBean(datasourceURL.toString()); 20 | Assert.assertEquals(2, allReps.size()); 21 | Assert.assertEquals(2, allReps.get(0).getMysqls().size()); 22 | Assert.assertEquals(2, allReps.get(1).getMysqls().size()); 23 | } 24 | @Test 25 | public void TestShardingRule() { 26 | URL datasourceURL=ConfigLoader.class.getResource("/sharding-rule.xml"); 27 | List allBeans=ConfigLoader.loadShardingRules(datasourceURL.toString()); 28 | Assert.assertEquals(1, allBeans.size()); 29 | Assert.assertEquals(2, allBeans.get(0).getParams().size()); 30 | Assert.assertEquals("sharding-by-enum.txt", allBeans.get(0).getParams().get("mapFile")); 31 | 32 | 33 | } 34 | 35 | @Test 36 | public void TestSheamBeans() { 37 | URL datasourceURL=ConfigLoader.class.getResource("/schema.xml"); 38 | List allBeans=ConfigLoader.loadSheamBeans(datasourceURL.toString()); 39 | Assert.assertEquals(2, allBeans.size()); 40 | Assert.assertEquals(0, allBeans.get(0).getTableDefBeans().size()); 41 | Assert.assertEquals(1, allBeans.get(1).getTableDefBeans().size()); 42 | 43 | 44 | 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/common/SimpleStateMachine.java: -------------------------------------------------------------------------------- 1 | package io.mycat.common; 2 | 3 | import io.mycat.net2.Connection; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by ynfeng on 2017/7/31. 11 | */ 12 | public class SimpleStateMachine implements StateMachine { 13 | private static final Logger LOGGER = LoggerFactory.getLogger(SimpleStateMachine.class); 14 | protected State state; 15 | private State nextState; 16 | private Connection connection; 17 | 18 | public SimpleStateMachine(Connection connection, State initialState) { 19 | this.state = initialState; 20 | this.connection = connection; 21 | } 22 | 23 | @Override 24 | public StateMachine setNextState(State state) { 25 | this.nextState = state; 26 | return this; 27 | } 28 | 29 | @Override 30 | public State getNextState() { 31 | return nextState; 32 | } 33 | 34 | @Override 35 | public void driveState(Object attachment) throws IOException { 36 | boolean result; 37 | do { 38 | if (this.nextState != null) { 39 | this.state = nextState; 40 | this.nextState = null; 41 | } 42 | LOGGER.debug(connection.getClass().getSimpleName() + "'s " + this.getClass().getSimpleName() + " drive to " + state.getClass().getSimpleName()); 43 | result = this.state.handle(this, connection, attachment); 44 | } while (result); 45 | } 46 | 47 | @Override 48 | public void driveState() throws IOException { 49 | driveState(null); 50 | } 51 | 52 | @Override 53 | public State getCurrentState() { 54 | return state; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendIdleState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import java.io.IOException; 5 | 6 | import io.mycat.mysql.state.PacketProcessStateTemplete; 7 | import io.mycat.net2.Connection; 8 | 9 | import io.mycat.backend.MySQLBackendConnection; 10 | import io.mycat.mysql.packet.MySQLPacket; 11 | 12 | /** 13 | * 空闲状态 14 | * 15 | * @author ynfeng 16 | */ 17 | public class BackendIdleState extends PacketProcessStateTemplete { 18 | 19 | public static final BackendIdleState INSTANCE = new BackendIdleState(); 20 | 21 | private BackendIdleState() { 22 | } 23 | 24 | @Override 25 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 26 | return false; 27 | } 28 | 29 | @Override 30 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 31 | return handleFullPacket(connection, attachment, packetStartPos, packetLen, type); 32 | } 33 | 34 | @Override 35 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 36 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 37 | switch (type) { 38 | case MySQLPacket.COM_QUERY: 39 | mySQLBackendConnection.getDataBuffer().packetIterator().fallback(); 40 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendComQueryState.INSTANCE); 41 | return true; 42 | default: 43 | break; 44 | } 45 | return false; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/ReadWaitingState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | import java.nio.channels.SelectionKey; 5 | 6 | import io.mycat.common.State; 7 | import io.mycat.common.StateMachine; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import io.mycat.net2.Connection; 12 | 13 | public class ReadWaitingState implements State { 14 | 15 | private static final Logger LOGGER = LoggerFactory.getLogger(ReadWaitingState.class); 16 | public static final ReadWaitingState INSTANCE = new ReadWaitingState(); 17 | 18 | private ReadWaitingState() { 19 | } 20 | 21 | @Override 22 | public boolean handle(StateMachine context, Connection connection, Object attachment) throws IOException { 23 | try { 24 | Connection.NetworkStateMachine networkStateMachine = ((Connection.NetworkStateMachine) context); 25 | connection.getProcessKey().interestOps(connection.getProcessKey().interestOps() & Connection.OP_NOT_WRITE); 26 | connection.getProcessKey().interestOps(connection.getProcessKey().interestOps() | SelectionKey.OP_READ); 27 | connection.getNetworkStateMachine().setNextState(ReadState.INSTANCE); 28 | if (connection != networkStateMachine.getDest()) { 29 | networkStateMachine.getDest().getNetworkStateMachine().setNextState(NoWriteState.INSTANCE); 30 | } 31 | connection.getProcessKey().selector().wakeup(); 32 | } catch (Exception e) { 33 | LOGGER.warn("enable read fail ", e); 34 | connection.getNetworkStateMachine().setNextState(ClosingState.INSTANCE); 35 | } 36 | return false; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/Alarms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql; 25 | 26 | /** 27 | * Mycat报警关键词定义 28 | * 29 | * @author mycat 30 | */ 31 | public interface Alarms { 32 | /** 默认报警关键词 **/ 33 | public static final String DEFAULT = "#!MyCat#"; 34 | 35 | /** 集群无有效的节点可提供服务 **/ 36 | public static final String CLUSTER_EMPTY = "#!CLUSTER_EMPTY#"; 37 | 38 | /** 数据节点的数据源发生切换 **/ 39 | public static final String DATANODE_SWITCH = "#!DN_SWITCH#"; 40 | 41 | /** 隔离区非法用户访问 **/ 42 | public static final String QUARANTINE_ATTACK = "#!QT_ATTACK#"; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/WriteWaitingState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | import java.nio.channels.SelectionKey; 5 | 6 | import io.mycat.common.State; 7 | import io.mycat.common.StateMachine; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import io.mycat.net2.Connection; 12 | 13 | public class WriteWaitingState implements State { 14 | 15 | private static final Logger LOGGER = LoggerFactory.getLogger(WriteWaitingState.class); 16 | public static final WriteWaitingState INSTANCE = new WriteWaitingState(); 17 | 18 | private WriteWaitingState() { 19 | } 20 | 21 | 22 | @Override 23 | public boolean handle(StateMachine context, Connection connection, Object attachment) 24 | throws IOException { 25 | SelectionKey processKey = connection.getProcessKey(); 26 | Connection.NetworkStateMachine networkStateMachine = ((Connection.NetworkStateMachine) context); 27 | try { 28 | processKey.interestOps(processKey.interestOps() & Connection.OP_NOT_READ); 29 | processKey.interestOps(processKey.interestOps() | SelectionKey.OP_WRITE); 30 | connection.getNetworkStateMachine().setNextState(WriteState.INSTANCE); 31 | if (connection != networkStateMachine.getDest()) { 32 | networkStateMachine.getDest().getNetworkStateMachine().setNextState(NoReadState.INSTANCE); 33 | } 34 | processKey.selector().wakeup(); 35 | } catch (Exception e) { 36 | LOGGER.warn("enable read fail " + e); 37 | connection.getNetworkStateMachine().setNextState(ClosingState.INSTANCE); 38 | } 39 | return false; 40 | } 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/ReadState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.State; 6 | import io.mycat.common.StateMachine; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import io.mycat.net2.Connection; 11 | import io.mycat.net2.states.network.TRY_READ_RESULT; 12 | 13 | 14 | public class ReadState implements State { 15 | private static final Logger LOGGER = LoggerFactory.getLogger(ReadState.class); 16 | public static final ReadState INSTANCE = new ReadState(); 17 | 18 | private ReadState() { 19 | } 20 | 21 | @Override 22 | public boolean handle(StateMachine context, Connection connection, Object attachment) 23 | throws IOException { 24 | TRY_READ_RESULT res; 25 | res = connection.try_read_network(); 26 | LOGGER.debug(connection.getClass().getSimpleName() + " read from network result " + res + "." + connection); 27 | switch (res) { 28 | case READ_NO_DATA_RECEIVED: 29 | connection.getNetworkStateMachine().setNextState(ReadWaitingState.INSTANCE); 30 | break; 31 | case READ_DATA_RECEIVED: /* 数据读取完成,开始解析命令 */ 32 | connection.getNetworkStateMachine().setNextState(ParseCmdState.INSTANCE); 33 | break; 34 | case READ_ERROR: 35 | connection.getNetworkStateMachine().setNextState(ClosingState.INSTANCE); 36 | break; 37 | case READ_MEMORY_ERROR: /* Failed to allocate more memory */ 38 | connection.getNetworkStateMachine().setNextState(ClosingState.INSTANCE); 39 | break; 40 | } 41 | return true; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendComQueryState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import java.io.IOException; 5 | 6 | import io.mycat.common.StateMachine; 7 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 8 | import io.mycat.net2.Connection; 9 | 10 | import io.mycat.backend.MySQLBackendConnection; 11 | import io.mycat.buffer.MycatByteBuffer; 12 | import io.mycat.net2.states.ReadWaitingState; 13 | import io.mycat.net2.states.WriteWaitingState; 14 | 15 | /** 16 | * 查询状态 17 | * 18 | * @author ynfeng 19 | */ 20 | public class BackendComQueryState extends AbstractMysqlConnectionState { 21 | public static final BackendComQueryState INSTANCE = new BackendComQueryState(); 22 | 23 | private BackendComQueryState() { 24 | } 25 | 26 | @Override 27 | public boolean handle(StateMachine stateMachine, Connection connection, Object attachment) throws IOException { 28 | MySQLBackendConnection conn = (MySQLBackendConnection) connection; 29 | MycatByteBuffer writeBuffer = conn.getDataBuffer(); 30 | if (conn.isPassthrough()) { //如果处于透传模式下,需要从共享buffer 获取数据 31 | conn.setDataBuffer(conn.getShareBuffer()); 32 | } 33 | /* 这里还没有办法区分是前端状态机驱动还是后端状态机驱动 */ 34 | conn.getNetworkStateMachine().setNextState(WriteWaitingState.INSTANCE) 35 | .driveState(); 36 | conn.setWriteCompleteListener(() -> { 37 | conn.getProtocolStateMachine().setNextState(BackendComQueryResponseState.INSTANCE); 38 | conn.setDataBuffer(writeBuffer); 39 | conn.getNetworkStateMachine().setNextState(ReadWaitingState.INSTANCE); 40 | conn.getShareBuffer().compact(); //透传buffer 使用compact 41 | conn.getDataBuffer().clear(); //非透传buffer 使用 clear 42 | }); 43 | return false; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/java/io/mycat/memalloc/TestMycatMemoryAlloctor.java: -------------------------------------------------------------------------------- 1 | package io.mycat.memalloc; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import org.junit.Test; 5 | 6 | import java.nio.ByteBuffer; 7 | import java.nio.CharBuffer; 8 | import java.nio.charset.Charset; 9 | import java.nio.charset.CharsetDecoder; 10 | 11 | /** 12 | * @author zagnix 13 | * @create 2017-01-18 11:19 14 | */ 15 | 16 | public class TestMycatMemoryAlloctor { 17 | @Test 18 | public void testMemAlloc(){ 19 | final MyCatMemoryAllocator memoryAllocator = 20 | new MyCatMemoryAllocator(Runtime.getRuntime().availableProcessors()*2); 21 | 22 | for (int i = 0; i <100 ; i++) { 23 | ByteBuf byteBuf = memoryAllocator.directBuffer(128); 24 | byteBuf.writeBytes("helll world".getBytes()); 25 | ByteBuffer byteBuffer = byteBuf.nioBuffer(0,128); 26 | String srt = getString(byteBuffer); 27 | byteBuf.release(); 28 | System.out.println("refCnt:" + byteBuf.refCnt()); 29 | // byteBuf.writeBytes(byteBuffer); 30 | // System.out.println("refCnt:" + byteBuf.refCnt()); 31 | } 32 | } 33 | 34 | public static String getString(ByteBuffer buffer) { 35 | Charset charset = null; 36 | CharsetDecoder decoder = null; 37 | CharBuffer charBuffer = null; 38 | try { 39 | charset = Charset.forName("UTF-8"); 40 | decoder = charset.newDecoder(); 41 | charBuffer = decoder.decode(buffer.asReadOnlyBuffer()); 42 | return charBuffer.toString(); 43 | } catch (Exception ex) { 44 | ex.printStackTrace(); 45 | return "error"; 46 | } 47 | } 48 | 49 | public static ByteBuffer getByteBuffer(String str) 50 | { 51 | return ByteBuffer.wrap(str.getBytes()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/sqlparser/SQLInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine.sqlparser; 25 | 26 | /** 27 | * 存放SQL解析的结果,重复使用 28 | * 29 | * @author wuzhihui 30 | * 31 | */ 32 | public class SQLInfo { 33 | /** 34 | * 上次解析的位置 35 | */ 36 | private int parsePos; 37 | private String db; 38 | 39 | public SQLInfo() { 40 | 41 | } 42 | 43 | public int getParsePos() { 44 | return parsePos; 45 | } 46 | 47 | public void setParsePos(int parsePos) { 48 | this.parsePos = parsePos; 49 | } 50 | 51 | public String getDb() { 52 | return db; 53 | } 54 | 55 | public void setDb(String db) { 56 | this.db = db; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/SQLCommandHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | 26 | import java.io.IOException; 27 | 28 | import io.mycat.buffer.MycatByteBuffer; 29 | import io.mycat.front.MySQLFrontConnection; 30 | 31 | /** 32 | * internal used for process sql command 33 | * 34 | * @author wuzhihui 35 | */ 36 | public interface SQLCommandHandler { 37 | /** 38 | * response received data 39 | * 40 | * @param frontCon 41 | * @param dataBuffer 42 | * @param packageType 43 | * @param pkgStartPos 44 | * @param pkgLen 45 | * @throws IOException 46 | */ 47 | public void processCmd(MySQLFrontConnection frontCon, MycatByteBuffer dataBuffer, byte packageType, int pkgStartPos, int pkgLen) throws IOException; 48 | } 49 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/dataChannel/DefaultDataTransferChannel.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.dataChannel; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import io.mycat.engine.dataChannel.impl.PassThrouthtoBackendDataHandler; 8 | import io.mycat.engine.dataChannel.impl.PassThrouthtoFrontDataHandler; 9 | import io.mycat.mysql.MySQLConnection; 10 | 11 | public class DefaultDataTransferChannel implements DataChannel { 12 | 13 | private List toFronthandlers = new ArrayList<>(); 14 | 15 | private List toBackendhandlers = new ArrayList<>(); 16 | 17 | { 18 | toFronthandlers.add(PassThrouthtoFrontDataHandler.INSTANCE); 19 | toBackendhandlers.add(PassThrouthtoBackendDataHandler.INSTANCE); 20 | } 21 | 22 | @Override 23 | public void transferToFront(MySQLConnection in, boolean isTransferLastPacket,boolean transferFinish, boolean isAllFinish) throws IOException { 24 | for(DataHandler handler:toFronthandlers){ 25 | handler.transfer(in,isTransferLastPacket,transferFinish, isAllFinish); 26 | } 27 | } 28 | 29 | @Override 30 | public void transferToBackend(MySQLConnection in, 31 | boolean isTransferLastPacket,boolean transferFinish, boolean isAllFinish) throws IOException { 32 | for(DataHandler handler:toBackendhandlers){ 33 | handler.transfer(in, isTransferLastPacket,transferFinish, isAllFinish); 34 | } 35 | } 36 | 37 | 38 | @Override 39 | public void addToFrontHandler(DataHandler handler) { 40 | toFronthandlers.add(handler); 41 | } 42 | 43 | @Override 44 | public void addToBackendHandler(DataHandler handler) { 45 | toBackendhandlers.add(handler); 46 | } 47 | 48 | @Override 49 | public void removeToFrontHandler(DataHandler handler) { 50 | toFronthandlers.remove(handler); 51 | } 52 | 53 | @Override 54 | public void removeToBackendHandler(DataHandler handler) { 55 | toBackendhandlers.remove(handler); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/front/MySQLFrontendConnectionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.front; 25 | 26 | import java.io.IOException; 27 | import java.nio.channels.SocketChannel; 28 | 29 | import io.mycat.net2.Connection; 30 | import io.mycat.net2.ConnectionFactory; 31 | /** 32 | * create front mysql connection 33 | * @author wuzhihui 34 | * 35 | */ 36 | public class MySQLFrontendConnectionFactory extends ConnectionFactory { 37 | 38 | 39 | @Override 40 | protected Connection makeConnection(SocketChannel channel) throws IOException { 41 | MySQLFrontConnection con = new MySQLFrontConnection(channel); 42 | // con.setPrivileges(MycatPrivileges.instance()); 43 | // con.setCharset("UTF-8"); 44 | // con.setLoadDataInfileHandler(new ServerLoadDataInfileHandler(c)); 45 | // c.setPrepareHandler(new ServerPrepareHandler(c)); 46 | // con.setTxIsolation(sys.getTxIsolation()); 47 | return con; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/buffer/DirectFixBufferAllocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, MyCAT and/or its affiliates. All rights reserved. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *

16 | */ 17 | package io.mycat.buffer; 18 | 19 | import java.nio.ByteBuffer; 20 | import java.util.LinkedList; 21 | 22 | /** 23 | * Created by ynfeng on 2017/7/7. 24 | */ 25 | public class DirectFixBufferAllocator implements MycatByteBufferAllocator { 26 | private final LinkedList freeBuffers = new LinkedList<>(); 27 | private int chunkSize; 28 | private MycatByteBufferAllocator parent; 29 | 30 | public DirectFixBufferAllocator(int capacity) { 31 | this.chunkSize = capacity; 32 | } 33 | 34 | @Override 35 | public MycatByteBuffer allocate() { 36 | MycatByteBuffer mycatByteBuffer = freeBuffers.pollLast(); 37 | if (mycatByteBuffer == null) { 38 | ByteBuffer byteBuffer = ByteBuffer.allocateDirect(chunkSize); 39 | mycatByteBuffer = new DirectFixBuffer(byteBuffer, chunkSize); 40 | } 41 | mycatByteBuffer.clear(); 42 | return mycatByteBuffer; 43 | } 44 | 45 | @Override 46 | public void recyle(MycatByteBuffer buffer) { 47 | if (buffer.capacity() == chunkSize) { 48 | freeBuffers.addFirst(buffer); 49 | } else { 50 | throw new IllegalArgumentException("Can't recyle MycatByteBuffer capacity " + buffer.capacity()); 51 | } 52 | } 53 | 54 | @Override 55 | public int getChunkSize() { 56 | return chunkSize; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendComQueryResponseState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import java.io.IOException; 5 | 6 | import io.mycat.mysql.state.PacketProcessStateTemplete; 7 | import io.mycat.net2.Connection; 8 | 9 | import io.mycat.backend.MySQLBackendConnection; 10 | import io.mycat.mysql.packet.MySQLPacket; 11 | 12 | /** 13 | * COM_QUERY响应 14 | * 15 | * @author ynfeng 16 | */ 17 | public class BackendComQueryResponseState extends PacketProcessStateTemplete { 18 | public static final BackendComQueryResponseState INSTANCE = new BackendComQueryResponseState(); 19 | 20 | private BackendComQueryResponseState() { 21 | } 22 | 23 | 24 | @Override 25 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 26 | return false; 27 | } 28 | 29 | @Override 30 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 31 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 32 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 33 | return false; 34 | } 35 | 36 | @Override 37 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 38 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 39 | if (type == MySQLPacket.ERROR_PACKET) { 40 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendIdleState.INSTANCE); 41 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 42 | interruptIterate(); 43 | return false; 44 | } else { 45 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendComQueryColumnDefState.INSTANCE); 46 | interruptIterate(); 47 | return true; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/states/WriteState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2.states; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.buffer.MycatByteBuffer; 6 | import io.mycat.common.State; 7 | import io.mycat.common.StateMachine; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import io.mycat.net2.Connection; 12 | import io.mycat.net2.states.network.TRANSMIT_RESULT; 13 | 14 | public class WriteState implements State { 15 | 16 | private static final Logger LOGGER = LoggerFactory.getLogger(WriteState.class); 17 | public static final WriteState INSTANCE = new WriteState(); 18 | 19 | private WriteState() { 20 | } 21 | 22 | @Override 23 | public boolean handle(StateMachine context, Connection connection, Object attachment) 24 | throws IOException { 25 | Connection.NetworkStateMachine networkStateMachine = (Connection.NetworkStateMachine) context; 26 | MycatByteBuffer byteBuffer = networkStateMachine.getBuffer(); 27 | TRANSMIT_RESULT result = connection.write(byteBuffer, networkStateMachine.getWriteRemaining()); 28 | LOGGER.debug(connection.getClass().getSimpleName() + " write to network result " + result + "." + connection); 29 | switch (result) { 30 | case TRANSMIT_COMPLETE: 31 | networkStateMachine.setWriteRemaining(0); 32 | connection.getNetworkStateMachine().setNextState(NewCmdState.INSTANCE); 33 | return true; 34 | case TRANSMIT_INCOMPLETE: 35 | int updateRemaining = networkStateMachine.getWriteRemaining() - (networkStateMachine.getWriteRemaining() - byteBuffer.readableBytes()); 36 | networkStateMachine.setWriteRemaining(updateRemaining); 37 | return true; //没有传输完成,继续保持当前状态,继续传输 38 | case TRANSMIT_HARD_ERROR: /* 连接断开了... */ 39 | connection.getNetworkStateMachine().setNextState(ClosingState.INSTANCE); 40 | return true; 41 | case TRANSMIT_SOFT_ERROR: /* socket write buffer pool is full */ 42 | return false; 43 | } 44 | return true; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/sqlcache/HintSQLDataLoader.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | import com.google.common.util.concurrent.*; 4 | import io.mycat.bigmem.sqlcache.BigSQLResult; 5 | import io.mycat.bigmem.sqlcache.IDataLoader; 6 | import io.mycat.bigmem.sqlcache.Keyer; 7 | import io.mycat.bigmem.console.LocatePolicy; 8 | import java.util.concurrent.Callable; 9 | import java.util.concurrent.Executors; 10 | 11 | import static com.google.common.hash.Hashing.murmur3_32; 12 | 13 | /** 14 | * SQL 异步加载结果集类 15 | * 16 | * @author zagnix 17 | * @create 2017-01-20 15:13 18 | */ 19 | 20 | public class HintSQLDataLoader implements IDataLoader { 21 | /** 22 | * 根据sql,异步从后台DB reload数据,替换旧值 23 | * @param keyer 24 | * @return 25 | */ 26 | @Override 27 | public V reload(Keyer keyer) { 28 | ListeningExecutorService executor = 29 | MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); 30 | 31 | final ListenableFuture listenableFuture = executor 32 | .submit(new Callable() { 33 | @Override 34 | public BigSQLResult call() throws Exception { 35 | //TODO 36 | String sql = keyer.getSql(); 37 | String sqlkey = keyer.getLastAccessTime() +"_"+murmur3_32().hashUnencodedChars(sql); 38 | BigSQLResult sqlResultCache 39 | = new BigSQLResult(LocatePolicy.Normal,sqlkey,32*1024*1024); 40 | 41 | 42 | return sqlResultCache; 43 | } 44 | }); 45 | 46 | Futures.addCallback(listenableFuture, new FutureCallback() { 47 | @Override 48 | public void onSuccess(BigSQLResult bigSQLResult) { 49 | //TODO 50 | } 51 | 52 | @Override 53 | public void onFailure(Throwable t) { 54 | //TODO 55 | } 56 | } 57 | ); 58 | return null; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/impl/AbstractComQueryCommandHandler.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.impl; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.SQLEngineCtx; 6 | import io.mycat.backend.MySQLBackendConnection; 7 | import io.mycat.backend.MySQLBackendConnectionFactory; 8 | import io.mycat.backend.MySQLDataSource; 9 | import io.mycat.backend.MySQLReplicatSet; 10 | import io.mycat.beans.DNBean; 11 | import io.mycat.engine.SQLCommandHandler; 12 | import io.mycat.front.MySQLFrontConnection; 13 | 14 | /** 15 | * ComQuery命令处理器基类 16 | * 17 | * @author ynfeng 18 | */ 19 | public abstract class AbstractComQueryCommandHandler implements SQLCommandHandler { 20 | 21 | protected MySQLBackendConnection getBackendFrontConnection(MySQLFrontConnection mySQLFrontConnection) throws IOException { 22 | // // 直接透传(默认)获取连接池 23 | // MySQLBackendConnection existCon = null; 24 | // UserSession session = mySQLFrontConnection.getSession(); 25 | // ArrayList allBackCons = session.getBackendCons(); 26 | // if (!allBackCons.isEmpty()) { 27 | // existCon = allBackCons.get(0); 28 | // } 29 | // if (existCon == null || existCon.isClosed()) { 30 | // if (existCon != null) { 31 | // session.removeBackCon(existCon); 32 | // } 33 | final DNBean dnBean = mySQLFrontConnection.getMycatSchema().getDefaultDN(); 34 | final String replica = dnBean.getMysqlReplica(); 35 | final SQLEngineCtx ctx = SQLEngineCtx.INSTANCE(); 36 | final MySQLReplicatSet repSet = ctx.getMySQLReplicatSet(replica); 37 | final MySQLDataSource datas = repSet.getCurWriteDH(); 38 | // 39 | // /** 40 | // * 如果该sql对应后端db,没有连接池,则创建连接池部分 41 | // */ 42 | // MySQLBackendConnection existCon = datas.getConnection(mySQLFrontConnection.getReactor(), dnBean.getDatabase(), true, mySQLFrontConnection, null); 43 | // } 44 | MySQLBackendConnection con = new MySQLBackendConnectionFactory().make(datas, mySQLFrontConnection.getReactor(), dnBean.getDatabase(), mySQLFrontConnection, null); 45 | mySQLFrontConnection.setBackendConnection(con); 46 | return con; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/AbstractMysqlConnectionState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.SQLEngineCtx; 6 | import io.mycat.backend.MySQLBackendConnection; 7 | import io.mycat.backend.MySQLBackendConnectionFactory; 8 | import io.mycat.backend.MySQLDataSource; 9 | import io.mycat.backend.MySQLReplicatSet; 10 | import io.mycat.beans.DNBean; 11 | import io.mycat.buffer.MycatByteBuffer; 12 | import io.mycat.common.State; 13 | import io.mycat.engine.dataChannel.TransferMode; 14 | import io.mycat.front.MySQLFrontConnection; 15 | import io.mycat.mysql.MySQLConnection; 16 | 17 | /** 18 | * 19 | * @author ynfeng 20 | */ 21 | public abstract class AbstractMysqlConnectionState implements State { 22 | 23 | protected MySQLBackendConnection getBackendFrontConnection(MySQLFrontConnection mySQLFrontConnection) throws IOException { 24 | // // 直接透传(默认)获取连接池 25 | // MySQLBackendConnection existCon = null; 26 | // UserSession session = mySQLFrontConnection.getSession(); 27 | // ArrayList allBackCons = session.getBackendCons(); 28 | // if (!allBackCons.isEmpty()) { 29 | // existCon = allBackCons.get(0); 30 | // } 31 | // if (existCon == null || existCon.isClosed()) { 32 | // if (existCon != null) { 33 | // session.removeBackCon(existCon); 34 | // } 35 | final DNBean dnBean = mySQLFrontConnection.getMycatSchema().getDefaultDN(); 36 | final String replica = dnBean.getMysqlReplica(); 37 | final SQLEngineCtx ctx = SQLEngineCtx.INSTANCE(); 38 | final MySQLReplicatSet repSet = ctx.getMySQLReplicatSet(replica); 39 | final MySQLDataSource datas = repSet.getCurWriteDH(); 40 | // 41 | // /** 42 | // * 如果该sql对应后端db,没有连接池,则创建连接池部分 43 | // */ 44 | // MySQLBackendConnection existCon = datas.getConnection(mySQLFrontConnection.getReactor(), dnBean.getDatabase(), true, mySQLFrontConnection, null); 45 | // } 46 | MySQLBackendConnection con = new MySQLBackendConnectionFactory().make(datas, mySQLFrontConnection.getReactor(), dnBean.getDatabase(), mySQLFrontConnection, null); 47 | mySQLFrontConnection.setBackendConnection(con); 48 | return con; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/sqlcache/HintSQLInfo.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Hint SQL 携带的属性KV 和 真实执行的sql 8 | * 9 | * @author zagnix 10 | * @version 1.0 11 | * @create 2017-01-16 17:32 12 | */ 13 | 14 | public class HintSQLInfo { 15 | private String functionName; 16 | private boolean isCache = false; 17 | private HintHandler hintHandler; 18 | private String hintSQL; 19 | private String execSQL; 20 | 21 | /** 22 | * paramsKv 中的Key必须是 cache-time,auto-refresh,access-count 23 | * cache-time=xxx auto-refresh=true access-count=5000 24 | */ 25 | private Map paramsKv = new HashMap<>(); 26 | 27 | public HintSQLInfo(String hintSQL){ 28 | this.hintSQL = hintSQL; 29 | } 30 | 31 | public String getExecSQL() { 32 | return execSQL; 33 | } 34 | 35 | public void setExecSQL(String execSQL) { 36 | this.execSQL = execSQL; 37 | } 38 | 39 | public Map getParamsKv() { 40 | return paramsKv; 41 | } 42 | 43 | public void setParamsKv(Map paramsKv) { 44 | this.paramsKv = paramsKv; 45 | } 46 | 47 | public String getFunctionName() { 48 | return functionName; 49 | } 50 | 51 | public void setFunctionName(String functionName) { 52 | this.functionName = functionName; 53 | } 54 | 55 | public String getHintSQL() { 56 | return hintSQL; 57 | } 58 | 59 | public void setHintSQL(String hintSQL) { 60 | this.hintSQL = hintSQL; 61 | } 62 | 63 | public HintHandler getHintHandler() { 64 | return hintHandler; 65 | } 66 | 67 | public void setHintHandler(HintHandler hintHandler) { 68 | this.hintHandler = hintHandler; 69 | } 70 | 71 | public boolean isCache() { 72 | return isCache; 73 | } 74 | 75 | public void setCache(boolean cache) { 76 | isCache = cache; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return "HintSQLInfo{" + 82 | "functionName='" + functionName + '\'' + 83 | ", hintSQL='" + hintSQL + '\'' + 84 | ", execSQL='" + execSQL + '\'' + 85 | ", paramsKv=" + paramsKv + 86 | '}'; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/BackConnectionCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.backend; 25 | 26 | import java.io.IOException; 27 | 28 | import io.mycat.buffer.MycatByteBuffer; 29 | import io.mycat.net2.ConnectionException; 30 | /** 31 | * 后端数据库的事件处理回调接口 32 | * @author wuzhihui 33 | * 34 | */ 35 | public interface BackConnectionCallback { 36 | 37 | /** 38 | * 无法获取连接 39 | * 40 | * @param e 41 | * @param conn 42 | */ 43 | void connectionError(ConnectionException e, MySQLBackendConnection conn); 44 | 45 | /** 46 | * 已获得有效连接的响应处理 47 | */ 48 | void connectionAcquired(MySQLBackendConnection conn); 49 | 50 | /** 51 | * 收到数据包的响应处理 52 | */ 53 | void handleResponse(MySQLBackendConnection conn, MycatByteBuffer dataBuffer, byte packageType, int pkgStartPos, int pkgLen) throws IOException ; 54 | 55 | /** 56 | * on connetion close event 57 | */ 58 | void connectionClose(MySQLBackendConnection conn, String reason); 59 | 60 | /** 61 | * 处理数据的过程中发生错误 62 | * @param e 63 | * @param conn 64 | */ 65 | void handlerError(Exception e,MySQLBackendConnection conn); 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/impl/NormalSchemaSQLCommandHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine.impl; 25 | 26 | 27 | /** 28 | * 不分片的Schema對應的 SQL Command Handler 29 | * 30 | * @author wuzhihui 31 | * 32 | */ 33 | public class NormalSchemaSQLCommandHandler extends AbstractSchemaSQLCommandHandler { 34 | 35 | // @Override 36 | // public void executeSetSQL(MySQLFrontConnection frontCon, ConDataBuffer dataBuffer, byte packageType, 37 | // int pkgStartPos, int pkgLen, String sql) throws IOException { 38 | // passThroughSQL(frontCon, dataBuffer, pkgStartPos, pkgLen); 39 | // 40 | // } 41 | // 42 | // @Override 43 | // public void executeShowSQL(MySQLFrontConnection frontCon, ConDataBuffer dataBuffer, byte packageType, 44 | // int pkgStartPos, int pkgLen, String sql) throws IOException { 45 | // passThroughSQL(frontCon, dataBuffer, pkgStartPos, pkgLen); 46 | // 47 | // } 48 | // 49 | // @Override 50 | // public void executeSelectSQL(MySQLFrontConnection frontCon, ConDataBuffer dataBuffer, byte packageType, 51 | // int pkgStartPos, int pkgLen, String sql) throws IOException { 52 | // passThroughSQL(frontCon, dataBuffer, pkgStartPos, pkgLen); 53 | // 54 | // } 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/util/Utils.java: -------------------------------------------------------------------------------- 1 | package io.mycat.util; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.Random; 6 | import java.util.regex.Pattern; 7 | 8 | public class Utils { 9 | private static final String illegalChars = "/" + '\u0000' + '\u0001' + "-" + '\u001F' + '\u007F' + "-" + '\u009F' + '\uD800' + "-" + '\uF8FF' + '\uFFF0' 10 | + "-" + '\uFFFF'; 11 | private static final Pattern p = Pattern.compile("(^\\.{1,2}$)|[" + illegalChars + "]"); 12 | 13 | public static void validateFolder(String name) { 14 | if (name == null || name.length() == 0) { 15 | throw new IllegalArgumentException("folder name is emtpy"); 16 | } 17 | if(name.length() > 255) { 18 | throw new IllegalArgumentException("folder name is too long"); 19 | } 20 | if (p.matcher(name).find()) { 21 | throw new IllegalArgumentException("folder name [" + name + "] is illegal"); 22 | } 23 | } 24 | 25 | public static boolean isFilenameValid(String file) { 26 | File f = new File(file); 27 | try { 28 | f.getCanonicalPath(); 29 | return true; 30 | } catch (IOException e) { 31 | return false; 32 | } 33 | } 34 | 35 | public static void deleteDirectory(File dir) { 36 | if (!dir.exists()) return; 37 | File[] subs = dir.listFiles(); 38 | if (subs != null) { 39 | for (File f : dir.listFiles()) { 40 | if (f.isFile()) { 41 | if(!f.delete()) { 42 | throw new IllegalStateException("delete file failed: "+f); 43 | } 44 | } else { 45 | deleteDirectory(f); 46 | } 47 | } 48 | } 49 | if(!dir.delete()) { 50 | throw new IllegalStateException("delete directory failed: "+dir); 51 | } 52 | } 53 | 54 | static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 55 | static Random rnd = new Random(); 56 | 57 | public static String randomString(int len ) 58 | { 59 | StringBuilder sb = new StringBuilder( len ); 60 | for( int i = 0; i < len; i++ ) 61 | sb.append( AB.charAt( rnd.nextInt(AB.length()) ) ); 62 | return sb.toString(); 63 | } 64 | 65 | 66 | public static void deleteFile(File file) { 67 | if (!file.exists() || !file.isFile()) { 68 | return; 69 | } 70 | if (!file.delete()) { 71 | throw new IllegalStateException("delete file failed: "+file); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendAuthenticatingState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import io.mycat.mysql.state.PacketProcessStateTemplete; 5 | import io.mycat.net2.Connection; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import io.mycat.backend.MySQLBackendConnection; 10 | import io.mycat.front.MySQLFrontConnection; 11 | import io.mycat.mysql.packet.MySQLPacket; 12 | 13 | import java.io.IOException; 14 | 15 | /** 16 | * 认证状态 17 | * 18 | * @author ynfeng 19 | */ 20 | public class BackendAuthenticatingState extends PacketProcessStateTemplete { 21 | private static final Logger LOGGER = LoggerFactory.getLogger(BackendAuthenticatingState.class); 22 | public static final BackendAuthenticatingState INSTANCE = new BackendAuthenticatingState(); 23 | 24 | private BackendAuthenticatingState() { 25 | } 26 | 27 | @Override 28 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 29 | return false; 30 | } 31 | 32 | @Override 33 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 34 | return false; 35 | } 36 | 37 | @Override 38 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 39 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 40 | try { 41 | if (type == MySQLPacket.ERROR_PACKET) { 42 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendCloseState.INSTANCE); 43 | } else if (type == MySQLPacket.OK_PACKET) { 44 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendIdleState.INSTANCE); 45 | MySQLFrontConnection mySQLFrontConnection = mySQLBackendConnection.getMySQLFrontConnection(); 46 | if (mySQLFrontConnection != null) { 47 | mySQLFrontConnection.executePendingTask(); 48 | } 49 | } 50 | } catch (Throwable e) { 51 | LOGGER.warn("BackendAuthenticatingState error:", e); 52 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendCloseState.INSTANCE); 53 | return true; 54 | } 55 | return false; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendIdleState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | 4 | import io.mycat.front.MySQLFrontConnection; 5 | import io.mycat.mysql.packet.MySQLPacket; 6 | import io.mycat.mysql.state.PacketProcessStateTemplete; 7 | import io.mycat.net2.Connection; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * 空闲状态 15 | * 16 | * @author ynfeng 17 | */ 18 | public class FrontendIdleState extends PacketProcessStateTemplete { 19 | public static final FrontendIdleState INSTANCE = new FrontendIdleState(); 20 | 21 | private FrontendIdleState() { 22 | } 23 | 24 | 25 | @Override 26 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 27 | return false; 28 | } 29 | 30 | @Override 31 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 32 | return internalProcess(connection, attachment, packetStartPos, packetLen, type, false); 33 | } 34 | 35 | @Override 36 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 37 | return internalProcess(connection, attachment, packetStartPos, packetLen, type, true); 38 | } 39 | 40 | private boolean internalProcess(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type, boolean isFullPacket) throws IOException { 41 | MySQLFrontConnection mySQLFrontConnection = (MySQLFrontConnection) connection; 42 | switch (type) { 43 | case MySQLPacket.COM_QUERY: 44 | //因为收到一个完整包,下一个状态不能迭代了,所以回退到上一个包,也就是本次的包,并立即中止迭代 45 | mySQLFrontConnection.getDataBuffer().packetIterator().fallback(); 46 | if (isFullPacket) { 47 | mySQLFrontConnection.getProtocolStateMachine().setNextState(FrontendComQueryState.INSTANCE); 48 | } 49 | interruptIterate(); 50 | return true; 51 | case MySQLPacket.COM_QUIT: 52 | mySQLFrontConnection.getProtocolStateMachine().setNextState(FrontendCloseState.INSTANCE); 53 | return true; 54 | default: 55 | break; 56 | } 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendComQueryColumnDefState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import java.io.IOException; 5 | 6 | import io.mycat.mysql.packet.MySQLPacket; 7 | import io.mycat.mysql.state.PacketProcessStateTemplete; 8 | import io.mycat.net2.Connection; 9 | 10 | import io.mycat.backend.MySQLBackendConnection; 11 | 12 | /** 13 | * 列定义传送状态 14 | * 15 | * @author ynfeng 16 | */ 17 | public class BackendComQueryColumnDefState extends PacketProcessStateTemplete { 18 | public static final BackendComQueryColumnDefState INSTANCE = new BackendComQueryColumnDefState(); 19 | 20 | 21 | private BackendComQueryColumnDefState() { 22 | } 23 | 24 | 25 | @Override 26 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 27 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 28 | if (mySQLBackendConnection.getDataBuffer().writableBytes() == 0) { 29 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 30 | } 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 36 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 37 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 38 | return false; 39 | } 40 | 41 | @Override 42 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 43 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 44 | if (type == MySQLPacket.EOF_PACKET) { 45 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendComQueryRowState.INSTANCE); 46 | interruptIterate(); 47 | return true; 48 | } 49 | if (mySQLBackendConnection.getDataBuffer().writableBytes() == 0) { 50 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 51 | interruptIterate(); 52 | } 53 | return false; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/buffer/PacketIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, MyCAT and/or its affiliates. All rights reserved. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *

16 | */ 17 | package io.mycat.buffer; 18 | 19 | /** 20 | * Created by ynfeng on 2017/7/27. 21 | */ 22 | public interface PacketIterator { 23 | 24 | /** 25 | * Returns {@code true} if there is a packet, {@code false} there is no more packet. 26 | */ 27 | boolean hasPacket(); 28 | 29 | /** 30 | * Get next packet. 31 | * If {@link #hasPacket()} return {@code false} this method return 0,{@code true} return a packet descriptor. 32 | * Packet descriptor is a 64-bit integer,the structure is as follows, 33 | *
34 |      * +-------------------------------------------+----------------------------+-----------------------------------+----------------+
35 |      * |                30 bits                    |           24 bits          |           8 bits                  |      2 bits    |
36 |      * | The packet start position in buffer       | The length of packet       |         command type              |   packet type  |
37 |      * +-------------------------------------------+----------------------------+-----------------------------------+----------------+
38 |      * 
39 | * A packet up to 16MB,24-bit is enough. 40 | * 2-bit packet type may be {@link PacketDescriptor.PacketType#LONG_HALF} or 41 | * {@link PacketDescriptor.PacketType#SHORT_HALF} or {@link PacketDescriptor.PacketType#FULL} 42 | * When packet type is {@link PacketDescriptor.PacketType#SHORT_HALF} the packet length and command type are meaningless. 43 | */ 44 | long nextPacket(); 45 | 46 | /** 47 | * Reset the internal state. 48 | */ 49 | void reset(); 50 | 51 | /** 52 | * fallback to previous packet. 53 | * if success return {@code true} 54 | */ 55 | boolean fallback(); 56 | } 57 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/packet/Reply323Packet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql.packet; 25 | 26 | import java.io.IOException; 27 | import java.io.OutputStream; 28 | 29 | import io.mycat.buffer.MycatByteBuffer; 30 | import io.mycat.util.StreamUtil; 31 | 32 | /** 33 | * @author mycat 34 | */ 35 | @Deprecated 36 | public class Reply323Packet extends MySQLPacket { 37 | 38 | public byte[] seed; 39 | 40 | public void write(OutputStream out) throws IOException { 41 | StreamUtil.writeUB3(out, calcPacketSize()); 42 | StreamUtil.write(out, packetId); 43 | if (seed == null) { 44 | StreamUtil.write(out, (byte) 0); 45 | } else { 46 | StreamUtil.writeWithNull(out, seed); 47 | } 48 | } 49 | 50 | public void write(MycatByteBuffer buffer, int pkgSize) { 51 | // BufferUtil.writeUB3(buffer, pkgSize); 52 | // buffer.put(packetId); 53 | // if (seed == null) { 54 | // buffer.put((byte) 0); 55 | // } else { 56 | // BufferUtil.writeWithNull(buffer, seed); 57 | // } 58 | } 59 | 60 | @Override 61 | public int calcPacketSize() { 62 | return seed == null ? 1 : seed.length + 1; 63 | } 64 | 65 | @Override 66 | protected String getPacketInfo() { 67 | return "MySQL Auth323 Packet"; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Mycat-Core/src/test/java/io/mycat/net2/TestReactorBufferPool.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.util.ArrayList; 5 | 6 | import org.junit.Test; 7 | 8 | import junit.framework.Assert; 9 | 10 | public class TestReactorBufferPool { 11 | 12 | @Test 13 | public void testLocateAndFree() { 14 | // String testS="test data only for "; 15 | // SharedBufferPool sharedPool = new SharedBufferPool(1024 * 1024 * 100, testS.length()+4); 16 | // ReactorBufferPool reactBufferPool = new ReactorBufferPool(sharedPool, Thread.currentThread(), 1000); 17 | // for (int i = 0; i < 10000; i++) { 18 | // ByteBufferArray bufArray = reactBufferPool.allocate(); 19 | // for (int j = 0; j < 100; j++) { 20 | // ByteBuffer buf = bufArray.addNewBuffer(); 21 | // buf.put(new String(testS + i).getBytes()); 22 | // } 23 | // bufArray.recycle(); 24 | // } 25 | // Assert.assertEquals(100, sharedPool.getNewCreated()); 26 | // Assert.assertEquals(100, reactBufferPool.getCurByteBuffersCount()); 27 | } 28 | 29 | @Test 30 | public void testMutilTreadLocateAndFree() { 31 | // String testS="test data only for "; 32 | // SharedBufferPool sharedPool = new SharedBufferPool(1024 * 1024 * 100, testS.length()+4); 33 | // // 十个reactor线程 34 | // ArrayList runthreads = new ArrayList(); 35 | // for (int k = 0; k < 10; k++) { 36 | // Thread thread = new Thread() { 37 | // public void run() { 38 | // ReactorBufferPool reactBufferPool = new ReactorBufferPool(sharedPool, Thread.currentThread(), 1000); 39 | // for (int i = 0; i < 10000; i++) { 40 | // ByteBufferArray bufArray = reactBufferPool.allocate(); 41 | // for (int j = 0; j < 100; j++) { 42 | // ByteBuffer buf = bufArray.addNewBuffer(); 43 | // buf.put(new String(testS + i).getBytes()); 44 | // } 45 | // bufArray.recycle(); 46 | // } 47 | // Assert.assertEquals(100, reactBufferPool.getCurByteBuffersCount()); 48 | // } 49 | // }; 50 | // thread.start(); 51 | // runthreads.add(thread); 52 | // } 53 | // boolean allFinished = false; 54 | // while (!allFinished) { 55 | // allFinished = true; 56 | // for (Thread thrd : runthreads) { 57 | // if (thrd.isAlive()) { 58 | // allFinished = false; 59 | // try { 60 | // Thread.sleep(1000); 61 | // } catch (InterruptedException e) { 62 | // // TODO Auto-generated catch block 63 | // e.printStackTrace(); 64 | // } 65 | // } 66 | // } 67 | // } 68 | // Assert.assertEquals(true, (sharedPool.getNewCreated()<=1000)); 69 | // 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/beans/ShardingRuleBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.beans; 25 | 26 | import java.util.Map; 27 | 28 | /** 29 | * sharding rule bean 30 | * 31 | * @author wuzhihui 32 | */ 33 | public class ShardingRuleBean { 34 | private String name; 35 | private String algorithm; 36 | private Map params; 37 | 38 | public ShardingRuleBean(String name, String algorithm, Map params) { 39 | super(); 40 | this.name = name; 41 | this.algorithm = algorithm; 42 | this.params = params; 43 | } 44 | 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | 53 | public String getAlgorithm() { 54 | return algorithm; 55 | } 56 | 57 | public void setAlgorithm(String algorithm) { 58 | this.algorithm = algorithm; 59 | } 60 | 61 | public Map getParams() { 62 | return params; 63 | } 64 | 65 | public void setParams(Map params) { 66 | this.params = params; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "ShardingRuleBean [name=" + name + ", algorithm=" + algorithm + ", params=" + params + "]"; 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/beans/MySQLRepBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.beans; 25 | 26 | import java.util.Collections; 27 | import java.util.List; 28 | 29 | /** 30 | * 表示一組MySQL Server复制集群,如主从或者多主 31 | * 32 | * @author wuzhihui 33 | */ 34 | public class MySQLRepBean { 35 | private final String name; 36 | private final int type; 37 | private int switchType; 38 | private List mysqls = Collections.emptyList(); 39 | 40 | public MySQLRepBean(String name, int type) { 41 | super(); 42 | this.name = name; 43 | this.type = type; 44 | } 45 | 46 | public int getSwitchType() { 47 | return switchType; 48 | } 49 | 50 | public void setSwitchType(int switchType) { 51 | this.switchType = switchType; 52 | } 53 | 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | public int getType() { 59 | return type; 60 | } 61 | 62 | public List getMysqls() { 63 | return mysqls; 64 | } 65 | 66 | public void setMysqls(List mysqls) { 67 | this.mysqls = mysqls; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "MySQLRepBean [name=" + name + ", type=" + type + ", switchType=" + switchType + ", mysqls=" + mysqls + "]"; 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendComQueryRowState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import java.io.IOException; 5 | 6 | import io.mycat.mysql.state.PacketProcessStateTemplete; 7 | import io.mycat.net2.Connection; 8 | 9 | import io.mycat.backend.MySQLBackendConnection; 10 | import io.mycat.mysql.packet.MySQLPacket; 11 | 12 | /** 13 | * 行数据传送状态 14 | * 15 | * @author ynfeng 16 | */ 17 | public class BackendComQueryRowState extends PacketProcessStateTemplete { 18 | public static final BackendComQueryRowState INSTANCE = new BackendComQueryRowState(); 19 | 20 | 21 | private BackendComQueryRowState() { 22 | } 23 | 24 | 25 | @Override 26 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 27 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 28 | if (mySQLBackendConnection.getDataBuffer().writableBytes() == 0) { 29 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 30 | } 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 36 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 37 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 38 | return false; 39 | } 40 | 41 | @Override 42 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 43 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 44 | if (type == MySQLPacket.EOF_PACKET) { 45 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendIdleState.INSTANCE); 46 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 47 | interruptIterate(); 48 | return false; 49 | } 50 | if (mySQLBackendConnection.getDataBuffer().writableBytes() == 0) { 51 | mySQLBackendConnection.startTransfer(mySQLBackendConnection.getMySQLFrontConnection(), mySQLBackendConnection.getDataBuffer()); 52 | interruptIterate(); 53 | } 54 | return false; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/impl/PartionSchemaSQLCommandHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine.impl; 25 | 26 | 27 | /** 28 | * 分片的Schema對應的 SQL Command Handler 29 | * @author wuzhihui 30 | * 31 | */ 32 | @Deprecated 33 | public class PartionSchemaSQLCommandHandler extends AbstractSchemaSQLCommandHandler{ 34 | public PartionSchemaSQLCommandHandler() { 35 | // TODO Auto-generated constructor stub 36 | } 37 | 38 | 39 | // @Override 40 | // public void executeSetSQL(MySQLFrontConnection frontCon, ConDataBuffer dataBuffer, byte packageType, 41 | // int pkgStartPos, int pkgLen, String sql) throws IOException { 42 | // frontCon.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Not implemented Yet,Welcome to be a Commiter ,Leader want you !!"); 43 | // } 44 | // 45 | // @Override 46 | // public void executeShowSQL(MySQLFrontConnection frontCon, ConDataBuffer dataBuffer, byte packageType, 47 | // int pkgStartPos, int pkgLen, String sql) throws IOException { 48 | // frontCon.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Not implemented Yet,Welcome to be a Commiter ,Leader want you !!"); 49 | // 50 | // } 51 | // 52 | // @Override 53 | // public void executeSelectSQL(MySQLFrontConnection frontCon, ConDataBuffer dataBuffer, byte packageType, 54 | // int pkgStartPos, int pkgLen, String sql) throws IOException { 55 | // frontCon.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Not implemented Yet,Welcome to be a Commiter ,Leader want you !!"); 56 | // 57 | // } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /bin/startup_nowrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #check JAVA_HOME & java 4 | noJavaHome=false 5 | if [ -z "$JAVA_HOME" ] ; then 6 | noJavaHome=true 7 | fi 8 | if [ ! -e "$JAVA_HOME/bin/java" ] ; then 9 | noJavaHome=true 10 | fi 11 | if $noJavaHome ; then 12 | echo 13 | echo "Error: JAVA_HOME environment variable is not set." 14 | echo 15 | exit 1 16 | fi 17 | #============================================================================== 18 | #set JAVA_OPTS 19 | JAVA_OPTS="-server -Xms2G -Xmx2G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=2G" 20 | #JAVA_OPTS="-server -Xms4G -Xmx4G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=6G" 21 | #performance Options 22 | #JAVA_OPTS="$JAVA_OPTS -Xss256k" 23 | #JAVA_OPTS="$JAVA_OPTS -XX:+AggressiveOpts" 24 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseBiasedLocking" 25 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseFastAccessorMethods" 26 | #JAVA_OPTS="$JAVA_OPTS -XX:+DisableExplicitGC" 27 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC" 28 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC" 29 | #JAVA_OPTS="$JAVA_OPTS -XX:+CMSParallelRemarkEnabled" 30 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSCompactAtFullCollection" 31 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly" 32 | #JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75" 33 | #JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75" 34 | #GC Log Options 35 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCApplicationStoppedTime" 36 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCTimeStamps" 37 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails" 38 | #debug Options 39 | #JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8065,server=y,suspend=n" 40 | #============================================================================== 41 | 42 | #set HOME 43 | CURR_DIR=`pwd` 44 | cd `dirname "$0"`/.. 45 | MYCAT_HOME=`pwd` 46 | cd $CURR_DIR 47 | if [ -z "$MYCAT_HOME" ] ; then 48 | echo 49 | echo "Error: MYCAT_HOME environment variable is not defined correctly." 50 | echo 51 | exit 1 52 | fi 53 | #============================================================================== 54 | 55 | #set CLASSPATH 56 | MYCAT_CLASSPATH="$MYCAT_HOME/conf:$MYCAT_HOME/lib/*:$MYCAT_HOME/classes" 57 | #============================================================================== 58 | 59 | #startup Server 60 | RUN_CMD="\"$JAVA_HOME/bin/java\"" 61 | RUN_CMD="$RUN_CMD -DMYCAT_HOME=\"$MYCAT_HOME\"" 62 | RUN_CMD="$RUN_CMD -classpath \"$MYCAT_CLASSPATH\"" 63 | RUN_CMD="$RUN_CMD $JAVA_OPTS" 64 | RUN_CMD="$RUN_CMD io.mycat.MycatCore $@" 65 | RUN_CMD="$RUN_CMD >> \"$MYCAT_HOME/logs/console.log\" 2>&1 &" 66 | echo $RUN_CMD 67 | eval $RUN_CMD 68 | #============================================================================== 69 | -------------------------------------------------------------------------------- /bin/startup_nowrap.sh.bak: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #check JAVA_HOME & java 4 | noJavaHome=false 5 | if [ -z "$JAVA_HOME" ] ; then 6 | noJavaHome=true 7 | fi 8 | if [ ! -e "$JAVA_HOME/bin/java" ] ; then 9 | noJavaHome=true 10 | fi 11 | if $noJavaHome ; then 12 | echo 13 | echo "Error: JAVA_HOME environment variable is not set." 14 | echo 15 | exit 1 16 | fi 17 | #============================================================================== 18 | #set JAVA_OPTS 19 | JAVA_OPTS="-server -Xms2G -Xmx2G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=2G" 20 | #JAVA_OPTS="-server -Xms4G -Xmx4G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=6G" 21 | #performance Options 22 | #JAVA_OPTS="$JAVA_OPTS -Xss256k" 23 | #JAVA_OPTS="$JAVA_OPTS -XX:+AggressiveOpts" 24 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseBiasedLocking" 25 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseFastAccessorMethods" 26 | #JAVA_OPTS="$JAVA_OPTS -XX:+DisableExplicitGC" 27 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC" 28 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC" 29 | #JAVA_OPTS="$JAVA_OPTS -XX:+CMSParallelRemarkEnabled" 30 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSCompactAtFullCollection" 31 | #JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly" 32 | #JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75" 33 | #JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75" 34 | #GC Log Options 35 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCApplicationStoppedTime" 36 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCTimeStamps" 37 | #JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails" 38 | #debug Options 39 | #JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8065,server=y,suspend=n" 40 | #============================================================================== 41 | 42 | #set HOME 43 | CURR_DIR=`pwd` 44 | cd `dirname "$0"`/.. 45 | MYCAT_HOME=`pwd` 46 | cd $CURR_DIR 47 | if [ -z "$MYCAT_HOME" ] ; then 48 | echo 49 | echo "Error: MYCAT_HOME environment variable is not defined correctly." 50 | echo 51 | exit 1 52 | fi 53 | #============================================================================== 54 | 55 | #set CLASSPATH 56 | MYCAT_CLASSPATH="$MYCAT_HOME/conf:$MYCAT_HOME/lib/*:$MYCAT_HOME/classes" 57 | #============================================================================== 58 | 59 | #startup Server 60 | RUN_CMD="\"$JAVA_HOME/bin/java\"" 61 | RUN_CMD="$RUN_CMD -DMYCAT_HOME=\"$MYCAT_HOME\"" 62 | RUN_CMD="$RUN_CMD -classpath \"$MYCAT_CLASSPATH\"" 63 | RUN_CMD="$RUN_CMD $JAVA_OPTS" 64 | RUN_CMD="$RUN_CMD io.mycat.engine.MycatCore $@" 65 | RUN_CMD="$RUN_CMD >> \"$MYCAT_HOME/logs/console.log\" 2>&1 &" 66 | echo $RUN_CMD 67 | eval $RUN_CMD 68 | #============================================================================== 69 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/UserSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.engine; 25 | 26 | import java.util.ArrayList; 27 | 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | import io.mycat.backend.MySQLBackendConnection; 32 | 33 | /** 34 | * user session ,mean's a mysql client session or pg client session 35 | * @author wuzhihui 36 | * 37 | */ 38 | public class UserSession { 39 | private static final Logger LOGGER = LoggerFactory.getLogger(UserSession.class); 40 | private SQLCommandHandler curCmdHandler; 41 | private ArrayList backConLst=new ArrayList(); 42 | 43 | public void changeCmdHandler(SQLCommandHandler newCmdHandler) 44 | { 45 | 46 | this.curCmdHandler=newCmdHandler; 47 | } 48 | 49 | public SQLCommandHandler getCurCmdHandler() { 50 | return curCmdHandler; 51 | } 52 | 53 | 54 | 55 | 56 | public void removeBackCon(MySQLBackendConnection con) 57 | { 58 | if(this.backConLst.remove(con)) 59 | { 60 | LOGGER.warn("remove back con ,but not found ! "+this); 61 | } 62 | 63 | 64 | } 65 | 66 | public void addBackCon(MySQLBackendConnection con) 67 | { 68 | if(this.backConLst.contains(con)) 69 | { 70 | throw new RuntimeException("add a duplicate back connection to session,schema: "+con.getSchema()); 71 | }else 72 | { 73 | backConLst.add(con); 74 | } 75 | 76 | 77 | } 78 | 79 | public ArrayList getBackendCons() { 80 | return backConLst; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/backend/BackendHandshakeState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.backend; 2 | 3 | 4 | import io.mycat.mysql.state.PacketProcessStateTemplete; 5 | import io.mycat.net2.Connection; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import io.mycat.backend.MySQLBackendConnection; 10 | import io.mycat.mysql.packet.HandshakePacket; 11 | import io.mycat.util.CharsetUtil; 12 | 13 | import java.io.IOException; 14 | 15 | /** 16 | * 握手状态 17 | * 18 | * @author ynfeng 19 | */ 20 | public class BackendHandshakeState extends PacketProcessStateTemplete { 21 | private static final Logger LOGGER = LoggerFactory.getLogger(BackendHandshakeState.class); 22 | public static final BackendHandshakeState INSTANCE = new BackendHandshakeState(); 23 | 24 | private BackendHandshakeState() { 25 | } 26 | 27 | @Override 28 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 29 | return false; 30 | } 31 | 32 | @Override 33 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 34 | return false; 35 | } 36 | 37 | @Override 38 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 39 | MySQLBackendConnection mySQLBackendConnection = (MySQLBackendConnection) connection; 40 | try { 41 | processHandShakePacket(mySQLBackendConnection); 42 | mySQLBackendConnection.authenticate(); 43 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendAuthenticatingState.INSTANCE); 44 | interruptIterate(); 45 | return false; 46 | } catch (Throwable e) { 47 | LOGGER.warn("Backend InitialState error", e); 48 | mySQLBackendConnection.getProtocolStateMachine().setNextState(BackendCloseState.INSTANCE); 49 | return true; 50 | } 51 | } 52 | 53 | private void processHandShakePacket(MySQLBackendConnection conn) { 54 | HandshakePacket packet = new HandshakePacket(); 55 | packet.read(conn.getDataBuffer()); 56 | conn.getDataBuffer().clear(); 57 | conn.setHandshake(packet); 58 | // 设置字符集编码 59 | int charsetIndex = (packet.serverCharsetIndex & 0xff); 60 | String charset = CharsetUtil.getCharset(charsetIndex); 61 | if (charset != null) { 62 | conn.setCharset(charsetIndex, charset); 63 | } else { 64 | String errmsg = "Unknown charsetIndex:" + charsetIndex + " of " + conn; 65 | LOGGER.warn(errmsg); 66 | return; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/callback/DummyCallBack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.backend.callback; 25 | 26 | import java.io.IOException; 27 | 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | import io.mycat.backend.BackConnectionCallback; 32 | import io.mycat.backend.MySQLBackendConnection; 33 | import io.mycat.buffer.MycatByteBuffer; 34 | import io.mycat.net2.ConnectionException; 35 | /** 36 | * callback witch do nothing 37 | * @author wuzhihui 38 | * 39 | */ 40 | public class DummyCallBack implements BackConnectionCallback{ 41 | private static final Logger LOGGER = LoggerFactory.getLogger(DummyCallBack.class); 42 | 43 | 44 | @Override 45 | public void handleResponse(MySQLBackendConnection source, MycatByteBuffer dataBuffer, byte packageType, int pkgStartPos, 46 | int pkgLen) throws IOException { 47 | LOGGER.warn("rereived not processed response "+source); 48 | 49 | } 50 | 51 | 52 | @Override 53 | public void connectionError(ConnectionException e, MySQLBackendConnection conn) { 54 | LOGGER.warn("connection error "+conn,e); 55 | 56 | } 57 | @Override 58 | public void connectionAcquired(MySQLBackendConnection conn) { 59 | LOGGER.info("connection acquired "+conn); 60 | 61 | 62 | } 63 | @Override 64 | public void connectionClose(MySQLBackendConnection conn, String reason) { 65 | LOGGER.info("connection closed ,reason:"+reason+ " "+conn); 66 | 67 | 68 | } 69 | @Override 70 | public void handlerError(Exception e, MySQLBackendConnection conn) { 71 | LOGGER.warn("hanlder error "+conn,e); 72 | 73 | 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/ConQueue.java: -------------------------------------------------------------------------------- 1 | package io.mycat.backend; 2 | 3 | import java.util.ArrayList; 4 | import java.util.concurrent.ConcurrentLinkedQueue; 5 | 6 | public class ConQueue { 7 | private final ConcurrentLinkedQueue autoCommitCons = new ConcurrentLinkedQueue(); 8 | private final ConcurrentLinkedQueue manCommitCons = new ConcurrentLinkedQueue(); 9 | private long executeCount; 10 | 11 | public MySQLBackendConnection takeIdleCon(boolean autoCommit) { 12 | ConcurrentLinkedQueue f1 = autoCommitCons; 13 | ConcurrentLinkedQueue f2 = manCommitCons; 14 | 15 | if (!autoCommit) { 16 | f1 = manCommitCons; 17 | f2 = autoCommitCons; 18 | 19 | } 20 | MySQLBackendConnection con = f1.poll(); 21 | if (con == null || con.isClosed()) { 22 | con = f2.poll(); 23 | } 24 | if (con == null || con.isClosed()) { 25 | return null; 26 | } else { 27 | return con; 28 | } 29 | 30 | } 31 | 32 | public long getExecuteCount() { 33 | return executeCount; 34 | } 35 | 36 | public void incExecuteCount() { 37 | this.executeCount++; 38 | } 39 | 40 | public void removeCon(MySQLBackendConnection con) { 41 | if (!autoCommitCons.remove(con)) { 42 | manCommitCons.remove(con); 43 | } 44 | } 45 | 46 | public boolean isSameCon(MySQLBackendConnection con) { 47 | if (autoCommitCons.contains(con)) { 48 | return true; 49 | } else if (manCommitCons.contains(con)) { 50 | return true; 51 | } 52 | return false; 53 | } 54 | 55 | public ConcurrentLinkedQueue getAutoCommitCons() { 56 | return autoCommitCons; 57 | } 58 | 59 | public ConcurrentLinkedQueue getManCommitCons() { 60 | return manCommitCons; 61 | } 62 | 63 | public ArrayList getIdleConsToClose(int count) { 64 | ArrayList readyCloseCons = new ArrayList(count); 65 | while (!manCommitCons.isEmpty() && readyCloseCons.size() < count) { 66 | MySQLBackendConnection theCon = manCommitCons.poll(); 67 | if (theCon != null) { 68 | readyCloseCons.add(theCon); 69 | } 70 | } 71 | while (!autoCommitCons.isEmpty() && readyCloseCons.size() < count) { 72 | MySQLBackendConnection theCon = autoCommitCons.poll(); 73 | if (theCon != null) { 74 | readyCloseCons.add(theCon); 75 | } 76 | 77 | } 78 | return readyCloseCons; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendComQueryState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | 4 | import io.mycat.backend.MySQLBackendConnection; 5 | import io.mycat.front.MySQLFrontConnection; 6 | import io.mycat.mysql.state.PacketProcessStateTemplete; 7 | import io.mycat.mysql.state.backend.BackendComQueryResponseState; 8 | import io.mycat.net2.Connection; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * 查询状态 14 | * 15 | * @author ynfeng 16 | */ 17 | public class FrontendComQueryState extends PacketProcessStateTemplete { 18 | public static final FrontendComQueryState INSTANCE = new FrontendComQueryState(); 19 | 20 | private FrontendComQueryState() { 21 | } 22 | 23 | @Override 24 | public boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException { 25 | return false; 26 | } 27 | 28 | @Override 29 | public boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 30 | return internalProcess(connection, false); 31 | } 32 | 33 | @Override 34 | public boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException { 35 | return internalProcess(connection, true); 36 | } 37 | 38 | private boolean internalProcess(Connection connection, boolean isFullPacket) throws IOException { 39 | MySQLFrontConnection frontCon = (MySQLFrontConnection) connection; 40 | MySQLBackendConnection backendConnection = frontCon.getBackendConnection(); 41 | if (backendConnection == null) { //往往新建立连接时,后端连接会是空 42 | backendConnection = getBackendFrontConnection(frontCon); 43 | MySQLBackendConnection finalBackendConnection = backendConnection; 44 | frontCon.addTodoTask(() -> { 45 | frontCon.startTransfer(finalBackendConnection, frontCon.getDataBuffer()); 46 | if (isFullPacket) { 47 | finalBackendConnection.getDataBuffer().clear(); 48 | finalBackendConnection.getProtocolStateMachine().setNextState(BackendComQueryResponseState.INSTANCE); 49 | frontCon.getProtocolStateMachine().setNextState(FrontendIdleState.INSTANCE); 50 | } 51 | }); 52 | } else { 53 | backendConnection.getDataBuffer().clear(); 54 | frontCon.startTransfer(backendConnection, frontCon.getDataBuffer()); 55 | if (isFullPacket) { 56 | backendConnection.getProtocolStateMachine().setNextState(BackendComQueryResponseState.INSTANCE); 57 | frontCon.getProtocolStateMachine().setNextState(FrontendIdleState.INSTANCE); 58 | } 59 | } 60 | return false; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/beans/TableDefBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.beans; 25 | 26 | /** 27 | * Mycat Table def Bean 28 | * 29 | * @author wuzhihui 30 | */ 31 | public class TableDefBean { 32 | private String name; 33 | private int type; 34 | private String shardingKey; 35 | private String shardingRule; 36 | 37 | public TableDefBean(String name, int type, String shardingKey, String shardingRule) { 38 | super(); 39 | this.name = name; 40 | this.type = type; 41 | this.shardingKey = shardingKey; 42 | this.shardingRule = shardingRule; 43 | } 44 | 45 | public TableDefBean() { 46 | 47 | } 48 | 49 | public String getName() { 50 | return name; 51 | } 52 | 53 | public void setName(String name) { 54 | this.name = name; 55 | } 56 | 57 | public String getShardingKey() { 58 | return shardingKey; 59 | } 60 | 61 | public void setShardingKey(String shardingKey) { 62 | this.shardingKey = shardingKey; 63 | } 64 | 65 | public String getShardingRule() { 66 | return shardingRule; 67 | } 68 | 69 | public void setShardingRule(String shardingRule) { 70 | this.shardingRule = shardingRule; 71 | } 72 | 73 | public int getType() { 74 | return type; 75 | } 76 | 77 | public void setType(int type) { 78 | this.type = type; 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | return "TableDefBean [name=" + name + ", type=" + type + ", shardingKey=" + shardingKey + ", shardingRule=" 84 | + shardingRule + "]"; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/util/RandomUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.util; 25 | 26 | /** 27 | * @author mycat 28 | */ 29 | public class RandomUtil { 30 | private static final byte[] bytes = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'q', 'w', 'e', 'r', 't', 31 | 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 32 | 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 33 | 'C', 'V', 'B', 'N', 'M' }; 34 | private static final long multiplier = 0x5DEECE66DL; 35 | private static final long addend = 0xBL; 36 | private static final long mask = (1L << 48) - 1; 37 | private static final long integerMask = (1L << 33) - 1; 38 | private static final long seedUniquifier = 8682522807148012L; 39 | 40 | private static long seed; 41 | static { 42 | long s = seedUniquifier + System.nanoTime(); 43 | s = (s ^ multiplier) & mask; 44 | seed = s; 45 | } 46 | 47 | public static final byte[] randomBytes(int size) { 48 | byte[] bb = bytes; 49 | byte[] ab = new byte[size]; 50 | for (int i = 0; i < size; i++) { 51 | ab[i] = randomByte(bb); 52 | } 53 | return ab; 54 | } 55 | 56 | private static byte randomByte(byte[] b) { 57 | int ran = (int) ((next() & integerMask) >>> 16); 58 | return b[ran % b.length]; 59 | } 60 | 61 | private static long next() { 62 | long oldSeed = seed; 63 | long nextSeed = 0L; 64 | do { 65 | nextSeed = (oldSeed * multiplier + addend) & mask; 66 | } while (oldSeed == nextSeed); 67 | seed = nextSeed; 68 | return nextSeed; 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/MySQLBackendConnectionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.backend; 25 | 26 | import java.io.IOException; 27 | import java.nio.channels.SocketChannel; 28 | 29 | import io.mycat.backend.callback.DummyCallBack; 30 | import io.mycat.beans.MySQLBean; 31 | import io.mycat.front.MySQLFrontConnection; 32 | import io.mycat.net2.NetSystem; 33 | import io.mycat.net2.states.ReadState; 34 | 35 | /** 36 | * bakcend mysql connection factory 37 | * 38 | * @author wuzhihui 39 | */ 40 | public class MySQLBackendConnectionFactory { 41 | 42 | private final DummyCallBack dummyCallBack = new DummyCallBack(); 43 | 44 | public MySQLBackendConnection make(MySQLDataSource pool, String reactor, String schema, MySQLFrontConnection mySQLFrontConnection, BackConnectionCallback userCallback) throws IOException { 45 | BackConnectionCallback callback = userCallback == null ? dummyCallBack : userCallback; 46 | MySQLBean dsc = pool.getConfig(); 47 | SocketChannel channel = SocketChannel.open(); 48 | channel.configureBlocking(false); 49 | 50 | MySQLBackendConnection c = new MySQLBackendConnection(pool, channel); 51 | NetSystem.getInstance().setSocketParams(c, false); 52 | // 设置NIOHandlers 53 | c.setHost(dsc.getIp()); 54 | c.setPort(dsc.getPort()); 55 | c.setUser(dsc.getUser()); 56 | c.setPassword(dsc.getPassword()); 57 | c.setSchema(schema); 58 | c.setPool(pool); 59 | c.setNIOReactor(reactor); 60 | c.setMySQLFrontConnection(mySQLFrontConnection); 61 | c.setUserCallback(callback); 62 | c.setIdleTimeout(NetSystem.getInstance().getNetConfig().getConIdleTimeout() * 60 * 1000L); 63 | c.getProtocolStateMachine().driveState(); 64 | return c; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/beans/SchemaBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.beans; 25 | 26 | import java.util.List; 27 | 28 | /** 29 | * Mycat Logic Schema 30 | * 31 | * @author wuzhihui 32 | */ 33 | 34 | public class SchemaBean { 35 | 36 | private String name; 37 | private DNBean defaultDN; 38 | /** 39 | * 是否非分片的Schema,意味著沒有任何分片表的Schema 40 | */ 41 | private final boolean normalSchema; 42 | private List tableDefBeans; 43 | 44 | public SchemaBean(String name, DNBean defaultDN, boolean normalSchema, List tableDefBeans) { 45 | super(); 46 | this.name = name; 47 | this.defaultDN = defaultDN; 48 | this.normalSchema = normalSchema; 49 | this.tableDefBeans = tableDefBeans; 50 | } 51 | 52 | 53 | public boolean isNormalSchema() { 54 | return normalSchema; 55 | } 56 | 57 | 58 | public String getName() { 59 | return name; 60 | } 61 | 62 | public void setName(String name) { 63 | this.name = name; 64 | } 65 | 66 | public DNBean getDefaultDN() { 67 | return defaultDN; 68 | } 69 | 70 | public void setDefaultDN(DNBean defaultDN) { 71 | this.defaultDN = defaultDN; 72 | } 73 | 74 | 75 | public void setTableDefBeans(List tableDefBeans) { 76 | this.tableDefBeans = tableDefBeans; 77 | } 78 | 79 | public List getTableDefBeans() { 80 | return tableDefBeans; 81 | } 82 | 83 | 84 | @Override 85 | public String toString() { 86 | return "SchemaBean [name=" + name + ", defaultDN=" + defaultDN + ", normalSchema=" + normalSchema 87 | + ", tableDefBeans=" + tableDefBeans + "]"; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/impl/FrontendComQueryCommandHandler.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.impl; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.backend.MySQLBackendConnection; 6 | import io.mycat.buffer.MycatByteBuffer; 7 | import io.mycat.engine.dataChannel.TransferMode; 8 | import io.mycat.front.MySQLFrontConnection; 9 | import io.mycat.mysql.state.backend.BackendComQueryResponseState; 10 | import io.mycat.net2.states.NoReadAndWriteState; 11 | 12 | /** 13 | * 前端查询命令响应 14 | *

15 | * 此类未根据sql类型做特殊处理,后面可根据实际情况,比如主从,获取对应的后端连接 16 | * 17 | * @author ynfeng 18 | */ 19 | public class FrontendComQueryCommandHandler extends AbstractComQueryCommandHandler { 20 | 21 | @Override 22 | public void processCmd(MySQLFrontConnection frontCon, MycatByteBuffer dataBuffer, byte packageType, int pkgStartPos, int pkgLen) throws IOException { 23 | frontCon.getProtocolStateMachine().setNextState(BackendComQueryResponseState.INSTANCE); 24 | MySQLBackendConnection backendConnection = frontCon.getBackendConnection(); 25 | if (backendConnection == null) { 26 | backendConnection = getBackendFrontConnection(frontCon); 27 | MySQLBackendConnection finalBackendConnection = backendConnection; 28 | frontCon.addTodoTask(() -> { 29 | 30 | //开启透传模式 31 | finalBackendConnection.setDirectTransferMode(TransferMode.COMPLETE_PACKET); //整包透传 32 | finalBackendConnection.setCurrentPacketLength(frontCon.getCurrentPacketLength()); 33 | finalBackendConnection.setCurrentPacketStartPos(frontCon.getCurrentPacketStartPos()); 34 | finalBackendConnection.setCurrentPacketType(frontCon.getCurrentPacketType()); 35 | 36 | finalBackendConnection.setShareBuffer(dataBuffer);// 37 | //TODO ??? 38 | // finalBackendConnection.getShareBuffer().setLastWritePos(0); 39 | // finalBackendConnection.getShareBuffer().readIndex(frontCon.getCurrentPacketLength()); 40 | finalBackendConnection.getProtocolStateMachine().driveState(); 41 | }); 42 | } else { 43 | 44 | //开启透传模式 45 | backendConnection.setDirectTransferMode(TransferMode.COMPLETE_PACKET); //整包透传 46 | backendConnection.setCurrentPacketLength(frontCon.getCurrentPacketLength()); 47 | backendConnection.setCurrentPacketStartPos(frontCon.getCurrentPacketStartPos()); 48 | backendConnection.setCurrentPacketType(frontCon.getCurrentPacketType()); 49 | 50 | backendConnection.setShareBuffer(dataBuffer); 51 | //TODO ??? 52 | // backendConnection.getShareBuffer().setLastWritePos(0); 53 | // backendConnection.getShareBuffer().readIndex(frontCon.getCurrentPacketLength()); 54 | backendConnection.getProtocolStateMachine().driveState(); 55 | } 56 | frontCon.getNetworkStateMachine().setNextState(NoReadAndWriteState.INSTANCE); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/packet/EOFPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql.packet; 25 | 26 | import io.mycat.buffer.MycatByteBuffer; 27 | 28 | /** 29 | * From Server To Client, at the end of a series of Field Packets, and at the 30 | * end of a series of Data Packets.With prepared statements, EOF Packet can also 31 | * end parameter information, which we'll describe later. 32 | * 33 | *

34 |  * Bytes                 Name
35 |  * -----                 ----
36 |  * 1                     field_count, always = 0xfe
37 |  * 2                     warning_count
38 |  * 2                     Status Flags
39 |  * 
40 |  * @see http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#EOF_Packet
41 |  * 
42 | * 43 | * @author mycat 44 | */ 45 | public class EOFPacket extends MySQLPacket { 46 | 47 | public static final byte FIELD_COUNT = (byte) 0xfe; 48 | public byte fieldCount = FIELD_COUNT; 49 | public int warningCount; 50 | public int status = 2; 51 | 52 | // public void read(ConDataBuffer byteBuffer) { 53 | // MySQLMessage mm = new MySQLMessage(byteBuffer); 54 | // packetLength = mm.readUB3(); 55 | // packetId = mm.read(); 56 | // fieldCount = mm.read(); 57 | // warningCount = mm.readUB2(); 58 | // status = mm.readUB2(); 59 | // } 60 | 61 | @Override 62 | public void write(MycatByteBuffer buffer, int pkgSize) { 63 | buffer.writeFixInt(3,pkgSize); 64 | buffer.writeByte(packetId); 65 | buffer.writeLenencInt(fieldCount); 66 | buffer.writeFixInt(2, warningCount); 67 | buffer.writeFixInt(2, status); 68 | } 69 | 70 | @Override 71 | public int calcPacketSize() { 72 | return 5;// 1+2+2; 73 | } 74 | 75 | @Override 76 | protected String getPacketInfo() { 77 | return "MySQL EOF Packet"; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/sqlcache/HintSQLParser.java: -------------------------------------------------------------------------------- 1 | package io.mycat.sqlcache; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.StringTokenizer; 9 | 10 | /** 11 | * 主要用来解析 Hint SQL 12 | * 兼容mycat 1.6版本 新的注解方式 13 | * 14 | * @author zagnix 15 | * @create 2017-01-16 17:23 16 | */ 17 | 18 | public class HintSQLParser { 19 | private static final Logger LOGGER = LoggerFactory.getLogger(HintSQLParser.class); 20 | 21 | //注解格式:/*!mycat:type=value */ sql. sql为真实的执行的sql语句 22 | private final static String MYCAT_HINT_START = "/*!mycat:"; 23 | private final static String HINT_PRO_SPLIT = " "; 24 | private final static String HINT_KV_SPLIT = "="; 25 | 26 | 27 | public static HintSQLInfo parserHintSQL(String sql){ 28 | if (sql == null) 29 | return null; 30 | 31 | HintSQLInfo hintSQLInfo = new HintSQLInfo(sql); 32 | Map hintKv = new HashMap(); 33 | int endIndex = sql.indexOf("*/"); 34 | 35 | if (endIndex !=-1 ){ 36 | String hintPart = sql.substring(0,endIndex); 37 | hintSQLInfo.setExecSQL(sql.substring(endIndex+2)); 38 | String kvsPart=hintPart.replace(MYCAT_HINT_START,"").replace("*/",""); 39 | StringTokenizer token = new StringTokenizer(kvsPart,HINT_PRO_SPLIT); 40 | 41 | /**hint功能*/ 42 | if (token.hasMoreElements()) { 43 | StringTokenizer function = new StringTokenizer(token.nextToken(), HINT_KV_SPLIT); 44 | if (function.countTokens()==2){ 45 | String kName = function.nextToken(); 46 | String vValue = function.nextToken(); 47 | if (kName.equalsIgnoreCase("cacheable") && vValue.equals("true")){ 48 | hintSQLInfo.setFunctionName(kName); 49 | hintSQLInfo.setCache(true); 50 | } 51 | 52 | }else { 53 | LOGGER.error(sql + "注解中的KV属性不对"); 54 | return null; 55 | } 56 | 57 | /**KV**/ 58 | while (token.hasMoreElements()) { 59 | StringTokenizer t = new StringTokenizer(token.nextToken(), HINT_KV_SPLIT); 60 | 61 | if (t.countTokens() == 2) { 62 | /**TODO 限制hintSQL中kv中k具体命名必须在{cacheable, cache-time,auto-refresh, access-count}*/ 63 | hintKv.put(t.nextToken(),t.nextToken()); 64 | }else { /**KV*/ 65 | LOGGER.error(sql + "注解中的KV属性不对"); 66 | return null; 67 | } 68 | } 69 | hintSQLInfo.setParamsKv(hintKv); 70 | }else { /**没有function name*/ 71 | LOGGER.error(sql + "注解中的功能没有名字"); 72 | return null; 73 | } 74 | }else { 75 | return null; 76 | } 77 | return hintSQLInfo; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/buffer/PacketDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, MyCAT and/or its affiliates. All rights reserved. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *

16 | */ 17 | package io.mycat.buffer; 18 | 19 | /** 20 | * Created by ynfeng on 2017/7/28. 21 | */ 22 | public class PacketDescriptor { 23 | 24 | public static long setPacketType(long packetDescriptor, PacketType packetType) { 25 | return (packetDescriptor & ~0x03L) | (packetType.getValue() & 0x03); 26 | } 27 | 28 | public static long setCommandType(long packetDescriptor, long commandType) { 29 | return (packetDescriptor & ~(0xFFL << 2)) | ((commandType & 0xFF) << 2); 30 | } 31 | 32 | public static long setPacketLen(long packetDescriptor, long packetLen) { 33 | return (packetDescriptor & ~(0xFFFFFFL << 10)) | ((packetLen & 0xFFFFFF) << 10); 34 | } 35 | 36 | public static long setPacketStartPos(long packetDescriptor, long packetStartPos) { 37 | return (packetDescriptor & ~(0x2FFFFFFFL << 34)) | ((packetStartPos & 0x2FFFFFFF) << 34); 38 | } 39 | 40 | public static PacketType getPacketType(long packetDescriptor) { 41 | int type = (int) (packetDescriptor & 0x03); 42 | PacketType packetType = null; 43 | switch (type) { 44 | case 0: 45 | packetType = PacketType.FULL; 46 | break; 47 | case 1: 48 | packetType = PacketType.LONG_HALF; 49 | break; 50 | case 2: 51 | packetType = packetType.SHORT_HALF; 52 | break; 53 | default: 54 | throw new IllegalArgumentException("Wrong packetDescriptor " + packetDescriptor); 55 | } 56 | return packetType; 57 | } 58 | 59 | public static byte getCommandType(long packetDescriptor) { 60 | return (byte) ((packetDescriptor >>> 2) & 0xFF); 61 | } 62 | 63 | public static int getPacketStartPos(long packetDescriptor) { 64 | return (int) ((packetDescriptor >>> 34) & 0x2FFFFFFF); 65 | } 66 | 67 | public static int getPacketLen(long packetDescriptor) { 68 | return (int) ((packetDescriptor >>> 10) & 0xFFFFFF); 69 | } 70 | 71 | public enum PacketType { 72 | FULL(0), LONG_HALF(1), SHORT_HALF(2); 73 | 74 | PacketType(int value) { 75 | this.value = value; 76 | } 77 | 78 | private int value; 79 | 80 | public int getValue() { 81 | return value; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/backend/ConnectionMeta.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.backend; 25 | 26 | /** 27 | * connection metadata info 28 | * 29 | * @author wuzhih 30 | * 31 | */ 32 | public class ConnectionMeta { 33 | private final String schema; 34 | private final String charset; 35 | private final int txIsolation; 36 | private final boolean autocommit; 37 | 38 | public ConnectionMeta(String schema, String charset, int txIsolation, boolean autocommit) { 39 | super(); 40 | this.schema = schema; 41 | this.charset = charset; 42 | this.txIsolation = txIsolation; 43 | this.autocommit = autocommit; 44 | } 45 | 46 | public String getSchema() { 47 | return schema; 48 | } 49 | 50 | public String getCharset() { 51 | return charset; 52 | } 53 | 54 | public int getTxIsolation() { 55 | return txIsolation; 56 | } 57 | 58 | public boolean isAutocommit() { 59 | return autocommit; 60 | } 61 | 62 | public boolean isSameSchema(MySQLBackendConnection theCon) { 63 | return theCon.getSchema().equals(schema); 64 | } 65 | 66 | /** 67 | * get metadata similarity 68 | * 69 | * @param theCon 70 | * @return 71 | */ 72 | public int getMetaSimilarity(MySQLBackendConnection theCon) { 73 | int result = 0; 74 | if (schema == null || schema.equals(theCon.getSchema())) { 75 | result++; 76 | } 77 | // if (charset == null || charset.equals(theCon.getCharset())) { 78 | // result++; 79 | // } 80 | // if (txIsolation == -1 || txIsolation == theCon.getTxIsolation()) { 81 | // result++; 82 | // } 83 | // if (autocommit == theCon.isAutocommit()) { 84 | // result++; 85 | // } 86 | return result; 87 | } 88 | 89 | @Override 90 | public String toString() { 91 | return "ConnectionMeta [schema=" + schema + ", charset=" + charset + ", txIsolation=" + txIsolation 92 | + ", autocommit=" + autocommit + "]"; 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/engine/dataChannel/impl/PassThrouthtoBackendDataHandler.java: -------------------------------------------------------------------------------- 1 | package io.mycat.engine.dataChannel.impl; 2 | 3 | import java.io.IOException; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import io.mycat.backend.MySQLBackendConnection; 9 | import io.mycat.buffer.MycatByteBuffer; 10 | import io.mycat.engine.dataChannel.DataHandler; 11 | import io.mycat.engine.dataChannel.TransferMode; 12 | import io.mycat.front.MySQLFrontConnection; 13 | import io.mycat.mysql.MySQLConnection; 14 | import io.mycat.net2.states.NoReadAndWriteState; 15 | import io.mycat.net2.states.ReadWaitingState; 16 | import io.mycat.net2.states.WriteWaitingState; 17 | 18 | /** 19 | * 透传到前端数据处理器 20 | * 21 | * @author yanjunli 22 | */ 23 | public class PassThrouthtoBackendDataHandler implements DataHandler { 24 | 25 | private static final Logger LOGGER = LoggerFactory.getLogger(PassThrouthtoBackendDataHandler.class); 26 | 27 | public static final PassThrouthtoBackendDataHandler INSTANCE = new PassThrouthtoBackendDataHandler(); 28 | 29 | private PassThrouthtoBackendDataHandler() { 30 | } 31 | 32 | /* 33 | * 透传时,进行前后端状态同步 34 | */ 35 | @Override 36 | public void transfer(MySQLConnection in, boolean isTransferLastPacket, boolean transferFinish, boolean isAllFinish) throws IOException { 37 | 38 | LOGGER.debug("current in PassThrouthtoBackendDataHandler "); 39 | 40 | MySQLFrontConnection frontCoxn = (MySQLFrontConnection) in; 41 | 42 | MycatByteBuffer frontDataBuffer = frontCoxn.getDataBuffer(); 43 | 44 | 45 | MySQLBackendConnection backendCoxn = frontCoxn.getBackendConnection(); 46 | //后端状态有可能是上一个包的状态, 这种情况出现在 最后一个包无法解析出报文类型的情况,最后一个包的前几个字节不传输. 47 | backendCoxn.getProtocolStateMachine().setNextState(frontCoxn.getProtocolStateMachine().getNextState()); 48 | backendCoxn.getNetworkStateMachine().setNextState(WriteWaitingState.INSTANCE); 49 | backendCoxn.getNetworkStateMachine().driveState(); 50 | 51 | MycatByteBuffer backdatabuffer = backendCoxn.getDataBuffer(); 52 | backendCoxn.setDataBuffer(frontDataBuffer); 53 | 54 | backendCoxn.setWriteCompleteListener(() -> { 55 | backdatabuffer.clear(); 56 | backendCoxn.getDataBuffer().compact(); 57 | backendCoxn.setDataBuffer(backdatabuffer); 58 | backendCoxn.clearCurrentPacket(); 59 | 60 | if (TransferMode.SHORT_HALF_PACKET.equals(frontCoxn.getDirectTransferMode())) { 61 | frontCoxn.clearCurrentPacket(); 62 | } 63 | if (transferFinish) { //透传全部完成 64 | backendCoxn.getNetworkStateMachine().setNextState(ReadWaitingState.INSTANCE); 65 | } else { 66 | backendCoxn.getNetworkStateMachine().setNextState(NoReadAndWriteState.INSTANCE); 67 | frontCoxn.getNetworkStateMachine().setNextState(ReadWaitingState.INSTANCE); 68 | frontCoxn.getNetworkStateMachine().driveState(); 69 | } 70 | 71 | if (isAllFinish) { //透传全部完成 72 | frontCoxn.setPassthrough(false); 73 | backendCoxn.setPassthrough(false); 74 | } 75 | }); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/util/CharTypes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.util; 25 | /** 26 | * @author mycat 27 | * @author mycat 28 | */ 29 | public class CharTypes { 30 | private final static boolean[] hexFlags = new boolean[256]; 31 | static { 32 | for (char c = 0; c < hexFlags.length; ++c) { 33 | if (c >= 'A' && c <= 'F') { 34 | hexFlags[c] = true; 35 | } else if (c >= 'a' && c <= 'f') { 36 | hexFlags[c] = true; 37 | } else if (c >= '0' && c <= '9') { 38 | hexFlags[c] = true; 39 | } 40 | } 41 | } 42 | 43 | public static boolean isHex(char c) { 44 | return c < 256 && hexFlags[c]; 45 | } 46 | 47 | public static boolean isDigit(char c) { 48 | return c >= '0' && c <= '9'; 49 | } 50 | 51 | private final static boolean[] identifierFlags = new boolean[256]; 52 | static { 53 | for (char c = 0; c < identifierFlags.length; ++c) { 54 | if (c >= 'A' && c <= 'Z') { 55 | identifierFlags[c] = true; 56 | } else if (c >= 'a' && c <= 'z') { 57 | identifierFlags[c] = true; 58 | } else if (c >= '0' && c <= '9') { 59 | identifierFlags[c] = true; 60 | } 61 | } 62 | // identifierFlags['`'] = true; 63 | identifierFlags['_'] = true; 64 | identifierFlags['$'] = true; 65 | } 66 | 67 | public static boolean isIdentifierChar(char c) { 68 | return c > identifierFlags.length || identifierFlags[c]; 69 | } 70 | 71 | private final static boolean[] whitespaceFlags = new boolean[256]; 72 | static { 73 | whitespaceFlags[' '] = true; 74 | whitespaceFlags['\n'] = true; 75 | whitespaceFlags['\r'] = true; 76 | whitespaceFlags['\t'] = true; 77 | whitespaceFlags['\f'] = true; 78 | whitespaceFlags['\b'] = true; 79 | } 80 | 81 | /** 82 | * @return false if {@link MySQLLexer#EOI} 83 | */ 84 | public static boolean isWhitespace(char c) { 85 | return c <= whitespaceFlags.length && whitespaceFlags[c]; 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/beans/DNBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.beans; 25 | 26 | /** 27 | * refer a database on a mysql replica 28 | * 29 | * @author wuzhihui 30 | */ 31 | 32 | public class DNBean { 33 | private String database; 34 | private String mysqlReplica; 35 | 36 | public DNBean(String database, String mysqlReplica) { 37 | super(); 38 | this.database = database; 39 | this.mysqlReplica = mysqlReplica; 40 | } 41 | 42 | public String getDatabase() { 43 | return database; 44 | } 45 | 46 | public void setDatabase(String database) { 47 | this.database = database; 48 | } 49 | 50 | public String getMysqlReplica() { 51 | return mysqlReplica; 52 | } 53 | 54 | public void setMysqlReplica(String mysqlReplica) { 55 | this.mysqlReplica = mysqlReplica; 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | final int prime = 31; 61 | int result = 1; 62 | result = prime * result + ((database == null) ? 0 : database.hashCode()); 63 | result = prime * result + ((mysqlReplica == null) ? 0 : mysqlReplica.hashCode()); 64 | return result; 65 | } 66 | 67 | @Override 68 | public boolean equals(Object obj) { 69 | if (this == obj) 70 | return true; 71 | if (obj == null) 72 | return false; 73 | if (getClass() != obj.getClass()) 74 | return false; 75 | DNBean other = (DNBean) obj; 76 | if (database == null) { 77 | if (other.database != null) 78 | return false; 79 | } else if (!database.equals(other.database)) 80 | return false; 81 | if (mysqlReplica == null) { 82 | if (other.mysqlReplica != null) 83 | return false; 84 | } else if (!mysqlReplica.equals(other.mysqlReplica)) 85 | return false; 86 | return true; 87 | } 88 | 89 | @Override 90 | public String toString() { 91 | return "DNBean [database=" + database + ", mysqlReplica=" + mysqlReplica + "]"; 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/Fields.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql; 25 | 26 | /** 27 | * 字段类型及标识定义 28 | * 29 | * @author mycat 30 | */ 31 | public interface Fields { 32 | 33 | /** field data type */ 34 | public static final int FIELD_TYPE_DECIMAL = 0; 35 | public static final int FIELD_TYPE_TINY = 1; 36 | public static final int FIELD_TYPE_SHORT = 2; 37 | public static final int FIELD_TYPE_LONG = 3; 38 | public static final int FIELD_TYPE_FLOAT = 4; 39 | public static final int FIELD_TYPE_DOUBLE = 5; 40 | public static final int FIELD_TYPE_NULL = 6; 41 | public static final int FIELD_TYPE_TIMESTAMP = 7; 42 | public static final int FIELD_TYPE_LONGLONG = 8; 43 | public static final int FIELD_TYPE_INT24 = 9; 44 | public static final int FIELD_TYPE_DATE = 10; 45 | public static final int FIELD_TYPE_TIME = 11; 46 | public static final int FIELD_TYPE_DATETIME = 12; 47 | public static final int FIELD_TYPE_YEAR = 13; 48 | public static final int FIELD_TYPE_NEWDATE = 14; 49 | public static final int FIELD_TYPE_VARCHAR = 15; 50 | public static final int FIELD_TYPE_BIT = 16; 51 | public static final int FIELD_TYPE_NEW_DECIMAL = 246; 52 | public static final int FIELD_TYPE_ENUM = 247; 53 | public static final int FIELD_TYPE_SET = 248; 54 | public static final int FIELD_TYPE_TINY_BLOB = 249; 55 | public static final int FIELD_TYPE_MEDIUM_BLOB = 250; 56 | public static final int FIELD_TYPE_LONG_BLOB = 251; 57 | public static final int FIELD_TYPE_BLOB = 252; 58 | public static final int FIELD_TYPE_VAR_STRING = 253; 59 | public static final int FIELD_TYPE_STRING = 254; 60 | public static final int FIELD_TYPE_GEOMETRY = 255; 61 | 62 | /** field flag */ 63 | public static final int NOT_NULL_FLAG = 0x0001; 64 | public static final int PRI_KEY_FLAG = 0x0002; 65 | public static final int UNIQUE_KEY_FLAG = 0x0004; 66 | public static final int MULTIPLE_KEY_FLAG = 0x0008; 67 | public static final int BLOB_FLAG = 0x0010; 68 | public static final int UNSIGNED_FLAG = 0x0020; 69 | public static final int ZEROFILL_FLAG = 0x0040; 70 | public static final int BINARY_FLAG = 0x0080; 71 | public static final int ENUM_FLAG = 0x0100; 72 | public static final int AUTO_INCREMENT_FLAG = 0x0200; 73 | public static final int TIMESTAMP_FLAG = 0x0400; 74 | public static final int SET_FLAG = 0x0800; 75 | 76 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/packet/ResultSetHeaderPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.mysql.packet; 25 | 26 | import io.mycat.buffer.MycatByteBuffer; 27 | import io.mycat.util.BufferUtil; 28 | 29 | /** 30 | * From server to client after command, if no error and result set -- that is, 31 | * if the command was a query which returned a result set. The Result Set Header 32 | * Packet is the first of several, possibly many, packets that the server sends 33 | * for result sets. The order of packets for a result set is: 34 | * 35 | *
36 |  * (Result Set Header Packet)   the number of columns
37 |  * (Field Packets)              column descriptors
38 |  * (EOF Packet)                 marker: end of Field Packets
39 |  * (Row Data Packets)           row contents
40 |  * (EOF Packet)                 marker: end of Data Packets
41 |  * 
42 |  * Bytes                        Name
43 |  * -----                        ----
44 |  * 1-9   (Length-Coded-Binary)  field_count
45 |  * 1-9   (Length-Coded-Binary)  extra
46 |  * 
47 |  * @see http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#Result_Set_Header_Packet
48 |  * 
49 | * 50 | * @author mycat 51 | */ 52 | @Deprecated 53 | public class ResultSetHeaderPacket extends MySQLPacket { 54 | 55 | public int fieldCount; 56 | public long extra; 57 | 58 | // public void read(ConDataBuffer buffer) { 59 | // MySQLMessage mm = new MySQLMessage(buffer); 60 | // this.packetLength = mm.readUB3(); 61 | // this.packetId = mm.read(); 62 | // this.fieldCount = (int) mm.readLength(); 63 | // if (mm.hasRemaining()) { 64 | // this.extra = mm.readLength(); 65 | // } 66 | // } 67 | 68 | @Override 69 | public void write(MycatByteBuffer buffer, int pkgSize) { 70 | // BufferUtil.writeUB3(buffer, pkgSize); 71 | // buffer.put(packetId); 72 | // BufferUtil.writeLength(buffer, fieldCount); 73 | // if (extra > 0) { 74 | // BufferUtil.writeLength(buffer, extra); 75 | // } 76 | } 77 | 78 | @Override 79 | public int calcPacketSize() { 80 | int size = BufferUtil.getLength(fieldCount); 81 | if (extra > 0) { 82 | size += BufferUtil.getLength(extra); 83 | } 84 | return size; 85 | } 86 | 87 | @Override 88 | protected String getPacketInfo() { 89 | return "MySQL ResultSetHeader Packet"; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/PacketProcessStateTemplete.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state; 2 | 3 | import io.mycat.buffer.MycatByteBuffer; 4 | import io.mycat.buffer.PacketDescriptor; 5 | import io.mycat.buffer.PacketIterator; 6 | import io.mycat.common.StateMachine; 7 | import io.mycat.net2.Connection; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * Created by ynfeng on 2017/7/31. 15 | *

16 | * 当状态需要处理收到的包时可继承此类,方便处理.如果不继承此类需要自行处理短半包,长半包和全包的情况 17 | */ 18 | public abstract class PacketProcessStateTemplete extends AbstractMysqlConnectionState { 19 | private static final Logger LOGGER = LoggerFactory.getLogger(PacketProcessStateTemplete.class); 20 | private boolean interrupted = false; 21 | 22 | @Override 23 | public boolean handle(StateMachine context, Connection connection, Object attachment) throws IOException { 24 | MycatByteBuffer buffer = connection.getDataBuffer(); 25 | PacketIterator it = buffer.packetIterator(); 26 | boolean result = false; 27 | while (it.hasPacket()) { 28 | long packetDescriptor = it.nextPacket(); 29 | int packetStartPos = PacketDescriptor.getPacketStartPos(packetDescriptor); 30 | int packetLen = PacketDescriptor.getPacketLen(packetDescriptor); 31 | byte type = PacketDescriptor.getCommandType(packetDescriptor); 32 | PacketDescriptor.PacketType packetType = PacketDescriptor.getPacketType(packetDescriptor); 33 | switch (packetType) { 34 | case FULL: 35 | LOGGER.debug(connection.getClass().getSimpleName() + ",handle A FULL packet.packetStartPos=" + packetStartPos + ",packetLen=" + packetLen + ",type=" + type); 36 | result = handleFullPacket(connection, attachment, packetStartPos, packetLen, type); 37 | break; 38 | case LONG_HALF: 39 | LOGGER.debug(connection.getClass().getSimpleName() + ",handle A FULL_HALF packet.packetStartPos=" + packetStartPos + ",packetLen=" + packetLen + ",type=" + type); 40 | result = handleLongHalfPacket(connection, attachment, packetStartPos, packetLen, type); 41 | interruptIterate(); 42 | break; 43 | case SHORT_HALF: 44 | LOGGER.debug(connection.getClass().getSimpleName() + ",handle A Short packet.packetStartPos=" + packetStartPos); 45 | result = handleShortHalfPacket(connection, attachment, packetStartPos); 46 | interruptIterate(); 47 | break; 48 | } 49 | if (interrupted) { 50 | interrupted = false; 51 | return result; 52 | } 53 | } 54 | return result; 55 | } 56 | 57 | /** 58 | * 用于强行停止迭代过程 59 | * 注意:因为读写缓冲区共享的原因,如果在迭代过程中向缓冲区写入了包, 60 | * 则必须要调用此方法中止迭代过程,否则会一直迭代新写入的包。 61 | * 另外当前包为两种半包的情况下也会一直迭代 62 | * //TODO 能否有更清晰的处理方式? 63 | */ 64 | public void interruptIterate() { 65 | this.interrupted = true; 66 | } 67 | 68 | public abstract boolean handleShortHalfPacket(Connection connection, Object attachment, int packetStartPos) throws IOException; 69 | 70 | public abstract boolean handleLongHalfPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException; 71 | 72 | public abstract boolean handleFullPacket(Connection connection, Object attachment, int packetStartPos, int packetLen, byte type) throws IOException; 73 | } 74 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/util/PacketUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.util; 25 | 26 | import java.io.UnsupportedEncodingException; 27 | 28 | import io.mycat.engine.ErrorCode; 29 | import io.mycat.mysql.packet.ErrorPacket; 30 | import io.mycat.mysql.packet.FieldPacket; 31 | import io.mycat.mysql.packet.ResultSetHeaderPacket; 32 | 33 | /** 34 | * @author mycat 35 | */ 36 | public class PacketUtil { 37 | private static final String CODE_PAGE_1252 = "Cp1252"; 38 | 39 | public static final ResultSetHeaderPacket getHeader(int fieldCount) { 40 | ResultSetHeaderPacket packet = new ResultSetHeaderPacket(); 41 | packet.packetId = 1; 42 | packet.fieldCount = fieldCount; 43 | return packet; 44 | } 45 | 46 | public static byte[] encode(String src, String charset) { 47 | if (src == null) { 48 | return null; 49 | } 50 | try { 51 | return src.getBytes(charset); 52 | } catch (UnsupportedEncodingException e) { 53 | return src.getBytes(); 54 | } 55 | } 56 | 57 | public static final FieldPacket getField(String name, String orgName, int type) { 58 | FieldPacket packet = new FieldPacket(); 59 | packet.charsetIndex = CharsetUtil.getIndex(CODE_PAGE_1252); 60 | packet.name = encode(name, CODE_PAGE_1252); 61 | packet.orgName = encode(orgName, CODE_PAGE_1252); 62 | packet.type = (byte) type; 63 | return packet; 64 | } 65 | 66 | public static final FieldPacket getField(String name, int type) { 67 | FieldPacket packet = new FieldPacket(); 68 | packet.charsetIndex = CharsetUtil.getIndex(CODE_PAGE_1252); 69 | packet.name = encode(name, CODE_PAGE_1252); 70 | packet.type = (byte) type; 71 | return packet; 72 | } 73 | 74 | public static final ErrorPacket getShutdown() { 75 | ErrorPacket error = new ErrorPacket(); 76 | error.packetId = 1; 77 | error.errno = ErrorCode.ER_SERVER_SHUTDOWN; 78 | error.message = "The server has been shutdown".getBytes(); 79 | return error; 80 | } 81 | 82 | // public static final FieldPacket getField(BinaryPacket src, String fieldName) { 83 | // FieldPacket field = new FieldPacket(); 84 | // field.read(src); 85 | // field.name = encode(fieldName, CODE_PAGE_1252); 86 | // field.packetLength = field.calcPacketSize(); 87 | // return field; 88 | // } 89 | 90 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/net2/NIOAcceptor.java: -------------------------------------------------------------------------------- 1 | package io.mycat.net2; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.Socket; 6 | import java.net.StandardSocketOptions; 7 | import java.nio.channels.SelectionKey; 8 | import java.nio.channels.Selector; 9 | import java.nio.channels.ServerSocketChannel; 10 | import java.nio.channels.SocketChannel; 11 | import java.util.Set; 12 | 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | /** 17 | * @author wuzh 18 | */ 19 | public final class NIOAcceptor extends Thread { 20 | private static final Logger LOGGER = LoggerFactory.getLogger(NIOAcceptor.class); 21 | private final int port; 22 | private final Selector selector; 23 | private final ServerSocketChannel serverChannel; 24 | private final ConnectionFactory factory; 25 | private long acceptCount; 26 | private final NIOReactorPool reactorPool; 27 | 28 | public NIOAcceptor(String name, String bindIp, int port, 29 | ConnectionFactory factory, NIOReactorPool reactorPool) 30 | throws IOException { 31 | super.setName(name); 32 | this.port = port; 33 | this.selector = Selector.open(); 34 | this.serverChannel = ServerSocketChannel.open(); 35 | this.serverChannel.configureBlocking(false); 36 | /** 设置TCP属性 */ 37 | serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true); 38 | serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024 * 16 * 2); 39 | // backlog=100 40 | serverChannel.bind(new InetSocketAddress(bindIp, port), 100); 41 | this.serverChannel.register(selector, SelectionKey.OP_ACCEPT); 42 | this.factory = factory; 43 | this.reactorPool = reactorPool; 44 | } 45 | 46 | public int getPort() { 47 | return port; 48 | } 49 | 50 | public long getAcceptCount() { 51 | return acceptCount; 52 | } 53 | 54 | @Override 55 | public void run() { 56 | final Selector selector = this.selector; 57 | for (;;) { 58 | ++acceptCount; 59 | try { 60 | selector.select(1000L); 61 | Set keys = selector.selectedKeys(); 62 | try { 63 | for (SelectionKey key : keys) { 64 | if (key.isValid() && key.isAcceptable()) { 65 | accept(); 66 | } else { 67 | key.cancel(); 68 | } 69 | } 70 | } finally { 71 | keys.clear(); 72 | } 73 | } catch (Throwable e) { 74 | LOGGER.warn(getName(), e); 75 | } 76 | } 77 | } 78 | 79 | /** 80 | * 接受新连接 81 | */ 82 | private void accept() { 83 | SocketChannel channel = null; 84 | try { 85 | channel = serverChannel.accept(); 86 | channel.configureBlocking(false); 87 | Connection c = factory.make(channel); 88 | c.setDirection(Connection.Direction.in); 89 | c.setId(ConnectIdGenerator.getINSTNCE().getId()); 90 | InetSocketAddress remoteAddr = (InetSocketAddress) channel 91 | .getRemoteAddress(); 92 | c.setHost(remoteAddr.getHostString()); 93 | c.setPort(remoteAddr.getPort()); 94 | // 派发此连接到某个Reactor处理 95 | NIOReactor reactor = reactorPool.getNextReactor(); 96 | reactor.postRegister(c); 97 | 98 | } catch (Throwable e) { 99 | closeChannel(channel); 100 | LOGGER.warn(getName(), e); 101 | } 102 | } 103 | 104 | private static void closeChannel(SocketChannel channel) { 105 | if (channel == null) { 106 | return; 107 | } 108 | Socket socket = channel.socket(); 109 | if (socket != null) { 110 | try { 111 | socket.close(); 112 | } catch (IOException e) { 113 | } 114 | } 115 | try { 116 | channel.close(); 117 | } catch (IOException e) { 118 | } 119 | } 120 | 121 | } -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/mysql/state/frontend/FrontendComLoadState.java: -------------------------------------------------------------------------------- 1 | package io.mycat.mysql.state.frontend; 2 | 3 | import java.io.IOException; 4 | 5 | import io.mycat.common.StateMachine; 6 | import io.mycat.mysql.state.AbstractMysqlConnectionState; 7 | import io.mycat.net2.Connection; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import io.mycat.SQLEngineCtx; 12 | import io.mycat.buffer.MycatByteBuffer; 13 | import io.mycat.front.MySQLFrontConnection; 14 | import io.mycat.mysql.MySQLConnection; 15 | import io.mycat.net2.states.NoReadAndWriteState; 16 | 17 | public class FrontendComLoadState extends AbstractMysqlConnectionState { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(FrontendComLoadState.class); 20 | public static final FrontendComLoadState INSTANCE = new FrontendComLoadState(); 21 | 22 | private FrontendComLoadState() { 23 | } 24 | 25 | @Override 26 | public boolean handle(StateMachine stateMachine, Connection connection, Object attachment) throws IOException { 27 | LOGGER.debug("Frontend in FrontendComLoadState"); 28 | MySQLFrontConnection frontCon = (MySQLFrontConnection) connection; 29 | boolean returnflag = false; 30 | try { 31 | frontCon.getNetworkStateMachine().setNextState(NoReadAndWriteState.INSTANCE); 32 | // 如果当前状态数据报文可能有多个,需要透传 33 | while (true) { 34 | // processPacketHeader(frontCon); 35 | MycatByteBuffer dataBuffer = frontCon.getDataBuffer(); 36 | switch (frontCon.getDirectTransferMode()) { 37 | case COMPLETE_PACKET: 38 | dataBuffer.writeLimit(frontCon.getCurrentPacketLength()); //设置当前包结束位置 39 | break; 40 | case LONG_HALF_PACKET: 41 | dataBuffer.writeLimit(dataBuffer.writeIndex()); //设置当前包结束位置 42 | frontCon.setCurrentPacketStartPos(frontCon.getCurrentPacketStartPos() - dataBuffer.writeIndex()); 43 | frontCon.setCurrentPacketLength(frontCon.getCurrentPacketLength() - dataBuffer.writeIndex()); 44 | //当前半包透传 45 | SQLEngineCtx.INSTANCE().getDataTransferChannel().transferToBackend(frontCon, true, false, false); 46 | return false; 47 | case SHORT_HALF_PACKET: 48 | if ((dataBuffer.writeIndex() - dataBuffer.writeLimit()) == MySQLConnection.msyql_packetHeaderSize) { 49 | dataBuffer.writeLimit(dataBuffer.writeIndex()); 50 | // frontCon.setNextState(BackendComQueryResponseState.INSTANCE); 51 | SQLEngineCtx.INSTANCE().getDataTransferChannel().transferToBackend(frontCon, true, true, false); 52 | return false; 53 | } 54 | //短半包的情况下,currentPacketLength 为 上一个包的结束位置,当前半包不透传,不需要设置 55 | // dataBuffer.writeLimit(mySQLBackendConnection.getCurrentPacketLength()); 56 | //当前半包不透传 57 | SQLEngineCtx.INSTANCE().getDataTransferChannel().transferToBackend(frontCon, false, false, false); 58 | return false; 59 | case NONE: 60 | break; 61 | } 62 | } 63 | } catch (IOException e) { 64 | LOGGER.warn("Backend BackendComQueryColumnDefState error", e); 65 | frontCon.getProtocolStateMachine().setNextState(FrontendCloseState.INSTANCE); 66 | returnflag = false; 67 | } 68 | return returnflag; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Mycat-Core/src/main/java/io/mycat/beans/MySQLBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software;Designed and Developed mainly by many Chinese 6 | * opensource volunteers. you can redistribute it and/or modify it under the 7 | * terms of the GNU General Public License version 2 only, as published by the 8 | * Free Software Foundation. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Any questions about this component can be directed to it's project Web address 21 | * https://code.google.com/p/opencloudb/. 22 | * 23 | */ 24 | package io.mycat.beans; 25 | 26 | /** 27 | * @author wuzhihui 28 | */ 29 | public class MySQLBean { 30 | private String hostName; 31 | private String ip; 32 | private int port; 33 | private String user; 34 | private String password; 35 | private String defaultSchema = "mysql"; 36 | private int maxCon = 1000; 37 | private int minCon = 1; 38 | 39 | public MySQLBean(String ip, int port, String user, String password) { 40 | super(); 41 | this.hostName = ip; 42 | this.ip = ip; 43 | this.port = port; 44 | this.user = user; 45 | this.password = password; 46 | } 47 | 48 | public MySQLBean() { 49 | 50 | } 51 | 52 | public String getHostName() { 53 | return hostName; 54 | } 55 | 56 | public void setHostName(String hostName) { 57 | this.hostName = hostName; 58 | } 59 | 60 | public String getIp() { 61 | return ip; 62 | } 63 | 64 | public void setIp(String ip) { 65 | this.ip = ip; 66 | } 67 | 68 | public int getPort() { 69 | return port; 70 | } 71 | 72 | public void setPort(int port) { 73 | this.port = port; 74 | } 75 | 76 | public String getUser() { 77 | return user; 78 | } 79 | 80 | public void setUser(String user) { 81 | this.user = user; 82 | } 83 | 84 | public String getPassword() { 85 | return password; 86 | } 87 | 88 | public void setPassword(String password) { 89 | this.password = password; 90 | } 91 | 92 | public String getDefaultSchema() { 93 | return defaultSchema; 94 | } 95 | 96 | public void setDefaultSchema(String defaultSchema) { 97 | this.defaultSchema = defaultSchema; 98 | } 99 | 100 | public int getMaxCon() { 101 | return maxCon; 102 | } 103 | 104 | public void setMaxCon(int maxCon) { 105 | this.maxCon = maxCon; 106 | } 107 | 108 | public int getMinCon() { 109 | return minCon; 110 | } 111 | 112 | public void setMinCon(int minCon) { 113 | this.minCon = minCon; 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return "MySQLBean [hostName=" + hostName + ", ip=" + ip + ", port=" + port + ", user=" + user + ", password=" 119 | + password + ", defaultSchema=" + defaultSchema + ", maxCon=" + maxCon + ", minCon=" + minCon + "]"; 120 | } 121 | 122 | } 123 | --------------------------------------------------------------------------------