
tag: Sybase, Hana Cloud
在云相关技术发展迅猛的今天,数据库作为存储与分析的后端,显得非常重要。老牌数据库Sybase ASE依旧在云平台里头起作着很重要的作用,外界用户难以接触到,主要是因为”云“本身的隐蔽性,同时它很少在其它云厂商的环境下进行部署。而主要依托在SAP的云环境下边,进行了大量的部署。这个体量非常大。因而很难说,它的市场是什么样子的。
设想你是一名运维开发或测试人员,有时候一套ASE环境下来,你要快速清除某个用户下边的表,或者要让你快速统计当前库下边占用空间最多的是哪些表,它们各占用几何?
这种需求很常见。下边就简要的介绍一下各自的实现:
具体思路,比较直观:
1) 遍历所有的表, 得到每张表所有的constraints,然后全都drop掉。
2) 逐个删除所有的表
3) 遍历所有的procedure,删除
4) 遍历所有的view, 删除
写成脚本就是:
1CREATE PROCEDURE cleandbv6
2AS
3 /*
4 * Author: Sean
5 * usage :
6 * exec cleandbv6
7 * NOTE: Please never use this script in the real PROD environment. Only using in the dev/testing envrionment to initialize the DB.
8 */
9BEGIN
10 DECLARE @strdrop VARCHAR(512)
11 DECLARE @username VARCHAR(32)
12 select @strdrop=''
13 -- not suser_name, use user_name as the db user name to execute the code
14 SELECT @username=user_name()
15 SET @strdrop = 'To DELETE content under user: ' + @username
16 PRINT @strdrop
17 CREATE TABLE #TTT123(id numeric(19, 0) IDENTITY NOT NULL primary key, col2 VARCHAR(512) NULL)
18 /* 1. begin drop all constraints */
19 DECLARE @tname VARCHAR(128), @tableid INT, @cid INT, @vname VARCHAR(128)
20 DECLARE @cname VARCHAR(128)
21 set @strdrop=''
22 DECLARE c_constraints CURSOR FOR
23 select a.id, c.tableid, a.name from sysobjects a, sysusers b, sysconstraints c where a.type='RI' and a.uid=b.uid and b.name=@username and c.constrid=a.id ORDER BY c.tableid, a.name
24 open c_constraints
25 FETCH c_constraints INTO @cid, @tableid, @cname
26 while (@@sqlstatus=0)
27 begin
28 select @tname=name from sysobjects where id=@tableid
29 set @strdrop='alter table ' + @username + '.' + @tname + ' drop constraint ' + @cname
30 set @strdrop='INSERT INTO #TTT123(col2) VALUES(''' + @strdrop + ''')'
31 EXEC (@strdrop)
32 fetch c_constraints INTO @cid, @tableid, @cname
33 end
34 close c_constraints
35 deallocate cursor c_constraints
36 /*2 drop tables */
37 set @tname=''
38 set @strdrop=''
39 DECLARE c_tables CURSOR FOR
40 select a.name from sysobjects a, sysusers b where a.type='U' and a.uid=b.uid and b.name=@username
41 open c_tables
42 fetch c_tables INTO @tname
43 while (@@sqlstatus = 0)
44 begin
45 set @strdrop = 'drop table ' + @username + '.' + @tname
46 set @strdrop='INSERT INTO #TTT123(col2) VALUES(''' + @strdrop + ''')'
47 EXEC (@strdrop)
48 fetch c_tables INTO @tname
49 end
50 close c_tables
51 deallocate cursor c_tables
52
53 /*3 Views dropping */
54 set @vname=''
55 set @strdrop=''
56 DECLARE c_views CURSOR FOR
57 select a.name from sysobjects a, sysusers b where a.type='V' and a.uid=b.uid and b.name=@username
58 open c_views
59 fetch c_views INTO @vname
60 while (@@sqlstatus = 0)
61 begin
62 set @strdrop = 'drop view ' + @username + '.' + @vname
63 set @strdrop='INSERT INTO #TTT123(col2) VALUES(''' + @strdrop + ''')'
64 EXEC (@strdrop)
65 fetch c_views INTO @vname
66 end
67 close c_views
68 deallocate cursor c_views
69
70 /*4 drop procedures*/
71 DECLARE @procname VARCHAR(128)
72 DECLARE c_procs CURSOR FOR
73 select a.name from sysobjects a, sysusers b where a.type='P' and a.uid=b.uid and b.name=@username and NOT a.name='cleandbv6'
74 open c_procs
75 fetch c_procs INTO @procname
76 while (@@sqlstatus=0)
77 begin
78 set @strdrop = 'drop procedure ' + @username + '.' + @procname
79 set @strdrop='INSERT INTO #TTT123(col2) VALUES(''' + @strdrop + ''')'
80 EXEC (@strdrop)
81 fetch c_procs INTO @procname
82 end
83 close c_procs
84 deallocate cursor c_procs
85
86 /* 5 drop from the temp table #TTT123 */
87 set @strdrop=''
88 DECLARE c_tmptable CURSOR FOR
89 SELECT col2 FROM #TTT123 ORDER BY id
90 open c_tmptable
91 FETCH c_tmptable INTO @strdrop
92 while (@@sqlstatus=0)
93 begin
94 print @strdrop
95 EXEC (@strdrop)
96 fetch c_tmptable INTO @strdrop
97 end
98 close c_tmptable
99 deallocate cursor c_tmptable
100
101end
102go
103--exec cleandbv6
104--go
105
106--DROP PROC cleandbv6
107--go
最后慎重严肃提醒一下,这个脚本只用于测试开发环境。千万不要在生产环境中执行这个!!
完整的语句如下:
1select convert(varchar(30),o.name) AS table_name,
2 row_count(db_id(), o.id) AS row_count,
3 (reserved_pages(db_id(), o.id, 0) + SUM ( reserved_pages(db_id(), i.id, i.indid) ) + reserved_pages(db_id(), o.id, 255)) * (@@maxpagesize/1024) AS KBS,
4 (CASE when row_count(db_id(), o.id) = 0 then 0 else
5 CONVERT(numeric(12, 3), (reserved_pages(db_id(), o.id, 0) + SUM ( reserved_pages(db_id(), i.id, i.indid) ) + reserved_pages(db_id(), o.id, 255)) * (@@maxpagesize/1024)/(row_count(db_id(), o.id))) end) AS ROW_KBS,
6 data_pages(db_id(), o.id, 0) AS data_pages,
7 data_pages(db_id(), o.id, 0) * (@@maxpagesize/1024) AS data_kbs,
8 (data_pages(db_id(), o.id, 255) + SUM ( data_pages(db_id(), i.id, i.indid) )) AS index_pages,
9 (data_pages(db_id(), o.id, 255) + SUM ( data_pages(db_id(), i.id, i.indid) )) * (@@maxpagesize/1024) AS index_kbs
10from sysobjects o, sysindexes i
11where o.id = i.id and o.type='U' and i.indid > 0 and (i.status > 0)
12group by o.name order by KBS desc, table_name asc
我们要特别注意where条件那一行:where o.id = i.id and o.type='U' and i.indid > 0 and (i.status > 0)
这是用来过滤是否是真正的用户表的。
一个样例结果如下:
可以看看上边有一列:data_kbs, 还有一列: index_kbs,有时候你会发现index_kbs值非常大,它不仅仅是索引页,可能还是LOB数据(TEXT, IMAGE字段)分配的LOB页(也叫index页)占用特别多的空间。
我在另一篇文章有单独介绍Sybase ASE的空间膨胀,里边就专门提到了这类页空间的占用及分配问题。
Sybase ASE数据库作为SQLServer的前一代,看起来,确实有些上了年纪,但目前仍然还在大规模商用。它的物理结构上的某些特性,其实相对于完全基于文件的PG,可能还便于控制。一个设备文件里头,可以分配空间给目标数据库。这个设备文件可以非常大。它不是以目录为单位来控制空间的。以设备文件的大小来控制空间,就变得非常简单易行了,尤其在云环境里头。
当初,Sybase ASE全称叫做:Sybase SQLServer -> Sybase Adaptive Server Enterprise (与微软的MS SQLServer相区分),当然,现在全名又改了,改做SAP ASE (Adaptive Server Enterprise)。我们这些老用户叫惯了Sybase,也懒得改了。
特别景仰Michael StoneBraker这位大侠,学术工业界跨界大佬,居然在他手上搞了那么多个DBMS,随便哪一个拿出来,足以撼动整个数据库界。不过,他也在PG里头命名了很多现在让人很拗口的一些术语,基本上全是当时学院派遗留下来的,基本上所有”对象“都是”关系“: rel。于是,你看到relclass, relproc, …,total_relation_size, 到处都能看到relation的身影。

原文作者:数据库杂记;如有侵权,请联系管理员删除。