先上官方文檔:html
由上圖能夠看到 Mycat 的核心配置文件均採用xml格式,這幾個配置文件的用途以下:前端
server.xml
:用於配置系統參數、用戶信息、訪問權限及SQL防火牆和SQL攔截功能等schema.xml
:用於配置邏輯庫、邏輯表相關信息rule.xml
:若是使用了水平切分,就須要使用該文件配置切分規則log4j2.xml
:Mycat日誌相關的配置,例如日誌輸出格式、日誌級別等應用鏈接Mycat服務時,Mycat首先會經過server.xml
中的配置信息進行用戶認證。用戶經過驗證後,所看到的邏輯庫、邏輯表都是schema.xml
中所配置的。當使用了水平切分時,Mycat會經過rule.xml
裏配置的規則來定位具體的物理數據庫位置,從而完成寫入/讀取數據。java
system
標籤用於配置 Mycat 的系統參數,其格式以下:mysql
<system> <!-- ${key}表示配置屬性的名稱,${value}表示該配置屬性的值 --> <property name="${key}">${value}</property> </system>
配置 Mycat 服務端口示例:git
<system> <property name="serverPort">3306</property> </system>
常見的系統參數舉例:github
<system> <!-- mycat 服務鏈接端口 --> <property name="serverPort">8066</property> <!-- mycat 服務管理端口 --> <property name="managerPort">9066</property> <!-- mycat 服務監聽的ip --> <property name="bindIp">0.0.0.0</property> <!-- 0爲須要密碼登錄、1爲不須要密碼登錄;默認爲0,設置爲1則須要指定默認帳戶--> <property name="nonePasswordLogin">0</property> <!-- 前端鏈接的寫隊列大小 --> <property name="frontWriteQueueSize">2048</property> <!-- 設置字符集編碼 --> <property name="charset">utf8</property> <!-- mycat 的進程數量 --> <property name="processors">8</property> <!-- 閒置鏈接超時時間,單位:毫秒 --> <property name="idleTimeout">1800000</property> <!-- 默認最大返回的數據集大小 --> <property name="defaultMaxLimit">100</property> <!-- 容許的最大包大小 --> <property name="maxPacketSize">104857600</property> <!-- 0趕上沒有實現的報文(Unknown command:),就會報錯、1爲忽略該報文,返回ok報文。 在某些mysql客戶端存在客戶端已經登陸的時候還會繼續發送登陸報文,mycat會報錯,該設置能夠繞過這個錯誤--> <property name="ignoreUnknownCommand">0</property> <property name="useHandshakeV10">1</property> <property name="removeGraveAccent">1</property> <!-- 1爲開啓實時統計、0爲關閉 --> <property name="useSqlStat">0</property> <!-- 1爲開啓全加班一致性檢測、0爲關閉 --> <property name="useGlobleTableCheck">0</property> <!-- SQL 執行超時 單位:秒--> <property name="sqlExecuteTimeout">300</property> <property name="sequnceHandlerType">1</property> <!--必須帶有MYCATSEQ_或者 mycatseq_進入序列匹配流程 注意MYCATSEQ_有空格的狀況--> <property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property> <!-- 子查詢中存在關聯查詢的狀況下,檢查關聯字段中是否有分片字段 .默認 false --> <property name="subqueryRelationshipCheck">false</property> <property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property> <!--默認爲type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool --> <property name="processorBufferPoolType">0</property> <!--分佈式事務開關,0爲不過濾分佈式事務,1爲過濾分佈式事務(若是分佈式事務內只涉及全局表,則不過濾),2爲不過濾分佈式事務,可是記錄分佈式事務日誌--> <property name="handleDistributedTransactions">0</property> <!-- off heap for merge/order/group/limit 1開啓;0關閉 --> <property name="useOffHeapForMerge">0</property> <!--是否採用zookeeper協調切換 --> <property name="useZKSwitch">false</property> <!--若是爲 true的話 嚴格遵照隔離級別,不會在僅僅只有select語句的時候在事務中切換鏈接--> <property name="strictTxIsolation">false</property> <!-- Mycat鏈接數據庫時使用的隔離級別 1 - 讀未提交 2 - 讀已提交 3 - 可重複讀 4 - 串行化 --> <property name="txIsolation">2</property> <property name="useZKSwitch">true</property> <!--若是爲0的話,涉及多個DataNode的catlet任務不會跨線程執行--> <property name="parallExecute">0</property> </system>
user
標籤用於配置Mycat的訪問用戶及權限,其格式以下:算法
<user name=${username}> <property name="${key}">${value}</property> ... </user>
配置示例:sql
<!-- 用戶名 --> <user name="mall"> <!-- 密碼 --> <property name="password">123456</property> <!-- 容許該用戶訪問的邏輯庫 --> <property name="schemas">mall_db</property> <!-- 可配置多個容許訪問的邏輯庫,使用逗號分隔 --> <!-- <property name="schemas">mall_db,db1,db2</property> --> <!-- 是否只讀 --> <property name="readOnly">false</property> </user>
除了配置對庫的權限可能還不夠,有時候咱們須要配置用戶對某些表的訪問權限。以下示例:數據庫
<!-- 用戶名 --> <user name="mall"> <!-- 密碼 --> <property name="password">123456</property> <!-- 容許該用戶訪問的邏輯庫 --> <property name="schemas">mall_db,db1,db2</property> <!-- 表級 DML 權限配置,check屬性表示是否開啓該配置 --> <privileges check="true"> <!-- 特別權限應用的邏輯庫 --> <schema name="mall_db" dml="0110"> <!-- 配置用戶對該表的訪問權限,dml屬性用於指定權限位, 若是table標籤沒有配置該屬性的話,默認取schema標籤的dml屬性值, 剩餘沒有配置的其餘表默認也是取schema標籤的dml屬性值 --> <table name="user_table" dml="0000"></table> <table name="order_table" dml="1111"></table> </schema> </privileges> </user>
dml
屬性配置的數字是權限位,分別對應着insert,update,select,delete
四種權限。例如,當dml
的值爲0110
時,表示擁有update
和select
權限,不具備insert
和delete
權限。因此權限位爲1
時表明擁有對應的操做權限,爲0
時表明沒有該操做權限。apache
在該示例中,mall
用戶對:
user_table
表不具備任何操做權限order_table
表擁有全部操做權限update
和select
權限以上配置用戶的示例中,密碼都是以明文的形式寫在配置文件中。但用戶的密碼是安全敏感的,通常不會直接在配置文件中寫明文密碼,而是寫一個加密事後的密碼。不然只要擁有查看server.xml
文件的權限,就能輕易獲取到各個用戶的密碼,這是很是不安全的。
所以,Mycat 提供了一個工具用於加密明文密碼,該工具在一個jar包內,可以使用以下命令對密碼進行加密:
[root@txy-server /usr/local/mycat]# java -cp lib/Mycat-server-1.6.7.4-release.jar io.mycat.util.DecryptUtil 0:root:123456
參數說明:
0
:表明的是mycat用戶登陸密碼加密(1
則是dataHost
加密)root
:用戶名123456
:明文密碼執行成功後,會獲得一個加密後的字符串:
GO0bnFVWrAuFgr1JMuMZkvfDNyTpoiGU7n/Wlsa151CirHQnANVk3NzE3FErx8v6pAcO0ctX3xFecmSr+976QA==
複製該字符串,替換配置文件中的明文密碼,以下示例:
<user name="root" defaultAccount="true"> <!-- 須要聲明使用的是加密後的密碼 --> <property name="usingDecrypt">1</property> <property name="password">GO0bnFVWrAuFgr1JMuMZkvfDNyTpoiGU7n/Wlsa151CirHQnANVk3NzE3FErx8v6pAcO0ctX3xFecmSr+976QA==</property> ... </user>
咱們都知道Mycat是使用Java進行開發的,因此其日誌框架也是使用Java生態圈內的log4j2
。Mycat日誌相關的配置都在 log4j2.xml
文件中,本小節將介紹一些經常使用的配置項。
Pattern
標籤用於配置 Mycat 日誌輸出格式,默認以下:
<PatternLayout> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] (%l) - %m%n</Pattern> </PatternLayout>
%d{yyyy-MM-dd HH:mm:ss.SSS}
:日誌的時間格式%5p
:輸出的日誌的級別%t
:輸出日誌的線程名稱%l
:日誌輸出語句所在的代碼位置%m
:輸出代碼中指定的日誌內容%n
:輸出一個換行符更多Pattern取值詳見官方文檔
這裏截取了一段 Mycat 的日誌內容,能夠看到與Pattern是一一對應上的:
2020-01-09 15:22:57.960 INFO [Timer1] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:564)) - no ilde connection in pool 1838161857 ,create new connection for hostM1 of schema db3 totalConnectionCount: 0 increamentCount: 1
level
屬性用於配置 Mycat 的日誌輸出級別,默認爲info
級別:
<asyncRoot level="info" includeLocation="true">
關於log4j2的內建日誌級別詳見官方文檔
當咱們須要經過Mycat實現數據分片時就得用到rule.xml
配置文件,該文件用於配置:
這是一個分片規則的配置示例:
<!-- name屬性指定分片規則的名稱,必須在 rule.xml 文件中是惟一的 --> <tableRule name="hash-mod-4_id"> <rule> <!-- 指定使用表中的哪一個列進行分片 --> <columns>id</columns> <!-- 指定表的分片算法,取值爲<function>標籤的name屬性 --> <algorithm>hash-mod-4</algorithm> </rule> </tableRule>
{分片算法名稱}-{分片數量}_{分片列}
;上面的示例就是採用的這種命名格式上面示例中所提到的<function>
標籤是用於配置表的分片算法或者說分片函數,以下示例:
<!-- name屬性指定分片算法的名稱,一樣須要是惟一的;class屬性指定該算法的具體實現類 --> <function name="hash-mod-4" class="io.mycat.route.function.PartitionByHashMod"> <!-- 要分片的數據庫節點數量,必須指定,不然無法分片 --> <property name="count">4</property> </function>
每一個分片算法的所需參數可能不同,因此property
標籤是能夠有多個的,其屬性也因具體的分片算法而異。以下示例:
<function name="partbyday" class="io.mycat.route.function.PartitionByDate"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sNaturalDay">0</property> <property name="sBeginDate">2014-01-01</property> <property name="sEndDate">2014-01-31</property> <property name="sPartionDay">10</property> </function>
Mycat 內置了很是多的分片算法,而且咱們也能夠針對實際狀況自行開發屬於本身的分片算法。咱們來看看經常使用分片算法都有哪些:
PartitionByMod
:簡單取模,直接經過列值進行取模得出分片位置PartitionByHashMod
:哈希取模,先將列值進行hash運算以後再取模得出分片位置PartitionByFileMap
:分片枚舉,根據枚舉值對數據進行分片,例如在異地多活的場景中經過地區id進行數據分片的場景PartitionByPrefixPattern
:字符串範圍取模,根據長字符串的前面幾位進行取模分片簡單取模分片算法的工做原理:
配置示例:
<tableRule name="mod-long-2_id"> <rule> <columns>id</columns> <algorithm>mod-long</algorithm> </rule> </tableRule> <function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <!-- 取模的基數,也就是分片數量 --> <property name="count">2</property> </function>
總結:
分片列 % 分片基數
io.mycat.route.function.PartitionByMod
當須要取模的列爲非整型時,就可使用哈希取模分片算法。其工做原理以下圖:
配置示例:
<tableRule name="hash-mod-2_login_name"> <rule> <columns>login_name</columns> <algorithm>hash-mod</algorithm> </rule> </tableRule> <function name="hash-mod" class="io.mycat.route.function.PartitionByHashMod"> <property name="count">2</property> </function>
總結:
hash(分片列) % 分片基數
io.mycat.route.function.PartitionByHashMod
前兩種分片算法都是經過算法自己去計算出分片位置,是沒法人工控制的。若是須要人工控制分片位置時,就可使用到分片枚舉算法。該算法使得咱們能夠指定一些枚舉值來對分片位置進行控制,其實也就至關因而人工指定了某些數據應該到哪一個分片。
例如,某張表中有個存儲用戶所在區域id的列,咱們但願將區域id與數據庫所在的區域進行映射,以實現區域id爲1的數據被分片到區域1數據庫中,區域id爲2的數據被分片到區域2數據庫中,以此類推。在這種場景下就可使用分片枚舉算法,其工做原理以下圖:
mapFile
配置一個分片關係映射,其格式爲key-value,key爲枚舉,value爲數據節點的索引。圖中的枚舉就是area_id
,一個area_id
對應着一個數據節點。沒有配置映射關係的area_id
則會被分片到DEFAULT_NODE
所對應的數據節點。配置示例:
<tableRule name="hash-int_area_id"> <rule> <columns>area_id</columns> <algorithm>hash-int</algorithm> </rule> </tableRule> <function name="hash-int" class="io.mycat.route.function.PartitionByFileMap"> <!-- mapFile 文件名,位於config目錄下 --> <property name="mapFile">partition-hash-int.txt</property> <!-- 指定mapFile中枚舉的數據類型,0爲整型;非0則爲字符串類型 --> <property name="type">0</property> <!-- 是否啓用默認節點,大於等於0爲啓用;小於等於0爲不啓用 --> <property name="defaultNode">0</property> </function>
mapFile
時須要注意這一點總結:
$MYCAT_HOME/conf
目錄下增長mapFile
來配置枚舉值同節點的映射關係hash(分片列) % 分片基數
io.mycat.route.function.PartitionByFileMap
以上所介紹到的分片算法都是根據列進行分片的,在實際工做中咱們可能會遇到這樣一個需求:須要經過字符串的前幾位或後幾位進行分片。例如,經過訂單號的前五位進行分片計算,或按用戶的姓氏進行分片。在這種場景下,就可使用字符串範圍取模分片算法。
例如,須要對ABCDEFGHI
這個字符串的前三位進行分片計算,其計算過程以下圖:
mapFile
裏配置的取值範圍與數據節點索引的映射關係得出分片的數據節點。所以,mapFile
須要配置全部可能的取值範圍,不然找不到對應的數據節點就會報錯。工做原理:
配置示例:
<tableRule name="sharding-by-prefix-pattern_login_name"> <rule> <columns>login_name</columns> <algorithm>sharding-by-prefix-pattern</algorithm> </rule> </tableRule> <function name="sharding-by-prefix-pattern" class="io.mycat.route.function.PartitionByPrefixPattern"> <!-- mapFile 文件名,位於config目錄下 --> <property name="mapFile">prefix-partition-pattern.txt</property> <!-- 求模基數 --> <property name="patternValue">128</property> <!-- 字符串範圍,這裏爲前兩位 --> <property name="prefixLength">2</property> </function>
總結:
$MYCAT_HOME/conf
目錄下增長mapFile
來配置取模範圍同節點的映射關係io.mycat.route.function.PartitionByPrefixPattern
用途:
schema
標籤用於定義邏輯庫,示例:
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1"> ... </schema>
checkSQLschema
屬性判斷是否檢查發給Mycat的SQL是否含有庫名,爲true
時會將SQL中的庫名刪除掉name
屬性定義邏輯庫的名字,必須惟一不能重複sqlMaxLimit
屬性用於限制返回結果集的行數,值爲-1
時表示關閉該限制。若是沒有開啓限制則默認取server.xml
裏配置的限制randomDataNode
屬性定義將一些隨機語句發送到該數據節點中使用了schema
標籤訂義邏輯庫以後,還須要使用table
標籤訂義邏輯表。示例:
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1"> <!-- 多表定義 --> <table name="travelrecord,address" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" splitTableNames ="true"/> <!-- 單表定義 --> <table name="oc_call" primaryKey="id" dataNode="dn1$0-743" rule="latest-month-calldate"/> </schema>
name
屬性定義邏輯表的名字,必須惟一不能重複且須要與數據庫中的物理表名一致。使用逗號分割配置多個表,即多個表使用這個配置primaryKey
屬性指定邏輯表中的主鍵,也是須要與物理表的主鍵一致dataNode
屬性指定物理表所在數據節點的名稱,配置多個數據節點時需按索引順序並使用逗號分隔,或指定一個索引範圍:dn1$0-743
。注意數據節點定義以後,順序不能再發生改變,不然會致使數據混亂rule
屬性用於指定分片規則名稱,對應rule.xml
中的<tableRule>
標籤的name
屬性,如無需分片能夠不指定splitTableNames
屬性定義是否容許多個表的定義dataNode
標籤用於定義數據節點,數據節點指向的是存儲邏輯表的物理數據庫。示例:
<dataNode name="dn1" dataHost="localhost1" database="db1" /> <dataNode name="dn2" dataHost="localhost1" database="db2" /> <dataNode name="dn3" dataHost="localhost1" database="db3" /> <!-- 能夠配置一個範圍 --> <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"/>
name
屬性定義數據節點的名稱,必須惟一dataHost
屬性指定分片所在的物理主機database
屬性指定物理數據庫的名稱dataHost
標籤用於定義後端物理數據庫主機信息,該標籤內有兩個子標籤,能夠定義一組數據庫主機信息。例如,定義一組主從集羣結構的數據庫主機信息:
writeHost
標籤配置寫實例,即主從中的master節點readHost
標籤配置讀實例,即主從中的salve節點readHost
是writeHost
的子標籤,與writeHost
有綁定關係在一個dataHost
內能夠定義多個writeHost
和readHost
。可是,若是writeHost
指定的後端數據庫宕機,那麼這個writeHost
綁定的全部readHost
都將不可用。另外一方面,因爲這個writeHost
宕機系統會自動的檢測到,並切換到備用的writeHost
上去。
配置示例:
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- 能夠配置多個寫實例 --> <writeHost host="localhost" url="localhost:3306" user="root" password="123456"> <readHost host="localhost" url="localhost:3306" user="root" password="123456"></readHost> </writeHost> </dataHost>
name
屬性用於定義主機名稱,必須惟一maxCon
屬性指定每一個讀/寫實例鏈接池的最大鏈接數。也就是說,標籤內嵌套的writeHost
、readHost
標籤都會使用這個屬性的值來實例化出鏈接池的最大鏈接數minCon
屬性指定每一個讀寫實例鏈接池的最小鏈接數,即初始化鏈接池的大小dbType
屬性指定後端鏈接的數據庫類型,目前支持二進制的mysql協議,還有其餘使用JDBC
鏈接的數據庫dbDriver
屬性指定鏈接後端數據庫使用的驅動,目前可選的值有native
和JDBC
slaveThreshold
屬性用於定義主從複製延時閾值,當Seconds_Behind_Master > slaveThreshold
時,讀寫分離篩選器會過濾掉此Slave機器,防止讀到好久以前的舊數據balance
屬性指定讀寫分離的負載均衡類型,目前的取值有4 種:
0
:不開啓讀寫分離機制,全部讀操做都發送到當前可用的 writeHost
上1
:所有的readHost
與stand by writeHost
參與select
語句的負載均衡2
:全部讀操做都隨機在writeHost
、readhost
上分發3
:全部讀請求隨機分發到 wiriterHost
對應的readhost
執行。即 writerHost
不負擔讀壓力,所有讀請求由 readhost
執行。注意該取值只在1.4及其之後版本有,1.3沒有writeType
屬性指定寫實例的負載均衡類型,目前的取值有4 種:
-1
:表示不自動切換0
:全部寫操做發送到配置的第一個writeHost
,第一個掛了切到還生存的第二個writeHost
。從新啓動後以切換後的爲準,切換記錄在配置文件中:dnindex.properties
1
:全部寫操做都隨機的發送到配置的writeHost
,1.5 之後廢棄不推薦使用2
:基於MySQL主從同步的狀態決定是否切換(1.4 新增)switchType
屬性用於指定主從切換的方式:
-1
:表示不自動切換1
:默認值,自動切換2
:基於MySQL主從同步的狀態決定是否切換,心跳檢測語句爲:show slave status
3
:基於MySQL galary cluster的切換機制(適合集羣,1.4.1新增),心跳檢測語句爲show status like 'wsrep%'
另外,slaveThreshold
屬性是用於配合writeType
屬性實現根據主從延時來進行主從切換的,其官方文檔描述以下:
1.4 開始支持MySQL主從複製狀態綁定的讀寫分離機制,讓讀更加安全可靠,配置以下:MyCAT 心跳檢查語句配置爲
show slave status
,dataHost
上定義兩個新屬性:switchType="2"
與slaveThreshold="100"
,此時意味着開啓MySQL主從複製狀態綁定的讀寫分離與切換機制,Mycat心跳機制經過檢測show slave status
中的"Seconds_Behind_Master
"、"Slave_IO_Running
"、"Slave_SQL_Running
" 三個字段來肯定當前主從同步的狀態以及Seconds_Behind_Master
主從複製時延,當Seconds_Behind_Master > slaveThreshold
時,讀寫分離篩選器會過濾掉此Slave機器,防止讀到好久以前的舊數據,而當主節點宕機後,切換邏輯會檢查Slave上的Seconds_Behind_Master
是否爲0
,爲0
時則表示主從同步,能夠安全切換,不然不會切換。
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
這兩個標籤都用於配置一組主從數據庫的相關信息,Mycat用這兩個標籤配置的鏈接信息實例化後端鏈接池。惟一不一樣的是,writeHost
配置寫實例(master)、readHost
配置讀實例(salve),而且readHost
爲writeHost
的子標籤。經過這兩個標籤能夠組合讀/寫實例以知足系統的要求。
在一個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
中做爲讀節點的權重usingDecrypt
屬性指定是否對密碼加密,默認爲0
, 若須要開啓則配置爲1
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1"> <table name="travelrecord,address" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" splitTableNames="true"/> <!-- <table name="order" primaryKey="id" dataNode="dn1$0-743" rule="auto-sharding-long" splitTableNames="true"/> --> </schema> <dataNode name="dn1" dataHost="localhost1" database="db1"/> <dataNode name="dn2" dataHost="localhost1" database="db2"/> <dataNode name="dn3" dataHost="localhost1" database="db3"/> <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"/> --> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="localhost:3306" user="root" password="123456"> <readHost host="hostS1" url="localhost:3306" user="root" password="123456"/> </writeHost> <writeHost host="hostM2" url="localhost:3306" user="root" password="123456"/> </dataHost> </mycat:schema>