2323 */
2424package io .mycat .backend .mysql .nio .handler ;
2525
26+ import java .io .IOException ;
2627import java .util .ArrayList ;
2728import java .util .List ;
2829import java .util .concurrent .atomic .AtomicInteger ;
3233
3334import io .mycat .MycatServer ;
3435import io .mycat .backend .BackendConnection ;
35- import io .mycat .backend .ConnectionMeta ;
3636import io .mycat .backend .datasource .PhysicalDBNode ;
3737import io .mycat .cache .CachePool ;
3838import io .mycat .config .MycatConfig ;
3939import io .mycat .net .mysql .ErrorPacket ;
4040import io .mycat .net .mysql .RowDataPacket ;
4141import io .mycat .route .RouteResultsetNode ;
42+ import io .mycat .server .ServerConnection ;
4243import io .mycat .server .parser .ServerParse ;
4344
4445/**
@@ -56,6 +57,67 @@ public class FetchStoreNodeOfChildTableHandler implements ResponseHandler {
5657 private volatile String dataNode ;
5758 private AtomicInteger finished = new AtomicInteger (0 );
5859 protected final ReentrantLock lock = new ReentrantLock ();
60+
61+ public String execute (String schema , String sql , List <String > dataNodes , ServerConnection sc ) {
62+
63+ String key = schema + ":" + sql ;
64+ CachePool cache = MycatServer .getInstance ().getCacheService ()
65+ .getCachePool ("ER_SQL2PARENTID" );
66+ String result = (String ) cache .get (key );
67+ if (result != null ) {
68+ return result ;
69+ }
70+ this .sql = sql ;
71+ int totalCount = dataNodes .size ();
72+ long startTime = System .currentTimeMillis ();
73+ long endTime = startTime + 5 * 60 * 1000L ;
74+ MycatConfig conf = MycatServer .getInstance ().getConfig ();
75+
76+ LOGGER .debug ("find child node with sql:" + sql );
77+ for (String dn : dataNodes ) {
78+ if (dataNode != null ) {
79+ return dataNode ;
80+ }
81+ PhysicalDBNode mysqlDN = conf .getDataNodes ().get (dn );
82+ try {
83+ if (LOGGER .isDebugEnabled ()) {
84+ LOGGER .debug ("execute in datanode " + dn );
85+ }
86+ RouteResultsetNode node = new RouteResultsetNode (dn , ServerParse .SELECT , sql );
87+ node .setRunOnSlave (false ); // 获取 子表节点,最好走master为好
88+
89+ /*
90+ * fix #1370 默认应该先从已经持有的连接中取连接, 否则可能因为事务隔离性看不到当前事务内更新的数据
91+ * Tips: 通过mysqlDN.getConnection获取到的连接不是当前连接
92+ *
93+ */
94+ BackendConnection conn = sc .getSession2 ().getTarget (node );
95+ if (sc .getSession2 ().tryExistsCon (conn , node )) {
96+ _execute (conn , node , sc );
97+ } else {
98+ mysqlDN .getConnection (mysqlDN .getDatabase (), sc .isAutocommit (), node , this , node );
99+ }
100+ } catch (Exception e ) {
101+ LOGGER .warn ("get connection err " + e );
102+ }
103+ }
104+
105+ while (dataNode == null && System .currentTimeMillis () < endTime ) {
106+ try {
107+ Thread .sleep (50 );
108+ } catch (InterruptedException e ) {
109+ break ;
110+ }
111+ if (dataNode != null || finished .get () >= totalCount ) {
112+ break ;
113+ }
114+ }
115+ if (dataNode != null ) {
116+ cache .putIfAbsent (key , dataNode );
117+ }
118+ return dataNode ;
119+
120+ }
59121
60122 public String execute (String schema , String sql , ArrayList <String > dataNodes ) {
61123 String key = schema + ":" + sql ;
@@ -84,7 +146,7 @@ public String execute(String schema, String sql, ArrayList<String> dataNodes) {
84146 RouteResultsetNode node = new RouteResultsetNode (dn , ServerParse .SELECT , sql );
85147 node .setRunOnSlave (false ); // 获取 子表节点,最好走master为好
86148
87- mysqlDN .getConnection (mysqlDN .getDatabase (), true , node , this , dn );
149+ mysqlDN .getConnection (mysqlDN .getDatabase (), true , node , this , node );
88150
89151// mysqlDN.getConnection(mysqlDN.getDatabase(), true,
90152// new RouteResultsetNode(dn, ServerParse.SELECT, sql),
@@ -115,6 +177,15 @@ public String execute(String schema, String sql, ArrayList<String> dataNodes) {
115177 return dataNode ;
116178
117179 }
180+
181+ private void _execute (BackendConnection conn , RouteResultsetNode node , ServerConnection sc ) {
182+ conn .setResponseHandler (this );
183+ try {
184+ conn .execute (node , sc , sc .isAutocommit ());
185+ } catch (IOException e ) {
186+ connectionError (e , conn );
187+ }
188+ }
118189
119190 @ Override
120191 public void connectionAcquired (BackendConnection conn ) {
@@ -162,7 +233,7 @@ public void rowResponse(byte[] row, BackendConnection conn) {
162233 }
163234 if (result == null ) {
164235 result = getColumn (row );
165- dataNode = (String ) conn .getAttachment ();
236+ dataNode = (( RouteResultsetNode ) conn .getAttachment ()). getName ();
166237 } else {
167238 LOGGER .warn ("find multi data nodes for child table store, sql is: "
168239 + sql );
0 commit comments