Alibaba Data Warehouse

阿里巴巴数据仓库

登录 注册

oracle列删除

暂无评论 »
shaomin.shim | 数据库 2011-11-26 9:46:02

上次在同步wholesale_property的时候,差点酿成了大祸,里面的一些东西可以拿出来分析。我当时对这个表添加了4个字段,希望当天同步最新的数据。后来发现有两个字段源表和目标表的差距有千万级别,由于同步是采用merge方式的,所以必定会招致机器宕机。还好及时发现问题,对2列做了drop操作,
rac删除列的时候大家需要注意,大的表如果达到千万级别,那么删除一列用普通的alter table tablename drop column columnname命令的话将会使用数十分钟。可以用alter table set unused(columnname)来替换,来处理紧急删除列的情况。这个命令会将该列标示为不可用,所以在desc的时候你将看不到被删除的列,但是这个命令不回收空间,所以速度非常快。可以在系统空闲的时候使用alter table drop unused columns来回收该空间,回收空间的时候速度和普通的drop column差不多,甚至可能更高。
为了说明问题,我拿了一个600多万的表说明问题,

SQL> select count(1) from sm_test2;

COUNT(1)
———-
6039192
SQL> alter table sm_test2 drop column OWNER;

Table altered

Executed in 69.547 seconds

SQL> alter table sm_test2 set unused(object_id);

Table altered

Executed in 1.25 seconds

SQL> alter table sm_test2 drop unused columns;

Table altered

Executed in 103.828 seconds

实用的补齐脚本

暂无评论 »
shaomin.shim | 代码世界 2011-9-22 8:38:37

//!/v1.1 修正空白行导致补齐错误bug
//v1.2修正去除错误
///*********************************************************************
//*功能: 补齐cfg指令
//*作者: shaomin.shism
//*时间: 2011-7-28 下午12:13:19
//*备注:
//主函数miniminicompletion
//1.判定是否选中行,如果没有选中,以当前光标所在行为选中行。
//2.将选中的文本赋给待处理的字符串。
//3.以换行符拆分字符串,每一行补齐处理赋值叠加到新字符串中
//4.输出新字符串
// 适用环境为ue
//v1.2
//功能增强,保留注释和空白行
//修正一些bug
//2011-8-21 上午10:14:35

//功能:补齐aone发布指令
//*********************************************************************/
String.prototype.Trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, “”);
}

function removeRem(str)
{
return str.replace(/^\#.*/g,”").trim();
}

function getLayerKeyWord(str)
{
if(str.indexOf(”_STG”)>0)
return “stage”;
if(str.indexOf(”_ODL”)>0)
return “odl”;
if(str.indexOf(”_BDL”)>0)
return “bdl”;
if(str.indexOf(”_IDL”)>0)
return “idl”;
if(str.indexOf(”_PUB”)>0)
return “pub”;
if(str.indexOf(”ADL”)>0 || str.indexOf(”APP”)>0 )
return “adl”;
}

function getFileName(str)
{
var index=str.lastIndexOf(”/”);
return str.substr(index+1);
}
function getTableName(str)
{
var index=str.lastIndexOf(”.sql”);
return str.substr(0,index);
}

function getMyDate(n)
{
var d =new Date();
d.setTime(d.getTime()+(n)*24*3600*1000);
var s=”";
s += d.getFullYear();
s += Math.floor((d.getMonth() + 1)/10) + “”+(d.getMonth() + 1)%10;
s += Math.floor(d.getDate()/10) + “”+d.getDate()%10;
return s;
}

function strCompletion(str)
{
var addressLine;
var keyword;
var filename;

var str1 = str.replace(/^\w+@/g,”"); //去除原来的指令
var result=”";

if(str1.indexOf(”.sql”)>=0) //sql脚本分为rac和gp
{
if(str1.indexOf(”rac_entities”)>=0 || str1.indexOf(”dss”)>=0 || str1.indexOf(”ods”)>=0)
{
result=”oracleFile@”+str1+”\r\n”;
}
else if(str1.indexOf(”gp”)>=0 || str1.indexOf(”TDL”)>=0 || str1.indexOf(”50_APPS”)>=0|| str1.indexOf(”_PUB”)>=0)
{
result=”enGpFile@”+str1+”\r\n”;
}
else
{
result=”oracleFile@”+str1+”\r\n”;
}
}
else if(str1.indexOf(”ssh “)>=0 || str1.indexOf(”scp “)>=0 || str1.indexOf(”export “)>=0)
{
result=”shell@”+str1+”\r\n”;
}
else if(str1.trim().length > 0 && str1.search(/pl$/g)<0)
{
if(str1.toLowerCase().indexOf(”exec”)<0 && str1.toLowerCase().indexOf(”dhw”)<0 && str1.toLowerCase().indexOf(”commit”)<0 && str1.toLowerCase().indexOf(”update”)<0 && str1.toLowerCase().indexOf(”.pl”)<0)
{
result=”enGpSql@”+str1+”\r\n”;
}
else
{
result=”oracleSql@”+str1+”\r\n”;
}
}
else if(str1.search(/pl$/g)>=0) //是perl脚本
{
result=”svnFile@”+str1+”\r\n”;
keyword = getLayerKeyWord(str1);
filename = getFileName(str1);
result=result+”shell@scp “+str1+” {INT_GP_HOME}/”+keyword+”\r\n”;
result=result+”shell@export PERL_DBCONN_GP=/home/dwapp/.gp_int_conn_profile;perl /home/dwapp/admin/alisql/task_gpint/”+keyword+”/”+filename+” -d \”to_date(’”+getMyDate(-2)+”‘,’yyyymmdd’)\”"+”\r\n”;
}

return result;
}

function canReplace(str)
{
if(str.toLowerCase().indexOf(”exec”)<0 && str.toLowerCase().indexOf(”dhw”)<0 && str.toLowerCase().indexOf(”commit”)<0 && str.toLowerCase().indexOf(”update”)<0)
return true;
return false;
}
function minicompletion()
{
var waitForTreat;

if (!UltraEdit.activeDocument.isSel())
waitForTreat=UltraEdit.activeDocument.selectLine();
waitForTreat=UltraEdit.activeDocument.selection.Trim();

var waitForTreatArray=waitForTreat.split(”\r\n”);

var pre=”";
var config=”";
var len=0;
for(i=0; i<waitForTreatArray.length; i++)
{
if(waitForTreatArray[i].search(/^\#.*/)<0 && waitForTreatArray[i].length>0)
{
waitForTreatArray[i]=strCompletion(waitForTreatArray[i]);

len=waitForTreatArray[i].indexOf(”@”)+1;
if(len>0)
{
config=waitForTreatArray[i].substring(0,len); //获取当前配置

}
if(config.indexOf(”Sql@”)>0 && config!=pre && pre.indexOf(”Sql@”)>0)
{
if(canReplace(waitForTreatArray[i]))
waitForTreatArray[i]=waitForTreatArray[i].replace(/\w+@/,pre);
else
pre=config;

}
else
{
pre=config;
}
}
else
waitForTreatArray[i]=waitForTreatArray[i]+”\r\n”;
UltraEdit.activeDocument.write(waitForTreatArray[i]);
}
}

minicompletion();

2011互联网大会随笔

1 条评论 »
姜 迅 | 数据库 2011-8-26 18:49:26

场间休息的时候,会场响起来陈奕迅的十年作为背景音乐,许多早已逝去的背影依稀被模糊的忆起,而与此同时,年轻的90CEO已经站在台上慷慨激昂的宣告新时代到来。第一天开幕式坐在台前的大佬们,仍然是李彦宏,马化腾,马云,曹国伟,丁磊,李开复这些老的面孔;整整三天,被各种各样的概念和广告清洗大脑,真切体会到互联网的热点和变化。有人说web is dead,有人说app快快长大;总的感觉,The More Things Change, The More They Stay The Same.

先说说氛围吧,真的很热闹的。虽然是第一次来参加这样的大会,听之前的参加过前几届的说起来,今年算是盛况空前。政府对互联网关注密切,工信部的苗副部长出席了开幕式,第二天还有人民搜索总经理邓亚萍的互联网首秀。电信,移动,联通,还有华为这样的运营商和制造商,也都很积极的参加这个大会,宣布在互联网上的雄心;微软,自嘲在这轮浪潮中已经落后,也借机展示windows mongo phone,宣称不会在这轮浪潮中被落下。不是简单的大家突然发现一座金山,想进来分一杯羹;被这样受重视,我的感觉互联网已经不再是一个单独的行业,渗透到生活的方方面面,成为各行各业的一个工具和平台,就像每个行业需要使用计算机一样,所有的行业都会需要互联网这个工具,需要被互联网化。

大会最后一天早上的一条重磅新闻是STEVE JOBS卸任。SO LO MO是一个被说烂的词。无线移动被无比受重视,所有人都应该感谢JOBS,是他开辟了一个新的时代,深刻的改变了生活。Next generation NUI,比较MAC AIR IPAD上的阅读体验,阅读需要的主要是你的屏幕,AIR上那突兀的键盘挺麻烦的,而IPAD带给我们更自然的用户体验。在手机上网的用户,不出意外会在2012年前后超过PC上网的用户。上升的不仅仅是用户数,更重要的是人们的生活对于手机会变得重度依赖。熟女,高学历人群,潮爸潮妈,农民工介入,独生子女一轮又一轮的用户热潮进入手机用户群,全球40亿手机,有10亿是智能机了吧。美国人现在平均每天2.7小时花费在移动终端, 查找店铺和购买物品是其中两个最普遍的应用。手机成为连接一切的终端 打开一切的要素,将是人们每天生活最早接触的媒介和最晚离开的媒介,年龄段在40岁之前收入越高的群体在睡觉之前抱着手机入睡的人比例也越高。手机解构了黄金时段的概念,不再存在垃圾时间。一个有趣的例子是,每天早上6点半和7点半之间上厕所的时间,成为一些购物网站的第一个高峰事件。主持人说,刚才洗手间发现边上好几个年轻人一边上厕所一边看微博,犀利啊。手机会把你生活的碎片时间填的满满当当。

GoogleJUSTIN在会上展示了HTML5的未来,结束的时候他分享了最喜欢的一张图片,一个小男孩站在鳞次梯比的十字路口中间,周围熙熙攘攘的是比他高大很多的成年人行色匆匆。小男孩手中拿了一部手机。手机是一个贴身的伴侣和管家,无论身处何地,都可以迅速的从互联网上获取你想要的咨询,和你想要的任何人或者服务器通讯。有了手机小男孩是强大的,无所不能的,比身边的成年人毫不逊色。

无线接入,手机终端,平台(包括云存储和支付)以及内容提供商这4者都在日渐成熟,让我们有可能无时不刻,随时随地接触到网络,为无线手机的繁荣奠定基础。我到了北京之后碰到很挫的一件事情是发现我的mac air没法上网。。。住的汉庭酒店只提供有线的宽带接入。好吧,我想去互联网大会的会场总应该有wifi信号吧;结果发现现场的wifi根本处于瘫痪的状态,根本无法拨入;无论是联通的,电信的还是移动的无线信号,都非常非常的慢。这个大会绝对是无线接入的一次压力测试,而我个人觉得最多只能打60分。无线网络,这条信息高速公路,目前不但收费还比较贵,马路也不够宽而且支路的建设还远没有到位。每个运营商都在标榜自己有多少多少千万,多少多少亿的移动用户,但是对于运营商,建设无线网络不是那么一件特别开心的事情,互联网的流量增长和业务收入增长并不相匹配,无论是AT&T还是中国移动,运营商们不想被管道化和工具化,不想只是提供一个水管却不到里面流动的是什么内容;做应用,做内容,做服务,运营商们不甘心禹只提供基础服务。他们的传统业务在下降(比如短信),无线的业务在迅速崛起,用户数变得越来越多,并开始习惯使用无线互联网,随之而来的洪水一般激增的流量带来系统扩容的成本,远远超出业务带来的收入;而另一方面,手机上网资费还是比较昂贵的。这个问题解决的好坏,会在一定程度影响移动互联网建设的步伐。

iPHONE gPHONEwPHONE,三个平台一个地球。中国人口基数巨大,年轻人消费能力高而且有很高的换机频率,虽然腾讯,新浪表示不会进入手机终端;阿里云手机,小米,还有创新工场都在想象中国这个巨大的市场。王雪红已经成为台湾首富,HTC和苹果的成功,都是对国内立志做智能手机厂家很好的激励。iPHONE还是用户体验做的最好的移动终端。Android的开放策略,让智能机从高端产品变为中端产品,可以被更多人所接受和使用。开放带来的问题是安全,当手机支付这样的重量级应用越来越活跃在手机上的时候,手机的安全会被大众所广泛接受和重视;360的切入点和当前的在windows平台一样,让其客户端应用在手机上被最广泛的安装。虽然360在台上演讲的时候被无数人通过微博呼吁要干货,不要广告,但是不得不承认,其APP STORE3亿PC用户,3000万手机用户;为手机应用提供安全模块支撑,提供应用的曝光和下载服务,在手机应用的推广服务上,能量巨大。

李开复在会场上被要要求点评阿里云手机和小米手机,马云做手机是很有机会的,他创立了阿里云,这个很神秘的机构做了很多年,他们会有自己的计划。阿里云选择手机为飞天的商业应用找到了一个很好的切入点。2009年我看过谢国忠的一篇文章,标题是《永远在线的社会》;当终端呈现移动化和多样化的趋势后,对数据的集中存储和管理就成为一个重要的要求。为手机应用提供一个可靠的远端存储,在无线网络的带宽可信任的情况下,用户可以真正做到在各个不同的终端设备之间切换。为基数巨大的手机开发者解决平台的问题,让手机开发者集中精力关注应用的开发,可以2-3个人,在2-3个月能迅速开发一款应用出来,这将促使手机应用的极大繁荣。

云服务,数据爆炸是内在驱动力,在廉价的机器上提供高性能可靠服务器,通过软件来解决系统的可用性和横向扩展;同样的应用所需要的服务器资源是10年钱的100分之1;大规模、弹性、资源抽象、资源共享和资源的按需分配,是云服务的主要特征。云化,虽然很多各个企业都有自己的计划和产品,感觉更多的是提供为自身企业服务的私有云,国内有计划开放给公众的,我个人所了解主要还是阿里云。IBM这样的厂商所提供的云服务更多的是在传统金融电信行业吃喝不愁。提供虚拟主机,邮箱服务,CDN;阿里巴巴-中国万网基于飞天提供上述的基础服务,更多还是基于存储资源,提供计算资源的云服务厂商还是缺乏的吧。

私有云,公有云,混合云,zynga在租用了amazon30%资源后,也从成本的角度考虑准备自建私有云满足传统主要应用,而小规模租用公有云用来孵化新应用来解决资源池的动态按需分配。从通用化服务器转向定制化服务器是一个明显的趋势,设备的利用率是永恒的话题;关于google使用的服务器数量,200万台,300万台都太低估了google的服务器利用率了。数据中心的资源管理、调度以及实时的流数据分析系统都会是当前需求下所需要重点考虑的问题。

电子商务的资本冬天即将到来了么?麦考林市值现在仅仅略高于其净资产,阿里巴巴B2B100亿港币的现金在手上,股价在持续的下跌。做好眼前的事情有时候很难支撑股价,需要有更多的故事和更大的想象空间。人们花费在电子商务的时间,3年的时间从2%提升到5%;电子商务带给生活的不仅仅只是便宜,更重要的还有方便快捷。阿里巴巴B2B拥有100万的诚信通中小企业主,是一座很大的金山。如果说,淘宝这样的平台将商务从现实带入虚拟,全世界所有人都可以在一家商店购物,打破了地域的概念,销售的对象主要是3C,书,服装,机票这样的商品;那么,现在基于地理位置的应用则虚拟了现实,online to offline,通过对线上人们地理位置和消费能力、习惯的分析,帮助诸如餐馆,影院这样的服务型商户从线上带来客户;对于这些服务型商户来说,每个店面所能够辐射的范围有限,曝光给位于其服务辐射范围之类的用户,这是基于地理位置信息的主要应用之一。有一个叫客多的公司,在做这样的尝试,建立商盟合作,对于不同行业的店铺,交换会员客户,相互间进行交叉营销,比如在各自的店面里安装液晶广告屏,相互播放对方的优惠广告。大屏幕液晶屏的普及,使得这种动态的广告可以接入现实,可以根据时段,甚至人群动态调整展示广告的内容。对于传统的店铺,locationlocationlocation,店铺的位置是接触用户最主要的方式,而基于地理位置信息的线上推广活动,是一个扩大店铺与用户接触面的有效手段,降低其获得新客户的成本。SNS+LBS,线上聚客,用服务模式将类似的散乱需求汇集到规模程度,进行大规模定制以降低服务企业的成本,尤其对于象影院,餐馆这些边际成本比较低的行业来说更为重要。

手机普及首先给我们带来的是方便,随时随地。通过手机上的股票交易软件,证券公司现金存量增加了一倍,交易翻了一番。因为人们可以在任何时间都拨上去进行股票交易。时间碎片化,信息碎片化,直接的影响是用户每天消耗在手机上的时间越来越多,粘度越来越高,成为战略必争的制高点。使用手机工具首要获取内容。实名化,强关系型的社区,带来的影响是对即时通讯依赖降低(35%->22%),微博成为社会化的主要手段;广告的预算永远是追逐用户的眼球,尤其是有价值的而用户的眼球。互联网广告在广告行业占比在国内达到15%,等同于全球水平。当手机应用控制越来越多的用户接触点,霸占,塞满越来越多的用户时间的时候,互联网广告所占的份额一定会继续提升。不但是因为用户的时间被你霸占,互联网的广告还有精准投放,效果跟踪,互动等等特性而优越于传统广告形式。这是一个巨大的市场!

用户为王,User profileuser segmentation是个性化定向营销的核心驱动力之一。对用户的主要的分析维度集中在人口的统计学属性(年龄,性别,星座)以及教育程度,婚姻状况,地域,收入和感兴趣商品类目(一级类目,比如:汽车,母婴用品,智能手机);这些属性最终都是为了和我们要推销广告的商品的类目通过模型为了能对用户进行持续的分析,我们需要把用户黏在平台上不断的挖掘价值;随着用户数增长,用户之间的共同关系增加越来越多,人的聚集效应开始显现;人群自然而然的根据相互之间的关系可以划分出不同的用户群。高学历,高收入的三高人群会被定义为高价值人群,他们会是诸如汽车,奢侈品等高端商品的目标客户;而比如网吧里低收入,低学历的流动人群虽然被定义为低价值人群,但因为人口众多,对于特定小额商品有非常旺盛的购买欲望和购买力,以满足身体劳累一天之后的精神文化需求,付费意愿度高。深圳富士康工厂边上的草根山寨手机的成功也说明了这些传统意义看来的三低人群,也是一个巨大的金矿。普适性通用指标是一方面,针对特定不同的人群,我们需要有专门的人跟进持续分析研究其行为习惯,从而真正能做到个性化定向。

消费痕迹,无论是大众点评还是想淘宝京东或者拉手高朋这样的公司所获得最有含金量的数据之一。这些数据反应的是最真实的消费行为和消费欲望,直接和钱相关,没有作弊。一个最简单的例子是做一轮对打印机的团购营销活动之后发现一体机卖的最好,那么第二次就专门组织一次针对一体机的团购营销;系统所收集的每一个消费痕迹都最终能反馈给系统并优化策略。

视频,也是一个当仁不让的热点之一, 互联网用户的消费内容,在线视频已经超过了新闻;电视每天开机率从已经从70%跌倒了40%不到;网络视频会成为主流媒体,越来越多的人,特别是城市中的高学历人群,习惯通过视频网站来获取, 35%高端用户已经不看电视。视频网站相较于传统媒体,在很大程度上提高媒体生命周期,一个电视剧在视频网站上可以在线几个月甚至几年,这在传统电视媒体是无法做到的。传统媒体和互联网媒体之间,越来越多的传统媒体顺应潮流互联网化,比如ifeng.com;想想每年央视天价的广告费,再回味最近中央二套对百度的滚动报道,视频网站的未来可以预见。

我记得有人和我说过,现在社会各个阶层之间的差距越来越大,各种社会资源越来越集中到上层精英社会中,教育是打通阶层之间上升通道的有效手段,但是因为经济能力的差异,不同阶层的人能享受到的教育是不同的,而互联网提供了一个廉价的手段让地球上所有的人都能够接收到相同的教育。丁磊虽然在会上一直被王利芬打趣说他怎么去养猪了,网易公开课虽然只是做了翻译的工作,但打通了语言的障碍,让中国人获取知识更为容易。每个人都用各自的方式去改变世界,网易15年前改变人获取咨询的方式,3年前,丁磊用自己的智慧去改造农村的种植业。丁磊会上几乎有点愤怒的说,养猪怎么了,工作没有贵贱之分。让生活更美好,这应该是我们做任何事情的出发点。

忽如一夜醒来繁花似锦,遍地黄金;这个时代融资和10年前相比容易很多。新浪,百度还有盛大这些公司之前的努力打开了融资的天花板,几千万美金、几亿美金、甚至10亿美金的融资都在身边发生;会场大屏幕上有一句微博我印象很深刻,希望这届大会不要成为一届吹牛会,网民数据作假,销售数据作假,融资数据作假这些不要再发生;有时候感觉到身边周围的大环境可能并不是太好,或许不远的将来会又有一波经济危机的浪潮袭来,有多少人会成为last standing man,大家还是都趁现在准备好足够过冬的粮食?无论如何,我们会拥有一个怎样未来,需要我们亲手去创造。

姜迅

设置ssh登录免验证

1 条评论 »
daniel.xiaoy | 数据库 2011-7-5 9:39:44

Setup passphraseless ssh

一、

ssh-keygen -t dsa -P ” -f ~/.ssh/id_dsa

二、

cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

vm虚拟机静态配置debianIP

1 条评论 »
daniel.xiaoy | 数据库 2011-7-4 17:13:48

一、VM NAT设置

二、配置网络信息

vi /etc/network/interfaces

#iface eth0 inet dhcp

iface eth0 inet static

address 192.168.25.132

netmask 255.255.255.0

gateway 192.168.25.2

 

三、配置geteway

vi /etc/resolv.conf

domain localdomain

search localdomain

nameserver 192.168.25.2

四、配置hostname

/etc/hostname

debian2

四、reboot

关于gp中的appendonly表

1 条评论 »
scutshuxue.chenxf | 数据库 2011-6-22 15:36:13

 在greenplum里面有一种appendonly表,只能insert,不能update、delete的一种表,对于压缩表跟列存储来说,前提是必须是appendonly的表。下面介绍appendonly表的一些特性。

 

1.首先建一张appendonly的表:

aligputf8=# create table cxf_test1 with(appendonly=true,compresslevel=5) as select generate_series(0,1000) a,’helloworld’::varchar(50) b distributed by (a);

SELECT 1001

 

2.查一下表的oid:

aligputf8=# select oid from pg_class where relname=’cxf_test1′;

  oid  

——–

 383660

(1 row)

 

aligputf8=# select oid,oid::regclass from pg_class where relname=’cxf_test1′ or relname like ‘%383660%’;

  oid   |              oid              

——–+——————————–

 383665 | pg_aoseg.pg_aoseg_383660

 383666 | pg_aoseg.pg_aoseg_383660_index

 383660 | cxf_test1

(3 rows)

 

在gp3.3.*的版本里面,aoseg表的信息是记录在pg_class中的relaosegrelid 字段,是以这个为准的

aligputf8=# select relaosegrelid from pg_class where relname=’cxf_test1′;

 relaosegrelid

—————

        383665

(1 row)

在gp4.*的版本里面,pg_class的relaosegrelid 字段已经取消掉了,这个信息保留在了pg_appendonly表中的segrelid字段中了。

 

3.aoseg表的字段信息

aligputf8=# \d pg_aoseg.pg_aoseg_383660

   ?o? “pg_aoseg.pg_aoseg_383660″

     Column      |       Type      

—————–+——————

 segno           | integer

 eof             | double precision

 tupcount        | double precision

 varblockcount   | double precision

 eofuncompressed | double precision

 

这个表每个字段的意思gp的文档里面没有,大概觉得每个字段信息应该是:

 

Segno: 这个字段还不是很清楚,第一次建表的时候是0,truncate之后就变成1了,再truncate还是1。

eof     :压缩后文件大小

tupcount:表的函数

varblockcount:表占用的块数量

eofuncompressed:未压缩表的大小

 

aligputf8=# select * from gp_dist_random(’pg_aoseg.pg_aoseg_383660′);

 segno | eof | tupcount | varblockcount | eofuncompressed

——-+—–+———-+—————+—————–

     0 | 732 |      161 |             1 |            4204

     0 | 728 |      161 |             1 |            4204

     0 | 720 |      159 |             1 |            4152

     0 | 808 |      181 |             1 |            4724

     0 | 796 |      178 |             1 |            4644

     0 | 728 |      161 |             1 |            4204

(6 rows)

通过gp_dist_random这个函数,我们可以知道gp底层每个数据节点数据量,数据文件大小的情况,这样子我们就能够分析表的数据分布情况,算出倾斜率等。

基于appendonly表,我开发了两个gp的函数:

get_table_count是获取append only表的行数的,appendonly表有一个字段是保存这些信息的。这个函数获取表的函数很快,支持分区表. 

aligputf8=# select * from get_table_count(’rtdc.cxf_test1′);
 get_table_count
—————–
            1001
(1 row)

get_table_info是更加详尽的表的信息:

create type public.table_info as (

tablename text                       –表名

,subparname text                      –分区名

,tablecount bigint                    –表的行数

,tablesize bigint                     –表大小(单位:字节)

,prettysize text                      –美化大小输出

,max_div_avg float                    –斜率,最大节点数据量/平均节点数据量

,compression_ratio float              –压缩率

);

第一行是整个分区表的汇总信息

aligputf8=# select * from get_table_info(’rtdc.cxf_test1′);
   tablename    | subparname | tablecount | tablesize | prettysize |  max_div_avg  | compression_ratio
—————-+————+————+———–+————+—————+——————-
 rtdc.cxf_test1 |            |       1001 |      4512 | 4512 bytes | 1.08491508492 |     5.79166666667
(1 row)

关于TOK_TABREF和TOK_TAB

暂无评论 »
weiguang.sunwg | 海量数据处理 2011-6-15 13:06:04

这两天在做hive的sql解析工作,表级的基本已经做完了。
昨天和taobao的同学讨论,告诉我hive里面已经有了sql解析的工具,lineageinfo。
而且taobao已经开发出比较完备的sql解析的工具,字段级别的。

和taobao的相关同学了解了一下,他们的hive的sql解析做得确实很不错。

也顺便看了看lineageinfo的相关代码,这个还是比较粗陋的,比我做的还是差一些的。
不过看代码后,我才发现hive的sql解析中TOK_TABREF和TOK_TAB的区别。

    switch (pt.getToken().getType()) {

    case HiveParser.TOK_TAB:
      OutputTableList.add(pt.getChild(0).getText());
      break;

    case HiveParser.TOK_TABREF:
      String table_name = ((ASTNode) pt.getChild(0)).getText();
      inputTableList.add(table_name);
      break;
    }
   
从上面LineageInfo.java的代码片段能看出来TOK_TAB代表输出的表,而TOK_TABREF代表输入的表。
有这样的区分解析起来就方便的很,只要遍历整棵语法树,然后将TOK_TAB和TOK_TABREF的分别查找出来就可以了。

hive> explain insert overwrite table sunwg01 select * from sunwg02; 
OK
ABSTRACT SYNTAX TREE:
  (TOK_QUERY (TOK_FROM (TOK_TABREF sunwg02)) (TOK_INSERT (TOK_DESTINATION (TOK_TAB sunwg01)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF))))

HIVE优化-MAPJOIN

暂无评论 »
xiaoxiao | 海量数据处理 2011-5-31 16:35:06

一个普通的SQL跑了2小时跑不出来。始终在做一个REDUCE
insert overwrite table xxx
select  user_id         AS user_id
               ,user_type       AS user_type
               ,act_object      AS act_object
               ,…      AS score
        from
                (      
                select   ft.user_id
                        ,ft.user_type
                        ,ft.act_object
                        ,…
                        ,…
                   FROM    (
                        select *
                        from    ag
                        where   ag.wai_dim_id=1
                        ) ag
                join
                        (
                        SELECT *
                        FROM  t1
                        WHERE   dt>date_sub(’2011-05-25′,30)
                        AND     dt<=’2011-05-25′
                        AND    wai_dim_id=1
                        )ft
                on      ft.wai_dim_id=ag.wai_dim_id
                AND     ft.action_type_id=ag.action_type_id
               GROUP BY ft.user_id
                         ,ft.user_type
                         ,ft.act_object
                         ,ft.action_type_id     
                 ) t1  

查看了日志信息。点击每一个TASK的COUNT下面,查看了一下跑不出来的REDUCE本地读写数据量。发现量很大。觉得是数据倾斜了。查了一把数据,发现果然如此,ATCION_TYPE为6的太大了。
1       77554717
2       3115032
3       6844
4       2496098
6       1142820816
7       1136873
8       940878
9       363630
11      1172047
12      735
13      809354
14      506320
15      3190841
只好优化。在子查询里加上wai_dim_id=1的限制,提前过滤。再使用MAP JOIN,把小表广播到每个机器上去。REDUCE就可以在本地做了。

总结:
发生数据倾斜时,通常的现象是:
?    任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。
?    查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。
数据倾斜一般是由于代码中的join或group by或distinct的key分布不均导致的,大量经验表明数据倾斜的原因是人为的建表疏忽或业务可以规避的。如果确认业务需要这样倾斜的逻辑,考虑一下优化的办法:
?    对于join,使用map join
?    对于group by或distinct,使用两次MR优化,即设定参数: hive.groupby.skewindata=true
?    MAPJOIN虽然能优化性能, 但并适合在所有的join场景中使用. 它仅针对一张小表(几百条记录的维表)和一张大表进行join时, 能够带来很好的优化效果.   上例中ag就是小表. 小表一旦不”小”, 则会导致OOM(OutOfMemory)的错误, join就会失败.

GP视图快速查询

暂无评论 »
stefanie.huang | 数据库 2011-5-31 16:33:51

还在为GP上rename物理表时不清楚上层是否有存在视图而烦恼么?为大家提供几个sql,方便在GP上查询物理表与视图对应关系,查询时修改relname like部分即可

1 GP上查询所有视图

select a.oid,b.nspname||’.'||a.relname,pg_get_viewdef(a.oid,true); AS view_name

from pg_catalog.pg_class a

INNER join (select oid,nspname from pg_catalog.pg_namespace where nspname not like ‘pg_%’ and nspname not like ‘information_%’ and nspname not like ‘en%’) b

ON a.relnamespace = b.oid

WHERE relkind = ‘v’;

阅读全文 »

Thrift 简介

3 条评论 »
joe.wangh | 数据库 2011-5-30 23:08:49

Thrift是一个跨语言服务部署框架,最初由Facebook于2007年开发,后于2008年进入Apache孵化器(Apache Incubator)。

类似于SOAP,COM 和CORBA,Thrift通过定义一个中间定义语言和Thrift代码生成工具,生成指定语言的代码。目前,Thrift支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml的代码生成。

简单分析其机理,Thrift就是实现C/S模式,通过代码生成工具将接口定义文件生成服务器端和客户端代码(可以为不同语言),从而实现服务端和客户端跨语言的支持。

更多的内容可以参看下面的链接

http://thrift.apache.org/

下面贴一些使用的例子,更便于理解。

1、首先安装thrift,这个就不多说了

./configure

make

makeinstall

2、编写.thrift文件,告诉Thrift你需要怎样的数据结构以及服务形式

#RTDCCmd.thrift

struct Rusult {
1: i32 status,
2: string output
}

service RTDCCommand{
Rusult osCmd(1: string cmd)
oneway void osCmdAsync(1: string cmd)
}

文件里定义了两个东西,一个是数据结构Rusult,类似于一个结构体,由两个元素组成,一个整型,一个字符型;另一个是服务RTDCCommand,里面定义了两个接口,一个是osCmd,用于执行一个操作系统命令,一个osCmdAsync,用于执行异步命令的调用(可以用于RPC场景)。

3、生成thrift相应的包、模块,下面分别生成PYTHON和PERL的

thrift -r –gen python RTDCCmd.thrift
thrift -r –gen perl RTDCCmd.thrift

执行完成以后,目录下分别会生成gen-py 和gen-perl两个文件夹,里面分别是需要用到的一些包、模块。

4、仅仅靠thrift自动生成的那些东西当然还不够,前面我们定义了一些接口,接下来我们需要对其进行实现。我把自己写的几个程序代码都贴上吧,便于理解

#RTDCCommandHandler.py

#!/bin/env python
from RTDCCmd.ttypes import *
from RTDCCmd import RTDCCommand
import commands
import os
import sys

class RTDCCommandHandler(RTDCCommand.Iface):

def __init__(self):
#RTDCCommand.Iface.__init__(self)
pass

def osCmd(self,cmd):
ret = commands.getstatusoutput(cmd)
result = Rusult(ret[0],ret[1])
return result
def osCmdAsync(self,cmd):
commands.getstatusoutput(cmd)

继承RTDCCommand.Iface,对其接口进行实现。

#RTDCServer.py

#!/bin/env python
from thrift.server.TServer import TServer
from thrift.server.TServer import TSimpleServer
from thrift.server.TServer import TThreadedServer
from thrift.transport.TSocket import TServerSocket
from thrift.transport.TTransport import *
from RTDCCommandHandler import RTDCCommandHandler
from RTDCCmd import *

if __name__ == ‘__main__’:
handler = RTDCCommandHandler()
processor = RTDCCommand.Processor(handler)
serverTransport = TServerSocket(9091)
server = TThreadedServer(processor,serverTransport)
print “start server……”
server.serve()

这个其实就是一个服务进程,client端连接server,进行相关请求。

#RTDCClient.py

#!/bin/env python
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from RTDCCmd.RTDCCommand import Client
from RTDCCmd.ttypes import *

class RTDCClient():

#static member
port = 9091
#constructor
def __init__():
pass

@staticmethod
def remoteOSCmd(host,cmd):
ret=[1,'err']
try:
transport = TSocket.TSocket(host,RTDCClient.port)
transport = TTransport.TBufferedTransport(transport)
#wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)

client = Client(protocol)
#open transport
transport.open()
result = client.osCmd(cmd)
ret = [result.status,result.output]
except:
s=sys.exc_info()
print str(s[1]) + ‘ on line ‘ + str(s[2].tb_lineno)
finally:
if transport:
transport.close()
return ret

@staticmethod
def remoteOSCmdAsync(host,cmd):
try:
transport = TSocket.TSocket(host,RTDCClient.port)
transport = TTransport.TBufferedTransport(transport)
#wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)

client = Client(protocol)
#open transport
transport.open()
client.osCmdAsync(cmd)
except:
s=sys.exc_info()
print str(s[1]) + ‘ on line ‘ + str(s[2].tb_lineno)
finally:
if transport:
transport.close()

这个是CLIENT端代码的实现,在其他程序中只要引用CLINET端里面的两个静态方法就可以实现远程调用的功能了。

下面给个示例程序,功能很简单,就是远程执行一个cat命令把testfile文件的内容打印出来,并返回。最后在程序中把程序的运行状态和输出结果分别print到标准输出上

#1.py

#!/bin/env python
from RTDCClient import RTDCClient
import time

ISOTIMEFORMAT=’%Y-%m-%d %X’

ret = RTDCClient.remoteOSCmd(”localhost”,”cat /home/gpadmin1/joe.wangh/thrift/test/gen-py/testfile”)
print time.strftime( ISOTIMEFORMAT, time.localtime() )
print ret[0]
print ret[1]

首先运行server进程

nohup python RTDCServer.py &

然后运行示例程序

[gpadmin1@hadoop5 gen-py]$ python 1.py

2011-05-24 14:40:45
0
haha
hehe

前面的那一堆东西,全是用PYTHON写的,没实现跨语言调用,不给力,总觉得没发挥Thrift价值,呵呵,下面用PERL来实现一个CLIENT试试。

#RTDCClient.pl

#!/usr/bin/perl
use strict; #declare using perl strict syntax
use Thrift;
use Thrift::Socket;
use Thrift::FramedTransport;
use Thrift::BinaryProtocol;
use Thrift::BufferedTransport;
use Thrift::Constants;
use Thrift::RTDCCommand;
use Thrift::Types;

package RTDCClient;

my $port = 1987;
my $host = “”;
my $cmd = “”;
my $result = Rusult->new(undef,undef);

#connect to db
sub remoteOSCmd
{
$host = @_[0];
$cmd = @_[1];
my $socket = Thrift::Socket->new($host,$port);
$socket->setRecvTimeout(1000000000);
my $transport = Thrift::BufferedTransport->new($socket);
my $protocol = Thrift::BinaryProtocol->new($transport);
my $client = RTDCCommandClient->new($protocol);
eval {$transport->open()};
if($@)
{
my $ex = $@;
die “error when transport open: $@”.$ex->{message}.”\n”;
}
#$result = RTDCCommandClient->osCmd($client,$cmd);
$result = $client->osCmd($cmd);
return $result;

}

sub remoteOSCmdAsync
{
$host = @_[0];
$cmd = @_[1];
my $socket = Thrift::Socket->new($host,$port);
$socket->setRecvTimeout(1000000000);
my $transport = Thrift::BufferedTransport->new($socket);
my $protocol = Thrift::BinaryProtocol->new($transport);
my $client = RTDCCommandClient->new($protocol);
eval {$transport->open()};
if($@)
{
my $ex = $@;
die “error when transport open: $@”.$ex->{message}.”\n”;
}
#$result = RTDCCommandClient->osCmd($client,$cmd);
$client->osCmdAsync($cmd);
}

1; #terminate the package with the required 1

示例程序如下

#1.pl

use strict;
use RTDCClient;

RTDCClient::remoteOSCmdAsync(”localhost”,”sleep 10;touch /home/dwapp/joe.wangh/gen-py/testfile1″);

该程序的功能是实现一个远程异步调用,在程序中我故意先sleep 10,你会看到在客户端程序很快就返回了。可是在服务端,过10秒钟以后才会生成一个testfile1文件。

差不多就写这些吧,在学习Thrift的过程中比较费事的是有时环境不正确,比如说PYTHONPATH或者PERL5LIB,或者机器上其他一些引用的库没有装。

完。


Copyright © 2010 Alibaba Date Warehouse is proudly powered by WordPress
浙ICP备10037027号