簡介 Schema.xml 作為 MyCat 中重要的配置文件之一,管理著 MyCat 的邏輯庫、表、分片規則、DataNode 以及 DataSource。弄懂這些配置,是正確使用 MyCat 的前提。這裡就一層層對該文件進行解析。 schema 標簽 schema 標簽用於定義 MyCat 實例 ...
簡介
Schema.xml 作為 MyCat 中重要的配置文件之一,管理著 MyCat 的邏輯庫、表、分片規則、DataNode 以及 DataSource。弄懂這些配置,是正確使用 MyCat 的前提。這裡就一層層對該文件進行解析。
schema 標簽
schema 標簽用於定義 MyCat 實例中的邏輯庫,如:
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"></schema>
name屬性
配置邏輯庫的名字(即資料庫實例名);
dataNode屬性
用於配置該邏輯庫預設的分片。沒有通過table標簽配置的表,就會走到預設的分片上。這裡註意沒有配置在table標簽的表,用工具查看是無法顯示的,但是可以正常使用。
如果沒有配置dataNode屬性,則沒有配置在table標簽的表,是無法使用的。註意,dual表在mycat中,也被視為一個表。
另外,通過mycat建表,而該表並沒有提前配置table標簽,則mycat會找到預設的dataNode,並把表建在預設的dataNode上。如果沒有配置預設dataNode,則mycat會報錯。
而如果該表有配置table標簽,則表會分別在table標簽指定的dataNode上建表。
checkSQLschema屬性
當該值設置為 true 時,如果我們執行語句select * from TESTDB.travelrecord;則 MyCat 會把語句修改
為select * from travelrecord;。即把表示 schema 的字元去掉,避免發送到後端資料庫執行時報(ERROR
1146 (42S02): Table ‘testdb.travelrecord’ doesn’t exist)。 不過,即使設置該值為 true ,如果語句所帶的是並非是 schema 指定的名字,例如:select * from
db1.travelrecord; 那麼 MyCat 並不會刪除 db1 這個欄位,如果沒有定義該庫的話則會報錯,所以在提供 SQL
語句的最好是不帶這個欄位。
false:會報錯
sqlMaxLimit屬性
當該值設置為某個數值時。每條執行的 SQL 語句,如果沒有加上 limit 語句,MyCat 也會自動的加上所對應
的值。例如設置值為 100,執行select * from TESTDB.travelrecord;的效果為和執行select * from
TESTDB.travelrecord limit 100;相同。
設置該值的話,MyCat 預設會把查詢到的信息全部都展示出來,造成過多的輸出。所以,在正常使用中,還
是建議加上一個值,用於減少過多的數據返回。
72
當然 SQL 語句中也顯式的指定 limit 的大小,不受該屬性的約束。
需要註意的是,如果運行的 schema 為非拆分庫的,那麼該屬性不會生效。需要手動添加 limit 語句。
table 標簽
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" ></table>
name 屬性
定義邏輯表的表名,這個名字就如同我在資料庫中執行 create table 命令指定的名字一樣,同個 schema 標
簽中定義的名字必須唯一。
dataNode 屬性
定義這個邏輯表所屬的 dataNode, 該屬性的值需要和 dataNode 標簽中 name 屬性的值相互對應。如果需
要定義的 dn 過多 可以使用如下的方法減少配置:
```xml
<table name="travelrecord" dataNode="multipleDn$0-99,multipleDn2$100-199" rule="auto-shardinglong" ></table>
<dataNode name="multipleDn$0-99" dataHost="localhost1" database="db$0-99" ></dataNode>
<dataNode name="multipleDn2$100-199" dataHost="localhost1" database=" db$100-199" ></dataNode>
```
這裡需要註意的是 database 屬性所指定的真實 database name 需要在後面添加一個,例如上面的例子中,
我需要在真實的 mysql 上建立名稱為 dbs0 到 dbs99 的 database。
rule 屬性
該屬性用於指定邏輯表要使用的規則名字,規則名字在 rule.xml 中定義,必須與 tableRule 標簽中 name 屬
性屬性值一一對應。
ruleRequired 屬性
該屬性用於指定表是否綁定分片規則,如果配置為 true,但沒有配置具體 rule 的話 ,程式會報錯
primaryKey 屬性
該邏輯表對應真實表的主鍵,例如:分片的規則是使用非主鍵進行分片的,那麼在使用主鍵查詢的時候,就
會發送查詢語句到所有配置的 DN 上,如果使用該屬性配置真實表的主鍵。難麽 MyCat 會緩存主鍵與具體 DN 的
信息,那麼再次使用非主鍵進行查詢的時候就不會進行廣播式的查詢,就會直接發送語句給具體的 DN,但是儘管
配置該屬性,如果緩存並沒有命中的話,還是會發送語句給具體的 DN,來獲得數據。
type 屬性
該屬性定義了邏輯表的類型,目前邏輯表只有“全局表”和”普通表”兩種類型。對應的配置:
全局表:global。
普通表:不指定該值為 globla 的所有表。
autoIncrement 屬性
mysql 對非自增長主鍵,使用 last_insert_id()是不會返回結果的,只會返回 0。所以,只有定義了自增長主
鍵的表才可以用 last_insert_id()返回主鍵值。
mycat 目前提供了自增長主鍵功能,但是如果對應的 mysql 節點上數據表,沒有定義 auto_increment,那
麽在 mycat 層調用 last_insert_id()也是不會返回結果的。
由於 insert 操作的時候沒有帶入分片鍵,mycat 會先取下這個表對應的全局序列,然後賦值給分片鍵。這樣
才能正常的插入到資料庫中,最後使用 last_insert_id()才會返回插入的分片鍵值。
如果要使用這個功能最好配合使用資料庫模式的全局序列。
74
使用 autoIncrement=“true” 指定這個表有使用自增長主鍵,這樣 mycat 才會不拋出分片鍵找不到的異
常。
使用 autoIncrement=“false” 來禁用這個功能,當然你也可以直接刪除掉這個屬性。預設就是禁用的。
subTables
使用方式添加 subTables="t_order$1-2,t_order3"。
目前分表 1.6 以後開始支持 並且 dataNode 在分表條件下只能配置一個,分表條件下不支持各種條件的join 語句。
needAddLimit 屬性
指定表是否需要自動的在每個語句後面加上 limit 限制。由於使用了分庫分表,數據量有時會特別巨大。這時候執行查詢語句,如果恰巧又忘記了加上數量限制的話。那麼查詢所有的數據出來,也夠等上一小會兒的。
所以,mycat 就自動的為我們加上 LIMIT 100。當然,如果語句中有 limit,就不會在次添加了。這個屬性預設為 true,你也可以設置成 false`禁用掉預設行為。
childTable 標簽
childTable 標簽用於定義 E-R 分片的子表。通過標簽上的屬性與父表進行關聯。
childTable 標簽的相關屬性:
屬性名 | 值 | 數量限制 |
---|---|---|
name | String | (1) |
joinKey | String | (1) |
parentKey | String | (1) |
primaryKey | String | (0..1) |
needAddLimit | boolean | (0..1) |
name 屬性
定義子表的表名。
joinKey 屬性
插入子表的時候會使用這個列的值查找父表存儲的數據節點。
parentKey 屬性
屬性指定的值一般為與父表建立關聯關係的列名。程式首先獲取 joinkey 的值,再通過 parentKey 屬性指定的列名產生查詢語句,通過執行該語句得到父表存儲在哪個分片上。從而確定子表存儲的位置。
primaryKey 屬性
同 table 標簽所描述的。
needAddLimit 屬性
同 table 標簽所描述的。
dataNode 標簽
<dataNode name="dn1" dataHost="lch3307" database="db1" ></dataNode>
dataNode 標簽定義了 MyCat 中的數據節點,也就是我們通常說所的數據分片。一個 dataNode 標簽就是
一個獨立的數據分片。
例子中所表述的意思為:使用名字為 lch3307 資料庫實例上的 db1 物理資料庫,這就組成一個數據分片,最後,我們使用名字 dn1 標識這個分片。
dataNode 標簽的相關屬性:
屬性 | 值 | 數量限制 |
---|---|---|
name | String | (1) |
dataHost | String | (1) |
database | String | (1) |
name 屬性
定義數據節點的名字,這個名字需要是唯一的,我們需要在 table 標簽上應用這個名字,來建立表與分片對應的關係。
dataHost 屬性
該屬性用於定義該分片屬於哪個資料庫實例的,屬性值是引用 dataHost 標簽上定義的 name 屬性。
database 屬性
該屬性用於定義該分片屬性哪個具體資料庫實例上的具體庫,因為這裡使用兩個緯度來定義分片,就是:實 例+具體的庫。因為每個庫上建立的表和表結構是一樣的。所以這樣做就可以輕鬆的對錶進行水平拆分。
dataHost 標簽
作為 Schema.xml 中最後的一個標簽,該標簽在 mycat 邏輯庫中也是作為最底層的標簽存在,直接定義了具體的資料庫實例、讀寫分離配置和心跳語句。現在我們就解析下這個標簽。
dataHost 標簽的相關屬性:
屬性名 | 值 | 數量限制 |
---|---|---|
name | String | (1) |
maxCon | Integer | (1) |
minCon | Integer | (1) |
balance | Integer | (1) |
writeType | Integer | (1) |
dbType | String | (1) |
dbDriver | String | (1) |
name 屬性
唯一標識 dataHost 標簽,供上層的標簽使用。
maxCon 屬性
指定每個讀寫實例連接池的最大連接。也就是說,標簽內嵌套的 writeHost、readHost 標簽都會使用這個屬性的值來實例化出連接池的最大連接數。
minCon 屬性
指定每個讀寫實例連接池的最小連接,初始化連接池的大小。
balance 屬 性
負載均衡類型,目前的取值有 3 種:
balance="0", 不開啟讀寫分離機制,所有讀操作都發送到當前可用的 writeHost 上。
- balance="1",全部的 readHost 與 stand by writeHost 參與 select 語句的負載均衡,簡單的說,當雙主雙從模式(M1->S1,M2->S2,並且 M1 與 M2 互為主備),正常情況下,M2,S1,S2 都參與 select 語句的負載均衡。
- balance="2",所有讀操作都隨機的在 writeHost、readhost 上分發。
balance="3",所有讀請求隨機的分發到 wiriterHost 對應的 readhost 執行,writerHost 不負擔讀壓力,註意 balance=3 只在 1.4 及其以後版本有,1.3 沒有。
writeType 屬性
負載均衡類型,目前的取值有 3 種:
writeType="0", 所有寫操作發送到配置的第一個 writeHost,第一個掛了切到還生存的第二個writeHost,重新啟動後已切換後的為準,切換記錄在配置文件中:dnindex.properties .
writeType="1",所有寫操作都隨機的發送到配置的 writeHost,1.5 以後廢棄不推薦。
switchType 屬性
- -1 表示不自動切換。
- 1 預設值,自動切換。
- 2 基於 MySQL 主從同步的狀態決定是否切換。
dbType 屬性
指定後端連接的資料庫類型,目前支持二進位的 mysql 協議,還有其他使用 JDBC 連接的資料庫。例如:
mongodb、oracle、spark 等。
dbDriver 屬性
指定連接後端資料庫使用的 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。
switchType 屬性
-1 表示不自動切換
1 預設值,自動切換
2 基於 MySQL 主從同步的狀態決定是否切換心跳語句為 show slave status
3 基於 MySQL galary cluster 的切換機制(適合集群)(1.4.1) 心跳語句為 show status like ‘wsrep%’
tempReadHostAvailable 屬性
如果配置了這個屬性 writeHost 下麵的 readHost 仍舊可用,預設 0 可配置(0、1)。
heartbeat 標簽
這個標簽內指明用於和後端資料庫進行心跳檢查的語句。例如,MYSQL 可以使用 select user(),Oracle 可以使用 select 1 from dual 等。
這個標簽還有一個 connectionInitSql 屬性,主要是當使用 Oracla 資料庫時,需要執行的初始化 SQL 語句就這個放到這裡面來。例如:alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'
1.4 主從切換的語句必須是:show slave status
writeHost 標簽、readHost 標簽
這兩個標簽都指定後端資料庫的相關配置給 mycat,用於實例化後端連接池。唯一不同的是,writeHost 指定寫實例、readHost 指定讀實例,組著這些讀寫實例來滿足系統的要求。
在一個 dataHost 內可以定義多個 writeHost 和 readHost。但是,如果 writeHost 指定的後端資料庫宕機, 那麼這個 writeHost 綁定的所有 readHost 都將不可用。另一方面,由於這個 writeHost 宕機系統會自動的檢測到,並切換到備用的 writeHost 上去。
這兩個標簽的屬性相同,這裡就一起介紹。
host 屬性
用於標識不同實例,一般 writeHost 我們使用M1,readHost 我們用S1。
url 屬性
後端實例連接地址,如果是使用 native 的 dbDriver,則一般為 address:port 這種形式。用 JDBC 或其他的
dbDriver,則需要特殊指定。當使用 JDBC 時則可以這麼寫:jdbc:mysql://localhost:3306/。
user 屬性
後端存儲實例需要的用戶名字。
password 屬性
後端存儲實例需要的密碼。
weight 屬性
權重 配置在 readhost 中作為讀節點的權重(1.4 以後)。
usingDecrypt 屬性
是否對密碼加密預設 0 否 如需要開啟配置 1,同時使用加密程式對密碼加密,加密命令為: 執行 mycat jar 程式(1.4.1 以後):