龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 数据库类 > Oracle 技术 >

Oracle Redo log并行机制详解(1)(2)

时间:2011-04-12 23:18来源:未知 作者:admin 点击:
分享到:
注意:对于未能获取到Private strand的redo allocation latch的事务,在事务结束前,即使已经有其它事务释放了Private strand,也不会再申请Private strand了。 每个P

注意:对于未能获取到Private strand的redo allocation latch的事务,在事务结束前,即使已经有其它事务释放了Private strand,也不会再申请Private strand了。

每个Private strand的大小为65K。10g中,shared pool中的Private strands的大小就是活跃会话数乘以65K,而11g中,在shared pool中需要为每个Private strand额外分配4k的管理空间,即:数量*69k。

  1. --10g:  
  2.  
  3. SQL> select * from V$sgastat where name like '%strand%';  
  4.  
  5. POOL NAME BYTES  
  6.  
  7. ------------ -------------------------- ----------  
  8.  
  9. shared pool private strands 1198080  
  10.  
  11. HELLODBA.COM>select trunc(value * KSPPSTVL / 100) * 65 * 1024  
  12.  
  13. from (select value from v$parameter where name = 'transactions') a,  
  14.  
  15. 3 (select val.KSPPSTVL  
  16.  
  17. from sys.x$ksppi nam, sys.x$ksppsv val  
  18.  
  19. where nam.indx = val.indx  
  20.  
  21. AND nam.ksppinm = '_log_private_parallelism_mul') b;  
  22.  
  23. TRUNC(VALUE*KSPPSTVL/100)*65*1024  
  24.  
  25. -------------------------------------  
  26.  
  27. 1198080  
  28.  
  29. --11g:  
  30.  
  31. HELLODBA.COM>select * from V$sgastat where name like '%strand%';  
  32.  
  33. POOL NAME BYTES  
  34.  
  35. ------------ -------------------------- ----------  
  36.  
  37. shared pool private strands 706560  
  38.  
  39. HELLODBA.COM>select trunc(value * KSPPSTVL / 100) * (65 + 4) * 1024  
  40.  
  41. from (select value from v$parameter where name = 'transactions') a,  
  42.  
  43. 3 (select val.KSPPSTVL  
  44.  
  45. from sys.x$ksppi nam, sys.x$ksppsv val  
  46.  
  47. where nam.indx = val.indx  
  48.  
  49. AND nam.ksppinm = '_log_private_parallelism_mul') b;  
  50.  
  51. TRUNC(VALUE*KSPPSTVL/100)*(65+4)*1024  
  52.  
  53. -------------------------------------  
  54.  
  55. 706560 

Private strand的数量受到2个方面的影响:logfile的大小和活跃事务数量。

参数_log_private_mul指定了使用多少logfile空间预分配给Private strand,默认为5。我们可以根据当前logfile的大小(要除去预分配给log buffer的空间)计算出这一约束条件下能够预分配多少个Private strand:

  1. HELLODBA.COM>select bytes from v$log where status = 'CURRENT';  
  2.  
  3. BYTES  
  4.  
  5. ----------  
  6.  
  7. 52428800  
  8.  
  9. HELLODBA.COM>select trunc(((select bytes from v$log where status = 'CURRENT') - (select to_number(value) from v$parameter where name = 'log_buffer'))*  
  10.  
  11. 2 (select to_number(val.KSPPSTVL)  
  12.  
  13. from sys.x$ksppi nam, sys.x$ksppsv val  
  14.  
  15. where nam.indx = val.indx  
  16.  
  17. AND nam.ksppinm = '_log_private_mul') / 100 / 66560)  
  18.  
  19. as "calculated private strands" 
  20.  
  21. from dual;  
  22.  
  23. calculated private strands  
  24.  
  25. --------------------------  
  26.  
  27. 5  
  28.  
  29. HELLODBA.COM>select count(1) "actual private strands" from x$kcrfstrand where last_buf_kcrfa = '00';  
  30.  
  31. actual private strands  
  32.  
  33. ----------------------  
  34.  

当logfile切换后(和checkpoint一样,切换之前必须要将所有Private strand的内容flush到logfile中,因此我们在alert log中可能会发现日志切换信息之前会有这样的信息:"Private strand flush not complete",这是可以被忽略的),会重新根据切换后的logfile的大小计算对Private strand的限制:

  1. HELLODBA.COM>alter system switch logfile;  
  2.  
  3. System altered.  
  4.  
  5. HELLODBA.COM>select bytes from v$log where status = 'CURRENT';  
  6.  
  7. BYTES  
  8.  
  9. ----------  
  10.  
  11. 104857600  
  12.  
  13. HELLODBA.COM>select trunc(((select bytes from v$log where status = 'CURRENT') - (select to_number(value) from v$parameter where name = 'log_buffer'))*  
  14.  
  15. 2 (select to_number(val.KSPPSTVL)  
  16.  
  17. from sys.x$ksppi nam, sys.x$ksppsv val  
  18.  
  19. where nam.indx = val.indx  
  20.  
  21. AND nam.ksppinm = '_log_private_mul') / 100 / 66560)  
  22.  
  23. as "calculated private strands" 
  24.  
  25. from dual;  
  26.  
  27. calculated private strands  
  28.  
  29. --------------------------  
  30.  
  31. 13  
  32.  
  33. HELLODBA.COM>select count(1) "actual private strands" from x$kcrfstrand where last_buf_kcrfa = '00';  
  34.  
  35. actual private strands  
  36.  
  37. ----------------------  
  38.  
  39. 13 

参数_log_private_parallelism_mul用于推算活跃事务数量在最大事务数量中的百分比,默认为10。Private strand的数量不能大于活跃事务的数量。

  1. HELLODBA.COM>show parameter transactions  
  2.  
  3. NAME TYPE VALUE  
  4.  
  5. ------------------------------------ ----------- ------------------------------  
  6.  
  7. transactions integer 222  
  8.  
  9. transactions_per_rollback_segment integer 5  
  10.  
  11. HELLODBA.COM>select trunc((select to_number(value) from v$parameter where name = 'transactions') *  
  12.  
  13. 2 (select to_number(val.KSPPSTVL)  
  14.  
  15. from sys.x$ksppi nam, sys.x$ksppsv val  
  16.  
  17. where nam.indx = val.indx  
  18.  
  19. AND nam.ksppinm = '_log_private_parallelism_mul') / 100 )  
  20.  
  21. as "calculated private strands" 
  22.  
  23. from dual;  
  24.  
  25. calculated private strands  
  26.  
  27. --------------------------  
  28.  
  29. 22  
  30.  
  31. HELLODBA.COM>select count(1) "actual private strands" from x$kcrfstrand where last_buf_kcrfa = '00';  
  32.  
  33. actual private strands  
  34.  
  35. ----------------------  
  36.  
  37. 22 

注:在预分配Private strand时,会选择上述2个条件限制下最小一个数量。但相应的shared pool的内存分配和redo allocation latch的数量是按照活跃事务数预分配的。

因此,如果logfile足够大,_log_private_parallelism_mul与实际活跃进程百分比基本相符的话,Private strand的引入基本可以消除redo allocation latch的争用问题。

  1. 浅谈在Oracle中如何利用REDO实现故障恢复
  2. 简析REDO LOGFILE
  3. 详解Oracle中数字与大写交换
  4. 浅析Oracle对象和数据的导入导出
  5. 分析探讨Oracle Data Guard
精彩图集

赞助商链接