Child Cursors Related with LANGUAGE_MISMATCH

The reason behind is NLS_SETTINGS



I generally use Stew Ashton's below query to summarize reasons why cursors are not shared. 

In one of our production database, the amount of child cursor count related with "LANGUAGE_MISMATCH" attracted my attention and i tried to make clear the reason behind.

NLS_SETTINGS are different


According to the Database Hang With 'cursor: mutex X' Contention Due To High Version Count Under LANGUAGE_MISMATCH (Doc ID 2542447.1), Whenever there are different NLS settings got changed in different combinations in every execution, it creates new child and version count increases with LANGUAGE_MISMATCH.

Exactly the same queries and PL/SQL packages are called from different applications. Different applications connect to database with different database users, but execute some common sql statements. Also These applications are deployed to different servers with different operating systems and client environments.

Some example child cursor reasons are as below.

<ChildNode><ChildNumber>14</ChildNumber><ID>44</ID><reason>NLS Settings(2)</reason><size>2x568</size><NLS_DATE_FORMAT>'DD/MM/RRRR'->'DD.MM.YYYY'</NLS_DATE_FORMAT></ChildNode> 

<ChildNode><ChildNumber>15</ChildNumber><ID>44</ID><reason>NLS Settings(2)</reason><size>2x568</size><NLS_DATE_FORMAT>'DD.MM.YYYY'->'DD/MM/RRRR'</NLS_DATE_FORMAT></ChildNode> 
<ChildNode><ChildNumber>16</ChildNumber><ID>44</ID><reason>NLS Settings(2)</reason><size>2x568</size><NLS_LANGUAGE>'TURKISH'->'AMERICAN'</NLS_LANGUAGE><NLS_TERRITORY>'TURKEY'->'AMERICA'</NLS_TERRITORY><NLS_CURRENCY>'TL'->'$'</NLS_CURRENCY><NLS_ISO_CURRENCY>'TURKEY'->'AMERICA'</NLS_ISO_CURRENCY><NLS_NUMERIC_CHARACTERS>',.'->'.,'</NLS_NUMERIC_CHARACTERS><NLS_DATE_FORMAT>'DD/MM/RRRR'->'DD-MON-RR'</NLS_DATE_FORMAT><NLS_DATE_LANGUAGE>'TURKISH'->'AMERICAN'</NLS_DATE_LANGUAGE><NLS_SORT>'TURKISH'->'BINARY'</NLS_SORT><NLS_TIME_FORMAT>'HH24:MI:SSXFF'->'HH.MI.SSXFF AM'</NLS_TIME_FORMAT><NLS_TIMESTAMP_FORMAT>'DD/MM/RRRR HH24:MI:SSXFF'->'DD-MON-RR HH.MI.SSXFF AM'</NLS_TIMESTAMP_FORMAT><NLS_TIME_TZ_FORMAT>'HH24:MI:SSXFF TZR'->'HH.MI.SSXFF AM TZR'</NLS_TIME_TZ_FORMAT><NLS_TIMESTAMP_TZ_FORMAT>'DD/MM/RRRR HH24:MI:SSXFF TZR'->'DD-MON-RR HH.MI.SSXFF AM TZR'</NLS_TIMESTAMP_TZ_FORMAT><NLS_DUAL_CURRENCY>'YTL'->'$'</NLS_DUAL_CURRENCY></ChildNode> 

First I checked all login triggers,  for some users there were "ALTER SESSION SET NLS_DATE_FORMAT" commands. They were added deliberately to prevent  some queries (without appropriated date format casting) from failing. I created login triggers like below to detect all NLS_SETTINGS for applications.

The most common format i detected was as below. 

PARAMETER VALUE
NLS_LANGUAGE TURKISH
NLS_TERRITORY TURKEY
NLS_CURRENCY ?
NLS_ISO_CURRENCY TURKEY
NLS_NUMERIC_CHARACTERS ,.
NLS_CALENDAR         GREGORIAN
NLS_DATE_FORMAT DD/MM/RRRR
NLS_DATE_LANGUAGE TURKISH
NLS_SORT         TURKISH
NLS_TIME_FORMAT HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT DD/MM/RRRR HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT DD/MM/RRRR HH24:MI:SSXFF TZR
NLS_DUAL_CURRENCY TL
NLS_COMP         BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE


Most of NLS_SETTINGS are derived from NLS_LANGUAGE and NLS_TERRITORY parameters. More information is available on blog post NLS defaults for LANGUAGE and TERRITORY by Franck Pachot. Also Oracle Official Documentation (NLS_LANG FAQ) is a must read document.

Also i found that some queries called from PL/SQL packages within scheduler_jobs are also generates child cursors with LANGUAGE_MISMATCH reason. This is derived from the fact that client environment session NLS_SETTINGS are different from the applications. Whenever a scheduler job is created, its NLS_SETTINGS are set according to the client's nls_session_parameters. You can use dbms_metadata.get_ddl function to detect them like below.

We changed NLS_ENV settings  of all scheduler jobs which are not owned by Oracle Internal Users and made them same with the common format. We used the command below.
 
Hope it helps.

Comments

Popular posts from this blog

Using table stats hint to force a direct path read but with a rownum predicate surprise

Oracle Grid Release Update by using Ansible Playbooks

Oracle Database Release Update by Using Ansible Playbooks