@@ -31,7 +31,7 @@ collection.
3131Procedures
3232----------
3333
34- To create a :doc :`TTL index </core/ index-ttl>`, use the
34+ To create a :ref :`TTL index <index-feature -ttl>`, use the
3535:method:`db.collection.createIndex()` method with the
3636``expireAfterSeconds`` option on a field whose value is either a
3737:ref:`date <document-bson-type-date>` or an array that contains
@@ -47,7 +47,7 @@ You can modify the ``expireAfterSeconds`` of an existing TTL index
4747using the :dbcommand:`collMod` command.
4848
4949Expire Documents after a Specified Number of Seconds
50- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50+ ----------------------------------------------------
5151
5252To expire data after a specified number of seconds has passed since the
5353indexed field, create a TTL index on a field that holds values of BSON
@@ -88,7 +88,7 @@ specified in ``expireAfterSeconds``.
8888 ``expireAfterSeconds``.
8989
9090Expire Documents at a Specific Clock Time
91- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91+ -----------------------------------------
9292
9393To expire documents at a specific clock time, begin by creating a TTL
9494index on a field that holds values of BSON date type or an array of
@@ -125,3 +125,91 @@ number of seconds specified in ``expireAfterSeconds``, i.e. ``0``
125125seconds older in this case. As such, the data expires at the specified
126126``expireAt`` value.
127127
128+ .. _expireData-warning:
129+
130+ Indexes Configured Using NaN
131+ ----------------------------
132+
133+ .. warning::
134+
135+ Possible Data Loss
136+
137+ When a TTL index has ``expireAfterSeconds`` set to ``NaN``, upgrade,
138+ downgrade, and certain syncing operations can lead to unexpected
139+ behavior and possible data loss.
140+
141+ Do not set ``expireAfterSeconds`` to ``NaN`` in your TTL index
142+ configuration.
143+
144+ Prior to MongoDB 5.0, when a TTL index has ``expireAfterSeconds`` set to
145+ ``NaN``, MongoDB logs an error and does not remove any records.
146+
147+ From MongoDB 5.0.0 - 5.0.13 (and 6.0.0 - 6.0.1), ``NaN`` is treated as
148+ ``0``. If a TTL index is configured with ``expireAfterSeconds`` set to
149+ ``NaN``, all TTL-indexed documents expire immediately.
150+
151+ .. include:: /includes/indexes/expireAfterSeconds-versions.rst
152+
153+ However, there are still some situations which may result in unexpected
154+ behavior. Documents may expire:
155+
156+ - During an initial sync to an earlier version from MongoDB 5.0.0 -
157+ 5.0.13 (or 6.0.0 - 6.0.1).
158+ - When upgrading from an earlier version to MongoDB 5.0.0 - 5.0.13.
159+ - When restoring a collection from a pre-5.0 :binary:`~bin.mongodump`
160+ into a MongoDB 5.0.0 - 5.0.13 (or 6.0.0 - 6.0.1) instance.
161+
162+ To avoid problems, either drop or correct any misconfigured TTL indexes.
163+
164+ .. procedure::
165+ :style: normal
166+
167+ .. step:: Identify misconfigured indexes.
168+
169+ Run the following script in the :binary:`mongosh` shell. The
170+ script does not work in the legacy ``mongo`` shell.
171+
172+ .. code-block:: javascript
173+
174+ function getNaNIndexes() {
175+ const nan_index = [];
176+
177+ const dbs = db.adminCommand({ listDatabases: 1 }).databases;
178+
179+ dbs.forEach((d) => {
180+ const listCollCursor = db
181+ .getSiblingDB(d.name)
182+ .runCommand({ listCollections: 1 }).cursor;
183+
184+ const collDetails = {
185+ db: listCollCursor.ns.split(".$cmd")[0],
186+ colls: listCollCursor.firstBatch.map((c) => c.name),
187+ };
188+
189+ collDetails.colls.forEach((c) =>
190+ db
191+ .getSiblingDB(collDetails.db)
192+ .getCollection(c)
193+ .getIndexes()
194+ .forEach((entry) => {
195+ if (Object.is(entry.expireAfterSeconds, NaN)) {
196+ nan_index.push({ ns: `${collDetails.db}.${c}`, index: entry });
197+ }
198+ })
199+ );
200+ });
201+
202+ return nan_index;
203+ };
204+
205+ getNaNIndexes();
206+
207+ .. step:: Correct misconfigured indexes.
208+
209+ Use the :dbcommand:`collMod` command to update any misconfigured
210+ ``expireAfterSeconds`` values that the script found.
211+
212+ As an alternative, you can :dbcommand:`drop <dropIndexes>` any
213+ misconfigured TTL indexes and recreate them later using the
214+ :dbcommand:`createIndexes` command.
215+
0 commit comments