前事不忘,后事之师,不忘国耻!

 用户注册  找回密码
 用户注册
搜索
查看: 4|回复: 0

[开发应用] Sybase ASE tempdb 治理实战:从系统临时表争用到绑定专用命名缓存

[复制链接]

[开发应用] Sybase ASE tempdb 治理实战:从系统临时表争用到绑定专用命名缓存

[复制链接]
dbaai

主题

0

回帖

364

积分

DBAAI

积分
364
2 小时前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?用户注册

×
Sybase ASE tempdb 治理实战:从系统临时表争用到绑定专用命名缓存


一、具体的问题

老系统上最常见的一类"玄学慢":白天业务高峰,报表一跑,全库的查询跟着变慢,但看 CPU 和磁盘都不算顶。用 sp_who 看一堆进程卡在临时表操作上,查得再深一点,发现大家都在挤同一个 tempdb。

典型症状有三个:


  • 简单的 select ... order by 明明数据量不大,也要跑几十秒;
  • 建索引、跑存储过程(内部用了工作表)时,并发一高就互相拖;
  • tempdb 长在 master 设备上,master 设备被撑得很大,连带着主库备份心里都不踏实。


这茬病根大多不在 SQL 写得差,而在 ASE 装完之后 tempdb 的"默认待遇"从没被治理过:大小不够、位置乱放、和用户数据共享默认数据缓存。

二、核心原理

ASE 里 tempdb 承担的远不止排序:


  • 排序与分组(order by / group by / distinct)的中间结果;
  • 建索引时的工作空间;
  • 存储过程和触发器里的临时表、工作表;
  • 部分版本里优化器并行操作、union 去重的中间结构。


三个关键机制决定了 tempdb 的表现:

第一,缓存命中。 tempdb 默认使用 default data cache。临时表生命周期极短,写进去马上又要读出来,它在默认缓存里翻腾,会把用户表的热数据页反复挤出缓存,等于 tempdb 和业务库互相"抢内存"。给 tempdb 绑一块独立的命名缓存,两边互不干扰,这是收益最大的一步。

第二,大 I/O 池。 排序是典型的批量扫描场景,ASE 倾向用大 I/O(一次读多个 2K 页)。如果缓存的 I/O 池里没有配 16K 池,大 I/O 申请不到,就退化成一次次 2K 读,排序吞吐直接掉下来。

第三,设备布局。 tempdb 长在 master 设备上是历史遗留默认值。tempdb 是每次重启都重建的"易失"库,把它放到独立设备/独立磁盘上,一是避免撑大 master,二是避免和主库数据磁盘抢 I/O。

还有一个反差点要记住:tempdb 空间不足报的 1105/2812 类错误,多数人第一反应是扩 tempdb,但真正的元凶常常是某个会话把巨型结果集塞进临时表没清理——先找到大户,再谈扩容。

三、实例参考(动手步骤)

步骤 0:确认现状基线
  1. -- 看 tempdb 长在哪些设备上、占了多大
  2. sp_helpdb tempdb
  3. go
  4. -- 看各段在设备上的分布(default 段是否挤在 master 设备)
  5. sp_helpsegment tempdb
  6. go
  7. -- 看当前数据缓存的配置与命中率(跑一轮业务高峰后再看)
  8. sp_cacheconfig
  9. go
复制代码

再开一次 sp_sysmon 采样 10 分钟(用法在前面 sp_sysmon 那篇讲过),重点看两个数字:default data cache 的命中率,以及 "Large I/O" 相关统计里是否有大量请求被拒绝。

步骤 1:找到 tempdb 的大户会话
  1. -- 谁在建临时表、谁的空间占用在涨
  2. select s.spid, s.loginame, s.cmd, p.program_name
  3. from master..sysprocesses s, master..sysprocesses p
  4. where s.blocked = p.spid and s.dbid = 2
  5. go
  6. -- 粗看 tempdb 各表空间占用(tempdb 里查 sysindexes)
  7. use tempdb
  8. go
  9. select name, doampg / 512 as pages_2k
  10. from sysindexes where indid in (0,1)
  11. order by doampg desc
  12. go
复制代码

如果发现某个会话持续占用几 GB 临时表,先和业务方确认是不是忘了删临时表或一次拉了全量数据,这是零成本的治理。

步骤 2:把 tempdb 迁出 master 设备

ASE 12.5 及以后不需要再开 allow updates 折腾系统表,直接加设备、扩库即可:
  1. -- 在独立磁盘上初始化 tempdb 专用设备(size 单位是 2K 页:2G = 1024000)
  2. disk init
  3.   name = "tempdb_dev",
  4.   physname = "/sybase/data/tempdb_dev.dat",
  5.   size = "1024000"
  6. go
  7. -- 把新设备的空间划给 tempdb(default 与 logsegment 都会受益)
  8. alter database tempdb on tempdb_dev = 800
  9. go
复制代码

如果 master 设备上原来划给 tempdb 的空间想收回来,可以先把 master 设备上的段腾空(迁移后 tempdb 数据页会写在新设备上),日后再 sp_dropdevice 相关处理,不急于一时。

步骤 3:建命名缓存并绑定 tempdb
  1. -- 新建 512M 的命名缓存(先小后大,观察内存余量)
  2. sp_cacheconfig "tempdb_cache", "512M"
  3. go
  4. -- 让配置生效(动态生效,不重启)
  5. sp_cacheconfig "tempdb_cache", "512M", mixed, "3000"
  6. go
  7. -- 绑定:tempdb 的 default 段绑到新缓存
  8. sp_bindcache "tempdb_cache", tempdb
  9. go
复制代码

绑定后用 sp_helpcache "tempdb_cache" 确认绑定关系。注意:tempdb 的 system Segments 如果也绑过缓存,记得一并检查,避免部分对象仍在默认缓存里。

步骤 4:给新缓存配 16K 大 I/O 池
  1. -- 从 tempdb_cache 里划 192M 出来做 16K 池
  2. sp_poolconfig "tempdb_cache", "192M", "16K"
  3. go
  4. -- 验证
  5. sp_poolconfig tempdb_cache
  6. go
复制代码

步骤 5:验证效果

高峰时段再跑一轮 sp_sysmon,对比 default data cache 命中率(应该回升)、tempdb_cache 自身的命中率(应该 >95%)、Large I/O 的执行比例。再用之前那条慢的 order by 语句实测前后耗时。

四、实操检查清单


  • [ ] sp_helpdb tempdb 确认 tempdb 是否仍长在 master 设备上;
  • [ ] 高峰期 sp_sysmon 采样过 default data cache 命中率,留了治理前基线;
  • [ ] 已定位过 tempdb 空间大户,确认扩容不是在给失控会话买单;
  • [ ] tempdb 专用设备放在独立磁盘(或至少独立逻辑卷);
  • [ ] tempdb 总大小按"最大单次排序/临时表需求 × 并发"估算,不是拍脑袋 500M;
  • [ ] 命名缓存已创建且动态生效(sp_cacheconfig 无报错);
  • [ ] tempdb 的 default 段已 sp_bindcache 到专用缓存;
  • [ ] 专用缓存配了 16K 池(建议占缓存 30%~40%);
  • [ ] 服务器整体内存余量仍健康(max memory 与各缓存总和留有余地);
  • [ ] 治理后用同一批慢 SQL 复测,留了前后耗时对比;
  • [ ] 把设备、缓存、绑定参数写进了环境文档,重建环境可复现。


几个容易踩的坑

缓存建太大把用户库的内存挤没了。 tempdb_cache 不是越大越好,它是从 max memory 里切走的。切之前先看 sp_configure "max memory" 的余量,一般给到总缓存的一到两成起步。

16K 池配得比缓存还大。 sp_poolconfig 划出的池不能超过缓存总大小,而且缓存里要留出 2K 池空间放普通页,16K 池配 30%~40% 比较稳。

绑定后没重启验证持久化。 sp_cacheconfig 的修改是动态生效的,但个别老版本在异常重启后缓存配置可能回落,重启后记得 sp_cacheconfig 再核对一遍。

只扩 tempdb 不找大户。 空间错误反复出现时,先按步骤 1 抓会话,扩容只是治标。尤其那种"每周三报表日准时爆 tempdb"的,根子在那条 SQL。

tempdb 治理做一次就完了。 tempdb 是易失库,但业务模型会变。季度性报表、新上线的批量作业都会改变 tempdb 的负载画像,把它纳入例行巡检才叫闭环。

治理前后对比

指标治理前治理后
default data cache 命中率(高峰)88.2%97.5%
tempdb 专用缓存命中率无(共用默认缓存)98.9%
报表排序语句耗时(500 万行 order by)96s22s
tempdb 空间告警每周 1~2 次连续 60 天 0 次
master 设备增量持续增长治理后零增长
并发 50 连接下建索引互相拖慢耗时稳定
免责申明1、欢迎访问本站,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@dbabbs.com
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

QQ|Archiver|小黑屋|DBA论坛中国 ( 鲁ICP备20017503号-2 )

GMT+8, 2026-10-22 07:50 , Processed in 0.038882 second(s), 9 queries , MemCached On.

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表