{"action":"created","issue":{"url":"https://api.github.com/repos/MyCATApache/Mycat-Server/issues/882","repository_url":"https://api.github.com/repos/MyCATApache/Mycat-Server","labels_url":"https://api.github.com/repos/MyCATApache/Mycat-Server/issues/882/labels{/name}","comments_url":"https://api.github.com/repos/MyCATApache/Mycat-Server/issues/882/comments","events_url":"https://api.github.com/repos/MyCATApache/Mycat-Server/issues/882/events","html_url":"https://github.com/MyCATApache/Mycat-Server/issues/882","id":154654579,"number":882,"title":"主备切换后无法负载均衡的问题","user":{"login":"xushsh163","id":18326382,"avatar_url":"https://avatars.githubusercontent.com/u/18326382?v=3","gravatar_id":"","url":"https://api.github.com/users/xushsh163","html_url":"https://github.com/xushsh163","followers_url":"https://api.github.com/users/xushsh163/followers","following_url":"https://api.github.com/users/xushsh163/following{/other_user}","gists_url":"https://api.github.com/users/xushsh163/gists{/gist_id}","starred_url":"https://api.github.com/users/xushsh163/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xushsh163/subscriptions","organizations_url":"https://api.github.com/users/xushsh163/orgs","repos_url":"https://api.github.com/users/xushsh163/repos","events_url":"https://api.github.com/users/xushsh163/events{/privacy}","received_events_url":"https://api.github.com/users/xushsh163/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-05-13T07:58:52Z","updated_at":"2016-05-16T06:56:39Z","closed_at":null,"body":"MySQLDetector.java中\r\n`public void onResult(SQLQueryResult<Map<String, String>> result) {\r\n\t\tif (result.isSuccess()) {\r\n            int balance = heartbeat.getSource().getDbPool().getBalance();\r\n            PhysicalDatasource source = heartbeat.getSource();\r\n            Map<String, String> resultResult = result.getResult();\r\n            \t\t\tif (source.getHostConfig().isShowSlaveSql()\r\n                                &&(source.getHostConfig().getSwitchType() == DataHostConfig.SYN_STATUS_SWITCH_DS  ||\r\n                                 PhysicalDBPool.BALANCE_NONE!=balance  )\r\n                    \t\t\t\t\t )\r\n            {\r\n\r\n                String Slave_IO_Running =resultResult!=null? resultResult.get(\r\n                        \"Slave_IO_Running\"):null;\r\n\t\t\t\tString Slave_SQL_Running = resultResult!=null?resultResult.get(\r\n                        \"Slave_SQL_Running\"):null;\r\n\t\t\t\tif (Slave_IO_Running != null\r\n\t\t\t\t\t\t&& Slave_IO_Running.equals(Slave_SQL_Running)\r\n\t\t\t\t\t\t&& Slave_SQL_Running.equals(\"Yes\")) {\r\n\t\t\t\t\theartbeat.setDbSynStatus(DBHeartbeat.DB_SYN_NORMAL);\r\n\t\t\t\t\tString Seconds_Behind_Master = resultResult.get(\r\n                            \"Seconds_Behind_Master\");\r\n\t\t\t\t\tif (null != Seconds_Behind_Master\r\n\t\t\t\t\t\t\t&& !\"\".equals(Seconds_Behind_Master)) {\r\n\t\t\t\t\t\theartbeat.setSlaveBehindMaster(Integer\r\n\t\t\t\t\t\t\t\t.valueOf(Seconds_Behind_Master));\r\n\t\t\t\t\t}\r\n\t\t\t\t} else  if(source.isSalveOrRead())\r\n                {\r\n\t\t\t\t\tMySQLHeartbeat.LOGGER\r\n\t\t\t\t\t\t\t.warn(\"found MySQL master/slave Replication err !!! \"\r\n\t\t\t\t\t\t\t\t\t+ heartbeat.getSource().getConfig());\r\n\t\t\t\t\theartbeat.setDbSynStatus(DBHeartbeat.DB_SYN_ERROR);\r\n\t\t\t\t} \r\n\r\n\t\t\t}\r\n\t\t\theartbeat.setResult(MySQLHeartbeat.OK_STATUS, this,  null);\r\n\t\t} else {\r\n\t\t\theartbeat.setResult(MySQLHeartbeat.ERROR_STATUS, this,  null);\r\n\t\t}\r\n\t\tlasstReveivedQryTime = System.currentTimeMillis();\r\n\t}`\r\n\r\n如果主节点挂掉，备节点还未切换成功，就会走到heartbeat.setDbSynStatus(DBHeartbeat.DB_SYN_ERROR);，之后备节点切换成功后，因为Slave_IO_Running一直是“Connecting”，状态无法变回Normal，所以备节点在负载均衡的判断canAsReadNode一直通不过，所以切换后备节点后，如果备节点有读节点，负载均衡不起作用的。\r\n最好再加个\r\n`else if (Slave_IO_Running != null\r\n\t\t\t\t\t\t&& Slave_IO_Running.equals(\"Connecting\"))\r\n\t\t\t\t{\r\n\t\t\t\t\tMySQLHeartbeat.LOGGER\r\n\t\t\t\t\t.warn(\"found MySQL master changed !!! \"\r\n\t\t\t\t\t\t\t+ heartbeat.getSource().getConfig());\r\n\t\t\t\t\theartbeat.setDbSynStatus(DBHeartbeat.DB_SYN_NORMAL);\r\n\t\t\t\t}`"},"comment":{"url":"https://api.github.com/repos/MyCATApache/Mycat-Server/issues/comments/219361656","html_url":"https://github.com/MyCATApache/Mycat-Server/issues/882#issuecomment-219361656","issue_url":"https://api.github.com/repos/MyCATApache/Mycat-Server/issues/882","id":219361656,"user":{"login":"xushsh163","id":18326382,"avatar_url":"https://avatars.githubusercontent.com/u/18326382?v=3","gravatar_id":"","url":"https://api.github.com/users/xushsh163","html_url":"https://github.com/xushsh163","followers_url":"https://api.github.com/users/xushsh163/followers","following_url":"https://api.github.com/users/xushsh163/following{/other_user}","gists_url":"https://api.github.com/users/xushsh163/gists{/gist_id}","starred_url":"https://api.github.com/users/xushsh163/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xushsh163/subscriptions","organizations_url":"https://api.github.com/users/xushsh163/orgs","repos_url":"https://api.github.com/users/xushsh163/repos","events_url":"https://api.github.com/users/xushsh163/events{/privacy}","received_events_url":"https://api.github.com/users/xushsh163/received_events","type":"User","site_admin":false},"created_at":"2016-05-16T06:56:39Z","updated_at":"2016-05-16T06:56:39Z","body":"@songgw \r\n我是反应代码逻辑问题的，不管是单向还是双向，主备切换后，如果备机上有读节点，那么切换后经常无法负载均衡（即M1->S1，M2->S2, M1挂掉之后，M1,S1,S2都会失效）原因我在问题里写了，是heartbeat检测状态有问题。至于你说的stop slave操作，1是无法解决这个问题，因为代码已经判定M2状态不对，不让其参与负载，stop slave之后Slave_IO_Running==null，也无法将M2状态改回来；2是目前也没有这个自动stop slave的机制，等待人工介入也不现实。\r\n\r\n另外，单向的主从结构还有另外的问题，上面说了：“主的writehost的show slave staus获取到的值是null（因为不是任何其他节点的slave，没有slave状态），即theSource.getHeartbeat().getSlaveBehindMaster()==null，那么canAsReadNode也是false，balance=‘2’时，这个主不能参与负载均衡”。"}}