Over a million developers have joined DZone.

What’s New in TokuMX 1.4, Part 2: Partitioned oplog

· Java Zone

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

We just released version 1.4.0 of TokuMX, our high-performance distribution of MongoDB. There are a lot of improvements in this version (release notes), the most of any release yet. In this series of blog posts, we describe the most interesting changes and how they’ll affect users.

In MongoDB, the replication oplog is a capped collection, with a fixed size on disk, and therefore the amount of history (measured in days) varies as the application makes changes faster or slower.

In TokuMX, capped collections don’t support as high concurrency levels as we want to provide for the oplog, so instead of picking a fixed disk size to cap it, we instead let users specify the number of days’ worth of operations to keep around (the expireOplogDays parameter) and we have background threads that delete old data to maintain this.

This is nice because it simplifies how you understand your cluster’s health. Unfortunately, it was achieved by running threads that are constantly trimming the tail of the oplog, which hold metadata locks and consume server resources. Sometimes they can cause bad stalls if a write lock (say, to add a member to the replica set) gets in line behind a long trimming operation.  Some of this risk was taken care of in TokuMX 1.3.3, but in TokuMX 1.4.0 we are getting rid of these threads completely.

In TokuMX 1.4.0 the oplog is now a “partitioned” collection, which is also a new type of collection, similar to SQL partitioned tables.  A partitioned collection is represented on disk by a set of normal collections, together with some metadata that specifies which data is in which collection.

There are currently many limitations for partitioned collections, so they probably aren’t useful for most applications yet, but they can be used by normal applications, and they’ll become more useful in the future.  The current limitations include:

  • Secondary indexes aren’t supported, they must use the default “_id” index as the only index, and they must be partitioned according to the _id field (and they cannot use primary keys).
  • Partitioned collections can’t be renamed.
  • The addPartition/dropPartition commands cannot be replicated, so they should not be used in a replica set outside of the local database.

For the oplog, each day a new partition is added and the oldest partition is dropped, which quickly and easily reclaims the space used by the oldest partition, without consuming extra resources or blocking other operations the way trimming could in the past.  This will make cluster administration much simpler with respect to the oplog, for many users.

To get information about the partitioning of the oplog there are commands to report this metadata:

rs0:PRIMARY> rs.oplogPartitionInfo()
{
       "numPartitions" : NumberLong(2),
       "partitions" : [
               {
                       "_id" : NumberLong(0),
                       "max" : {
                               "" : BinData(0,"AAAAAAAAAAEAAAAAAAAAAA==")
                       },
                       "createTime" : ISODate("2014-02-03T21:04:00.983Z")
               },
               {
                       "_id" : NumberLong(1),
                       "max" : {
                               "" : { "$maxKey" : 1 }
                       },
                       "createTime" : ISODate("2014-02-03T21:04:47.494Z")
               }
       ],
       "ok" : 1
}
rs0:PRIMARY> rs.oplogRefsPartitionInfo()
{
       "numPartitions" : NumberLong(2),
       "partitions" : [
               {
                       "_id" : NumberLong(0),
                       "max" : {
                               "" : {
                                       "oid" : ObjectId("52f004416ae5e77a3cbbbc4c"),
                                       "seq" : NumberLong(3)
                               }
                       },
                       "createTime" : ISODate("2014-02-03T21:04:01.109Z"),
                       "maxRefGTID" : BinData(0,"AAAAAAAAAAEAAAAAAAAAAA==")
               },
               {
                       "_id" : NumberLong(1),
                       "max" : {
                               "" : { "$maxKey" : 1 }
                       },
                       "createTime" : ISODate("2014-02-03T21:04:47.543Z")
               }
       ],
       "ok" : 1
}

To manually trim partitions, you can specify a GTID or a timestamp to trim to. For example, with the above information, either of these commands will trim the first partition away:

rs0:PRIMARY> rs.trimToGTID(BinData(0,"AAAAAAAAAAEAAAAAAAAAAA=="))
rs0:PRIMARY> rs.trimToTS(ISODate("2014-02-03T21:04:47.494Z"))

On upgrade, existing oplogs will be converted to partitioned collections with the old data all in one partition and an empty one after it for new data, and after enough time, it will be dropped all at once.

Want to check out the newest version of TokuMX?  Download TokuMX 1.4.0 here:

MongoDB DownloadMongoDB Download

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.

Topics:

Published at DZone with permission of Leif Walsh, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}