{"id":3534,"date":"2020-09-20T18:00:27","date_gmt":"2020-09-20T18:00:27","guid":{"rendered":"https:\/\/nenadnoveljic.com\/blog\/?p=3534"},"modified":"2022-02-16T19:52:32","modified_gmt":"2022-02-16T19:52:32","slug":"aq-alerts-private-strands","status":"publish","type":"post","link":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/","title":{"rendered":"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage"},"content":{"rendered":"<h1>Private strands<\/h1>\n<p>Private strands reduce contention on the public redo log buffer. Without them a process would have to write to public redo buffer more frequently and compete with other processes. <a href=\"http:\/\/www.hellodba.com\/reader.php?ID=28&amp;lang=EN\">[1]<\/a><\/p>\n<p>Message Advanced Queues (AQ) and alerts can prevent processes from using private strands.<\/p>\n<p>For example, the following transaction isn&#8217;t using private strands:<\/p>\n<pre><code>create table t (n number);\ninsert into t values (1);\n\nselect decode(bitand(ktcxbflg, 4096),0,1,0) used_private_strand\n    from x$ktcxb, v$session\n    where ktcxbses = saddr and sid = userenv('sid');\n\nUSED_PRIVATE_STRAND\n-------------------\n                  0<\/code><\/pre>\n<p><i>x$ktcxb<\/i> is the SQL interface to the transaction table. The <ins>un<\/ins>set 13th bit of the bitmap <i>ktcxbflg<\/i> indicates that the transaction is using a private strand.<\/p>\n<h1>In-memory undo buffers<\/h1>\n<p>In-memory undo (IMU) buffer is a prerequisite for using a private strand <a href=\"https:\/\/fritshoogland.wordpress.com\/2016\/11\/15\/redo-a-blogpost\/\">[2]<\/a>. But in my case, the process couldn&#8217;t allocate it:<\/p>\n<pre><code>select n.name, s.value from v$statname n, v$sesstat s \n  where n.statistic# = s.statistic# and s.sid =  userenv('SID') \n    and n.name like '%IMU%' and value != 0 ;\n\nNAME                                                                  VALUE\n---------------------------------------------------------------- ----------\nIMU pool not allocated                                                    1<\/code><\/pre>\n<p><i>x$ktifp<\/i> externalizes the IMU pool:<\/p>\n<pre><code>select ktifptxflg, count(*) from x$ktifp group by ktifptxflg ;\n\nKTIFPTXFLG   COUNT(*)\n---------- ----------\n         7         64\n         1        107<\/code><\/pre>\n<p>All IMU buffers are currently occupied &#8211; none of them has <i>ktifptxflg<\/i> set to zero.<\/p>\n<p>According to <i>v$transaction<\/i> there aren&#8217;t any open transactions:<\/p>\n<pre><code>select count(*) from v$transaction ;\n\n  COUNT(*)\n----------\n         0<\/code><\/pre>\n<p>But who then has allocated all IMU buffers?<\/p>\n<p>To answer this question, I selected transactions from the fixed table <i>x$ktcxb<\/i> instead of <i>v$transaction<\/i>. I also joined the result with the IMU buffer fixed table <i>x$ktifp<\/i> and <i>v$session<\/i>:<\/p>\n<pre><code>column sid format 9999\ncolumn minutes format 9999999\ncolumn program format a23\ncolumn event format a48\n\nselect \n    sid, \n    round(( sysdate - to_date(ktcxbstm,'mm\/dd\/rr hh24:mi:ss') ) * 24 * 60) \n      minutes, \n    decode(bitand(ktcxbflg,2),2,1,0) bit2,\n    to_number(ktifprpc,'xxxxxxxxxxxxxxxx') -\n    to_number(ktifprpb,'xxxxxxxxxxxxxxxx')  redo_bytes,\n    to_number(ktifpupc, 'xxxxxxxxxxxxxxxx') - \n    to_number(ktifpupb, 'xxxxxxxxxxxxxxxx') undo_bytes,\n    program, \n    event\n  from x$ktifp, x$ktcxb, v$session ses \n  where ktifpxcb = ktcxbxba and ktcxbses = saddr\n  order by ktcxbstm desc ;\n\n  SID  MINUTES  BIT2 REDO_BYTES UNDO_BYTES PROGRAM                 EVENT\n----- -------- ----- ---------- ---------- ----------------------- ------------------------------------------------\n...\n 1536       47     0          0         72 oracle@serverxx (J07T)  Streams AQ: waiting for messages in the queue\n  333       47     0          0         72 oracle@serverxx (J08S)  Streams AQ: waiting for messages in the queue\n 1098       47     0          0         72 oracle@serverxx (J06I)  Streams AQ: waiting for messages in the queue\n   98       47     0          0         72 oracle@serverxx (J089)  Streams AQ: waiting for messages in the queue\n 1462       47     0          0         72 oracle@serverxx (J03X)  Streams AQ: waiting for messages in the queue\n  730       47     0          0         72 oracle@serverxx (J02N)  Streams AQ: waiting for messages in the queue\n  787       47     0          0         72 oracle@serverxx (J02T)  Streams AQ: waiting for messages in the queue\n  839       47     0          0         72 oracle@serverxx (J07Z)  Streams AQ: waiting for messages in the queue\n 1422       47     0          0         72 oracle@serverxx (J03V)  Streams AQ: waiting for messages in the queue\n  114       47     0          0         72 oracle@serverxx (J07R)  Streams AQ: waiting for messages in the queue\n   55       47     0          0         72 oracle@serverxx (J07Y)  Streams AQ: waiting for messages in the queue\n 1343       47     0          0         72 oracle@serverxx (J07M)  pipe get\n   54       47     0          0         72 oracle@serverxx (J01E)  Streams AQ: waiting for messages in the queue\n 1425       47     0          0         72 oracle@serverxx (J010)  Streams AQ: waiting for messages in the queue\n  394       47     0          0         72 oracle@serverxx (J04Z)  Streams AQ: waiting for messages in the queue\n  918       47     0          0         72 oracle@serverxx (J00C)  Streams AQ: waiting for messages in the queue\n  593       47     0          0         72 oracle@serverxx (J002)  Streams AQ: waiting for messages in the queue\n 1265       47     0          0         72 oracle@serverxx (J06Y)  Streams AQ: waiting for messages in the queue\n 1216       47     0          0         72 oracle@serverxx (J04C)  Streams AQ: waiting for messages in the queue\n  177       47     0          0         72 oracle@serverxx (J068)  Streams AQ: waiting for messages in the queue\n  809       47     0          0         72 oracle@serverxx (J008)  Streams AQ: waiting for messages in the queue\n 1436       47     0          0         72 oracle@serverxx (J07L)  Streams AQ: waiting for messages in the queue\n 1496       47     0          0         72 oracle@serverxx (J02L)  Streams AQ: waiting for messages in the queue\n  665       47     0          0         72 oracle@serverxx (J02H)  Streams AQ: waiting for messages in the queue\n\n  SID  MINUTES  BIT2 REDO_BYTES UNDO_BYTES PROGRAM                 EVENT\n----- -------- ----- ---------- ---------- ----------------------- ------------------------------------------------\n 1120       47     0          0         72 oracle@serverxx (J03W)  Streams AQ: waiting for messages in the queue\n  496       47     0          0         72 oracle@serverxx (J029)  Streams AQ: waiting for messages in the queue\n 1176       47     0          0         72 oracle@serverxx (J01T)  Streams AQ: waiting for messages in the queue\n 1523       47     0          0         72 oracle@serverxx (J020)  Streams AQ: waiting for messages in the queue\n 1366       47     0          0         72 oracle@serverxx (J08V)  Streams AQ: waiting for messages in the queue\n  355       47     0          0         72 oracle@serverxx (J04Y)  Streams AQ: waiting for messages in the queue\n 1470       47     0          0         72 oracle@serverxx (J03Y)  Streams AQ: waiting for messages in the queue\n 1202       47     0          0         72 oracle@serverxx (J00K)  Streams AQ: waiting for messages in the queue\n  641       48     0          0         72 oracle@serverxx (J02K)  Streams AQ: waiting for messages in the queue\n  573       48     0          0         72 oracle@serverxx (J02E)  Streams AQ: waiting for messages in the queue\n   41       48     0          0         72 oracle@serverxx (J01F)  Streams AQ: waiting for messages in the queue\n  487       48     0          0         72 oracle@serverxx (J03J)  Streams AQ: waiting for messages in the queue\n 1407      108     0          0         72 oracle@serverxx (J046)  pipe get\n 1448      108     0          0         72 oracle@serverxx (J012)  pipe get\n 1291      108     0          0         72 oracle@serverxx (J06V)  pipe get\n  864      108     0          0         72 oracle@serverxx (J08Z)  pipe get\n  850      108     0          0         72 oracle@serverxx (J08P)  pipe get\n\n  SID  MINUTES  BIT2 REDO_BYTES UNDO_BYTES PROGRAM                 EVENT\n----- -------- ----- ---------- ---------- ----------------------- ------------------------------------------------\n 1368      468     0          0         72 oracle@serverxx (J03R)  pipe get\n 1457      468     0          0         72 oracle@serverxx (J071)  Streams AQ: waiting for messages in the queue\n 1201      468     0          0         72 oracle@serverxx (J06G)  PL\/SQL lock timer\n 1136      468     0          0         72 oracle@serverxx (J036)  Streams AQ: waiting for messages in the queue\n 1189      468     0          0         72 oracle@serverxx (J03B)  pipe get\n 1174      468     0          0         72 oracle@serverxx (J03A)  pipe get\n 1162      468     0          0         72 oracle@serverxx (J06D)  pipe get\n 1145      468     0          0         72 oracle@serverxx (J038)  pipe get\n  521      468     <span style=\"color:red\">0          0<\/span>         72 oracle@serverxx (J000)  pipe get\n\n171 rows selected.<\/code><\/pre>\n<p>The transactions above look strange:<\/p>\n<ul>\n<li>None of them has allocated any redo space.<\/li>\n<li>They have all allocated exactly 72 bytes in the undo buffer.<\/li>\n<li>They&#8217;ve been holding IMU buffers for hours.<\/li>\n<li>The 2nd bit in <i>ktcxbflg<\/i> isn&#8217;t set.<\/li>\n<\/ul>\n<h1>ktcxbflg<\/h1>\n<p>It&#8217;s unusual to leave the 2nd bit of <i>ktcxbflg<\/i> unset. <i>v$transaction<\/i>, by the way, filters such transactions out:<\/p>\n<pre><code>BITAND (ktcxbflg, 2) != 0<\/code><\/pre>\n<p>Let&#8217;s compare the transactions above with a regular transaction:<\/p>\n<pre><code>insert into t values (1);\n\n  SID  MINUTES       BIT2 REDO_BYTES UNDO_BYTES PROGRAM                 EVENT\n----- -------- ---------- ---------- ---------- ----------------------- ------------------------------------------------\n  257        0          <span style=\"color:blue\">1        572<\/span>        576 sqlplus@svdbp01i (TNS V PGA memory operation\n                                                1-V3)<\/code><\/pre>\n<p>The 2nd bit of <i>ktcxbflg<\/i> is set, and the transaction is using some redo space.<\/p>\n<p>What has produced the transactions holding the IMU buffers?<\/p>\n<h1>Inter-process communication<\/h1>\n<p>Based on the wait events <i>pipe get<\/i> and <i>Streams AQ: waiting for messages in the queue<\/i> we can conclude that the sessions have been involved in inter-process communication. The errorstack for these wait events provides more details.<\/p>\n<h2>AQ<\/h2>\n<pre><code>ALTER session SET EVENTS 'wait_event[\"Streams AQ: waiting for messages in the queue\"] {occurence:end_after 100} errorstack()';<\/code><\/pre>\n<pre><code>----- PL\/SQL Call Stack -----\n  object      line  object\n  handle    number  name\nc1a5e6e0       750  package body <span style=\"color:red\">SYS.DBMS_AQ.DEQUEUE<\/span>\nc31eb7a0      2859  package body K.MSG_EXTL#.GET_NEXT_IN_MSG\nc33f9130       489  package body K.MSG_IN#.GET_NEXT_MSG\nc6fdb388      1215  procedure K.BGP_MSG_IN\nc6fdb388      1404  procedure K.BGP_MSG_IN\nbfb9fa78         1  anonymous block<\/code><\/pre>\n<p>The PL\/SQL process was waiting on an AQ.<\/p>\n<p>We can reproduce this behavior with the test case from <a href=\"https:\/\/oracle-base.com\/articles\/9i\/advanced-queuing-9i\">the Tim Hall&#8217;s tutorial<\/a>:<\/p>\n<pre><code>DECLARE\n  l_dequeue_options     DBMS_AQ.dequeue_options_t;\n  l_message_properties  DBMS_AQ.message_properties_t;\n  l_message_handle      RAW(16);\n  l_event_msg           event_msg_type;\nBEGIN\n  DBMS_AQ.dequeue(queue_name          =&gt; 'event_queue',\n                  dequeue_options     =&gt; l_dequeue_options,\n                  message_properties  =&gt; l_message_properties,\n                  payload             =&gt; l_event_msg,\n                  msgid               =&gt; l_message_handle);\nEND;\n\/<\/code><\/pre>\n<pre><code>  SID  MINUTES       BIT2 REDO_BYTES UNDO_BYTES PROGRAM                 EVENT\n----- -------- ---------- ---------- ---------- ----------------------- ------------------------------------------------\n  265        2          0          0         72 sqlplus@svdbp01i (TNS V Streams AQ: waiting for messages in the queue\n                                                1-V3)<\/code><\/pre>\n<p>There were no incoming messages. Simply put, the dequeue procedure creates a transaction and allocates an IMU buffer. This transaction remains open during the whole waiting time.<\/p>\n<h2>Alerts<\/h2>\n<pre><code>ALTER session SET EVENTS 'wait_event[\"pipe get\"] {occurence:end_after 100} errorstack()'<\/code><\/pre>\n<pre><code>c2e8a078       169  package body SYS.DBMS_PIPE.RECEIVE_MESSAGE\nc42bdc00       165  package body SYS.DBMS_ALERT.PIPE_WAIT\nc42bdc00       363  package body <span style=\"color:red\">SYS.DBMS_ALERT.WAITONE<\/span><\/code><\/pre>\n<p>This process was waiting for an alert.<\/p>\n<p>Also here, we can easily reproduce the behavior:<\/p>\n<pre><code>declare\n  L_MSG                     VARCHAR2(240);\n  l_status                  pls_integer ;\nbegin\n  DBMS_ALERT.WAITONE('TEST2', L_MSG, L_STATUS, 1000);\n  insert into t values(1);\nend;<\/code><\/pre>\n<pre><code>exec DBMS_ALERT.SIGNAL('TEST2', 'message_text2'); \ncommit;<\/code><\/pre>\n<pre><code>  SID  MINUTES       BIT2 REDO_BYTES UNDO_BYTES PROGRAM                 EVENT\n----- -------- ---------- ---------- ---------- ----------------------- ------------------------------------------------\n  265        1          0          0         72 sqlplus@svdbp01i (TNS V pipe get\n                                                1-V3)<\/code><\/pre>\n<p>Similarly, the session holds the allocated IMU buffer while waiting for an alert.<\/p>\n<h2>Is it a bug or a feature?<\/h2>\n<p>In both cases, the session is waiting for an incoming message\/alert. Even though it&#8217;s an idle wait, the process started a pseudo-transaction which allocated 72 bytes in the IMU buffer. It&#8217;s a non-obvious and undocumented behavior. Many such processes could use up the IMU pool. Consequently, &#8220;real&#8221; transactions wouldn&#8217;t be able to use private strands.<\/p>\n<h1>Avaloq<\/h1>\n<p>The banking application Avaloq is particularly at risk as it heavily relies on AQ and alerts. For example, our production database has more than 350 job queue processes waiting for a message.<\/p>\n<p>We need enough IMU buffers to handle the peak load. The number of IMU buffers can&#8217;t be explicitly specified. It&#8217;s rather derived from the <i>transactions<\/i> parameter (#IMU buffers = 0.1 * <i>transactions<\/i>).<\/p>\n<h1>MTTR advisor<\/h1>\n<p>There is another undocumented quirk related to public redo buffers. A process sometimes counts dirty buffers on all working data sets while holding a redo copy latch to prepare the information for the MTTR advisor. As the number of working data sets equals the number of CPUs, larger servers suffer more. <a href=\"https:\/\/nenadnoveljic.com\/blog\/redo-copy-latch-mttr-advisor\/\">[3]<\/a><\/p>\n<p>Our primary goal is to reduce public redo buffer writes. But you can disable the MTTR advisor to alleviate the redo copy latch contention, until increasing the <i>transactions<\/i> parameter.<\/p>\n<h1>ORA-00600: [krcput_overwrite]<\/h1>\n<p>We&#8217;ve been occasionally hitting ORA-00600: [krcput_overwrite]. The affected Avaloq test databases had the transactions parameter set so low, that processes weren&#8217;t using private strands.<\/p>\n<p>The error has being thrown in the Oracle function <i>krcput<\/i>:<\/p>\n<pre><code>...\nkrcput()+2249        call     ksesin()             008C173D0 ? 000000004 ?\n                                                   000000000 ? 00000003E ?\n                                                   000000000 ? 00000003E ?\nkcrfw_redo_gen_ext(  call     krcput()             091ED0FD8 ? 7FFFBFFF18F8 ?\n)+22019                                            7FFFBFFF24C0 ? 000000000 ?\n                                                   000000002 ? 00000003E ?\nkcbchg1_main()+7114  call     kcrfw_redo_gen_ext(  000000002 ? 7FFFBFFF24C0 ?\n                              )                    7FFFBFFF2480 ? 000000000 ?\n                                                   7FFFBFFF2188 ? 7FFFBD869CD0 ?\nkcbchg()+482         call     kcbchg1_main()       000000008 ? 000000002 ?\n                                                   000000037 ? 7FFFBFFF2DB0 ?\n                                                   7FFFBFFF2E00 ? 000000000 ?\nktuapundo()+497      call     kcbchg()             000000008 ? 000000002 ?\n...<\/code><\/pre>\n<p><i>krcput<\/i> writes changed block addresses into the block change tracking buffer <a href=\"\nhttps:\/\/www.freelists.org\/post\/oracle-l\/intermittent-long-log-file-sync-waits,71\">[4]<\/a>, and its caller <i>kcrfw_redo_gen_ext<\/i> copies changes to the public redo buffer. <a href=\"\nhttps:\/\/fritshoogland.wordpress.com\/2018\/01\/29\/a-look-into-oracle-redo-part-1-redo-allocation-latches\/\">[5]<\/a><\/p>\n<p>According to the support note <i>Bug 30295790 &#8211; DB Crashes with ORA-00600 [krcput_overwrite] (Doc ID 30295790.8)<\/i> it&#8217;s a concurrency issue: &#8220;DBA buffers are updated by CTWR as well as multiple foreground process to read and write krcpe entries in it.&#8221;<\/p>\n<p>In other words, the problem occurs during concurrent writes to the public redo log buffer. Private strands reduce these calls, and help avoid the bug.<\/p>\n<h1>Summary<\/h1>\n<p>Private strands reduce contention on the public redo buffer and improve scalability. A process that hasn&#8217;t allocated an IMU buffer can&#8217;t use private strands.<\/p>\n<p>A process waiting for an AQ message or an alert allocates an IMU buffer and holds it while waiting. Many such processes could use up the IMU pool. That would prevent other sessions from using private strands, and cause performance issues. This problem is worse on servers with more CPUs, because the MTTR advisor code protected by redo copy latch takes more time to complete.<\/p>\n<p>The banking application Avaloq needs a thorough consideration, because it configures many background job queue processes to wait for AQ messages and alerts. Set the <i>transactions<\/i> parameter high enough to ensure that private strands are being used during the peak load.<\/p>\n<h1>References<\/h1>\n<ul>\n<li><a href=\"http:\/\/www.hellodba.com\/reader.php?ID=28&amp;lang=EN\">[1]<\/a> Wei Huang, <i>Oracle Redo Strand.<\/i> December 18, 2009.<\/li>\n<li><a href=\"https:\/\/fritshoogland.wordpress.com\/2016\/11\/15\/redo-a-blogpost\/\">[2]<\/a> Frits Hoogland, <i>Redo a blogpost.<\/i> November 15, 2016.<\/li>\n<li><a href=\"https:\/\/nenadnoveljic.com\/blog\/redo-copy-latch-mttr-advisor\/\">[3]<\/a> Nenad Noveljic, <i>Redo Copy Latch Contention 2: MTTR Advisor.<\/i> June 16, 2020.<\/li>\n<li><a href=\"https:\/\/www.freelists.org\/post\/oracle-l\/intermittent-long-log-file-sync-waits,71\">[4]<\/a> Tanel Poder, <i>Oracle-l: intermittent long &#8220;log file sync&#8221; waits.<\/i> Februar 10, 2020.<\/li>\n<li><a href=\"https:\/\/fritshoogland.wordpress.com\/2018\/01\/29\/a-look-into-oracle-redo-part-1-redo-allocation-latches\/\">[5]<\/a> Frits Hoogland, <i>A look into Oracle redo, part 1: redo allocation latches.<\/i> January 29, 2019.<\/li>\n<\/ul>\n<h1>Updates<\/h1>\n<h2>October 10, 2020<\/h2>\n<p>A correction: The unset (not the set) 13th bit in x$ktcxb.ktcxbflg indicates that the private strands are being used. Thanks to <a href=\"http:\/\/ksun-oracle.blogspot.com\/\">Kun Sun<\/a> for pointing this out.<\/p>\n<h2>October 23, 2020<\/h2>\n<p>The fix for the bug <i>30295790  DB Crashes with ORA-00600 [krcput_overwrite]<\/i> is included in 19.9 19.9.0.0.DBRU:201020 (OCT 2020).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it&#8217;s waiting, even when there aren&#8217;t any incoming mesages. Many such processes can prevent private strands usage.<br \/>\n <a href=\"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/\" class=\"more-link\">Continue Reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[13,51,5,37],"tags":[],"class_list":["post-3534","post","type-post","status-publish","format-standard","hentry","category-avaloq","category-ora-00600","category-oracle","category-redo"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage - All-round Database Topics<\/title>\n<meta name=\"description\" content=\"A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it&#039;s waiting, even when there aren&#039;t any incoming messages. Many such processes can prevent private strands usage.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage - All-round Database Topics\" \/>\n<meta property=\"og:description\" content=\"A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it&#039;s waiting, even when there aren&#039;t any incoming messages. Many such processes can prevent private strands usage.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/\" \/>\n<meta property=\"og:site_name\" content=\"All-round Database Topics\" \/>\n<meta property=\"article:published_time\" content=\"2020-09-20T18:00:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-02-16T19:52:32+00:00\" \/>\n<meta name=\"author\" content=\"Nenad Noveljic\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@NenadNoveljic\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nenad Noveljic\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/\"},\"author\":{\"name\":\"Nenad Noveljic\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"headline\":\"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage\",\"datePublished\":\"2020-09-20T18:00:27+00:00\",\"dateModified\":\"2022-02-16T19:52:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/\"},\"wordCount\":969,\"commentCount\":4,\"articleSection\":[\"Avaloq\",\"ORA-00600\",\"Oracle\",\"redo\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/\",\"name\":\"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage - All-round Database Topics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\"},\"datePublished\":\"2020-09-20T18:00:27+00:00\",\"dateModified\":\"2022-02-16T19:52:32+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\"},\"description\":\"A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it's waiting, even when there aren't any incoming messages. Many such processes can prevent private strands usage.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/aq-alerts-private-strands\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/\",\"name\":\"All-round Database Topics\",\"description\":\"Nenad Noveljic\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/#\\\/schema\\\/person\\\/51458d9dd86dbbdd19f5add451d44efa\",\"name\":\"Nenad Noveljic\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g\",\"caption\":\"Nenad Noveljic\"},\"sameAs\":[\"nenad-noveljic-9b746a6\",\"https:\\\/\\\/x.com\\\/NenadNoveljic\"],\"url\":\"https:\\\/\\\/nenadnoveljic.com\\\/blog\\\/author\\\/nenad\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage - All-round Database Topics","description":"A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it's waiting, even when there aren't any incoming messages. Many such processes can prevent private strands usage.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/","og_locale":"en_US","og_type":"article","og_title":"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage - All-round Database Topics","og_description":"A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it's waiting, even when there aren't any incoming messages. Many such processes can prevent private strands usage.","og_url":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/","og_site_name":"All-round Database Topics","article_published_time":"2020-09-20T18:00:27+00:00","article_modified_time":"2022-02-16T19:52:32+00:00","author":"Nenad Noveljic","twitter_card":"summary_large_image","twitter_creator":"@NenadNoveljic","twitter_misc":{"Written by":"Nenad Noveljic","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/#article","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/"},"author":{"name":"Nenad Noveljic","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"headline":"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage","datePublished":"2020-09-20T18:00:27+00:00","dateModified":"2022-02-16T19:52:32+00:00","mainEntityOfPage":{"@id":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/"},"wordCount":969,"commentCount":4,"articleSection":["Avaloq","ORA-00600","Oracle","redo"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/","url":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/","name":"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage - All-round Database Topics","isPartOf":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#website"},"datePublished":"2020-09-20T18:00:27+00:00","dateModified":"2022-02-16T19:52:32+00:00","author":{"@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa"},"description":"A process waiting on an Advanced Queue or alert allocates an in-memory undo buffer and holds it as long as it's waiting, even when there aren't any incoming messages. Many such processes can prevent private strands usage.","breadcrumb":{"@id":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nenadnoveljic.com\/blog\/aq-alerts-private-strands\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nenadnoveljic.com\/blog\/"},{"@type":"ListItem","position":2,"name":"A Case Study: How Advanced Queuing and Alerts Prevented Private Strands Usage"}]},{"@type":"WebSite","@id":"https:\/\/nenadnoveljic.com\/blog\/#website","url":"https:\/\/nenadnoveljic.com\/blog\/","name":"All-round Database Topics","description":"Nenad Noveljic","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nenadnoveljic.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/nenadnoveljic.com\/blog\/#\/schema\/person\/51458d9dd86dbbdd19f5add451d44efa","name":"Nenad Noveljic","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a97b796613ea48ec8a7b79c8ffe1c685dcffc920c68121f6238d5caab5070670?s=96&d=mm&r=g","caption":"Nenad Noveljic"},"sameAs":["nenad-noveljic-9b746a6","https:\/\/x.com\/NenadNoveljic"],"url":"https:\/\/nenadnoveljic.com\/blog\/author\/nenad\/"}]}},"_links":{"self":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/3534","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/comments?post=3534"}],"version-history":[{"count":2,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/3534\/revisions"}],"predecessor-version":[{"id":4206,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/posts\/3534\/revisions\/4206"}],"wp:attachment":[{"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/media?parent=3534"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/categories?post=3534"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nenadnoveljic.com\/blog\/wp-json\/wp\/v2\/tags?post=3534"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}