学习内容关键字:
DM动态视图查询、慢SQL调优、sqllog分析思路、数据库运维监控、gdb分析core堆栈
1.DM8动态视图获取及管理经验汇总
概述:通过动态视图更快收集数据库中的信息,基于获取到的信息能更高效的运维和制定相应管理策略
1.1 常用动态视图
查询刷盘( v$mtab_used_history)
定位慢SQL( v$sql_history)
hash连接刷盘(v$hash_merge_used_history)
排序刷盘(v$sort_history)
查看资源信息 (V$SYSSTAT)
统计信息(v$sysstat)
1.2 查看页大小、簇大小、大小写敏感、字符集信息
可以通过搜索dm.ini中的相关配置,或使用:
v$segment_info查看段信息、
v$extents显示所有的簇信息、
v$segementinfo查找索引、
v$btree_inner_pages/v$btree_leaf_pages查看索引的页字段/内节点段的页信息视图、
v$btree_inner_pages查看表中大字段的页信息视图、
v$lob_seg查看个表大字段的段首页中记录的信息、
v$resource_limit显示表的空间限制信息、
v$segment_pages显示段中数据页的信息视图、
v$pseg_sys显示当前回滚段信息、
v$pseg_items显示回滚系统中当前回滚项信息、
v$pseg_commit_trx显示回滚项中已提交但未purge的事务信息、
v$pseg_page_info显示当前回滚页信息、
v$purge显示当前purge回滚段信息、
v$purge_pseg_obj显示purge系统中,正在待purge的所有对象purge信息、
v$purge_pseg_tab显示待purge表信息
1.3 查看dm服务状态以及版本号信息
包含license、版本、数据文件、错误码、所有权等:
v$license显示license信息
v$version显示版本信息,包括服务器版本号和DB版本号
v$datafile显示数据文件信息
v$database显示数据库信息
v$id显示下一个创建的数据库对象的id
v$instance显示实例信息
gv$instance显示全局实例信息
v$reserved_words显示关键字和保留字的分类信息
v$err_info显示系统中的错误码信息
v$hint_ini_info显示支持的hint参数信息
v$dynamic_tables显示当前数据库中的动态视图
v$dynamic_table_columns显示当前数据库中所有动态视图的列信息
v$authorities显示当前数据库中的所有权信息
1.4 统计数据库中各个用户下的不同对象信息
数据库对象包括表空间、序列、包、索引和函数等:
v$tablespace显示表空间信息
v$huge_tablespace显示混合表空间的huge数据文件副本策略和路径统计信息
v$huge_tablespace_path显示混合表空间的huge数据文件路径信息
v$seqcache显示当前系统中缓存的序列的信息
v$pkgprocs显示当前用户拥有执行权限的包中方法
v$pkgprocinfos显示当前用户拥有执行权限的包中方法的相关信息
v$pkgprocparams显示当前用户拥有执行权限的报中方法的参数信息
v$db_cache数据字典缓存表,用于记录数据字典的实时信息
v$db_object_cache显示数据字典对象缓存表,用于记录数据字典中每个对象的信息
v$object_usage记录索引监控信息
v$ifun显示数据库提供的所有函数
v$ifun_arg显示数据库提供的所有函数的参数
v$sysstat显示系统中统计对象的信息
v$jobs_running显示系统中正在执行的作业信息
v$auto_stat_table_idu用户表中增删改数据的实时变化信息(要AUTO_STAT_OBJ=1)
v$hfile显示当前系统打开的huge表列中存储的文件信息
v$policy_cache记录缓存中的对象策略信息
v$policy_cache_item记录指定对象的具体策略信息,需要带where条件并指定对象id
v$sessstat和sysstat类似,但sessstat显示当前会话的统计信息
2.慢SQL语句信息统计及调整
2.1获取慢SQL
--获取目前执行时间较长的SQL
select datediff(ss, last_recv_time, sysdate) ss ,
dbms_lob.substr(sf_get_session_sql(sess_id)), --抓取sql的全部内容
curr_sch,
sess_id,
substr(clnt_ip, 8, instr(clnt_ip,':',8)-8)
from v$sessions
where state='ACTIVE'
order by 1 desc;
--查询最近10000条SLQ历史记录,按照耗时倒序排列
SELECT * FROM v$sql_history ORDER BY time_used DESC;
--查询显示系统自启动以来执行时间最长的300条SQL语句
SELECT * FROM V$SYSTEM_LONG_EXEC_SQLS ORDER BY EXEC_TIME DESC;
--历史SQL EXEC_TIME执行时间 MAX_MEM_USED内存使用峰值(K)
SELECT SQL_TXT,EXEC_TIME,MAX_MEM_USED/1024 FROM V$SQL_STAT_HISTORY ORDER BY 3 DESC;
--当前SQL
SELECT SQL_TXT,EXEC_TIME,MAX_MEM_USED/1024 FROM V$SQL_STAT ORDER BY 3 DESC;
--统计历史慢SQL执行情况
SELECT sql_text,
COUNT(0) 执行次数,
MAX(EXEC_TIME) 最大执行时间,
TRUNC(AVG(EXEC_TIME),2) 平均执行时间
FROM v$long_exec_sqls a
GROUP BY sql_text
ORDER BY COUNT(0) DESC,
MAX(EXEC_TIME);
2.2慢SLQ应急处理方法
--清理执行计划
SP_CLEAR_PLAN_CACHE(plan_id);
plan_id:指定计划 ID,其值可以从动态视图 V$CACHEPLN 中的 CACHE_ITEM 列获得
select CACHE_ITEM, from SYS."V$CACHEPLN" where sqlstr like '%LEFT JOIN tss.QN_TELEPHONE_RECORD_TASK%';
--查杀执行时间超过300s
select datediff(ss, last_recv_time, sysdate) ss ,
dbms_lob.substr(sf_get_session_sql(sess_id)), --抓取sql的全部内容
'sp_close_session('||sess_id||');'
from v$sessions
where state='ACTIVE' and datediff(ss, last_recv_time, sysdate) >100;
2.3 慢SQL日常处理方法
- 更新统计信息:分析表数据量与统计信息下的数据量差值是否较大,较大时需要重新收集统计信息
select count(*) from SCHEMA.TABLENAME;--查询表的数据量
--统计信息查询
dbms_stats.table_stats_show('SCHEMA','TABLENAME');--查询表的数据量
dbms_stats.index_stats_show('SCHEMA','INDEXNAME');--查询索引的数据量
dbms_stats.column_stats_show('SCHEMA','TABLENAME','COLUMNNAME');--查询字段数据量
--更新表的统计信息
DBMS_STATS.GATHER_TABLE_STATS('SCHEMA','TABLENAME', NULL, 100, TRUE, 'FOR ALL COLUMNS SIZE AUTO');
--更新索引的统计信息
DBMS_STATS.GATHER_INDEX_STATS('SCHEMA',REC.INDEX_NAME,NULL,100);
--服务器使用脚本更新统计信息
/opt/dmdbms/jdk/bin/java -jar ./statcmd-1.0.4.jar 16 SCHEMA TABLENAME 0 SYSDBA/'密码'@IP:端口
1. 添加索引:当查询sql比较慢,执行计划中显示走的全表扫描,可以针对条件字段添加索引或者组合索引
--普通索引
CREATE INDEX "IDXNAME" ON "'SCHEMA'"."TABLENAME"("'COLUMNNAME'" ASC) ONLINE;
--组合索引
CREATE INDEX "IDXNAME" ON "'SCHEMA'"."TABLENAME"("'COLUMNNAME1'" ASC,"'COLUMNNAME2'" ASC) ONLINE;
2. 添加hint:通过执行计划,发现部分表有索引但走的全表扫描,或者条件中有or之类的判断时,可以通过添加hint方式,改变sql的执行计划,优化执行效率
常用的hint:
/*+INDEX(TABLENAME, IDX_NAME)*/--强制使用索引;
/*+ENABLE_HASH_JOIN(0)*/--禁用hash join关联;
/*+OPTIMIZER_OR_NBEXP(2)*/--条件中含有or时可以使用;
--/*+ENABLE_RQ_TO_NONREF_SPL(3)*/--执行计划中有SPL时使用。
3. 绑定hint:实际生产中,部分慢SQL执行频率较高、业务短期内没有升级需求或者其他特殊情况,无法及时处理,可以通过模糊绑定hint方式,使sql强制走hint的执行计划
--模糊绑定 部分SQL
SF_INJECT_HINT('SQL_TEXT ','HINT_TEXT', 'add_optimize_or01', '', TRUE, NULL);
·SQL_TEXT为需要添加hint的sql文本,必须跟查出来的慢SQL结构保持一致,且尽量保证不与其他sql相同。
·HINT_TEXT是具体绑定的hint内容,如ENABLE_HASH_JOIN(0)。
·add_optimize_or01是绑定的名称,类似主键ID。
--查询所有绑定的SQL:
select * from SYSINJECTHINT;
3.数据库运维监控相关
3.1内存相关
total = used + free +buff/cache
available = free + buff/cache(部分)
问题:swappines(取值范围1~100)
解决:
检查:cat /proc/sys/vm/sqappiness
修改:vim /etc/sysctl.conf
vm.swappiness = 10
sysctl -p 生效
问题:arena相关
解决:MALLOC_ARENA_MAX = 1(大大降低数据库内存使用)
3.2磁盘相关
%iowait值过高,表示存在I/O瓶颈
%idle过高,表明CPU较空闲
%idle值持续低于10,表明CPU处理能力相对较低
注意:系统中最需要先解决的资源是CPU
dd命令测试磁盘写入速度:
dd if=/dev/zero of=test bs=8k count=64k oflag=dsync
3.3网络(集群环境)
集群架构环境需要重点关注
使用nmon或DEM监控
保证网络连通性
3.4服务器时间同步
正式生产环境建议添加NTP服务器进行时间同步
影响集群MAL系统
影响与时间戳相关的服务
3.5操作系统命令
top:显示系统整体和各个进程的资源使用情况
pref top:可以实时查看当前系统进程函数占用率情况
free:显示物理内存与交换分区使用情况
dd:对比磁盘写入性能以相同bs为基础,oflag=dsync
iostat:监控设备io负载情况
netstat:监控网络接口状态和统计信息
ethtool:查询和设置网卡设备信息,关注网卡工作速度
lsblk:查看磁盘LVM关系
3.6第三方工具
nmon:推荐正式环境部署
Zabbix:企业级的分布式开源监控解决方案,能够提供对众多服务器及软件的监控
Prometheus:使用DEM提供的接口进行资源监控
3.7数据库运维相关思考
大部分问题都是直接或间接由于外部因素变化而导致,包括但不限于业务模块变更、数据对象结构变更、数据量陡增、并发量陡增、网络环境变更、存储环境变更,需要多沟通保持信息同步,避免高风险操作,涉及到业务系统要做好评估后再进行操作。
4.SQL日志分析
4.1优化目标
并发非常高:SQL数量少于5%,但执行频率高达每秒上百次,只要一慢则可能瘫痪,应当最优先处理。
并发一般:SQL占大多数约80%,有执行较慢的对系统整体稳定性影响不大,次优先处理。
并发很少但特别慢:数量少于15%,通常是复杂查询,一天仅执行几次,对系统影响小且优化难度大,最后处理。
4.2优化思路
高并发情况将单个SQL调整至最快,对于低并发的复杂SQL最后再处理
5.gdb分析core文件
5.1使用流程
确保系统上安装了GDB
使用GDB打开产生core文件的程序
加载core文件
查看堆栈跟踪以确定导致崩溃的代码位置
5.2应用示例
eg Bash: gdb <executable> <core-file>
eg GDB: (gdb) info threads
(gdb) thread <thread-number>
(gdb) bt
(gdb) frame <frame-number>
(gdb) list
说明:
<executable> 是导致生成core文件的程序名,<core-file> 是生成的core文件名,<thread-number> 是线程编号,<frame-number> 是堆栈帧编号;
info threads 查看所有线程的信息, thread 切换到崩溃线程,bt (backtrace) 查看堆栈跟踪,frame 命令可以用来查看特定的堆栈帧,list 命令显示源码;
如果程序在不同的机器上编译则需要指定与程序编译时相同的调试符号文件。
6. 本周遇到的问题及解决方式
有时候sql非常复杂,用了大量的表和索引,又不确定统计信息是否准
——可以用explain for +SQL的方式,能够显示出用了哪些表和索引,拷贝到excel里,去重一下,针对用到的表和索引去收集下统计信息;
回滚表空间ROLL过大
——业务系统的INSERT , UPDATE , DELETE 操作都会占用回滚表空间,这类事务都存在可以回滚的情况,当表空间数据文件大小增长后,就算事务提交,数据文件不会自动变小,但里面的空闲比率会变大,可以定时自动查询并记录未提交事务;
详细分析Linux中的core dump异常
——一些常见的导致 core dump 的错误:
段错误(Segmentation fault):程序访问了无效的内存地址,比如试图访问未分配的内存或者已经释放的内存
空指针引用(Null pointer dereference):程序试图使用空指针(null pointer)访问内存中的数据时,会导致空指针引用错误
内存访问越界(Out of bounds memory access):程序试图访问数组或者其他数据结构超出其边界范围的内存,就会发生内存访问越界错误
使用已释放的内存(Use after free):程序试图在已经释放的内存地址上进行读取或写入操作时,就会发生使用已释放的内存错误
栈溢出(Stack overflow):程序递归调用层数过深或者在栈上分配了过多的内存时,会导致栈溢出错误
无效的指令或操作码(Invalid instruction or opcode):执行了不存在或无效的机器指令或操作码,会导致无效指令错误
硬件故障或操作系统错误:如内存损坏、内核崩溃等情况