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.

Intermediate110–135 minutesZero-downtime migration labElasticsearch 9.5.3 · OpenSearch 3.8.0Last reviewed: September 2026

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.

01

Explain read aliases, write aliases and the role of is_write_index when an alias names multiple indices.

02

Use alias filters and routing only when their security and shard-selection consequences are understood.

03

Perform a multi-action alias cutover atomically instead of issuing independent add/remove requests.

04

Prove alias state before and after a change using metadata and application-level smoke tests.

05

Design rollback so it does not depend on data that was already destroyed or transformed irreversibly.

Chapter baseline reviewed 11 September 2026

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.

Execution and measurement note

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.

Execution and safety note

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

Dev Tools · create deterministic v1 fixture
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

Dev Tools · install application 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.

Atomic means the alias action set is committed together

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

Filtered tenant alias
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.

Routing-aware alias example
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

Dev Tools · prepare v2
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"}
  }}
}
Atomic cutover after validation
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.

Pre/post evidence checklist
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

  1. What does an alias store?
  2. Why set is_write_index explicitly?
  3. Why is a filtered alias not a complete tenant-security boundary?
  4. What does an atomic alias update guarantee?
  5. 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

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.