从Oracle到PostgreSQL:动态性能视图 vs 标准统计视图
Oracle数据库的性能视图几乎可以说是最引以为骄傲的功能,在那样细粒度的采样统计强度下,依然保持卓越的性能,基于这些性能数据采样之后形成的AWR,更是Oracle DBA分析数据库性能问题的最重要手段之一。
那么在誉为最接近Oracle的开源数据库PostgreSQL中,如果要诊断性能问题,又有哪些视图可以使用呢?作为Oracle DBA,在学习PostgreSQL的时候,不可避免地会将PostgreSQL和Oracle进行比较。
以下SQL命令,在mydb=#提示符下的均为在PostgreSQL中执行的,在SQL>提示符下的均为在Oracle中执行的。
先看一下在PostgreSQL中存在那些统计信息视图。PostgreSQL中数据字典的命名还是很规范的,所有统计信息基本上都以pg_stat_开头。
mydb=# select relname from pg_class where relname like 'pg_stat_%'; relname
---------------------------------- pg_statistic pg_stats pg_stat_all_tables pg_stat_xact_all_tables pg_stat_sys_tables pg_stat_xact_sys_tables pg_stat_user_tables pg_stat_xact_user_tables pg_statio_all_tables pg_statio_sys_tables pg_statio_user_tables pg_statio_all_indexes pg_statio_sys_indexes pg_statio_user_indexes pg_statio_all_sequences pg_statio_sys_sequences pg_statio_user_sequences pg_stat_activity pg_stat_replication pg_stat_database pg_stat_database_conflicts pg_stat_user_functions pg_stat_xact_user_functions pg_stat_archiver pg_stat_bgwriter pg_stat_all_indexes pg_stat_sys_indexes pg_stat_user_indexes pg_statistic_relid_att_inh_index
(29 rows)
pg_stat_activity
该视图显示了连接入一个Cluster下所有数据库的会话的统计信息,每个会话一行记录,类似于Oracle中的V$SESSION视图。
pg_stat_activity.query字段直接显示了该会话正在执行的SQL或者上次执行的SQL语句文本。在Oracle中检查一个会话正在执行的SQL语句文本,则需要通过V$SESSION和V$SQL视图Join才可以。
pg_stat_activity.pid字段直接显示了该会话在操作系统上的进程ID,这样通过top命令看到的繁忙操作系统进程,可以很简单地通过该字段定位,来作进一步的诊断。在Oracle中则需要通过V$SESSION和V$PROCESS视图Join才可以。
pg_stat_archiver
该视图始终只有一条记录,显示了负责一个cluster下所有数据库的重做日志(PostgreSQL中称为WAL file)归档进程的统计信息,记录项比较简单。last_archived_wal和last_archived_time分别显示了最近一次归档的文件名和最近一次归档时间。
类似于Oracle中的V$ARCHIVE_DEST_STATUS。由于PostgreSQL中的归档实现实在是太简单了,所以几乎跟Oracle没有太多可比性。
pg_stat_bgwriter
该视图始终只有一条记录,显示了负责一个cluster下所有数据库的后台写进程的统计信息,也就是在操作系统中看到的postgres: writer process。该进程每隔bgwriter_delay初始化参数定义的间隔(默认200ms)会唤醒,将Buffer Pool中修改过的页写入到磁盘。跟Oracle的后台进程DBWR非常相仿。
在Oracle中没有专门记录DBWR进程的性能视图,V$BGPROCESS视图也同样没有提供类似的信息,但是在V$SYSSTAT却记录了DBWR的统计信息,这部分跟pg_stat_bgwriter中记录的信息相仿。Oracle 11gR2中有超过600项的统计信息记录在V$SYSSTAT视图中。
SQL> select NAME,VALUE from v$sysstat where upper(name) like '%DBWR%'; NAME VALUE
---------------------------------------------------------------- ----------
flash cache insert skip: DBWR overloaded 0
DBWR checkpoint buffers written 1564210
DBWR thread checkpoint buffers written 0
DBWR tablespace checkpoint buffers written 2852
DBWR parallel query checkpoint buffers written 0
DBWR object drop buffers written 324
DBWR transaction table writes 81619
DBWR undo block writes 485016
DBWR revisited being-written buffer 0
DBWR lru scans 0
DBWR checkpoints 4158
DBWR fusion writes 0 12 rows selected.
pg_stat_database
该视图对于每个database显示一行记录,PostgreSQL中的Cluster类似于Oracle的一个Instance,一个Cluster下可以创建多个database。
该视图中记录了每个数据库提交了多少事务,回滚了多少事务,读了多少数据块,查询、插入、更新、删除了多少记录(在PostgreSQL中用Tuple这个奇怪的词表示跟Row相同的概念),产生过多少死锁。总之这是一个数据库级别相对很简单的统计信息。
但是,在Oracle中还真没有与此类似的性能视图,实际上Oracle没有一个视图简单地记录了一个Schema下面总共查询或者DML了多少条记录,但是却有DBA_TAB_MODIFICATIONS这样的视图详细记录每一张表的DML数量。查询了多少数据?可能Oracle认为这个数字是太不重要了,或者说实在是太大了,完全没必要记录。
对于事务级别的统计,同样可以在Oracle的V$SYSSTAT视图中查询包含“ROLLBACK”和“COMMIT”字样的统计值,远比PostgreSQL中记录地要更多样。
pg_stat_all_tables/pg_stat_sys_tables/pg_stat_user_tables
在PostgreSQL的统计信息视图中,all表示一个数据库下所有的表,sys表示所有的系统表,user表示所有用户创建的表,这三个配套的视图我们放在一起看。以下类似的也相同。
该视图对于每张表显示一条记录,显示了一张表上进行过多少全表扫描,多少索引扫描,查询、插入、更新、删除过多少记录,表中现在有多少记录,表的分析时间等。
在Oracle中表的分析信息存储在DBA_TABLES中,而对于每个表上DML的信息如前所述,可以从DBA_TAB_MODIFICATIONS视图中查询,而经历过怎样的IO则又可以从V$SEGSTAT视图中查询。好吧,实际上,在Oracle中根本也不关注一个表上读取过多少记录这样的数字,所以在PostgreSQL中但凡跟Tuple相关的统计值在Oracle中都找不到对应的记录。对于Oracle来说,IO都以Block为单位,所以读取一条记录还是读取一个块,在IO消耗上没有区别。而至于对于返回记录数等的优化,则归结到SQL层面,那则可以通过V$SQLSTAT等一系列视图作更详细的分析。
Oracle在视图层面从Table概念和Segment概念上做了详细的区分,看似复杂,实际清晰而且详尽,而在PostgreSQL中则混为一谈了,当然在PostgreSQL中通过后面会谈到的pg_statio_系列视图又对表和索引上的IO统计信息进行了记录。
pg_stat_xact_all_tables/pg_stat_xact_sys_tables/pg_stat_xact_user_tables
该系列视图与上述相仿,只是增加了xact前缀,xact表示transaction,统计的是当前会话对于表操作的信息,这部分信息通常还没有更新到pg_stat_all_tables视图中。
在Oracle中由于性能数据的抓取粒度是如此之细,所以并未区分当前会话还是已经结束的会话,要知道V$SEGSTAT中的信息几乎是real-time在更新的。所以,在Oracle中无需此类视图。
pg_stat_all_indexes/pg_stat_sys_indexes/pg_stat_user_indexes
该视图对于每个索引显示一条记录,显示的信息如下:
mydb=# select * from pg_stat_all_indexes where relname='t1'; relid | indexrelid | schemaname | relname | indexrelname | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+---------+--------------+----------+--------------+--------------- 24604 | 24613 | public | t1 | t1_index | 3 | 58960 | 47817
(1 row)
可见记录的信息非常简单,就是一个索引上进行过多少次扫描,通过这个索引扫描读取了多少记录,返回了多少记录。
在Oracle中,由于索引是Segment的一种,因此类似的统计信息都可以从V$SEGSTAT中获取。
pg_statio_all_tables/pg_statio_sys_tables/pg_statio_user_tables
pg_statio_all_indexes/pg_statio_sys_indexes/pg_statio_user_indexes
这两部分放在一起描述,具有statio前缀的视图显示的是表或索引在数据块级别的IO统计信息,而stat前缀的视图(如前面看到的)则显示的是表或索引在记录级别的IO统计信息。以pg_statio_all_indexes为例:
mydb=# select * from pg_statio_all_indexes where relname='t1'; relid | indexrelid | schemaname | relname | indexrelname | idx_blks_read | idx_blks_hit
-------+------------+------------+---------+--------------+---------------+-------------- 24604 | 24613 | public | t1 | t1_index | 150 | 453
(1 row)
显示了读取过多少个数据块,这些读取中有多少数据块是直接命中缓存的。
在Oracle中是我们提到了多次的V$SEGSTAT视图。
pg_statio_all_sequences/pg_statio_sys_sequences/pg_statio_user_sequences
PostgreSQL对sequence上的IO独立给出了一系列视图,PostgreSQL中的sequence跟Oracle中的sequence概念基本一致,为存储序列号等的字段生成序列值。
该视图对于每个序列显示一条记录,显示的信息如下:
mydb=# select * from pg_statio_all_sequences;
relid | schemaname | relname | blks_read | blks_hit
-------+------------+--------------+-----------+---------- 24614 | public | users_id_seq | 1 | 3
(1 row)
非常简单,显示了读取过多少个数据块,多少数据块的读取是直接命中缓存的。
在Oracle中,由于序列是系统自身对象的一部分,因此如果要诊断跟序列相关的问题,通常要依赖等待事件,比如“enq: SQ – contention”或者“row cache lock”,另外在V$ROWCACHE视图中存储了与序列相关的整体统计值。
SQL> select PARAMETER,GETS,GETMISSES from v$rowcache where PARAMETER='dc_sequences'; PARAMETER GETS GETMISSES
-------------------------------- ---------- ----------
dc_sequences 2145 54
pg_stat_user_functions/pg_stat_xact_user_functions
有xact前缀和没有前缀的区别在前面描述pg_stat_xact_all_tables系列视图时已经提过,因此放在一起描述。
该视图对于每个指定要跟踪的用户自定义函数显示一条记录,这通过初始化参数track_functions来控制,默认不开启任何跟踪,视图结构如下:
mydb=# \d pg_stat_user_functions
View "pg_catalog.pg_stat_user_functions" Column | Type | Modifiers
------------+------------------+----------- funcid | oid | schemaname | name | funcname | name | calls | bigint | total_time | double precision | self_time | double precision |
calls字段记录了对于用户函数进行过多少次调用;
total_time字段记录了运行这个函数总共消耗了多长时间(毫秒为单位),包括调用其它函数的时间;
self_time字段记录了运行这个函数本身消耗了多长时间(毫秒为单位),不包括调用其它函数的时间。
Oracle中没有类似的视图,Oracle的关于函数或者存储过程的执行统计信息,都是详细到其中每一条SQL语句的,实际上如果像PostgreSQL这样能有一个函数或者存储过程级别的性能统计值,也是极好的。
pg_stat_replication
在设置了复制的环境中,该视图对于每个WAL sender进程(WAL sender进程负责将本机的重做日志发送到远端复制环境)显示一条记录,显示内容大致如下:
postgres=# select pid,application_name,client_addr,state,sent_location,replay_location from pg_stat_replication; pid | application_name | client_addr | state | sent_location | replay_location
-------+------------------+----------------+-----------+---------------+----------------- 27855 | walreceiver | 192.168.56.105 | streaming | 0/50188CE8 | 0/50188CE8
(1 row)
每个视图中都能直接显示操作系统进程ID,实在是很方便的事情。在操作系统上可以直接查看pid=27855的进程。
[root@pg1-enmotech-com ~]# ps -ef|grep 2785|grep postgres
postgres 27855 1119 0 00:45 ? 00:00:00 postgres: wal sender process postgres 192.168.56.105(57046) streaming 0/50188CE8
从操作系统的ps命令中看到实际上已经将视图中的这些字段内容更新到了该进程描述中,在进程描述中会更新一些很有用的信息(比如server进程的状态,是等待还是空闲等),这也是PostgreSQL非常方便的一个地方。
在Oracle中与PostgreSQL的复制相类似的功能是Physical Data Guard,在DG中重做日志的传输是通过归档路径来完成的,因此类似的信息可以从V$ARCHIVE_DEST_STATUS和V$MANAGED_STANDBY视图中获取。
pg_stat_database_conflicts
该视图仅对于Standby数据库有效,对于每个数据库显示一条记录,显示内容如下:
postgres=# select * from pg_stat_database_conflicts; datid | datname | confl_tablespace | confl_lock | confl_snapshot | confl_bufferpin | confl_deadlock
-------+-----------+------------------+------------+----------------+-----------------+---------------- 1 | template1 | 0 | 0 | 0 | 0 | 0 13051 | template0 | 0 | 0 | 0 | 0 | 0 13056 | postgres | 0 | 0 | 0 | 0 | 0 16384 | mydb | 0 | 0 | 0 | 0 | 0 24587 | mydb_bak | 0 | 0 | 0 | 0 | 0
(5 rows)
由于PostgreSQL的机制,在备库上的查询会跟一些诸如删除表空间、删除数据库、vacuum cleanup的操作相冲突,为了不让备库的WAL replay操作延时太久,PostgreSQL内建了强制取消当前备库上运行的查询以避免跟应用重做日志这样更重要的动作相冲突的机制。而该视图则是记录由于不同原因取消掉的查询的次数。对于每个数据库显示一条记录。
Oracle中不会出现这样的问题,因此也没有相应的视图。
总结
当然,PostgreSQL中除了这些统计信息视图之外,还有不少类似于pg_tables,pg_users这样与Oracle中的数据字典视图相仿的视图,另外还有比如pg_locks这样用于记录锁信息的诊断视图。但是仅仅用一篇文章的长度就可以将所有的统计信息视图全部介绍完毕,PostgreSQL确实是很简洁的数据库。
张乐奕
ACOUG联合创始人,Oracle ACE总监
盖国强:从 Oracle 到 PostgreSQL :从 Uptime 到数据库实例运行时间
编辑:尹文敏
公司简介 | 恩墨学院 | 招聘 | DTCC | 数据技术嘉年华 | 免费课程 | 入驻华为严选商城
zCloud | SQM | Bethune Pro2 | zData一体机 | Mydata一体机 | ZDBM 备份一体机
Oracle技术架构 | 免费课程 | 数据库排行榜 | DBASK问题集萃 | 技术通讯
升级迁移 | 性能优化 | 智能整合 | 安全保障 |
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
从Oracle到PostgreSQL:动态性能视图 vs 标准统计视图相关推荐
- 十三、oracle 数据字典和动态性能视图
一.概念 数据字典是oracle数据库中最重要的组成部分,它提供了数据库的一些系统信息. 动态性能视图记载了例程启动后的相关信息. 二.数据字典 1).数据字典记录了数据库的系统信息,它是只读表和视图 ...
- ORACLE常用的动态性能视图
V$FIXED_TABLE用于列出所有可用的动态性能视图和动态性能表. V$INSTANCE用于获取当前例程的详细信息. V$SGA用于取得SGA更详细的信息. V$PARAMETER用于取得初始化参 ...
- Oracle 原理 : 动态性能视图和数据字典
Oracle 的数据字典包含了两部分:数据字典表和数据字典视图.数据字典基本表是由$ORACLE_HOME\RDBMS\ADMIN\sql.bsq这文件所创建.表名大多以$结尾,属于sys用户,放在S ...
- oracle报错查询动态视图,oracle基表和动态性能视图
1. 数据字典是oracle数据库中最重要的组成部分,它提供了数据库的一些系统信息.它是只读表和视图的集合,所有者为sys用户.用户自能在数据字典上执行查询操作,而维护和修改是由系统自动完成的. 数据 ...
- oracle 查看动态性能视图,oracle常用动态性能视图
今天通过视频学习,和网上搜索总结了一些oracle 常用的动态性能视图和大家分享 要查看oralce有哪些可用的动态性能视图可以看v$fixed_table 1.关于数据库/实例的动态性能视图 v$d ...
- oracle表是动态表怎么算排名,Oracle学习动态性能表
按照OracleDocument中的描述,v$sysstat存储自数据库实例运行那刻起就开始累计全实例(instance-wide)的资源使用情况. 类似于v$s Oracle 学习动态性能表 v$l ...
- DBA必知的170张Oracle常用动态性能表介绍
DBA必知的170张Oracle常用动态性能表介绍 常用动态性能表.pdf 附录C 动态性能(V$)视图 本附录介绍动态性能视图.这些视图一般作为V$视图引用.本附录包括下列内容: ???? 动态性 ...
- oracle 条件动态视图,oracle最重要的9个动态性能视图
oracle最重要的9个动态性能视图 v$session v$session_wait (在10g里功能被整合,凑合算1个吧.) v$process v$sql v$sqltext v$bh (更宁愿 ...
- Oracle 9i学习日志(9)--数据字典与动态性能视图及练习
一.数据字典 不仅是每个Oracle数据库的核心组件之一,也是所有数据库用户重要的信息资源:描述数据与对象的数据:包含只读的表和视图:存储在系统表空间:所有者为sys:由Oracle server维护 ...
最新文章
- .NET中的加密算法总结(自定义加密Helper类续)
- 《系统集成项目管理工程师》必背100个知识点-76配置审计
- NOIp 2014 #2 联合权值 Label:图论 !!!未AC
- 【easy】206. Reverse Linked List 链表反转
- 如何在站点静态文件下查找某关键字并修改文件名?
- java.net.UnknownServiceException: CLEARTEXT communication to wanandroid.com not permitted by network
- C/C++构造及析构顺序及变量的生命周期
- 23.vs2015创建Qt界面动态库
- 电脑内存16g和32g,有什么区别?
- ASP.NET之通过JS向服务端(后台)发出请求(__doPostBack is undefined)
- django-dynamic-scraper(DDS)配置中的一些问题
- tt按键精灵从入门到精通完整版
- mp4文件如何转换为webm格式
- OBJ(3D模型)文件格式
- 数据库原理必背简答题【计算机考研复试】
- cd在linux命令意思,linux的cd .. 和cd / 命令分别是什么意思?
- python-小米-句子反转
- 百度地图结合echarts实现飞线
- 用防火墙可以防御DDoS攻击吗?
- 计算机播放音乐无声音,笔记本电脑放歌没声音的解决方法
热门文章
- 开源压缩算法brotli_Google的Brotli压缩算法,C ++核心准则以及更多新闻
- C语言自增自减运算辨析
- es6 for...of 循环
- 习题7.10 使用割线法求解方程
- oracle内存最多用到2g,在Oracle数据库中如何使用超过2G内存
- mongodb 存储过程 遍历表数据_一个mongodb存储过程
- img pdf 展示_pdf.js实现图片在线预览
- mysql innodb myisam 区别_InnoDB与MyISAM的六大区别_MySQL
- antdesign 柱状图_以Ant Design为例:看B端设计的基本套路
- 从零开始的LCA(最近公共祖先)