TSpider 1.6功能介绍

jopen 8年前
 

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相关参数关闭解决。

TSpider 1.6功能介绍

Select * from t1 where key1 = 1 or key1 = 2; 对spider同样会依次分发key1=1,key1=2到后端,优化后则一次性分发key1=1 or key1=2到后期,提升效率。控制参数是index_range,spider上关闭index range行为。

TSpider 1.6功能介绍

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');