();
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 |
--------------------------------------------------------------------------------