Jonathan,
It does not look like LGWR is an issue, because it writes much faster
then DBWR.
Here is an example. I increased db block buffers to 24GB - much bigger
size then test table size. In this case whole table fits into db cache
and dbwr writes nothing to hdd during normal insert, only lgwr writes
with speed close to 130MB/sec.
iostat -k 5
avg-cpu: %user %nice %system %iowait %steal %idle
10.67 0.00 2.73 0.60 0.00 86.00
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.80 0.00 6.80 0 34
sdb 1.80 16.00 6.80 80 34
sdc 460.80 0.00 132140.20 0 660701
sdd 460.80 0.00 132140.20 0 660701
sde 0.00 0.00 0.00 0 0
sdf 0.20 1.60 0.00 8 0
sdg 0.00 0.00 0.00 0 0
md2 0.20 1.60 0.00 8 0
md1 460.80 0.00 132140.20 0 660701
md0 1.40 16.00 6.40 80 32
After commit and some idle time DBWR starts flushing dirty db blocks
but never reaches sustained speed more than 50MB/sec.
iostat -k 5
avg-cpu: %user %nice %system %iowait %steal %idle
0.83 0.00 0.80 5.76 0.00 92.61
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 374.20 0.00 42636.80 0 213184
sdb 375.40 19.20 42636.80 96 213184
sdc 1.20 0.00 134.30 0 671
sdd 1.20 0.00 134.30 0 671
sde 9.80 0.00 670.20 0 3351
sdf 9.80 0.00 670.20 0 3351
sdg 0.00 0.00 0.00 0 0
md2 5.20 0.00 665.60 0 3328
md1 0.40 0.00 133.50 0 667
md0 375.40 19.20 42636.80 96 213184
top
Tasks: 234 total, 1 running, 233 sleeping, 0 stopped, 0 zombie
Cpu(s): 1.4%us, 1.1%sy, 0.0%ni, 90.9%id, 6.3%wa, 0.1%hi,
0.2%si, 0.0%st
Mem: 32895864k total, 14264500k used, 18631364k free, 7768k
buffers
Swap: 75641852k total, 305920k used, 75335932k free, 13378736k
cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+
COMMAND
2839 oracle 20 0 25.3g 7.1g 7.1g S 8.6 22.8 0:12.19
oracle
[root@dataworks etc]# ps -ef|grep 2839
oracle 2839 1 2 15:40 ? 00:00:15 ora_dbw0_market
root 2920 2111 0 15:49 pts/3 00:00:00 grep --color=auto 2839
DBWR write speed never reaches LGWR write speed.
I can guess several explanations here:
1. dbwr can't perform fast enough to saturate io bandwidth
2. it does not write blocks sequentially and random io is much slower
than sequential
3. 8k db block size is too small (bonnie++ uses 4MB buffer and lgwr
buffer is 32MB)
4. io calls and parameters that DBWR is using are not as fast as ones
used by LGWR, direct path or bonnie++.