Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-2910

Update with upsert and $inc modifier breaks find()

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major - P3 Major - P3
    • None
    • 1.6.5, 1.8.0
    • None
    • None
    • Linux version 2.6.31-22-server (buildd@allspice) (gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) ) #69-Ubuntu SMP Wed Nov 24 09:25:59 UTC 2010

      Test ran on 1.6.5 and reproduced on 1.8.0.
    • ALL

    Description

      There is a strange bug when using update() with a upset and a large $inc modifier. This bug is best explained with a reproducible example.

      1.
      use testbug;

      2.
      db.metrics.ensureIndex(

      {name: 1,period: 1, start_date: 1,aggregates: 1}

      );

      3.
      db.metrics.update(

      {'name': 'tab_content.tabviews', 'period': 'day', 'end_date': '2010-11-02 23:59:59', 'start_date': '2010-11-02 00:00:00'}

      ,
      {'$inc': {'aggregates.2204': 1, 'aggregates.241': 3, 'aggregates.2061': 1, 'aggregates.549': 2, 'aggregates.1634': 1, 'aggregates.1242': 1, 'aggregates.1269': 1, 'aggregates.75': 1, 'aggregates.2023': 79, 'aggregates.2245': 1, 'aggregates.987': 13, 'total': 200, 'aggregates.497': 1, 'aggregates.553': 1, 'aggregates.715': 1, 'aggregates.304': 9, 'aggregates.1842': 1, 'aggregates.1840': 1, 'aggregates.151': 2, 'aggregates.297': 2, 'aggregates.499': 1, 'aggregates.2238': 7, 'aggregates.932': 1, 'aggregates.1513': 4, 'aggregates.1270': 1, 'aggregates.2074': 11, 'aggregates.1579': 11, 'aggregates.2230': 3, 'aggregates.1398': 5, 'aggregates.285': 1, 'aggregates.2366': 1, 'aggregates.2033': 1, 'aggregates.1498': 3, 'aggregates.1355': 1, 'aggregates.628': 2, 'aggregates.233': 1, 'aggregates.166': 2, 'aggregates.1290': 5, 'aggregates.1796': 7, 'aggregates.2003': 2, 'aggregates.925': 2, 'aggregates.101': 1, 'aggregates.1793': 5}},
      true);

      4.
      db.metrics.find(

      {start_date: '2010-11-02 00:00:00', name: 'tab_content.tabviews', period: 'day'}

      ).pretty();
      // Document in Step 3 is returned as expected.

      5.
      db.metrics.update(

      {'name': 'tab_content.tabviews', 'period': 'day', 'end_date': '2010-11-02 23:59:59', 'start_date': '2010-11-02 00:00:00'}

      ,
      {'$inc': {'aggregates.2238': 15, 'aggregates.2108': 1, 'aggregates.2204': 2, 'aggregates.1634': 1, 'aggregates.297': 3, 'aggregates.1244': 1, 'aggregates.1111': 1, 'aggregates.2023': 65, 'aggregates.2245': 1, 'aggregates.987': 5, 'total': 200, 'aggregates.264': 2, 'aggregates.1868': 1, 'aggregates.249': 2, 'aggregates.910': 2, 'aggregates.166': 1, 'aggregates.304': 4, 'aggregates.303': 3, 'aggregates.497': 3, 'aggregates.73': 1, 'aggregates.1750': 1, 'aggregates.499': 1, 'aggregates.498': 1, 'aggregates.1781': 1, 'aggregates.1826': 1, 'aggregates.2074': 8, 'aggregates.1579': 18, 'aggregates.1398': 11, 'aggregates.1513': 6, 'aggregates.646': 3, 'aggregates.1760': 1, 'aggregates.75': 2, 'aggregates.1355': 3, 'aggregates.233': 1, 'aggregates.1292': 1, 'aggregates.1290': 5, 'aggregates.1855': 1, 'aggregates.961': 2, 'aggregates.724': 2, 'aggregates.1796': 4, 'aggregates.647': 1, 'aggregates.1793': 11, 'aggregates.129': 1}},
      true);

      6.
      db.metrics.find(

      {start_date: '2010-11-02 00:00:00', name: 'tab_content.tabviews', period: 'day'}

      ).pretty();
      // After the second update in Step 5, nothing is returned for this query now.

      7.
      db.metrics.find();
      // This will return the document we want.

      8.
      db.metrics.update(

      {'name': 'tab_content.tabviews', 'period': 'day', 'end_date': '2010-11-02 23:59:59', 'start_date': '2010-11-02 00:00:00'}

      ,
      {'$inc': {'aggregates.2204': 3, 'aggregates.2106': 1, 'aggregates.1637': 1, 'aggregates.71': 2, 'aggregates.1244': 1, 'aggregates.166': 2, 'aggregates.1187': 1, 'aggregates.2023': 91, 'aggregates.987': 6, 'total': 200, 'aggregates.963': 2, 'aggregates.266': 1, 'aggregates.553': 2, 'aggregates.715': 1, 'aggregates.304': 4, 'aggregates.497': 3, 'aggregates.1840': 2, 'aggregates.2238': 11, 'aggregates.1780': 1, 'aggregates.2105': 2, 'aggregates.2074': 11, 'aggregates.1579': 13, 'aggregates.2230': 1, 'aggregates.1398': 4, 'aggregates.1513': 2, 'aggregates.1355': 1, 'aggregates.549': 2, 'aggregates.1292': 1, 'aggregates.1290': 5, 'aggregates.1855': 1, 'aggregates.214': 1, 'aggregates.1796': 6, 'aggregates.1793': 13, 'aggregates.1956': 2}},
      true);

      9.
      db.metrics.find(

      {start_date: '2010-11-02 00:00:00', name: 'tab_content.tabviews', period: 'day'}

      ).pretty();
      // Only the document in Step 8 was returned.

      10.
      db.metrics.find();
      // Finds 2 separate documents.

      Note

      • After step 6, running a db.metrics.find( {start_date: '2010-11-02 00:00:00', name: 'tab_content.tabviews', period: 'day'}

        ).explain();
        {
        "cursor" : "BtreeCursor start_date_1_name_1_period_1_aggregates_1",
        "nscanned" : 0,
        "nscannedObjects" : 0,
        "n" : 0,
        "millis" : 0,
        "indexBounds" :

        Unknown macro: { "start_date" }

        }

      • When using a $inc modifier with only a single property increment, the bug does not exist.
      • If the index is modified to be {start_date: 1, name: 1, period: 1}

        then the bug no longer exists as we can tell. Our current fix is to use this index as we have no current direct use for indexing the "aggregates" property. This bug though to the best of our knowledge does not seem to be intended and by design.

      Attachments

        Activity

          People

            Unassigned Unassigned
            duoduo Duo Zheng
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: