codeconsole commented on code in PR #16208:
URL: https://github.com/apache/grails-core/pull/16208#discussion_r4067571564
##########
grails-data-mongodb/docs/src/docs/asciidoc/querying/queryIndexes.adoc:
##########
@@ -142,6 +142,107 @@ WARNING: Dropping and recreating an index rebuilds it
from scratch, during which
A change to a TTL index's `expireAfterSeconds` is handled automatically and
does not require `recreateOnConflict`, because GORM updates the expiry in place
rather than rebuilding the index.
+==== Disabling Index Creation on Startup
+
+
+By default GORM creates and reconciles every index declared in a mapping block
when the datastore starts. Set `buildIndexes` to `false` in
`grails-app/conf/application.yml` to switch that off:
+
+[source,yaml]
+----
+grails:
+ mongodb:
+ buildIndexes: false
+----
+
+or, in `application.groovy`:
+
+[source,groovy]
+----
+grails {
+ mongodb {
+ buildIndexes = false
+ }
+}
+----
+
+With this setting no `createIndex` or `collMod` command is issued for any
domain class, and the indexes already present on the server are left exactly as
they are. Queries are unaffected and continue to use whichever indexes exist.
This is useful when deploying against live data whose indexes are managed
separately — by a DBA or a migration step — so that a deployment does not build
an index against a large production collection, and so an application running
against an older index set does not have those indexes reconciled underneath it.
+
+It also suppresses index creation for domain classes registered after startup.
Declared at the top level the setting applies to every connection, and each
connection can override it:
+
+[source,yaml]
+----
+grails:
+ mongodb:
+ buildIndexes: false
+ connections:
+ reporting:
+ url: mongodb://localhost/reporting
+ buildIndexes: true
+----
+
+NOTE: Because nothing is created, a collection that has never been initialised
with `buildIndexes` enabled will have no declared indexes at all. Turn the
setting off only where the indexes are already in place or are applied by other
means. The setting governs only the indexes GORM derives from the mapping
blocks; an explicit `createIndex` call made by application code against a
collection is unaffected.
+
+==== Building Indexes in the Background
+
+
+MongoDB answers a `createIndex` command only once the index has been built, so
by default the thread that creates the datastore — in an application, the
startup thread — waits for every declared index before the application finishes
starting. On an empty collection that is instant; on a large existing
collection an index build can take minutes, and a deployment waits for all of
them in turn.
+
+Set `buildIndexesAsync` to have the startup index build run on a background
thread instead:
+
+[source,yaml]
+----
+grails:
+ mongodb:
+ buildIndexesAsync: true
+----
+
+Startup then continues without waiting. The indexes are still built one at a
time per connection, on a daemon thread named after its connection, such as
`gorm-mongo-index-build-default-1`. Different connections can build indexes
concurrently, including when they use the same MongoDB server. The thread is
released after the build finishes and it has been idle for one second.
+
+Two consequences are worth planning for:
+
+* A query issued before its index has been built is served without it —
correctly, but with the performance of an unindexed query. The same applies to
a `unique` index: it constrains nothing until the build finishes.
+* Because startup no longer waits, a failure to build an index can no longer
fail startup. It is logged at error level, and the application runs without
that index. With the default synchronous build the exception propagates and the
application does not start.
+
+The setting is ignored when `buildIndexes` is `false`, and it applies only to
the index build performed when the datastore starts — a domain class registered
after startup is indexed on the thread registering it.
+
+NOTE: If the application shuts down while a background build is still running,
GORM stops waiting for it, but the server carries on building the index it was
asked for. A datastore stopped for a checkpoint and restored (with CRaC) runs a
build it cut short again once it is restarted, on every connection.
+
+==== What the Index Build Reports
+
+
+An index build that finishes without error logs one summary line at `INFO`:
+
+----
+Index build for database [myDb] finished in 412ms: 2 created, 5 already
present, from 3 domain class(es)
+----
+
+The domain class count includes every class considered for indexing, including
classes that declare no indexes. The created and already-present counts
describe index declarations; declaring the same keys twice can report one
created and one already present.
+
+The elapsed time is what the caller actually spent waiting — startup with the
default settings, or the background thread when `buildIndexesAsync` is enabled,
where this line is also the only signal that the build has finished.
+
+The split between created and already present is what makes that time
interpretable. MongoDB answers a `createIndex` for an index it already has
immediately and without building anything, so a restart that changed no
mappings reports everything as already present and costs milliseconds; a line
reporting indexes created is the one that accounts for a slow start. An index
that `recreateOnConflict` dropped and built again costs as much as a new one,
and is counted apart as recreated:
+
+----
+Index build for database [myDb] finished in 9315ms: 0 created, 1 recreated, 6
already present, from 3 domain class(es)
+----
+
+If any declaration failed, the summary is logged at `WARN` instead and reports
how many; the failures themselves are logged individually as they happen. A
build that stops partway — a lost connection or a timeout — reports how far it
got before stopping, also at `WARN`:
+
+----
+Index build for database [myDb] did not finish, stopping after 812ms at 1 of 3
domain class(es): 1 created, 0 already present
+----
+
Review Comment:
Fixed in 91a7eb489b. The section now covers all three forms the summary
takes. The partial case has its own example line and says what it means: those
declarations were applied, and only the created/already-present split is
missing for a collection whose `listIndexes` failed. The `N index
declaration(s) applied` form is tied to its actual condition, nothing
classified (the logger at `WARN`, or no collection's indexes readable), with an
example of the line you get at `WARN`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]