讀寫分離mycat簡單配置

https://www.cnblogs.com/kevingrace/p/9365840.html

 

系統開發中,數據庫是非常重要的一個點。除了程序的本身的優化,如:SQL語句優化、代碼優化,數據庫的處理本身優化也是非常重要的。主從、熱備、分表分庫等都是系統發展遲早會遇到的技術問題問題。Mycat是一個廣受好評的數據庫中間件,已經在很多產品上進行使用了。下面就針對Mycat的基礎知識和應用做一總結性梳理,這些內容有的是從網上收集的,有的是自己做的測試驗證信息,如有錯誤,煩請諒解和指出!

一、MyCat簡單介紹


MyCat是一個開源的分佈式數據庫系統,是一個實現了MySQL協議的服務器,前端用戶可以把它看作是一個數據庫代理(類似於Mysql Proxy),用MySQL客戶端工具和命令行訪問,而其後端可以用MySQL原生協議與多個MySQL服務器通信,也可以用JDBC協議與大多數主流數據庫服務器通信,其核心功能是分表分庫,即將一個大表水平分割爲N個小表,存儲在後端MySQL服務器裏或者其他數據庫裏。

MyCat發展到目前的版本,已經不是一個單純的MySQL代理了,它的後端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流數據庫,也支持MongoDB這種新型NoSQL方式的存儲,未來還會支持更多類型的存儲。而在最終用戶看來,無論是那種存儲方式,在MyCat裏,都是一個傳統的數據庫表,支持標準的SQL語句進行數據的操作,這樣一來,對前端業務系統來說,可以大幅降低開發難度,提升開發速度。

Mycat可以簡單概括爲
-  一個徹底開源的,面向企業應用開發的大數據庫集羣
-  支持事務、ACID、可以替代MySQL的加強版數據庫
-  一個可以視爲MySQL集羣的企業級數據庫,用來替代昂貴的Oracle集羣
-  一個融合內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server
-  結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品
-  一個新穎的數據庫中間件產品

Mycat關鍵特性
-  支持SQL92標準
-  遵守Mysql原生協議,跨語言,跨平臺,跨數據庫的通用中間件代理
-  基於心跳的自動故障切換,支持讀寫分離,支持MySQL主從,以及galera cluster集羣
-  支持Galera for MySQL集羣,Percona Cluster或者MariaDB cluster
-  基於Nio實現,有效管理線程,高併發問題
-  支持數據的多片自動路由與聚合,支持sum,count,max等常用的聚合函數,支持跨庫分頁
-  支持單庫內部任意join,支持跨庫2表join,甚至基於caltlet的多表join
-  支持通過全局表,ER關係的分片策略,實現了高效的多表join查詢
-  支持多租戶方案
-  支持分佈式事務(弱xa)
-  支持全局序列號,解決分佈式下的主鍵生成問題
-  分片規則豐富,插件化開發,易於擴展
-  強大的web,命令行監控
-  支持前端作爲mysq通用代理,後端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉
-  支持密碼加密
-  支持服務降級
-  支持IP白名單
-  支持SQL黑名單、sql注入攻擊攔截
-  支持分表(1.6)
-  集羣基於ZooKeeper管理,在線升級,擴容,智能優化,大數據處理(2.0開發版)

二、爲什麼要用MyCat


這裏要先搞清楚Mycat和MySQL的區別(Mycat的核心作用)。我們可以把上層看作是對下層的抽象,例如操作系統是對各類計算機硬件的抽象。那麼我們什麼時候需要抽象?假如只有一種硬件的時候,我們需要開發一個操作系統嗎?再比如一個項目只需要一個人完成的時候不需要leader,但是當需要幾十人完成時,就應該有一個管理者,發揮溝通協調等作用,而這個管理者對於他的上層來說就是對項目組的抽象。

同樣的,當我們的應用只需要一臺數據庫服務器的時候我們並不需要Mycat,而如果你需要分庫甚至分表,這時候應用要面對很多個數據庫的時候,這個時候就需要對數據庫層做一個抽象,來管理這些數據庫,而最上面的應用只需要面對一個數據庫層的抽象或者說數據庫中間件就好了,這就是Mycat的核心作用。所以可以這樣理解:數據庫是對底層存儲文件的抽象,而Mycat是對數據庫的抽象。

三、Mycat工作原理


Mycat的原理並不複雜,複雜的是代碼。Mycat的原理中最重要的一個動詞是“攔截”,它攔截了用戶發送過來的SQL語句,首先對SQL語句做了一些特定的分析:如分
片分析、路由分析、讀寫分離分析、緩存分析等,然後將此SQL發往後端的真實數據庫,並將返回的結果做適當的處理,最終再返回給用戶。

上述圖片裏,Orders表被分爲三個分片datanode(簡稱dn),這三個分片是分佈在兩臺MySQL Server上(DataHost),即datanode=database@datahost方式,因此你可以用一臺到N臺服務器來分片,分片規則爲(sharding rule)典型的字符串枚舉分片規則,一個規則的定義是分片字段(sharding column)+分片函數(rule function),這裏的分片字段爲prov而分片函數爲字符串枚舉方式。

當Mycat收到一個SQL時,會先解析這個SQL,查找涉及到的表,然後看此表的定義,如果有分片規則,則獲取到SQL裏分片字段的值,並匹配分片函數,得到該SQL對應的分片列表,然後將SQL發往這些分片去執行,最後收集和處理所有分片返回的結果數據,並輸出到客戶端。以select * from Orders where prov=?語句爲例,查到prov=wuhan,按照分片函數,wuhan返回dn1,於是SQL就發給了MySQL1,去取DB1上的查詢結果,並返回給用戶。

如果上述SQL改爲select * from Orders where prov in (‘wuhan’,‘beijing’),那麼,SQL就會發給MySQL1與MySQL2去執行,然後結果集合並後輸出給用戶。但通常業務中我們的SQL會有Order By 以及Limit翻頁語法,此時就涉及到結果集在Mycat端的二次處理,這部分的代碼也比較複雜,而最複雜的則屬兩個表的Jion問題,爲此,Mycat提出了創新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及結合Storm/Spark引擎等十八般武藝的解決辦法,從而成爲目前業界最強大的方案,這就是開源的力量!

四、Mycat應用場景


Mycat發展到現在,適用的場景已經很豐富,而且不斷有新用戶給出新的創新性的方案,以下是幾個典型的應用場景:
-   單純的讀寫分離,此時配置最爲簡單,支持讀寫分離,主從切換;
-   分表分庫,對於超過1000萬的表進行分片,最大支持1000億的單表分片;
-   多租戶應用,每個應用一個庫,但應用程序只連接Mycat,從而不改造程序本身,實現多租戶化;
-   報表系統,藉助於Mycat的分表能力,處理大規模報表的統計;
-   替代Hbase,分析大數據;
-   作爲海量數據實時查詢的一種簡單有效方案,比如100億條頻繁查詢的記錄需要在3秒內查詢出來結果,除了基於主鍵的查詢,還可能存在範圍查詢或其他屬性查詢,此時Mycat可能是最簡單有效的選擇;
-   Mycat長期路線圖;
-   強化分佈式數據庫中間件的方面的功能,使之具備豐富的插件、強大的數據庫智能優化功能、全面的系統監控能力、以及方便的數據運維工具,實現在線數據擴容、遷移等高級功能;
-   進一步挺進大數據計算領域,深度結合Spark Stream和Storm等分佈式實時流引擎,能夠完成快速的巨表關聯、排序、分組聚合等 OLAP方向的能力,並集成一些熱門常用的實時分析算法,讓工程師以及DBA們更容易用Mycat實現一些高級數據分析處理功能。
-   不斷強化Mycat開源社區的技術水平,吸引更多的IT技術專家,使得Mycat社區成爲中國的Apache,並將Mycat推到Apache
基金會,成爲國內頂尖開源項目,最終能夠讓一部分志願者成爲專職的Mycat開發者,榮耀跟實力一起提升。

五、Mycat不適合的應用場景


-  設計使用Mycat時有非分片字段查詢,請慎重使用Mycat,可以考慮放棄!
-  設計使用Mycat時有分頁排序,請慎重使用Mycat,可以考慮放棄!
-  設計使用Mycat時如果要進行表JOIN操作,要確保兩個表的關聯字段具有相同的數據分佈,否則請慎重使用Mycat,可以考慮放棄!
-  設計使用Mycat時如果有分佈式事務,得先看是否得保證事務得強一致性,否則請慎重使用Mycat,可以考慮放棄!

需要注意:  在生產環境中, Mycat節點最好使用雙節點, 即雙機熱備環境, 防止Mycat這一層出現單點故障. 可以使用的高可用集羣方式有:  Keepalived+Mycat+MysqlKeepalived+LVS+Mycat+MysqlKeepalived+Haproxy+Mycat+Mysql

六、利用MyCAT實現MySQL的讀寫分離、主從切換、分庫分表的操作記錄

Mycat實現Mysql主從複製,其中寫操作在master主節點上執行,包括insert,delete,update 語句操作;讀操作在slave節點上執行,只有select語句操作,其他操作均由主master的二進制文件決定;MyCat支持雙主多從,多主多從情況需要配置多個writeHost兄弟節點,多個readHost節點即可!

Mycat的架構其實很好理解,Mycat是數據庫代理中間件,Mycat後面就是物理數據庫。和Web服務器的Nginx類似。對於使用者來說,訪問的都是Mycat,不會接觸到後端的數據庫。如下案例是做一個主從、讀寫分離,簡單分庫分表的示例。結構如下圖:

服務器信息如下(實驗環境,關閉機器的iptables防火牆和selinux):

1

2

3

4

5

6

7

8

9

10

11

12

服務器主機名       ip                  說明

Mycat-node       192.168.10.210      mycat服務器,連接數據庫時,連接此服務器

Mysql-node1      192.168.10.205      物理數據庫1,真正存儲數據的數據庫,這裏爲Master主數據庫

Mysql-node2      192.168.10.206      物理數據庫2,真正存儲數據的數據庫,這裏爲Slave主數據庫

 

三臺機器分佈修改主機名,並做hosts綁定

# vim /etc/hosts

192.168.10.205 Mysql-node1

192.168.10.206 Mysql-node1

192.168.10.210 Mycat-node

 

爲方便做實驗,關閉三臺機器的iptables防火牆和selinux 

Mycat作爲主數據庫中間件,肯定是與代碼弱關聯的,所以代碼是不用修改的,使用Mycat後,連接數據庫是不變的,默認端口是8066。連接方式和普通數據庫一樣,比如:jdbc:mysql://192.168.10.210:8066/

1)Mysql安裝及主從複製部署(Mysql-node1和Mysql-node2兩臺機器上操作)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

a)安裝Mysql,安裝過程要在兩個Mysql節點機器上都要操作。

安裝過程參考:http://www.cnblogs.com/kevingrace/p/6109679.html

這裏省去安裝過程~~

 

b)Mysql主從複製(兩個節點的mysql登錄用戶名和密碼都是root/123456

參考:http://www.cnblogs.com/kevingrace/p/6256603.html

 

====================================================

首先是Mysql-node1主節點配置操作

[root@Mysql-node1 ~]# cp /usr/local/mysql/my.cnf /usr/local/mysql/my.cnf.bak

[root@Mysql-node1 ~]# vim /usr/local/mysql/my.cnf        #在[mysqld]區域添加下面內容

......

[mysqld]

server-id=1       

log-bin=mysql-bin 

#binlog-do-db=kevin         #需要同步的數據庫。如果是多個同步庫,就以此格式另寫幾行即可。如果不指明對某個具體庫同步,就去掉此行,表示同步所有庫(除了ignore忽略的庫)        

binlog-ignore-db = mysql,information_schema

sync_binlog = 1     

binlog_checksum = none 

binlog_format = mixed  

 

重啓mysql服務

[root@Mysql-node1 ~]# /etc/init.d/mysql restart

 

登錄mysql,授予slave從機複製權限

mysql> grant replication slave,replication client on *.* to slave@'192.168.10.206' identified by "slave@123";

Query OK, 0 rows affected (0.05 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.06 sec)

 

授權之後,要保證192.168.10.206這臺slave節點機器能使用上面的權限信息登錄到本機的mysql

 

將數據庫鎖住,僅僅允許讀,以保證數據一致性;

mysql> FLUSH TABLES WITH READ LOCK;                 #注意,鎖定後,如果自己同步對方數據,同步前一定要記得先解鎖!

Query OK, 0 rows affected (0.00 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.05 sec)

 

查看主節點的master複製信息

mysql> show master status;

+------------------+----------+--------------+--------------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |

+------------------+----------+--------------+--------------------------+-------------------+

| mysql-bin.000003 |     1349 |              | mysql,information_schema |                   |

+------------------+----------+--------------+--------------------------+-------------------+

1 row in set (0.00 sec)

 

 

====================================================

接着是slave從節點操作

[root@Mysql-node2 ~]# cp /usr/local/mysql/my.cnf /usr/local/mysql/my.cnf.bak

[root@Mysql-node2 ~]# vim /usr/local/mysql/my.cnf

.......

[mysqld]

.......

server-id=2  

log-bin=mysql-bin  

#replicate-do-db=kevin    #需要同步的數據庫名。如果不指明同步哪些庫,就去掉這行,表示所有庫的同步(除了ignore忽略的庫)。 

replicate-ignore-db=mysql 

slave-skip-errors = all

 

重啓mysql服務

[root@Mysql-node2 ~]# /etc/init.d/mysql restart

 

登錄slave節點的mysql,進行主從同步設置

mysql> stop slave;

Query OK, 0 rows affected (0.09 sec)

 

mysql> change  master to master_host='192.168.10.205',master_user='slave',master_password='slave@123',master_log_file='mysql-bin.000003',master_log_pos=1349; 

Query OK, 0 rows affected, 2 warnings (0.21 sec)

 

mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

 

mysql> show slave status \G;

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.10.205

                  Master_User: slave

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000003

          Read_Master_Log_Pos: 1349

               Relay_Log_File: mysql-relay-bin.000002

                Relay_Log_Pos: 283

        Relay_Master_Log_File: mysql-bin.000003

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB:

          Replicate_Ignore_DB: mysql

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 1349

              Relay_Log_Space: 456

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

             Master_Server_Id: 1

                  Master_UUID: 747977ea-8fba-11e8-86c0-525400b19c93

             Master_Info_File: /data/mysql/data/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

           Master_Retry_Count: 86400

                  Master_Bind:

      Last_IO_Error_Timestamp:

     Last_SQL_Error_Timestamp:

               Master_SSL_Crl:

           Master_SSL_Crlpath:

           Retrieved_Gtid_Set:

            Executed_Gtid_Set:

                Auto_Position: 0

1 row in set (0.00 sec)

 

ERROR:

No query specified

 

mysql>

 

 

=========================================================

通過上面的信息,可知主從複製環境已經OK(Slave_IO_Running和Slave_SQL_Running狀態均爲YES),下面驗證下主從複製是否正常?

 

在Mysql-node1主節點上操作

mysql> unlock tables;

Query OK, 0 rows affected (0.00 sec)

 

mysql> CREATE DATABASE kevin CHARACTER SET utf8 COLLATE utf8_general_ci;      

Query OK, 1 row affected (0.06 sec)

 

mysql> use kevin;

Database changed

mysql> create table if not exists haha (id int(10) PRIMARY KEY AUTO_INCREMENT,name varchar(50) NOT NULL);

Query OK, 0 rows affected (0.34 sec)

 

在Mysql-node2從節點上查看(保證從節點上查看slave狀態時,Slave_IO_Running和Slave_SQL_Running狀態均爲YES,這樣就能保證主從複製在進行中)

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| kevin              |

| mysql              |

| performance_schema |

test               |

+--------------------+

5 rows in set (0.00 sec)

 

mysql> use kevin;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

+-----------------+

1 row in set (0.00 sec)

 

接着在Mysql-node1主節點插入數據

mysql> insert into kevin.haha values(1,"wangshibo"),(2,"linan"),(3,"zhangminmin");      

Query OK, 3 rows affected (0.04 sec)

Records: 3  Duplicates: 0  Warnings: 0

 

然後再在MYsql-node2從節點查看,如下發現已經同步過來了!

mysql> use kevin;

Database changed

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

+-----------------+

1 row in set (0.00 sec)

 

mysql> select * from haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

+----+-------------+

3 rows in set (0.00 sec)

 

由此可見,Mysql的主從複製已經實現!

2)Mycat中間件安裝、配置和測試(Mycat-node節點機器上操作)
2.1)Mycat安裝

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

建議下載1.6-RELEASE 版本,畢竟是比較穩定的版本。

下載官網地址:http://dl.mycat.io/

 

[root@Mycat-node ~]# cd /usr/local/src/

[root@Mycat-node src]# wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

[root@Mycat-node src]# tar -zvxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

[root@Mycat-node src]# mv mycat /data/

[root@Mycat-node src]# ls /data/mycat/

bin  catlet  conf  lib  logs  version.txt

 

mycat安裝完成後,目錄如下:

bin     mycat命令,啓動、重啓、停止等

catlet  catlet爲Mycat的一個擴展功能

conf    Mycat 配置信息,重點關注

lib     Mycat引用的jar包,Mycat是java開發的

logs    日誌文件,包括Mycat啓動的日誌和運行的日誌。

 

 

Mycat的配置文件都在conf目錄裏面,這裏介紹幾個常用的文件:

server.xml   Mycat的配置文件,設置賬號、參數等

schema.xml   Mycat對應的物理數據庫和數據庫表的配置

rule.xml     Mycat分片(分庫分表)規則

 

[root@Mycat-node src]# cd /data/mycat/conf

[root@Mycat-node conf]# ll server.xml     

-rwxrwxrwx. 1 root root 3740 Jul 25 12:19 server.xml

[root@Mycat-node conf]# ll schema.xml     

-rwxrwxrwx. 1 root root 4667 Jul 31 02:54 schema.xml

2.2)Mycat相關配置
server.xml文件其實跟讀寫分離策略關係不大,但是需要用此文件來配置連接MyCat的用戶及權限等,因此在這裏簡單說明。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

[root@Mycat-node conf]# cp server.xml server.xml.bak

[root@Mycat-node conf]# vim server.xml

.......

        <user name="bobo">

                <property name="password">bo@123</property>

                <property name="schemas">mycat/property>

 

                <!-- 表級 DML 權限設置 -->

                <!--

                <privileges check="false">

                        <schema name="TESTDB" dml="0110" >

                                <table name="tb01" dml="0000"></table>

                                <table name="tb02" dml="1111"></table>

                        </schema>

                </privileges>

                 -->

        </user>

 

        <!--                         #注意,由於這裏只定義了一個標籤,所以把多餘的都註釋了。如果這個打開,也需要將TESTDB庫改爲和上面一樣的mycat庫名。

        <user name="user">

                <property name="password">user</property>

                <property name="schemas">TESTDB</property>

                <property name="readOnly">true</property>

        </user>

       -->

</mycat:server>

.......

 

重點關注上面這段配置,其他默認即可。

=======================================

參數           說明

user          用戶配置節點

name          登錄的用戶名,也就是連接Mycat的用戶名。

password      登錄的密碼,也就是連接Mycat的密碼

schemas       數據庫名,這裏會和schema.xml中的配置關聯,多個用逗號分開,例如需要這個用戶需要管理兩個數據庫db1,db2,則配置db1,dbs

privileges    配置用戶針對表的增刪改查的權限

readOnly      mycat邏輯庫所具有的權限。true爲只讀,false爲讀寫都有,默認爲false

=======================================

我這裏配置了一個賬號boo,密碼爲bo@123,邏輯數據庫爲mycat,這些信息都可以自己隨意定義,讀寫權限都有,沒有針對表做任何特殊的權限。

注意:

- server.xml文件裏登錄mycat的用戶名和密碼可以任意定義,這個賬號和密碼是爲客戶機登錄mycat時使用的賬號信息。

- 邏輯庫名(如上面的mycat,也就是登錄mycat後顯示的庫名,切換這個庫之後,顯示的就是代理的真實mysql數據庫的表)要在schema.xml裏面也定義,否則會導致mycat服務啓動失敗!

- 這裏只定義了一個標籤,所以把多餘的都註釋了。如果定義多個標籤,即設置多個連接mycat的用戶名和密碼,那麼就需要在schema.xml文件中定義多個對應的庫!

schema.xml是最主要的配置項,此文件關聯mysql讀寫分離策略!讀寫分離、分庫分表策略、分片節點都是在此文件中配置的!
MyCat作爲中間件,它只是一個代理,本身並不進行數據存儲,需要連接後端的MySQL物理服務器,此文件就是用來連接MySQL服務器的!

schemaxml文件中配置的參數解釋

1

2

3

4

參數            說明

schema         數據庫設置,此數據庫爲邏輯數據庫,name與server.xml中schema對應

dataNode       分片信息,也就是分庫相關配置

dataHost       物理數據庫,真正存儲數據的數據庫

配置說明

1

2

3

4

name屬性唯一標識dataHost標籤,供上層的標籤使用。

maxCon屬性指定每個讀寫實例連接池的最大連接。也就是說,標籤內嵌套的

writeHost、readHost標籤都會使用這個屬性的值來實例化出連接池的最大連接數。

minCon屬性指定每個讀寫實例連接池的最小連接,初始化連接池的大小。

每個節點的屬性逐一說明

1

2

3

4

5

schema:

屬性             說明

name               邏輯數據庫名,與server.xml中的schema對應

checkSQLschema     數據庫前綴相關設置,建議看文檔,這裏暫時設爲folse

sqlMaxLimit    select 時默認的limit,避免查詢全表

table

1

2

3

4

5

6

屬性             說明

name               表名,物理數據庫中表名

dataNode       表存儲到哪些節點,多個節點用逗號分隔。節點爲下文dataNode設置的name

primaryKey     主鍵字段名,自動生成主鍵時需要設置

autoIncrement      是否自增

rule               分片規則名,具體規則下文rule詳細介紹

dataNode

1

2

3

4

屬性             說明

name               節點名,與table中dataNode對應

datahost       物理數據庫名,與datahost中name對應

database       物理數據庫中數據庫名

dataHost

1

2

3

4

5

6

屬性             說明

name               物理數據庫名,與dataNode中dataHost對應

balance            均衡負載的方式

writeType      寫入方式

dbType             數據庫類型

heartbeat      心跳檢測語句,注意語句結尾的分號要加

schema.xml文件中有三點需要注意:balance="1",writeType="0" ,switchType="1" 
schema.xml中的balance的取值決定了負載均衡對非事務內的讀操作的處理。balance 屬性負載均衡類型,目前的取值有 4 種:

1

2

3

4

5

6

7

8

9

10

balance="0":      不開啓讀寫分離機制,所有讀操作都發送到當前可用的writeHost 上,即讀請求僅發送到writeHost上。

 

balance="1":      讀請求隨機分發到當前writeHost對應的readHost和standby的writeHost上。即全部的readHost與stand by writeHost 參與

                   select 語句的負載均衡,簡單的說,當雙主雙從模式(M1 ->S1 , M2->S2,並且 M1 與 M2 互爲主備),正常情況下, M2,S1,

                   S2 都參與 select 語句的負載均衡

 

balance="2":      讀請求隨機分發到當前dataHost內所有的writeHost和readHost上。即所有讀操作都隨機的在writeHost、 readhost 上分發。

 

balance="3":      讀請求隨機分發到當前writeHost對應的readHost上。即所有讀請求隨機的分發到 wiriterHost 對應的 readhost 執行,

                   writerHost 不負擔讀壓力,注意 balance=3 只在 1.4 及其以後版本有,1.3 沒有。

writeType 屬性,負載均衡類型,目前的取值有 3 種

1

2

3

writeType="0"   所有寫操作發送到配置的第一個 writeHost,第一個掛了切到還生存的第二個writeHost,重新啓動後已切換後的爲準,切換記錄在配置文件中:dnindex.properties .

writeType="1"   所有寫操作都隨機的發送到配置的 writeHost。

writeType="2"   沒實現。

對於事務內的SQL默認走寫節點

1

2

3

4

5

以 /*balance*/ 開頭,可以指定SQL使用特定負載均衡方案。例如在大環境開啓讀寫分離的情況下,特定強一致性的SQL查詢需求;

slaveThreshold:近似的主從延遲時間(秒)Seconds_Behind_Master < slaveThreshold ,讀請求才會分發到該Slave,確保讀到的數據相對較新。

 

schema.xml中的writeType的取值決定了負載均衡對寫操作的處理:

writeType="0":所有的寫操作都發送到配置文件中的第一個write host。(第一個write host故障切換到第二個後,即使之後修復了仍然維持第二個爲寫庫)。推薦取0值,不建議修改.

主從切換(雙主failover):switchType 屬性

1

2

3

4

5

6

7

8

如果細心觀察schem.xml文件的話,會發現有一個參數:switchType,如下配置:

 <dataHost name="237_15" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native"switchType="1"  slaveThreshold="100">

 

參數解讀

switchType="-1":  不自動切換

switchType="1":   默認值,自動切換

switchType="2":   基於MySQL主從同步的狀態來決定是否切換。需修改heartbeat語句(即心跳語句):show slave status

switchType="3":   基於Mysql Galera Cluster(集羣多節點複製)的切換機制。需修改heartbeat語句(即心跳語句):show status like 'wsrep%'

dbType屬性

1

指定後端連接的數據庫類型,目前支持二進制的mysql協議,還有其他使用JDBC連接的數據庫。例如:mongodb、oracle、spark等。

dbDriver屬性指定連接後端數據庫使用的

1

2

3

4

5

6

7

Driver,目前可選的值有native和JDBC。

 

使用native的話,因爲這個值執行的是二進制的mysql協議,所以可以使用mysql和maridb。

其他類型的數據庫則需要使用JDBC驅動來支持。從1.6版本開始支持postgresql的native原始協議。

 

如果使用JDBC的話需要將符合JDBC 4標準的驅動JAR包放到MYCAT\lib目錄下,並檢查驅動JAR包中包括如下目錄結構的文件:

META-INF\services\java.sql.Driver。在這個文件內寫上具體的Driver類名,例如:com.mysql.jdbc.Driver。

heartbeat標籤

1

2

3

4

5

6

這個標籤內指明用於和後端數據庫進行心跳檢查的語句。例如,MYSQL可以使用select user(),Oracle可以使用select 1 from dual等。

這個標籤還有一個connectionInitSql屬性,主要是當使用Oracla數據庫時,需要執行的初始化SQL

 

語句就這個放到這裏面來。例如:altersession set nls_date_format='yyyy-mm-dd hh24:mi:ss'

 

1.4主從切換的語句必須是:showslave status

writeHost標籤、readHost標籤

1

2

3

4

5

6

這兩個標籤都指定後端數據庫的相關配置給mycat,用於實例化後端連接池。

 

唯一不同的是:writeHost指定寫實例、readHost指定讀實例,組着這些讀寫實例來滿足系統的要求。

 

在一個dataHost內可以定義多個writeHost和readHost。但是,如果writeHost指定的後端數據庫宕機,那麼這個writeHost綁定的所有readHost都將不可用。

另一方面,由於這個writeHost宕機系統會自動的檢測到,並切換到備用的writeHost上去。

應用場景1--->Mycat讀寫分離(負載均衡)、主從自動切換

目前有大量Mycat的生產實踐案例是屬於簡單的讀寫分離類型的,此案例主要用到Mycat的以下特性:
- 讀寫分離支持
- 高可用

大多數讀寫分離的案例是同時支持高可用性的,即Mycat+MySQL主從複製的集羣,並開啓Mycat的讀寫分離功能,這種場景需求下,Mycat是最爲簡單並且功能最爲
豐富的一類Proxy,正常情況下,配置文件也最爲簡單,不用每個表配置,只需要在schema.xml中的元素上增加dataNode=“defaultDN”屬性,並配置此dataNode
對應的真實物理數據庫的database,然後dataHost開啓讀寫分離功能即可。

修改mycat的schema.xml:
balance爲1:讓全部的readHost及備用的writeHost參與select的負載均衡。 
switchType爲2:基於MySQL主從同步的狀態決定是否切換。 
heartbeat:主從切換的心跳語句必須爲show slave status。

僅僅進行讀寫分離的schema.xml配置(備份原來的schema.xml文件,清空,直接複製下面內容):不想要自動切換功能,即MySQL寫節點宕機後不自動切換到備用節點:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[root@Mycat-node conf]# vim schema.xml  

<?xml version="1.0"?>

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">

<mycat:schema xmlns:mycat="http://io.mycat/">

 

        <schema name="mycat" checkSQLschema="false" sqlMaxLimit="100" dataNode="haha">

        </schema>

         

<dataNode name="haha" dataHost="Mycat-node" database="kevin" />

 

    <dataHost name="Mycat-node" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

        <heartbeat>show slave status</heartbeat>   //測試的時候報錯 改爲使用select user();

        <writeHost host="Mysql-node1" url="192.168.10.205:3306" user="root" password="123456">

             <readHost host="Mysql-node2" url="192.168.10.206:3306" user="root" password="123456">

             </readHost>

        </writeHost>

    </dataHost>

 

</mycat:schema>

實現主從自動切換的schema.xml配置:即MySQL寫節點宕機後自動切換到備用節點(也就是把從機也配置成writeHosts):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

[root@Mycat-node conf]# vim schema.xml

<?xml version="1.0"?>

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">

<mycat:schema xmlns:mycat="http://io.mycat/">

 

        <schema name="mycat" checkSQLschema="false" sqlMaxLimit="100" dataNode="haha">

        </schema>

         

<dataNode name="haha" dataHost="Mycat-node" database="kevin" />

 

    <dataHost name="Mycat-node" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

        <heartbeat>show slave status</heartbeat>

        <writeHost host="Mysql-node1" url="192.168.10.205:3306" user="root" password="123456">

             <readHost host="Mysql-node2" url="192.168.10.206:3306" user="root" password="123456">

             </readHost>

<!-#########################-->

<!--這裏有一個坑   因爲前面的時候配置第一個writehost有錯誤 所有後面測試插入的時候寫入的是slave服務器 而

儘管觀察日誌 把第一個writehost改正確以後,還是默認的寫入到了slave服務器 解決辦法是把配置的第二個writehost先註釋掉或者刪除 就會寫入到第一個master服務器數據庫 -->  

        </writeHost>

        <writeHost host="Mysql-node1" url="192.168.10.206:3306" user="root" password="123456">

        </writeHost>

    </dataHost>

 

</mycat:schema>

上面配置中,balance改爲1,表示讀寫分離。
以上配置達到的效果就是192.168.10.205爲主庫,192.168.10.206爲從庫。
注意:要保證192.168.10.205和192.168.10.206機器能使用root/123456權限成功登錄mysql數據庫。同時,也一定要授權mycat機器能使用root/123456權限成功登錄這兩臺機器的mysql數據庫!!這很重要,否則會導致登錄mycat後,對庫和表操作失敗!

一主一從結構是最簡單的配置。 
MyCat支持雙主多從,如果有N個主,那麼就配置N個writeHost兄弟節點;如果有M個從節點,那麼就配置M個readHost節點即可。 
也可以有多臺MySQL服務器,或者SQL Server、Oracle等,配置多個dataHost節點就可以。

需要注意的是:
Mycat主從分離只是在讀的時候做了處理,寫入數據的時候,只會寫入到writehost,需要通過mycat的主從複製將數據複製到readhost!這個問題需要弄明白!!
如果沒有提前做mysql主從複製,會發現Mycat讀寫分離配置後,數據寫入writehost後,readhost一直沒有數據!因爲Mycat就沒有實現主從複製的功能,畢竟數據庫本身自帶的這個功能纔是最高效穩定的。

特別注意:

1

2

3

4

5

6

7

8

9

10

11

1)本案例採用的一主一從模式的兩個mysql實例,並且針對單一的數據庫名進行測試;大多數mycat使用場景都是在多主多從模式並針對多個庫進行的。

2)要想登錄Mycat後看到mysql的真實數據庫的表內容,需要在schema.xml文件中指明database,其中dataNote和dataHost名稱可以自定義,database名稱要是mysql上的庫名。

3)如果針對的是mysql的多個庫,比如mysql的真實庫名是kevin、grace、shanshan,那麼schema.xml文件裏應該指明多個庫名,如:

       在測試時這樣配置時有問題的mycat不能啓動 報錯 找不到響應的datanode節點 

<schema name="mycat" checkSQLschema="false" sqlMaxLimit="100" dataNode="haha,heihei,hengheng">

       </schema>

應該做如下配置 分開配置多個schema 

 

<schema name="mycat" checkSQLschema="false" sqlMaxLimit="100" dataNode="haha">

       </schema>

 

<schema name="mycat2" checkSQLschema="false" sqlMaxLimit="100" dataNode="heihei">

       </schema>

 

<schema name="mycat3" checkSQLschema="false" sqlMaxLimit="100" dataNode="hengheng">

       </schema>

 

 

   <dataNode name="haha" dataHost="Mycat-node" database="kevin" />

   <dataNode name="heihei" dataHost="Mycat-node" database="grace" />

   <dataNode name="hengheng" dataHost="Mycat-node" database="shanshan" />

   ........

4)主從自動切換配置後,第一個writeHost故障後,會自動切換到第二個,第二個故障後自動切換到第三個;

   如果當是1主3從模式,可以把第1個從節點配置爲writeHost 2,第2個和第3個從節點則配置爲writeHost 1的readHost;

Mycat服務啓動

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

[root@Mycat-node ~]# cd /data/mycat/bin/

[root@Mycat-node bin]#

[root@Mycat-node bin]# ./mycat start      #開啓

[root@Mycat-node bin]# ./mycat stop       #關閉

[root@Mycat-node bin]# ./mycat restart    #重啓

[root@Mycat-node bin]# ./mycat status     #查看啓動狀態

[root@Mycat-node bin]# ./mycat console    #前臺運行

[root@Mycat-node bin]# ./mycat pause      #暫停

 

mycat啓動後,執行命令不成功,可能實際上配置有錯誤,導致後面的命令沒有很好的執行。

如果在啓動時發現異常,在logs目錄中查看日誌。

[root@Mycat-node ~]# cd /data/mycat/logs/

[root@Mycat-node logs]# ls

2018-07  mycat.log  mycat.pid  wrapper.log

 

- wrapper.log  爲程序啓動的日誌,啓動時的問題看這個

- mycat.log    爲腳本執行時的日誌,SQL腳本執行報錯後的具體錯誤內容,查看這個文件。mycat.log是最新的錯誤日誌,歷史日誌會根據時間生成目錄保存。

 

[root@Mycat-node conf]# cd /data/mycat/bin/

[root@Mycat-node bin]# ./mycat start

Starting Mycat-server...

[root@Mycat-node bin]# ps -ef|grep cat 

root      5693     1  0 11:28 ?        00:00:00 /data/mycat/bin/./wrapper-linux-x86-64 /data/mycat/conf/wrapper.conf wrapper.syslog.ident=mycat wrapper.pidfile=/data/mycat/logs/mycat.pid wrapper.daemonize=TRUE wrapper.lockfile=/var/lock/subsys/mycat

root      5695  5693 58 11:28 ?        00:00:01 java -DMYCAT_HOME=. -server -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=2G -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1984 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xmx4G -Xms1G -Djava.library.path=lib -classpath lib/wrapper.jar:conf:lib/zookeeper-3.4.6.jar:lib/velocity-1.7.jar:lib/disruptor-3.3.4.jar:lib/hamcrest-library-1.3.jar:lib/curator-client-2.11.0.jar:lib/mysql-binlog-connector-java-0.4.1.jar:lib/curator-framework-2.11.0.jar:lib/wrapper.jar:lib/log4j-1.2.17.jar:lib/kryo-2.10.jar:lib/objenesis-1.2.jar:lib/log4j-core-2.5.jar:lib/log4j-1.2-api-2.5.jar:lib/log4j-slf4j-impl-2.5.jar:lib/leveldb-api-0.7.jar:lib/minlog-1.2.jar:lib/mongo-java-driver-2.11.4.jar:lib/netty-3.7.0.Final.jar:lib/sequoiadb-driver-1.12.jar:lib/libwrapper-linux-x86-64.so:lib/curator-recipes-2.11.0.jar:lib/dom4j-1.6.1.jar:lib/commons-lang-2.6.jar:lib/guava-19.0.jar:lib/commons-collections-3.2.1.jar:lib/reflectasm-1.03.jar:lib/slf4j-api-1.6.1.jar:lib/joda-time-2.9.3.jar:lib/jline-0.9.94.jar:lib/libwrapper-linux-x86-32.so:lib/leveldb-0.7.jar:lib/Mycat-server-1.6-RELEASE.jar:lib/jsr305-2.0.3.jar:lib/libwrapper-linux-ppc-64.so:lib/univocity-parsers-2.2.1.jar:lib/hamcrest-core-1.3.jar:lib/log4j-api-2.5.jar:lib/asm-4.0.jar:lib/mapdb-1.0.7.jar:lib/fastjson-1.2.12.jar:lib/druid-1.0.26.jar:lib/ehcache-core-2.6.11.jar -Dwrapper.key=ZcN0KgylpD8RMkUx -Dwrapper.port=32000 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.pid=5693 -Dwrapper.version=3.2.3 -Dwrapper.native_library=wrapper -Dwrapper.service=TRUE -Dwrapper.cpu.timeout=10 -Dwrapper.jvmid=1 org.tanukisoftware.wrapper.WrapperSimpleApp io.mycat.MycatStartup start

root      5729 24581  0 11:29 pts/0    00:00:00 grep cat

 

Mycat服務端口默認是8066

[root@Mycat-node bin]# lsof -i:8066

COMMAND  PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME

java    5695 root   79u  IPv6 37036522      0t0  TCP *:8066 (LISTEN)[root@Mycat-node conf]# lsof -i:9066

 

Mycat還有一個管理端口,默認是9066

[root@Mycat-node conf]# lsof -i:9066

COMMAND  PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME

java    5695 root   75u  IPv6 37036520      0t0  TCP *:9066 (LISTEN)

在客戶機遠程登錄Mycat登錄mysql(將mycat啓動起來後,遠程連接,默認端口是8066,邏輯庫名和賬號密碼就是在schema.xml裏配置的信息。代碼裏用jdbc方式連接)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

Mycat帶來的最大好處就是:

使用是完全不用修改原有代碼的,在mycat通過命令啓動後,你只需要將數據庫連接切換到Mycat的地址就可以了。

如下面就可以進行連接了(注意使用server.xml文件中定義的用戶名和密碼連接mycat)

登錄mycat的前提是:兩臺mysql機器要授權mycat服務器使用root/123456成功登錄這兩個mysql。

[root@client-server ~]# mysql -h192.168.10.210 -P8066 -ubobo -pbo@123

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB)

 

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

 

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql> show databases;

+----------+

| DATABASE |

+----------+

| mycat    |

+----------+

1 row in set (0.01 sec)

 

mysql> use mycat;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

+-----------------+

1 row in set (0.00 sec)

 

mysql> select * from haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

+----+-------------+

3 rows in set (0.00 sec)

 

mysql>

 Mycat讀寫分離測試

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

將mycat的日誌輸出級別改完debug(默認是info級別),在conf/log4j2.xml裏配置,然後去查詢去添加數據在/logs/mycat.log日誌文件裏查看sql被路由到了

哪個服務器上

 

特別注意:查詢語句不要加事務,否則讀操作會被分發到寫服務器上。

 

[root@Mycat-node ~]# vim /data/mycat/conf/log4j2.xml

......

<asyncRoot level="info" includeLocation="true">

改成

<asyncRoot level="debug" includeLocation="true">

 

重啓mycat服務

[root@Mycat-node ~]# /data/mycat/bin/mycat restart

Stopping Mycat-server...

Stopped Mycat-server.

Starting Mycat-server...

[root@Mycat-node ~]# lsof -i:8066

COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME

java    18955 root   79u  IPv6 3812293      0t0  TCP *:8066 (LISTEN)

 

 

登錄mycat

[root@client-server ~]# mysql -h192.168.10.210 -P8066 -ubobo -pbo@123

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 2

Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB)

 

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

 

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql> show databases;   

+----------+

| DATABASE |

+----------+

| mycat    |

+----------+

1 row in set (0.00 sec)

 

mysql> use mycat;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

+-----------------+

1 row in set (0.00 sec)

 

mysql> select * from haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

+----+-------------+

3 rows in set (0.00 sec)

 

mysql>

 

 

通過mycat寫入一條數據或讀數據,查看sql被路由到了代理的哪個mysql服務器上了:

mysql> insert into kevin.haha values(4,"lihuan");

Query OK, 1 row affected (0.31 sec)

 

mysql> select * from haha;                      

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

|  4 | lihuan      |

+----+-------------+

4 rows in set (0.01 sec)

 

mysql>

 

 

然後查看mycat.log的debug日誌,觀察mysql的sql被路由到了哪個服務器上了(下面日誌中的192.168.10.203是遠程客戶機的ip地址)。

[root@Mycat-node ~]# tail -f /data/mycat/logs/mycat.log

.......

2018-07-31 08:50:12.616 DEBUG [$_NIOREACTOR-1-RW] (io.mycat.server.NonBlockingSession.execute(NonBlockingSession.java:110)) - ServerConnection

[id=2, schema=mycat, host=192.168.10.203, user=bobo,txIsolation=3, autocommit=true, schema=mycat]insert into kevin.haha values(4,"lihuan"),

route={

   1 -> haha{insert into kevin.haha values(4,"lihuan")}

.......

.......

2018-07-31 08:50:12.617 DEBUG [$_NIOREACTOR-1-RW] (io.mycat.backend.mysql.nio.MySQLConnection.synAndDoExecute(MySQLConnection.java:448)) -

con need syn ,total syn cmd 1 commands SET names latin1;schema change:false con:MySQLConnection [id=6, lastTime=1532998212617, user=root,

schema=kevin, old shema=kevin, borrowed=true, fromSlaveDB=false, threadId=55, charset=latin1, txIsolation=3, autocommit=true, attachment=

haha{insert into kevin.haha values(4,"lihuan")}, respHandler=SingleNodeHandler [node=haha{insert into kevin.haha values(4,"lihuan")}, packetId=0],

host=192.168.10.205, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]

.......

.......

2018-07-31 08:50:14.358 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -

release connection MySQLConnection [id=12, lastTime=1532998214353, user=root, schema=kevin, old shema=kevin, borrowed=true, fromSlaveDB=true,

threadId=29, charset=latin1, txIsolation=3, autocommit=true, attachment=haha{select * from haha}, respHandler=SingleNodeHandler [node=haha

{select * from haha}, packetId=8], host=192.168.10.206, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]

 

 

從日誌中可以看出,"insert into ...."插入語句路由到了192.168.10.205的主機上了,"select * ..."的查詢語句路由到了192.168.10.206的從機上了。

這就實現了mysql的讀寫分離!!

 Mycat主從自動切換測試(採用上面自動切換的schema.xml配置)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

首先關閉主機192.168.10.205的mysql服務,此時從機192.168.10.206的mysql已經失去了和主機192.168.10.205的mysql主從關係。

[root@Mysql-node1 ~]# /etc/init.d/mysql stop

Shutting down MySQL............ SUCCESS!

[root@Mysql-node1 ~]# lsof -i:3306

[root@Mysql-node1 ~]#

 

[root@Mysql-node2 ~]# mysql -p123456

........

mysql> show slave status \G;

*************************** 1. row ***************************

.......

             Slave_IO_Running: Connecting

            Slave_SQL_Running: Yes

.......

                Last_IO_Error: error reconnecting to master '[email protected]:3306' - retry-time: 60  retries: 1

 

 

然後客戶機登錄mycat進行讀寫操作

[root@client-server ~]# mysql -h192.168.10.210 -P8066 -ubobo -pbo@123

......

mysql> use mycat; 

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

+-----------------+

1 row in set (0.00 sec)

 

mysql> select * from haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

|  4 | lihuan      |

+----+-------------+

4 rows in set (0.00 sec)

 

mysql> insert into kevin.haha values(5,"gengmei");

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from haha;                       

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

|  4 | lihuan      |

|  5 | gengmei     |

+----+-------------+

5 rows in set (0.00 sec)

 

 

 

同時查看mycat.log的debug日誌,觀察讀寫操作都被路由到哪裏了:

[root@Mycat-node ~]# tail -f /data/mycat/logs/mycat.log

.......

2018-07-31 09:10:19.261  INFO [$_NIOConnector] (io.mycat.net.AbstractConnection.close(AbstractConnection.java:508)) - close connection,reason:java.net.

ConnectException: Connection refused ,MySQLConnection [id=0, lastTime=1532999419254, user=root, schema=kevin, old shema=kevin, borrowed=false, fromSlaveDB=false,

threadId=0, charset=utf8, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=192.168.10.205, port=3306, statusSync=null, writeQueue=0,

modifiedSQLExecuted=false]

2018-07-31 09:10:19.261  INFO [$_NIOConnector] (io.mycat.sqlengine.SQLJob.connectionError(SQLJob.java:114)) - can't get connection for sql :show slave status

.......

2018-07-31 09:06:20.139 DEBUG [$_NIOREACTOR-1-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -

release connection MySQLConnection [id=17, lastTime=1532999180134, user=root, schema=kevin, old shema=kevin, borrowed=true, fromSlaveDB=false,

threadId=46, charset=latin1, txIsolation=3, autocommit=true, attachment=haha{insert into kevin.haha values(5,"gengmei")}, respHandler=SingleNodeHandler

[node=haha{insert into kevin.haha values(5,"gengmei")}, packetId=1], host=192.168.10.206, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]

......

2018-07-31 09:06:21.727 DEBUG [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.MySQLConnection.synAndDoExecute(MySQLConnection.java:448)) - con need syn ,total

syn cmd 1 commands SET names latin1;schema change:false con:MySQLConnection [id=16, lastTime=1532999181727, user=root, schema=kevin, old shema=kevin, borrowed

=true, fromSlaveDB=false, threadId=48, charset=latin1, txIsolation=3, autocommit=true, attachment=haha{select * from haha}, respHandler=SingleNodeHandler [node=

haha{select * from haha}, packetId=0], host=192.168.10.206, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]

 

 

從上面的日誌中可以看出,主機192.168.10.205已經斷開從mycat連接,insert寫語句和select讀語句都被路由分配到了從機192.168.10.206的mysql上了,

這就看出來已經實現了mysql主從啓動切換了!!!

 

 

登錄從機192.168.10.206的mysql,發現新插入的數據已經寫進去了

[root@Mysql-node2 ~]# mysql -p123456

.......

mysql> use kevin;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> select * from kevin.haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

|  4 | lihuan      |

|  5 | gengmei     |

+----+-------------+

5 rows in set (0.00 sec)

 

mysql>

Mycat分表分庫的原理
mycat裏面通過定義路由規則來實現分片表(路由規則裏面會定義分片字段,以及分片算法)。分片算法有多種,你所說的hash是其中一種,還有取模、按範圍分片等等。在mycat裏面,會對所有傳遞的sql語句做路由處理(路由處理的依據就是表是否分片,如果分片,那麼需要依據分片字段和對應的分片算法來判斷sql應該傳遞到哪一個、或者哪幾個、又或者全部節點去執行)

Mycat適用於哪些場景?
數據量大到單機hold不住,而又不希望調整架構切換爲NoSQL數據庫,這個場景下可以考慮適用mycat。當然,使用前也應該做規劃,哪些表需要分片等等。另外mycat對跨庫join的支持不是很好,在使用mycat的時候要注意規避這種場景。

應用場景2--->MYcat分庫分表配置及測試:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

接着上面的操作繼續:

 

啓動主機192.168.10.205的mysql

[root@Mysql-node1 ~]# /etc/init.d/mysql start

Starting MySQL... SUCCESS!

[root@Mysql-node1 ~]# lsof -i:3306

COMMAND   PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME

mysqld  11645 mysql   17u  IPv4 10457025      0t0  TCP *:mysql (LISTEN)

mysqld  11645 mysql   39u  IPv4 10457749      0t0  TCP Mysql-node1:mysql->Mycat-node:39252 (ESTABLISHED)

mysqld  11645 mysql   40u  IPv4 10458099      0t0  TCP Mysql-node1:mysql->Mysql-node1:57270 (ESTABLISHED)

 

登錄從機192.168.10.206的mysql,重啓slave的主從同步關係

[root@Mysql-node2 ~]# mysql -p123456

......

mysql> show slave status \G;

......

             Slave_IO_Running: Connecting

            Slave_SQL_Running: Yes

......

                Last_IO_Error: error reconnecting to master '[email protected]:3306' - retry-time: 60  retries: 81

......

 

 

mysql> stop slave;

Query OK, 0 rows affected (0.08 sec)

 

mysql> start slave;

Query OK, 0 rows affected (0.04 sec)

 

mysql> show slave status \G;

......

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

.....

 

在主機192.168.10.205的mysql上再創建一個數據庫grace

現在需要將haha表放在kevin庫裏,將heihei表拆分放到kevin和grace庫了。

 

操作如下(在主機mysql裏操作,從機mysql自動會同步過來):

登錄grace庫裏創建heihei表,同時在kevin庫裏也創建heihei表。

 

特別需要注意的是:

- 分表的表在創建時一定要創建主鍵,否則在mycat端寫入數據時會報錯主鍵衝突!!

- 分表的表要在兩個庫上都要創建。

 

mysql> CREATE DATABASE grace CHARACTER SET utf8 COLLATE utf8_general_ci;      

Query OK, 1 row affected (0.00 sec)

 

mysql> use grace;

Database changed

 

mysql> CREATE TABLE heihei (

    -> id INT NOT NULL AUTO_INCREMENT,

    -> city varchar(50) NOT NULL,

    -> PRIMARY KEY (id)

    -> )AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.23 sec)

 

mysql> insert into grace.heihei values(1,"beijing");

Query OK, 1 row affected (0.03 sec)

 

mysql> show tables;

+-----------------+

| Tables_in_grace |

+-----------------+

| heihei          |

+-----------------+

1 row in set (0.00 sec)

 

mysql> select * from grace.heihei;    

+----+---------+

id | name    |

+----+---------+

|  1 | beijing |

+----+---------+

1 row in set (0.00 sec)

 

mysql> use kevin;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

+-----------------+

1 row in set (0.00 sec)

 

mysql> CREATE TABLE heihei (

    -> id INT NOT NULL AUTO_INCREMENT,

    -> city varchar(50) NOT NULL,

    -> PRIMARY KEY (id)

    -> )AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.23 sec)

 

mysql> show tables;

+-----------------+

| Tables_in_kevin |

+-----------------+

| haha            |

| heihei          |

+-----------------+

2 rows in set (0.00 sec)

 

mysql> insert into kevin.heihei values(1,"shanghai");    

Query OK, 1 row affected (0.13 sec)

 

mysql> select * from kevin.heihei;

+----+----------+

id | name     |

+----+----------+

|  1 | shanghai |

+----+----------+

1 row in set (0.00 sec)

 

上面在從機的mysql裏操作後,從機的mysql會自動把數據同步過來!

 

 

登錄mycat機器192.168.10.210機器,分別設置server.xml文件、rule.xml文件、schema.xml文件

server.xml文件在上面已經設置過了,這裏就不用修改了:

[root@Mycat-node ~]# vim /data/mycat/conf/server.xml

......

<!-- mycat的服務端口默認爲8066,管理端口默認爲9066 -->

         <property name="serverPort">8066</property> <property name="managerPort">9066</property>

.....

<!-- 任意設置登陸 mycat 的用戶名,密碼,數據庫  -->

        <user name="bobo">

                <property name="password">bo@123</property>

                <property name="schemas">mycat</property>

 

                <!-- 表級 DML 權限設置 -->

                <!--

                <privileges check="false">

                        <schema name="TESTDB" dml="0110" >

                                <table name="tb01" dml="0000"></table>

                                <table name="tb02" dml="1111"></table>

                        </schema>

                </privileges>

                 -->

        </user>

 

         <!--

        <user name="user">

                <property name="password">user</property>

                <property name="schemas">TESTDB</property>

                <property name="readOnly">true</property>

        </user>

       -->

</mycat:server>

 

 

分庫分表配置還涉及到rule.xml文件,配置如下(備份文件,清空,直接複製下面內容):

[root@Mycat-node conf]# cp rule.xml rule.xml.bak

[root@Mycat-node conf]# vim rule.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- - - Licensed under the Apache License, Version 2.0 (the "License");

    - you may not use this file except in compliance with the License. - You

    may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0

    - - Unless required by applicable law or agreed to in writing, software -

    distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT

    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the

    License for the specific language governing permissions and - limitations

    under the License. -->

<!DOCTYPE mycat:rule SYSTEM "rule.dtd">

<mycat:rule xmlns:mycat="http://io.mycat/">

  

    <tableRule name="mycat-rule">                <!-- heihei表分片的規則名,這裏定義爲mycat-rule,這個需要在schema.xml文件中引用 -->

        <rule>

            <columns>id</columns>                  <!--heihei表的分片列 -->

            <algorithm>mod-long</algorithm>

        </rule>

    </tableRule>

  

    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">

        <!-- how many data nodes -->

        <property name="count">2</property>        <!-- count值與分片個數相同,這裏heihei表分片到kevin庫和grace庫裏,共2份。 -->

    </function>

</mycat:rule>

 

 

接着配置schema.xml文件(server.xml文件配置在已經已經完成),分庫分表配置如下

(要將rule.xml裏定義的分片模型寫進去,由於這裏的heihei表配置了主鍵,所以primaryKey="id"這個也寫進去,其他情況看錶結構,也可以不寫):

[root@Mycat-node conf]# cp schema.xml schema.xml.old

[root@Mycat-node conf]# vim schema.xml

<?xml version="1.0"?>

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">

<mycat:schema xmlns:mycat="http://io.mycat/">

  

        <schema name="mycat" checkSQLschema="false" sqlMaxLimit="100">

        <table name="haha" primaryKey="id"  dataNode="kevin_db" />

        <table name="heihei" primaryKey="id" dataNode="kevin_db,grace_db" rule="mycat-rule" />

        </schema>

          

<dataNode name="kevin_db" dataHost="Mycat-node" database="kevin" />

<dataNode name="grace_db" dataHost="Mycat-node" database="grace" />

  

    <dataHost name="Mycat-node" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

        <heartbeat>show slave status</heartbeat>

        <writeHost host="Mysql-node1" url="192.168.10.205:3306" user="root" password="123456">

             <readHost host="Mysql-node2" url="192.168.10.206:3306" user="root" password="123456">

             </readHost>

        </writeHost>

        <writeHost host="Mysql-node1" url="192.168.10.206:3306" user="root" password="123456">

        </writeHost>

    </dataHost>

  

</mycat:schema>

 

 

重啓mycat服務

[root@Mycat-node conf]# /data/mycat/bin/mycat restart

Stopping Mycat-server...

Stopped Mycat-server.

Starting Mycat-server...

[root@Mycat-node conf]# lsof -i:8066                

COMMAND PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME

java    971 root   79u  IPv6 4024290      0t0  TCP *:8066 (LISTEN)

[root@Mycat-node conf]# lsof -i:9066

COMMAND PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME

java    971 root   75u  IPv6 4024288      0t0  TCP *:9066 (LISTEN)

 

 

在客戶機遠程登錄Mycat

[root@client-server ~]# mysql -h192.168.10.210 -P8066 -ubobo -pbo@123

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB)

 

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

 

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql> show databases;

+----------+

| DATABASE |

+----------+

| mycat    |

+----------+

1 row in set (0.01 sec)

 

mysql> use mycat;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+-----------------+

| Tables in mycat |

+-----------------+

| haha            |

| heihei          |

+-----------------+

2 rows in set (0.01 sec)

 

mysql> select * from haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

|  4 | lihuan      |

+----+-------------+

4 rows in set (0.12 sec)

 

mysql> select * from heihei;

+----+----------+

id | city     |

+----+----------+

|  1 | beijing  |

|  1 | shanghai |

+----+----------+

2 rows in set (0.04 sec)

 

mysql>

 

 

分別在mycat裏往heihei和grace.heihei表裏插入一些數據

mysql> insert into haha values(10,"wangbiao");

insert into haha values(11,"zhangcaiyi");Query OK, 1 row affected (0.06 sec)

 

mysql> insert into haha values(11,"zhangcaiyi");

Query OK, 1 row affected (0.06 sec)

 

mysql> insert into heihei(id,city) values(20,"chognqing");        

Query OK, 1 row affected (0.09 sec)

 

mysql> insert into heihei(id,city) values(22,"xianggang");

insert into heihei(id,city) values(28,"chengdu");Query OK, 1 row affected (0.02 sec)

 

mysql> insert into heihei(id,city) values(23,"huoqiu");

Query OK, 1 row affected (0.02 sec)

 

mysql> insert into heihei(id,city) values(24,"haikou");

Query OK, 1 row affected (0.03 sec)

 

mysql> insert into heihei(id,city) values(25,"anqing");

Query OK, 1 row affected (0.03 sec)

 

mysql> insert into heihei(id,city) values(26,"tianqing");

Query OK, 1 row affected (0.02 sec)

 

mysql> insert into heihei(id,city) values(27,"hangzhou");

Query OK, 1 row affected (0.04 sec)

 

mysql> insert into heihei(id,city) values(28,"chengdu");

Query OK, 1 row affected (0.26 sec)

 

特別注意:

1)在配置了sharding分片策略之後(如heihei表),mycat裏分片的表做插入數據時,即使插入所有字段的數據,也一定要在表名後面寫明插入數據的字段名稱,

   否則插入數據會報錯:ERROR 1064 (HY000): partition table, insert must provide ColumnList

2)沒有配置sharding分片策略的表(如haha表),插入所有字段的數據時,表名後面不需要寫明字段名稱,默認就是所有字段插入數據,如上面的haha表。

 

   

登錄主機和從機,查看從mycat端寫入的數據

mysql> select * from kevin.haha;

+----+-------------+

id | name        |

+----+-------------+

|  1 | wangshibo   |

|  2 | linan       |

|  3 | zhangminmin |

|  4 | lihuan      |

| 10 | wangbiao    |

| 11 | zhangcaiyi  |

+----+-------------+

6 rows in set (0.00 sec)

 

mysql> select * from grace.heihei;

+----+-----------+

id | city      |

+----+-----------+

|  1 | beijing   |

| 21 | guangzhou |

| 23 | huoqiu    |

| 25 | anqing    |

| 27 | hangzhou  |

+----+-----------+

5 rows in set (0.00 sec)

 

mysql> select * from kevin.heihei;    

+----+-----------+

id | city      |

+----+-----------+

|  1 | shanghai  |

| 20 | chognqing |

| 22 | xianggang |

| 24 | haikou    |

| 26 | tianqing  |

| 28 | chengdu   |

+----+-----------+

6 rows in set (0.00 sec)

 

mysql>

 

從上面可以看出:

在mycat裏往做了sharding分片策略的heihei表裏寫入的數據,已經分片到kevin和grace兩個庫裏了,即成功實現了分庫分表功能!

 

查看mycat的debug日誌,可以觀察到mysql讀寫分離和分庫分表情況

[root@Mycat-node logs]# tail -f mycat.log

這裏需要注意:
-  查詢語句不要加事務,否則讀操作會被分發到寫服務器上。
-  主從複製是mysql自己實現的,mycat只是代理插件,它本身不能實現主從複製,只能實現了讀寫分離、主從切換、分庫分表功能。

爲了提升查詢的性能,有人創新的設計了一種MySQL主從複製的模式,主節點爲InnoDB引擎,讀節點爲MyISAM引擎,經過實踐,發現查詢性能提升不少。

此外,爲了減少主從複製的時延,也建議採用MySQL 5.6+的版本,用GTID同步複製方式減少複製的時延,可以將一個Database中的表,根據寫頻率的不同,
分割成幾個Database,用Mycat虛擬爲一個Database,這樣就滿足了多庫併發複製的優勢,需要注意的是,要將有Join關係的表放在同一個庫中。

對於某些表,要求不能有複製時延,則可以考慮這些表放到Gluster集羣裏,消除同步複製的時延問題,前提是這些表的修改操作並不很頻繁,需要做性能測試,
以確保能滿足業務高峯。

總結一下,Mycat做讀寫分離和高可用,可能的方案很靈活,只有你沒想到的,沒有做不到的。

=================Mycat常見問題及注意點==================
1)Mycat自動切換需要人工處理麼?
Mycat通過心跳檢測,自主切換數據庫,保證高可用性,無須手動切換。

2)Mycat支持集羣麼?
目前Mycat沒有實現對多Mycat集羣的支持,可以暫時使用haproxy來做負載,或者統計硬件負載。

3)Mycat目前有生產案例了麼?
目前Mycat初步統計大概600家公司使用。

4)Mycat穩定性與Cobar如何?
目前Mycat穩定性優於Cobar,而且一直在更新,Cobar已經停止維護,可以放心使用。

5)Mycat除了Mysql還支持哪些數據庫?
mongodb、oracle、sqlserver 、hive 、db2 、 postgresql。

6)Mycat如何配置字符集?
在配置文件server.xml配置,默認配置爲utf8。

7)Mycat後臺管理監控如何使用?
9066端口可以用JDBC方式執行命令,在界面上進行管理維護,也可以通過命令行查看命令行操作。 
命令行操作是:mysql -h127.0.0.1 -utest -ptest -P9066 登陸,然後執行相應命令。

8)Mycat主鍵插入後應用如何獲取?
獲得自增主鍵,插入記錄後執行select last_insert_id()獲取。

9)Mycat運行sql時經常阻塞或卡死是什麼原因?
如果出現執行sql語句長時間未返回,或卡死,請檢查是否是虛機下運行或cpu爲單核。如果仍舊無法解決,可以暫時跳過,目前有些環境阻塞卡死原因未知。

10)Mycat中,舊系統數據如何遷移到Mycat中?
舊數據遷移目前可以手工導入,在mycat中提取配置好分配規則及後端分片數據庫,然後通過dump或loaddata方式導入,後續Mycat就做舊數據自動數據遷移工具。

11)Mycat如何對舊分片數據遷移或擴容,支持自動擴容麼?
目前除了一致性hash規則分片外其他數據遷移比較困難,目前暫時可以手工遷移,未提供自動遷移方案,具體遷移方案情況Mycat權威指南對應章節。

12)Mycat支持批量插入嗎?
目前Mycat1.3.0.3以後支持多values的批量插入,如insert into(xxx) values(xxx),(xxx) 。

13)Mycat支持多表Join嗎?
Mycat目前支持2個表Join,後續會支持多表Join,具體Join請看Mycat權威指南對應章節。

14)Mycat 啓動報主機不存在的問題?
需要添加ip跟主機的映射。

15)Mycat連接會報無效數據源(Invalid datasource)?
例如報錯:mysql> select * from company; 
ERROR 3009 (HY000): java.lang.IllegalArgumentException: Invalid DataSource:0 
這類錯誤最常見是一些配置問題例如schema.xml中的dataNode的配置和實際不符合,請先仔細檢查配置項,確保配置沒有問題。
如果不是配置問題,分析具體日誌看出錯原因,常見的有: 
- 如果是應用連:在某些版本的Mysql驅動下連接Mycat會報錯,可升級最新的驅動包試下。 
- 如果是服務端控制檯連,確認mysql是否開啓遠程連接權限,或防火牆是否設置正確,或者數據庫database是否配置,或用戶名密碼是否正確。

16)Mycat支持的或者不支持的語句有哪些?
insert into,複雜子查詢,3表及其以上跨庫join等不支持。

17)MycatJDBC連接報 PacketTooBigException異常
檢查mysqljdbc驅動的版本,在使用mycat1.3和mycat1.4版本情況下,不要使用jdbc5.1.37和38版本的驅動,會出現如下異常報錯:
com.mysql.jdbc.PacketTooBigException: Packet for query is too large (60 > -1). You can change this value on the server by setting the max_allowed_packet’ variable。
建議使用jdbc5.1.35或者36的版本。

18)Mycat中文亂碼的問題
答:如果在使用mycat出現中文插入或者查詢出現亂碼,請檢查三個環節的字符集設置:
a)客戶端環節(應用程序、mysql命令或圖形終端工具)連接mycat字符集
b)mycat連接數據庫的字符集
c)數據庫(mysql,oracle)字符集。這三個環節的字符集如果配置一致,則不會出現中文亂碼,其中尤其需要注意的是客戶端連接mycat時使用的連接字符集,
通常的中文亂碼問題一般都由此處設置不當引出。其中mycat內部默認使用utf8字符集,在最初啓動連接數據庫時,mycat會默認使用utf8去連接數據庫,當客戶
端真正連接mycat訪問數據庫時,mycat會使用客戶端連接使用的字符集修改它連接數據庫的字符集,在mycat環境的管理9066端口,可以通過"show @@backend"命令
查看後端數據庫的連接字符集,通過show @@connection命令查看前端客戶端的連接字符集。客戶端的連接可以通過指定字符集編碼或者發送SET命令指定連接mycat
時connection使用的字符集,常見客戶端連接指定字符集寫法如下: 
-   jdbcUrl=jdbc:mysql://localhost:8066/databaseName? characterEncoding=iso_1 
-   SET character_set_client = utf8;用來指定解析客戶端傳遞數據的編碼 
    SET character_set_results = utf8;用來指定數據庫內部處理時使用的編碼 
    SET character_set_connection = utf8;用來指定數據返回給客戶端的編碼方式 
-   mysql –utest –ptest –P8066 –default-character-set=gbk

19)Mycat無法登陸Access denied
Mycat正常安裝配置完成,登陸mycat出現以下錯誤: 
[mysql@master ~]$ mysql -utest -ptest -P8066 
ERROR 1045 (28000): Access denied for user 'test’@’localhost’ (using password: YES) 
請檢查在schema.xml中的相關dataHost的mysql主機的登陸權限,一般都是因爲配置的mysql的用戶登陸權限不符合,mysql用戶權限管理不熟悉的請自己度娘。
只有一種情況例外,mycat和mysql主機都部署在同一臺設備,其中主機localhost的權限配置正確,使用-hlocalhost能正確登陸mysql但是無法登陸mycat的情況,
請使用-h127.0.0.1登陸,或者本地網絡實際地址,不要使用-hlocalhost,很多使用者反饋此問題,原因未明。

20)Mycat的分片數據插入報異常IndexOutofBoundException
在一些配置了分片策略的表進行數據插入時報錯,常見的報錯信息如下:java.lang.IndexOutOfBoundsException:Index:4,size:3
這類報錯通常由於分片策略配置不對引起,請仔細檢查並理解分片策略的配置,例如:使用固定分片hash算法,PartitionByLong策略,如果schema.xml裏面設置
的分片數量dataNode和rule.xml配置的partitionCount 分片個數不一致,尤其是出現分片數量dataNode小於partitionCount數量的情況,插入數據就可能會報錯。
很多使用者都沒有仔細理解文檔中對分片策略的說明,用默認rule.xml配置的值,沒有和自己實際使用環境進行參數覈實就進行分片策略使用造成這類問題居多。

21)Mycat ER分片子表數據插入報錯
一般都是插入子表時出現不能找到父節點的報錯。報錯信息如: [Err] 1064 - can’t find (root) parent sharding node for sql:。
此類ER表的插入操作不能做爲一個事務進行數據提交,如果父子表在一個事務中進行提交,顯然在事務沒有提交前子表是無法查到父表的數據的,因此就無法確定
sharding node。如果是ER關係的表在插入數據時不能在同一個事務中提交數據,只能分開提交。

22)Mycat最大內存無法調整至4G以上
mycat1.4的JVM使用最大內存調整如果超過4G大小,不能使用wrapper.java.maxmemory參數,需要使用wrapper.java.additional的寫法,注意將
wrapper.java.maxmemory參數註釋,例如增加最大內存至8G:wrapper.java.additional.10=-Xmx8G。

23)Mycat使用過程中報錯怎麼辦
記住無論什麼時候遇到報錯,如果不能第一時間理解報錯的原因,首先就去看日誌,無論是啓動(wrapper.log)還是運行過程中(mycat.log),請相信良好的
日誌是編程查錯的終極必殺技。日誌如果記錄信息不夠,可以調整conf/log4j.xml中的level級別至debug,所有的詳細信息均會記錄。另外如果在羣裏面提問,
儘量將環境配置信息和報錯日誌提供清楚,這樣別人才能快速幫你定位問題。

***************當你發現自己的才華撐不起野心時,就請安靜下來學習吧***************

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章