今天有幸参加了RWP性能之旅——深圳站的活动。
RWP,全称是Oracle Real-World Performance,是 Oracle 总部数据库研发部门的一部分,是一个由天才组成的团队。之前翻译过《深入理解Exadata》的黄凯耀,以及现在在SSC团队的SQL优化大神刘永甫(微信公众号:老虎刘谈SQL优化)都曾经是这个团队的一员。
Andrew Holdsworth是他们的老板,今天Andrew的有句话让我印象很深,提到RWP的价值在哪里,说在现有的条件下,你确实可以花钱买硬件来提升性能,但是升级硬件能让性能提升1000倍吗?(一般来说,普通硬件升级,性能提升5~10倍已经算了不起了,就算HDD升级到SSD也就提升了100倍),RWP的价值在于他们可以让你的性能飞跃1000倍!
另外还有Graham Wood,是 AWR,ASH,ADDM 的架构师,在职oracle 31年了(甚至比Andrew还长),号称AWR之父的,也是参加此次活动的嘉宾。
此外,亮相的还RWP中国团队的Christine和Cary。
非常感谢Cary帮我向Graham引见,使得我有机会私下问Graham关于AWR如何引入到MSSQL或者MySQL中去。
上次RWP团队的活动是2015年在北京举行,当时的嘉宾除了Andrew和Graham,还有Thomas Kyte。而这次是Tom大师退隐之后的RWP的第一次公开亮相。所以本次活动的含金量不言而喻。
活动地点在深圳信息职业技术学院举行,活动组织的很完美。如果真的有些美中不足的话,那应该就是活动没有设置门槛,英语不好或者oracle基础不好,不太能听明白Andrew和Graham讲的东西。导致上午参加的人不少,可能还有学生党,但是到了下午,基本上只有5年以上经验的老腊肉留下了听讲和互动了。人数太少,觉得有点对不住这么高级别的专家。
本次活动主要是通过一个一个的demo来讲解一个一个real world中存在的问题。我简单记录一下活动中我的一些收获,记得不全,只是记录了一些觉得比较重点的东西。
(1)SSD的平均响应时间可能会到5毫秒,通常情况下,SSD的平均响应时间应该是在0.0x毫秒,到了5毫秒可能是SSD在做re-organize
(2)logon/logoff是个成本很高的操作,因为登录和退出是需要解析,在频繁的连接环境中,你将会看到数据库的CPU比较高,但是数据库本身没什么压力(CPU主要时间花在linux kernel上),用户的response time主要消耗在connection queue上。如下图的左上部分,是表示response time,而其中的蓝色的connection queue部分占了大多数。另外,你可以注意到logon的次数几乎和每秒的事务数相近,可以猜想一个session登陆后,做完一件事情,就立即退出了。解决方法是建议使用连接池。
(3)连接池建议使用,但Dynamic connection pool不建议使用,如果使用,不建议设置max connection很高。因为在某些情况下(如连接风暴),过高的connection会导致response time过高,应该在适当的时候降低连接池的connection数。
RWP的演示demo有一个dashboard,左上显示应用端的response time(端到端),右上显示thoughput(TPS),中间部分显示active session(不同颜色分别表示ON CPU,User IO,System IO,Concurrency,Commit,Cluster,Scheduler,Other),下面部分显示主机CPU(包括db instance CPU,App server-1 CPU和App server-2 CPU)
在一个演示的demo中,随着动态连接池中的连接数从100多增加到5000多,TPS逐渐增加,到了一定时候不再增加,当连接池的连接数从4000多到5000多的时候,中间的active session出现了争用,端到端的response time开始增加,TPS下降。
想要让TPS吞吐量上升,还是得降低连接数,因为降低了连接数,减少了CPU使用率,原来在cpu上的latch等待消失,原来那些浪费在latch上的cpu时间被分配到数据库的事物上,另外由于连接数减少,这些连接能容易的获得cpu调度,也就是说,那些对应进程的memory page也会稳定在某个cpu一级或者二级缓存中,不会在内存和缓存中来回倒腾,从而得到更快的响应时间,提高TPS。
这个demo用照片无法说明,还是看看下面的2个youtube视频会比较好(国内的朋友可以访问这里【甲骨文视界】):
Real-World Performance – 13 – Large Dynamic Connection Pools – Part 1
Real-World Performance – 13 – Large Dynamic Connection Pools – Part 2
所以,建议不使用动态连接池,如果使用,配置较小的max connection数,一般是几倍的cpu数,而不是几百倍的cpu数。
(4)性能差还可能不是数据库服务器的问题,可能是应用服务器CPU高。在分析的时候,可能db服务器没有任何压力,但是如果应用服务器的CPU高,同样也会影响应用的执行效率。
(5)硬解析的影响。随着硬解析升高,出现CPU高(主要是在user部分),library cache mutex X等待,latch row cache object等待。
(6)leak,泄露。有三种泄露:包括cursor的泄露,session的泄露,lock的泄露。
cursor泄露是指cursor打开没有关闭,通常情况下,一个session的一个语句在v$open_curosr不会多于,1,2个open cursor。另外,如果你在awr中看到cursor/session也在2个snapshot中有变化,也有可能是cursor leak。
session泄露是指session打开不关闭。session是由应用层面引起。如果session不释放,而设置的最大session是96个的话,那么只需96次session泄露,session干完了活不释放,中间件发起的新连接数据库无法接收(因为已经到最大的session值),此时中间件到数据库之间的connection pool就会大大增加,且此时TPS由于session没有干活,所以也会急剧下降。测试session泄露的一个方式是让jvm跑一个数据库连接,如果有session泄露,那么jvm就会挂起。
lock泄露是指一个session发起dml,但是没有commit,一直持有锁。通过的解决方式是kill holder。
(7)如何看awr。
(7.1)一定要先看系统资源,如cpu核数,session数等等,从理论上讲,你不太可能1个core跑100个session。你可以对比awr中的db cpu time中的per second中,看看是否大于cpu的核数。
(7.2)要注意看后面的初始化参数,因为里面可能有很多特殊设置的参数或者隐含参数。
(7.3)不做好绑定变量,直接将页面的值带入到数据库,会造成安全问题,如sql注入
(7.4)OLTP系统,设置的block size应该小一些,不应该用16k,应该用默认8k或更小。
(7.5)不应该用cursor sharing=force,oracle会将常量值变成SYS_B_001这样的变量。加重shared pool的负担。
(7.6)mutex类的等待应该是在微秒级别,不应该在毫秒级别,毫秒级别的是传统IO的速度。
8.多核CPU在操作系统层面看不忙,可能不准,因为他可能一个核忙一个核不忙。而平均的idle量看上去还是比较高。
9.关于是系统调优还是sql调优,先问问single user执行是否有问题,如果否,则看awr调优系统,如果是,则看sql monitor调优sql。
10. 关于parallel的PX SEND BROADCAST,oracle会根据cost,计算是将小表broadcast到每个hash table,做table-hash好(注,根据parallel度,做成n份广播),还是将小表和大表都切成hash,做hash-hash好。(注,切的分数也根据parallel度)。
11. 一个需要收集extend statistics的案例。
12. 坏的应用设计,如“智能代码”,一串数字“752376”,前面2位代表城市,中间2位代表街道,最后2位代表房号。而在使用的时候,city=substr(code,1,2)=75,这样的使用方式,即让统计信息得不到准确的预估,有不能使用到索引(需要函数索引)。
13. 一些常用的响应指标,如CPU是纳秒级,磁盘是毫秒级别,flash是0.0x毫秒级别。
14. CPU繁忙程度,和被cpu调度到的可能性。可以看到,如果CPU50%忙,那么大约有二分之一的机会被调度到;CPU如果90%忙,那么大概就只有十分之一的机会被调度到了。
15.DB time的解释,注意在一个繁忙的系统中,DB time还包含了很多CPU调度切换的时间(浅绿色部分):
PS:课堂和课后