Estas usando file systems para tu base de datos y todo opera en aparente normalidad, pero ¿sabías que por defecto Oracle no aprovecha todas las mejoras que los file systems modernos tienen implementados? Pues esa es la cruda realidad, si te interesa saber cómo puedes sacarle el jugo al I/O de tus discos con solo cambiar un parámetro, entonces debemos empezar por algo de teoría no Oracle.
File Buffer Cache
Un archivo no es más que una colección de bits almacenados en un medio persistente. Cuando un proceso requiere acceder a los datos de un archivo, el sistema operativo los lleva a la memoria principal, donde el proceso puede hacer uso del mismo, modificarlo, y luego solicitar que sea nuevamente guardado en disco. Pero teniendo en mente que los discos son mucho más lentos que la memoria principal, los sistemas operativos hacen normalmente uso de un buffer en memoria, llamado file buffer cache. Como resultado, el sistema operativo primero intenta obtener los datos del buffer cache, si no la encuentra allí la lee de disco y la coloca en el buffer cache. De forma similar, las escrituras también pasan por el buffer cache de forma que las futuras lecturas puedan ser satisfechas sin necesidad de acceder a los discos.
Direct I/O
Hasta acá el uso del file buffer cache parecería beneficioso, pero no olvidemos que Oracle ya tiene su propia implementación: el database buffer cache. Al ser el propio Oracle quien controla qué bloques requieren de permanecer o no en el cache, bajo un algoritmo LRU con el que no cuenta el sistema operativo, la existencia del file buffer cache puede resultar indeseable e innecesario al tener que viajar los datos primero al file buffer cache y luego al database buffer cache, conllevando a un consumo adicional de CPU y también de memoria principal, la cual ya no está disponible para Oracle. Tomando esto en cuenta, hace su aparición el Direct I/O, como una forma de evitar el uso del file buffer cache, de hecho es la forma con que se interactúa con los raw devices (porciones de disco no formateados); en la actualidad prácticamente todos los sistemas operativos soportan direct I/O y en algunos casos incluso versiones más sofisticadas como concurrent i/o provisto por IBM con JFS2.
Habilitando Direct I/O
En Oracle existe una forma de controlar la forma en que se interactúa con los file systems, se trata de filesystemio_options, que acepta como valores:
- none. La grabación será síncrona con bloqueo, es decir la aplicación espera a que la llamada al sistema se complete antes de poder hacer una nueva llamada. Es universalmente soportada pero es la más forma más lenta.
- asynch. La aplicación no espera a que la llamada al sistema se complete, puede realizar otras tareas mientras espera la confirmación de la llamada previa.
- directio. La grabación es síncrona sin pasar por el file buffer cache (las dos modalidades previas hacen uso del file buffer cache).
- setall. La grabación es asíncrona y sin pasar por el file buffer cache. Presenta la posibilidad de máximo desempeño.
Dependiendo de la plataforma Oracle le asigna a éste parámetro el valor por defecto none (ejm. Linux) o asynch (ejm. Solaris), para habilitar direct I/O los valores a escoger han de ser directio o mejor aún setall (asynch + directio). Este parámetro no se puede cambiar online por lo que luego de aplicar el cambio en el spfile.ora debes reiniciar la base de datos para que entre en efecto.
SYS@orcl > show parameter filesystemio_options NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ filesystemio_options string none SYS@orcl > alter system set filesystemio_options=setall scope=spfile; System altered. SYS@orcl > shutdown immediate Database closed. Database dismounted. ORACLE instance shut down. SYS@orcl > startup ORACLE instance started. Total System Global Area 209715200 bytes Fixed Size 1279360 bytes Variable Size 109054592 bytes Database Buffers 96468992 bytes Redo Buffers 2912256 bytes Database mounted. Database opened.
Estamos probando con Linux, de allí el valor none, ahora para verificar que estamos trabajando con asynch y directio en simultáneo, podemos valernos de algunos utilitarios propios de Linux, pero que tienen sus similares en otros sistemas operativos. Primero veamos la situación original, es decir cuando filesystemio_options=none.
SYS@orcl> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@orcl> startup mount;
ORACLE instance started.
Total System Global Area 205520896 bytes
Fixed Size 1266608 bytes
Variable Size 142609488 bytes
Database Buffers 58720256 bytes
Redo Buffers 2924544 bytes
Database mounted.
$ ps -ef | grep dbw
oracle 28532 1 0 16:56 ? 00:00:00 ora_dbw0_orcl
SYS@orcl> alter database open;
Database altered.
$ more /tmp/trace_dbwr.out
. . .
open("/u02/oradata/ORCL/datafile/o1_mf_system_3wqn5ypm_.dbf", O_RDWR|O_SYNC|O_LARGEFILE) = 17
. . .
$ cat /proc/slabinfo | grep kio
kioctx 18 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
kiocb 0 0 128 31 1 : tunables 120 60 0 : slabdata 0 0 0
Ahora con filesystemio_options=setall.
$ more /tmp/trace_dbwr.out . . . open("/u02/oradata/ORCL/datafile/o1_mf_system_3wqn5ypm_.dbf", O_RDONLY|O_DIRECT|O_LARGEFILE) = 17 . . . $ cat /proc/slabinfo | grep kio kioctx 17 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0 kiocb 7 31 128 31 1 : tunables 120 60 0 : slabdata 1 1 0
Que DBWR abra los datafiles con O_DIRECT es señal del uso de Direct I/O, mientras que la presencia de valores distintos de cero para kiocb lo es del uso de Asynch I/O.
¿File buffer cache o Direct I/O?
La decisión no es simple, antes de optar por uno u otro debemos tener en cuenta cómo puede afectar a nuestras aplicaciones, para empezar vemos el caso de una aplicación simulada que es intensiva en lecturas aleatorias, lo cual es típico de las aplicaciones OLTP.
Random.sh sqlplus / as sysdba << EOF alter system flush buffer_cache; exit; EOF sqlplus /nolog @Random.sql & sqlplus /nolog @Random.sql & sqlplus /nolog @Random.sql & sqlplus /nolog @Random.sql & Random.sql connect test/test set timing on alter session set events '10046 trace name context forever, level 8'; begin for i in 1..200000 loop execute immediate 'select data from testio where id = :id' using ROUND(dbms_random.value(1,200000)); end loop; end; / exit
Analizando los tiempos con tkprof:
filesystemio_options=none select data from testio where id = :id call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 4 0.00 1.38 0 0 0 0 Execute 800000 51.29 172.13 1 1 0 0 Fetch 0 0.00 0.00 0 0 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 800004 51.30 173.51 1 1 0 0 === filesystemio_options=setall select data from testio where id = :id call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 4 0.00 0.00 0 0 0 0 Execute 800000 38.84 128.18 0 0 0 0 Fetch 0 0.00 0.00 0 0 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 800004 38.85 128.18 0 0 0 0
Ahora con una aplicación intensiva en Full Table Scans, típico de las aplicaciones DSS.
Full.sh sqlplus / as sysdba << EOF alter system flush buffer_cache; exit; EOF sqlplus /nolog @Full.sql & sqlplus /nolog @Full.sql & sqlplus /nolog @Full.sql & sqlplus /nolog @Full.sql & Full.sql connect test/test set timing on alter session set events '10046 trace name context forever, level 8'; declare v_data testio.data%type; begin for i in 1..25 loop select max(data) into v_data from testio; end loop; end; / exit
Resumen de traces analizados con tkprof.
filesystemio_options=none SELECT MAX(DATA) FROM TESTIO call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 4 0.00 0.00 0 0 0 0 Execute 100 0.01 0.01 0 0 0 0 Fetch 100 61.89 232.97 503813 1446600 0 100 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 204 61.91 232.99 503813 1446600 0 100 Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ db file sequential read 146 0.00 0.00 db file scattered read 13771 0.67 19.53 ==== filesystemio_options=setall SELECT MAX(DATA) FROM TESTIO call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 4 0.01 1.22 1 1 0 0 Execute 100 0.02 0.06 0 0 0 0 Fetch 100 70.63 366.62 259438 1446600 0 100 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 204 70.66 367.91 259439 1446601 0 100 Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ read by other session 20820 0.24 133.64 db file scattered read 8942 0.99 100.00 latch: cache buffers chains 193 0.02 0.73 db file sequential read 302 0.07 1.39
Con filesystemio_options=setall las lecturas aleatorias mejoraron en 26%, mientras que los Full Table Scans empeoraron en casi 58%!
Conclusiones
Revisando los resultados de los escenarios simulados, podemos concluir que, ante la activación de direct I/O, las aplicaciones intensivas en acceso aleatorio a los discos se ven beneficiadas mientras que las intensivas en Full Table Scans se ven perjudicadas, de allí que no debemos saltar a la conclusión de que con solo habilitar el direct I/O nuestra base de datos será mágicamente más rápida, es posible que así sea, como también es posible que el impacto sea nulo e incluso adverso, primero hagan las pruebas del caso durante un periodo de carga típica antes de decidir dejarlo permanentemente. Lo que sí es seguro que mejorará el desempeño es el uso de filesystemio_options=asynch, por lo que es lo mínimo con lo que deberías configurar tu base de datos.
Cada plataforma tiene sus particularidades en cuanto a la aplicabilidad de los diversos valores para filesystemio_options e incluso hay algunos bugs específicos para ciertas combinaciones de versión de Oracle + versión de Sistema Operativo, por ello es conveniente que te informes más del tema. Te recomiendo la lectura de los Notes 462072.1 File System's Buffer Cache versus Direct I/O, 555601.1 How To Verify Whether DIRECTIO is Being Used, 237299.1 How To Check if Asynchronous I/O is Working On Linux y 432854.1 Asynchronous I/O Support on OCFS/OCFS2 and Related Settings: filesystemio_options, disk_asynch_io, finalmente Boost application performance using asynchronous I/O.
Post Relacionados:
¿Te pareció interesante este artículo?, ¿te quedaron algunas dudas?, ¿quieres sugerirme un tema a tratar?, pues déjame tus comentarios o envíame un email y para que NO te pierdas ningún Post, suscríbete por email ahora mismo!
6 comentarios, agrega el tuyo!
hola Kike;
se tendra algun tip para base sobre ASM... u OCFS
Hola Ulises, te recomiendo darle una lectura al Note 432854.1 Asynchronous I/O Support on OCFS/OCFS2 and Related Settings: filesystemio_options, disk_asynch_io. Allí se indica que Oracle usa por default Direct I/O cuando se trata de OCFS, OCFS2 y ASM, solamente te queda la opción de usar o no Asynch I/O, si se desea usarlo entonces hay que establecer filesystemio_options=setall.
hola Kike, disculpa la ignorancia. Como puedo hacer para un proceso que aparece 'activo' pero está en espera del evento db file scattered read. Y no me bloquee mas las tablas
Hola Baraka, que la sesión esté en espera del evento db file scattered read es una señal de que la tabla en cuestión está siendo leída por un Full Table Scan, es decir en su totalidad, si esto no es correcto y debería estar usando algún índice entonces tienes que revisar la sintaxis de la sentencia SQL para que haga uso del mismo o si falta un índice entonces debes crearlo.
Gracias por la explicación Enrique.
Consulta para el caso de las bases de datos sobre Windows, este parámetro seteado a setall podría darnos alguna mejora?
Finally, you will get a 100% match in your third deposit a lot as} £500. If you deposited the total amount for each of those three deposits, you then would find yourself with a complete bonus of £1,000. Finally, gamers can use mBit’s 24/7 live chat feature to reach out with questions or considerations. 45 live recreation reveals present a 온라인카지노 refreshing change of tempo in between rounds. Betting minimums begin at $0.20 throughout the board, however the “VIP” selection lets high rollers wager a lot as} $50,000 per hand.
Publicar un comentario