这篇博文整理自我的帖子: RAC中的gc current block busy与redo log flush
对于log file sync(本质上是 write redolog慢)引发gc buffer busy acquire /release 集群等待事件的这个命题的真伪,其实Oracle在开发性能调优组件ADDM时一早给了我们答案:
RECOMMENDATION 2: Host Configuration, 12% benefit (507182 seconds)
ACTION: Investigate the possibility of improving the performance of I/O
to the online redo log files.
RATIONALE: The average size of writes to the online redo log files was
40 K and the average time per write was 10 milliseconds.
ADDITIONAL INFORMATION:
Waits on event “log file sync” were the cause of significant database
wait on “gc buffer busy” when releasing a data block. Waits on event
“log file sync” in this instance can cause global cache contention on
remote instances.
如果你在ADDM(?/rdbms/admin/addmrpt)中找到上述文字,那么基本可以确认gc buffer busy的源头是log file sync(虽然本质上不是),那么优先解决log file sync的问题; log file sync 当然有少数的bug存在,但更多的是存储、板卡、链路等硬件因素造成的。解决了log file sync后,那么gc buffer busy往往也就解决了。
gc current block busy 等待是RAC中global cache全局缓存当前块的争用等待事件, 该等待事件时长由三个部分组成:
Time to process current block request in the cache= (pin time + flush time + send time)
gc current block flush time
The current block flush time is part of the service (or processing) time for a current block. The pending redo needs to be flushed to the log file by LGWR before LMS sends it. The operation is asynchronous in that LMS queues the request, posts LGWR, and continues
processing. The LMS would check its log flush queue for completions and then send the block, or go to sleep and be posted by LGWR. The redo log write time and redo log sync time can influence the overall service time significantly.
flush time 是Oracle为了保证Instance Recovery实例恢复机制,而要求每一个current block在本地节点local instance被修改后(modify/update) 必须要将该current block相关的redo 写入到logfile 后(要求LGWR必须完成写入后才能返回),才能由LMS进程传输给其他节点使用。
而gc buffer busy acquire/release 往往是 gc current block busy的衍生产品, 当同一实例内的 多个进程并发地访问同一个数据块时 , 首先发起的进程 将进入 gc current block busy的等待 ,而在 buffer waiter list 上的后续进程 会陷入gc buffer busy acquire/release 等待(A user on the same instance has started a remote operation on the same resource and the request has not completed yet or the block was requested by another node and the block has not been released by the local instance when the new local access was made), 这里存在一个排队效应, 即 gc current block busy是缓慢的,那么在 排队的gc buffer busy acquire/release就会更慢:
Pin time = (time to read the block into cache) + (time to modify/process the buffer)
Busy time = (average pin time) * (number of interested users waiting ahead of me)
不局限于current block (reference AWR Avg global cache current block flush time (ms)), cr block(Avg global cache cr block flush time (ms)) 也存在flush time。
可以通过 设置_cr_server_log_flush to false(LMS are/is waiting for LGWR to flush the pending redo during CR fabrication. Without going too much in to details, you can turn off the behaviour by setting _cr_server_log_flush to false.) 来禁止cr server flush redo log,_gc_log_flush(if TRUE, flush redo log before a current block transfer)来让current block transfer不用flush redo。 但是上述2个参数是有其副作用的……….. 大多数情况不要考虑去设置它们,用它们是个馊主意。
_gc_split_flush if TRUE, flush index split redo before rejecting bast FALSE ==> 控制index split redo flush,默认为FALSE
以上告诉我们 IO 在RAC中是十分重要的,特别是log file的write性能, 其重要性不亚于CPU 和 Interconnect network。
信息系统的核心是数据库,系统出问题时最先要查的就是SQL语句,怎样在浩瀚的日志中快速找到那条SQL语句是件比较痛苦的事情。 SQL语句全部大写并不能彻底解决这一问题,但在一堆代码中间找一行全部大写的字符相对容易些,你的眼睛会感谢你。
设置方法:菜单Tools --> Preferences --> Editor --> Keyword Case --> Uppercase
二. SQL Window中根据光标位置自动选择语句
设置方法:Tools -->Preferences --> Window Types --> SQL Window,将AutoSelect statement选中即可。注意,每条语句后面要加分号。
三. 自定义快捷键
设置方法:菜单Tools --> Preferences --> Key Configuration 找到想要设置的快捷键,直接键盘操作即可.
设置对比:
未设置前:执行语句为,选中要执行的语句,然后按默认的快捷键F8.
设置 SQL Window中根据光标位置自动选择语句 然后自定义快捷键,即可达到相关操作.
设置后操作:执行语句 为:将光标移动到要执行的语句位置,然后按相应的快捷键.
步骤如下:
1.) SQL Window中根据光标位置自动选择语句 Preferences --> Window Types --> SQL Window,将AutoSelect statement选中
2.)自定义快捷键 Tools --> Preferences --> Key Configuration 找到想要设置的快捷键,直接键盘操作,如我的设置为shift+Enter.即安这个快捷键时,执行语句.
其它相关设置:
设置字体:
Tools --> Preferences-->字体
设置颜色:
菜单Tools --> Preferences --> Editor
记住密码
设置方法:菜单Tools --> Preferences --> Oracle --> Logon History --> Store With Password
数据库查询总是很让人纠结,以前用的也不多,就是那么几个语句,来回倒,但是在学习的过程中发现,发现一个真理“搞不懂的问题,总是要牵绊你”,这就好比,“出来混,总是要换的”,以前的知识没有学踏实,现在必须补回来。
一、数据库连接。
很简单,不多说,只需要一下几步。
1、创建连接字符串——connectionstring。
2、生成Sqlconnection对象。
3、打开sqlconnction对象——(进行操作)
4、(操作完毕)——关闭sqlconnction对象
代码如下
'定义连接字符串 Dim strconn as string = "Data Source=xiaohong—pc; Initial Catalog=shujukumingcheng;user id=sa; password=mima" '定义连接对象 Dim conn As New SqlConnection(strconn) '打开连接 If (conn.State =ConnectionState.Closed) Then conn.Open() End If '关闭连接 conn.Close()
二、数据库查询
这里主要介绍非脱机数据库查询。
1、使用sqlcommand
(1)、创建SqlCommand对象——三种方式
A、直接New一个新的sqlcommand对象。
Dim cmd asnew sqlcommand()
Cmd.connection=conn
Cmd.commandtext=strsql
B、使用参数化构造函数
Dim cmd asnew sqlcommand(conn,strsql)
C、使用connection对象创建
Dim cmd=conn.createcommand()
Cmd.commandtext=strsql
总结:这里要说明的两点:数据库命令对象(sqlcommand)不是单独存在的,要依附于连接对象,
一定要设置sqlcommand的connection属性;有命令对象,执行就要设置commandtext,它执行内容,否则毫无意义。
(2)、使用Sqlcommand执行查询
A、执行返回行的查询
使用sqlcommand的executereader方法,返回一个sqldatareader对象,通过这个对象来检查查询的结果。
sqldatareader是一行一行读取数据库中的记录,且一次只读取一行数据。
使用:dim reader assqldatareader =cmd.executereader()
优点:执行速度快。
缺点:不可返回,读取下一行数据后,上一行数据就会消失。
注意:执行完后,关闭sqldatareader。
分析:虽然一次只可以读取一行记录,但是在数据库查询的时候,遇到返回结果集是多行记录的时候,如果不适用dataset或者datatable之类的方法时,我们也是可以使用reader的。这就需要我们每次在取出