TSpider 1.6功能介紹
TSpider 1.6功能介紹
【新功能】
1. 增加跨分區操作性能視圖,通過Show query_response_times來顯示
2. 在參數spider_get_sts_or_crd=1時,支持show table status和show index語句來收集統計信息
3. spider的錯誤日志增加當前語句和當前庫信息
【優化】
1. 解決delete/update .. limit ..語句效率較低的問題
默認情況下,delete/update .. limit .. 無法使用direct_delete/direct_update優化,即都是先查詢結果再根據主鍵逐行刪除/更新,這樣的效率較低。
解決方式: delete/update .. limit .. 支持direct_delete/direct_update
2. 修改spider_semi_split_read默認值為1,避免limit放大
在spider上執行類似limit語句 select id from test_incr limit 2;在remote每個節點是執行select id from test_incr limit 4; 每次都會將limit擴大2倍,存在無意義的性能損耗。這里是受參數spider_semi_split_read控制,默認為2(表示limit的兩 倍),現將默認值修改為1。
【Bug Fixed】
1. 修復group by結果錯誤的問題,涉及兩個問題:
a) Select key1, min(key2) from t group by key1; (key1, key2)是一個索引。這個是由于direct aggregate使用不當導致。
b) select key from t group by key; key是索引唯一列
該語句使用了計劃Using index for group-by,該優化在spider上不能得到正確結果,禁用該計劃。
同理,select count (distinct key) from t;有同樣的問題。
2. 解決預讀導致spider備份異常的問題
原因分析:在spider_quick_mode = 1時, 執行mysqldump可能失敗的原因是remote DB net_read_timeout/net_write_timeout超時。一個表共16個分區,當并發導出時,每個分區預先讀取100條記錄 (pre_scan)。當拉取最后若干分區的數據,時間已超過默認的60s,remotedb就會kill掉當前連接,導致spider獲取結果出錯。
解決方式:
a) 當指定SQL_NO_CACHE(mysqldump)時,禁用pre_scan優化
b) 另外,新增參數spider_use_pre_scan,控制是否啟用pre_scan優化,默認TRUE;
c) 解決insert .. select ..失敗的問題
原因同上,解決方式:非select語句禁用pre_scan優化
4. 修改spider對索引的執行優化的bug
Select * from t1_spider where key1 = 1 or key2 = 1; 此語句spider會依次執行where key1=1, key2=1兩個索引,再進行result union。對datetime類型會引發crash(修復)。但該spider分發語句方式效率低下,而且可能結果出錯(重復結果),通過將index merge相關參數關閉解決。
Select * from t1 where key1 = 1 or key1 = 2; 對spider同樣會依次分發key1=1,key1=2到后端,優化后則一次性分發key1=1 or key1=2到后期,提升效率。控制參數是index_range,spider上關閉index range行為。
5. 修復時間類型如now()沒有在spider正確計算的問題。這可能導致在線遷移數據不一致。
測例:
set timestamp=123456;
update t set c1=now() where id = 10;
spider發給remote的sql直接發的now()函數,故導致時間不對。
6. 修復包含timestamp列,direct_update未處理時間戳的問題。
測例:
CREATE TABLE `test_timestamp` (
`id` int(11) NOT NULL,
`c1` int(11) DEFAULT NULL,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=SPIDER DEFAULT CHARSET=latin1 COMMENT='shard_key "id"'
/*!50100 PARTITION BY LIST (crc32(id)%2)
(PARTITION pt0 VALUES IN (0) COMMENT = 'database "d1", table " test_timestamp", server "SPT0"' ENGINE = SPIDER,
PARTITION pt1 VALUES IN (1) COMMENT = 'database "d1", table " test_timestamp", server "SPT1"' ENGINE = SPIDER) */
update test_timestamp set c1 = 1 where id = 1時,spider未轉發時間戳,則更新后的update_time字段時間不正確。
現在的處理是,同時滿足以下條件,會執行非direct_udpate:
a. 有set timestamp = xxxx操作
b. 表有timestamp列,并且on update CURRENT_TIMESTAMP
c. update語句沒有指定timestamp列的值
即:update t1 set c1 = 2 where id = 1 (表t1有update列)會轉化為select c1 from t1 where id = 1;
如果c1值無變化,則返回。否則,執行update t1 set c1 = 2, update_time='根據timestamp計算' where id = 1 limit 1;
另外replace into t1(id, c1) values(1,2),可以繼續保持direct_dup_insert,因為timestamp值總是更新的。
7. 修復上述問題后,引發timestamp 類型的的SQL在非dierct_update可能出現部分列沒取,導致更新失敗的問題。
測例:
CREATE TABLE `t_account_loginstatus_0` (
`uuid` varchar(128) NOT NULL,
`openid` varchar(128) NOT NULL,
`context` tinyblob NOT NULL,
`updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`createtime` int(11) unsigned DEFAULT '0',
KEY `uuid` (`uuid`),
KEY `uuid_2` (`uuid`,`openid`),
KEY `uuid_3` (`uuid`,`context`(32))
) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='shard_key "uuid"'
/*!50100 PARTITION BY LIST (crc32(`uuid`)%2)
(PARTITION pt0 VALUES IN (0) COMMENT = 'database "d1", table " t_account_loginstatus_0",
server "SPT0"' ENGINE = SPIDER,
PARTITION pt1 VALUES IN (1) COMMENT = 'database "d1", table " t_account_loginstatus_0",
server "SPT1"' ENGINE = SPIDER) */;
insert into t_account_loginstatus_0 values('007b02fd-d068-4caf-81ef-2860f842b48e','79d7a7eb-b3bc-40e8-b208-68fbbc52285a', 'aaabbb', '2015-06-08 15:20:03',1403218866);
SET TIMESTAMP=1442820567;
update t_account_loginstatus_0 set openid='2e8d2577-624b-44e0-b7eb-14558fdfadfe', context='aaabbb' where
(uuid='007b02fd-d068-4caf-81ef-2860f842b48e' and openid='2e8d2577-624b-44e0-b7eb-14558fdfadfe') or
(uuid='007b02fd-d068-4caf-81ef-2860f842b48e' and context='aaabbb');