Chapter 12 · Aliases, Rollover, Reindex, Update/Delete by Query, and Zero-Downtime Index Changes
Read/Write Aliases, Filters, Routing, is_write_index, and Atomic Alias Updates
Use AtlasMart read/write aliases as an indirection and cutover layer, reason about filtered/routed aliases and write-index selection, and prove an alias migration is atomic and reversible.
Learning outcomes
AtlasMart wants to replace the physical product index without
changing the application endpoint. The application should
continue reading from atlasmart-products-read and
writing to atlasmart-products-write while
operations can move those logical names from v1 to v2. An
index alias is cluster metadata that resolves a
logical name to one or more concrete indices. It is not a copied
dataset, not a DNS record, and not a backup.
Explain read aliases, write aliases and the role of is_write_index when an alias names multiple indices.
Use alias filters and routing only when their security and shard-selection consequences are understood.
Perform a multi-action alias cutover atomically instead of issuing independent add/remove requests.
Prove alias state before and after a change using metadata and application-level smoke tests.
Design rollback so it does not depend on data that was already destroyed or transformed irreversibly.
Examples target self-managed Elasticsearch 9.5.3 and OpenSearch 3.8.0 with the established AtlasMart lab conventions: Elasticsearch on https://localhost:9200 using the copied CA certificate, OpenSearch on https://localhost:9201 using the disposable demo certificate only for local learning, pinned server versions, and no moving latest tags. Alias semantics are broadly similar across both products, but authorization, data-stream alias behavior and managed-service restrictions must be validated on the target deployment.
The generation environment does not run both search servers. Requests below are deterministic lab specifications reviewed against current product documentation. Expected output describes invariants, not fabricated captured results. Execute against disposable AtlasMart resources and record your own task IDs, counts, conflicts, throttling time, p95/p99 latency, CPU, disk growth and rollback evidence.
Run mutating, destructive, security, lifecycle, snapshot, failure-injection, and load-test commands only in the disposable AtlasMart lab or an equivalently isolated environment. Verify the target cluster, index, tenant, credentials, and rollback path before execution; treat shown output as an expected invariant unless the lesson explicitly labels it as captured evidence.
1. Build the physical index before introducing indirection
PUT atlasmart-products-v1
{
"settings":{"number_of_shards":1,"number_of_replicas":0},
"mappings":{"dynamic":"strict","properties":{
"sku":{"type":"keyword"},
"name":{"type":"text","fields":{"keyword":{"type":"keyword"}}},
"category":{"type":"keyword"},
"price":{"type":"scaled_float","scaling_factor":100},
"available":{"type":"boolean"},
"updated_at":{"type":"date"}
}}
}
POST _bulk?refresh=true
{"index":{"_index":"atlasmart-products-v1","_id":"P-1001"}}
{"sku":"P-1001","name":"Wireless Noise Cancelling Headphones","category":"audio","price":199.99,"available":true,"updated_at":"2026-09-11T07:00:00Z"}
{"index":{"_index":"atlasmart-products-v1","_id":"P-1002"}}
{"sku":"P-1002","name":"USB-C Travel Charger","category":"power","price":49.95,"available":true,"updated_at":"2026-09-11T07:01:00Z"}
{"index":{"_index":"atlasmart-products-v1","_id":"P-1003"}}
{"sku":"P-1003","name":"Ergonomic Mechanical Keyboard","category":"input","price":129.00,"available":false,"updated_at":"2026-09-11T07:02:00Z"}
The concrete index remains the storage object. The alias is a pointer in cluster metadata. Keeping those concepts separate is essential because operations such as deleting a physical index or reindexing into v2 act on the concrete index even if the application normally talks only to an alias.
2. Create explicit read and write aliases
POST _aliases
{
"actions":[
{"add":{"index":"atlasmart-products-v1","alias":"atlasmart-products-read"}},
{"add":{"index":"atlasmart-products-v1","alias":"atlasmart-products-write","is_write_index":true}}
]
}
GET _alias/atlasmart-products-read
GET _alias/atlasmart-products-write
For a write alias that can eventually reference multiple indices, explicitly mark the write index. OpenSearch and Elasticsearch both reject ambiguous writes when an alias resolves to multiple indices and no write target is selected. Explicitness also makes operational intent reviewable before a migration.
The POST _aliases request accepts multiple
add/remove actions as one cluster-state update. That avoids
the application-visible gap created by “remove old alias”
followed later by “add new alias.” Atomic metadata change does
not make your entire data migration transactional; writes that
happened before the cutover still require a consistency
strategy.
3. Filters and routing change semantics, not just convenience
POST _aliases
{
"actions":[
{"add":{
"index":"atlasmart-products-v1",
"alias":"atlasmart-products-audio",
"filter":{"term":{"category":"audio"}}
}}
]
}
GET atlasmart-products-audio/_search
{
"query":{"match_all":{}}
}
A filtered alias constrains searches through the alias, but it is not a substitute for a complete tenant-authorization design. Access to the underlying concrete index can bypass that logical filter unless security privileges prevent it. Alias routing similarly influences shard selection; it can improve locality for a known access pattern but can also create hot shards or missing results when the application supplies inconsistent routing.
POST _aliases
{
"actions":[
{"add":{
"index":"atlasmart-products-v1",
"alias":"atlasmart-products-tenant-a",
"filter":{"term":{"tenant_id":"tenant-a"}},
"index_routing":"tenant-a",
"search_routing":"tenant-a"
}}
]
}
Only use this form when documents were indexed with compatible routing. A filter cannot recover a document that was routed to a shard excluded by the alias search routing.
4. Prepare v2, then switch both aliases in one request
PUT atlasmart-products-v2
{
"settings":{"number_of_shards":1,"number_of_replicas":0},
"mappings":{"dynamic":"strict","properties":{
"sku":{"type":"keyword"},
"name":{"type":"text","analyzer":"standard","fields":{"keyword":{"type":"keyword"}}},
"category":{"type":"keyword"},
"price":{"type":"scaled_float","scaling_factor":100},
"available":{"type":"boolean"},
"updated_at":{"type":"date"},
"schema_version":{"type":"keyword"}
}}
}
POST _aliases
{
"actions":[
{"remove":{"index":"atlasmart-products-v1","alias":"atlasmart-products-read"}},
{"remove":{"index":"atlasmart-products-v1","alias":"atlasmart-products-write"}},
{"add":{"index":"atlasmart-products-v2","alias":"atlasmart-products-read"}},
{"add":{"index":"atlasmart-products-v2","alias":"atlasmart-products-write","is_write_index":true}}
]
}
GET _alias/atlasmart-products-read
GET _alias/atlasmart-products-write
This is safe only after v2 is complete enough for the chosen migration strategy. An atomic pointer switch cannot repair writes that landed only in v1 while the reindex was still copying. Later lessons make that change-data window explicit.
5. Deliberately wrong approach: two independent alias calls
A common runbook says “remove the old alias, verify, then add
the new alias.” The verification pause creates downtime because
the application name resolves to nothing. A second failure mode
is adding v2 first and removing v1 later while both are write
candidates without is_write_index. Repair by
validating v2 first and sending all intended alias changes in
one _aliases action set.
BEFORE
GET _alias/atlasmart-products-read
GET _alias/atlasmart-products-write
GET atlasmart-products-read/_count
GET atlasmart-products-read/_search?q=sku:P-1001
CUTOVER
POST _aliases # one multi-action request
AFTER
GET _alias/atlasmart-products-read
GET _alias/atlasmart-products-write
GET atlasmart-products-read/_count
GET atlasmart-products-read/_search?q=sku:P-1001
POST atlasmart-products-write/_doc/P-1999?refresh=true
{"sku":"P-1999","name":"Cutover Smoke Product","category":"test","price":1.00,"available":true,"updated_at":"2026-09-11T08:00:00Z","schema_version":"v2"}
6. Rollback is another atomic alias change
If the application fails smoke tests and v1 still contains a compatible, sufficiently current copy, reverse the alias actions. If writes have already advanced only in v2, pointing reads back to v1 can lose those writes from the application view. This is why rollback design must be tied to write coordination, not written as a ceremonial final step.
Check your understanding
- What does an alias store?
- Why set is_write_index explicitly?
- Why is a filtered alias not a complete tenant-security boundary?
- What does an atomic alias update guarantee?
- What determines whether rollback is safe?
Review the answers
1. Cluster metadata mapping a logical alias name to one or more concrete indices or data streams, plus optional filter/routing/write-index metadata.
2. To remove ambiguity when an alias references more than one index and to make migration intent auditable.
3. Direct access to the underlying index can bypass the filter unless authorization prevents it.
4. The listed alias metadata actions are applied as one cluster-state change; it does not make the data-copy phase transactional.
5. Whether the old target still satisfies schema/application expectations and contains every write that must remain visible.
Production judgment
Use aliases as deployment indirection, not as a substitute for data synchronization. Record the exact pre-cutover alias state, source/destination counts, high-value search fixtures, current write strategy and rollback deadline. Measure the cluster-state publication time and application p95/p99 around cutover, but do not invent a universal “safe” timeout. Access to alias-management APIs should be tightly controlled because a single metadata change can redirect tenant reads and writes.
Summary and next step
You can now separate a stable application endpoint from concrete indices and switch targets atomically. Next, rollover applies the same write-index concept repeatedly as an index grows or as a data stream creates a new backing index.
Authoritative references
- Elastic aliases — Alias filters, routing, write-index behavior and alias management.
- Elastic update aliases API — Multi-action alias changes through POST /_aliases.
- Elastic rollover API — Manual rollover for data streams and index aliases; conditions and write-index semantics.
- Elastic reindex API — Reindex requirements, throttling, slicing, remote sources and destination preparation.
- Elastic update by query — Snapshot semantics, conflicts, slicing, throttling and task monitoring.
- Elastic task API — Task progress and status for long-running operations.
- OpenSearch aliases API — Atomic alias action sets, filters, routing and write-index behavior.
- OpenSearch rollover API — Rollover for aliases/data streams with age, docs and size conditions.
- OpenSearch reindex API — Local/remote reindex, slicing, throttling, background tasks and validation fields.
- OpenSearch update by query — Snapshot-based update-by-query, conflicts and partial completion semantics.
- OpenSearch delete by query — Snapshot-based deletion, conflicts and non-rollback behavior.
- OpenSearch cancel tasks — Cancellation behavior and cancellable task checks.