学习总结
当客户端向数据库发起一条select查询语句,首先到达数据库监听,数据库监听会为该客户端和数据库服务器之间建立起一个独自的连接,这样客户端就可以直接和数据库通信了。
监听常见的问题:dns解析有问题:nslookup命令查看域名
当客户端和数据库建立一条通信以后,数据库首先验证客户端数据库登录用户和密码。
数据库的现象是大量的library cahce lock等待事件,v$session中用户为空,
awr时间模型统计也能看到用户登录失败的信息排在前面(没有实际的awr,下图仅为表示在哪里)
客户端成功登录后,开始执行select查询语句,sql语句传输到数据库后,数据库会将sql转化为对应的ascii值,然后按照hash算法计算出该sql对应的hash值。
去share pool的library cache中查找sql对应的hash值是否存在,如果不存在则进行以下步骤。
3)获取对象相关的解析锁(相关对象处:library cache:mutex x)
表的连接方式:nsloop,hash join,排序合并连接
适合场景:小表驱动大表,驱动表结果集比较少,被驱动表的关联条件选择行比较高,最好走(index unique scan和index range scan),返回较少的结果集
索引扫描方式:索引唯一扫描,索引范围扫描,索引全扫描,索引快速全扫描,索引跳跃扫描
按照上诉的各种信息,查询优化器进行各种计算(算出各种场景的cbo),得出最优的执行计划
当遇到复杂的查询时(层次查询,union all等)将会固定查询计划,这时候就需要sql改写。
存储过程使用批量操作bluck into 和 forall组合。
如果library cache中能找到sql对应的hash值,上述1,2,3,4,5步骤可直接跳过
首先查看sga中是否存在所需的数据,如果没有,需要读取磁盘,将相关数据加载到内存中。
lru链表,当数据块被加载到sga中,负责分配数据块到那个地方及覆盖那些不常用的数据块。
当有数据需要被加载到内存中时,首先扫描lru链表查找是否存在可用的内存块。
当扫描超过一定范围时,就会触犯free buffer wait等待事件,该等待事件会触发dbwr进程写脏块。
用户从内存中读取所需的数据时,数据在内存中会按照hash算法分配到不同的bucket中,
为了保护内存的数据结构,会引入一个latch锁来保护。一个latch可能保护多个bucket。
所以当sql查询的结果集较多或频繁的修改某个数据块时,会引起latch的争用。
常见的等待事件为:latch buffer cache chain(热块或者热链)
sql优化(减少结果集,隐藏参数生成更多的bucket),热快(缓存等 ·· )
buffer busy wait(数据块,undo块,索引块)
当修改某个数据块,该数据块正在被其他会话占用。基本都是dml语句造成。
如果sql语句是dml语句,将内存中需要数据块copy一份,并且在块头事务槽中插入事务相关信息,对数据进行修改。(以前的内存块就是cr块)
将变更的信息(修改的数据内容,及源数据内容,undo相关信息)写入redo buffer,lgwr进程负责将log buffer内容持久化。
常见的等待事件:log file sync(数据库事务多,redo磁盘性能差)
redo logfile文件太小(默认50m,增加redo logfiel大小)
查看log file parallel write的avg wait判断是否是磁盘性能问题
在undo表空间充足的情况下,为每个事务单独分配独立的回滚段
share pool是当前oracle 内存中最容易发生问题的地方。
硬解析:latch share pool library cache:mutex x,latch:row cache objects
软解析:cursor:mutex x cursor: mutex S
软软解析:cursor: pin X cursor: pin S cursor: pin S wait on X
存储过程编译:library cache lock library cache pin cursor: pin S wait on X
某业务拼接了一个sql,sql有20w行,导致sql一直卡在解析那个步骤,同时占用相关的对象资源未释放,导致其他会话解析相关的对象时,发生等待。查看v$session视图的blocking_session会话源头就是正在解析的那个sql。
当时相关的等待事件:library cache:mutex x及library cache lock