Skip to content
This repository was archived by the owner on Oct 17, 2022. It is now read-only.

Commit 6370d8a

Browse files
authored
RFC for Mango on FDB (#407)
RFC for Mango on FDB
1 parent 3f3e27b commit 6370d8a

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

rfcs/006-mango-fdb.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Mango RFC
2+
3+
---
4+
5+
name: Formal RFC
6+
about: Submit a formal Request For Comments for consideration by the team.
7+
title: ‘Mango JSON indexes in FoundationDB’
8+
labels: rfc, discussion
9+
assignees: ‘’
10+
11+
---
12+
13+
[note]: # " ^^ Provide a general summary of the RFC in the title above. ^^ "
14+
15+
# Introduction
16+
17+
This document describes the data model, querying and indexing management for Mango JSON indexes with FoundationDB.
18+
19+
## Abstract
20+
21+
This document details the data model for storing Mango indexes. Indexes will be updated in the transaction that a document is written to FoundationDB. When an index is created on an existing database, a background task will build the index up to the Sequence that the index was created at.
22+
23+
## Requirements Language
24+
25+
[note]: # " Do not alter the section below. Follow its instructions. "
26+
27+
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
28+
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this
29+
document are to be interpreted as described in
30+
[RFC 2119](https://www.rfc-editor.org/rfc/rfc2119.txt).
31+
32+
## Terminology
33+
34+
`Sequence`: a 13-byte value formed by combining the current `Incarnation` of the database and the `Versionstamp` of the transaction. Sequences are monotonically increasing even when a database is relocated across FoundationDB clusters. See (RFC002)[LINK TBD] for a full explanation.
35+
36+
---
37+
38+
# Detailed Description
39+
40+
Mango is a declarative JSON querying syntax that allows a user to retrieve documents based on a selector. Indexes can be defined to improve query performance. In CouchDB Mango is a query layer built on top of Map/Reduce indexes. Each Mango query follows a two-step process, first a subset of the selector is converted into a map query to be used with a predefined index or falling back to `_all_docs` if no indexes are available. Each document retrieved from the index is then matched against the full query selector.
41+
42+
With CouchDB on FoundationDB, all new created Mango indexes have the `interactive: true` option set. Thereby Mango indexes will be indexed in the same transaction that a document is add/updated to the database.
43+
44+
## Data Model
45+
46+
### Index Definitions
47+
48+
A Mango index is defined as:
49+
50+
```json
51+
{
52+
"name": "view-name",
53+
"index": {
54+
"fields": ["fieldA", "fieldB"]
55+
},
56+
"partial_filter_selector": {}
57+
}
58+
```
59+
60+
The above index definition would be converted into a map index that looks like this:
61+
62+
```json
63+
{
64+
"_id": "_design/ddoc",
65+
"language": "query",
66+
"views": {
67+
"view-name": {
68+
"map": {
69+
"fields": [{ "fieldA": "asc" }, { "fieldB": "asc" }],
70+
"selector": {}
71+
}
72+
}
73+
},
74+
"options": [{ "autoupdate": false }, { "interactive": true }]
75+
}
76+
```
77+
78+
- `{"autoupdate": false}` means that the index will not be auto updated in the background
79+
- `{"interactive": true}` configures the index to be updated in the document update transaction
80+
81+
### Index Definition
82+
83+
Mango indexes are a layer on top of map indexes. So the index definition is the same as the map index definition.
84+
85+
### Index Limits
86+
87+
This design has certain defined limits for it to work correctly:
88+
89+
- The index definition (`name`, `fields` and `partial_filter_selector`) cannot exceed 64 KB FDB value limit
90+
- The sorted keys for an index cannot exceed the 8 KB key limit
91+
- To be able to update the index in the transaction that a document is updated in, there will have to be a limit on the number of Mango indexes for a database so that the transaction stays within the 10MB transaction limit. This limit is still TBD based on testing.
92+
93+
## Index building and management
94+
95+
When an index is created on an existing database, the index will be updated in a background job up to the versionstamp that the index was added to the database at. The process for building a new index would be:
96+
97+
1. Save index to the database, along with a creation versionstamp and set the index status to `building` so that is it not used to service any queries until it is updated. Add a job to `couch_jobs` to build the index.
98+
2. Any write requests (document updates) after the saved index definition will update the index in the document update. Index writers can assume that previous versions of the document have already been indexed.
99+
3. `couch_jobs` will start reading sections of the changes feed and building the index, this background process will keep processing the changes read until it reaches the creation versionstamp. Once it reaches that point, the index is up to date and `build_status` will be marked as `active` and the index can be used to service queries.
100+
4. There is some subtle behavior around step 3 that is worth mentioning. The background process will have the 5-second transaction limit, so it will process smaller parts of the changes feed. Which means that it won’t have one consistent view of the changes feed throughout the index building process. This will lead to a conflict situation when the background process transaction is adding a document to the index while at the same time a write request has a transaction that is updating the same document. There are two possible outcomes to this, if the background process wins, the write request will get a conflict. At that point the write request will try to process the document again, read the old values for that document, remove them from the index and add the new values to the index. If the write request wins, and the background process gets a conflict, then the background process can try again, the document would have been removed from its old position in the changes feed and moved to the later position, so the background process won’t see the document and will then move on to the next one.
101+
102+
## Advantages
103+
104+
- Indexes are kept up to date when documents are changed, meaning you can read your own writes
105+
- Makes Mango indexes first-class citizens and opens up the opportunity to create more Mango specific functionality
106+
107+
## Disadvantages
108+
109+
- FoundationDB currently does not allow CouchDB to do the document selector matching at the shard level. However, there is a discussion for this [Feature Request: Predicate pushdown](https://forums.foundationdb.org/t/feature-request-predicate-pushdown/954)
110+
111+
## Key Changes
112+
113+
- Mango indexes will be stored separately to Map/Reduce indexes.
114+
- Mango Indexes will be updated when a document is updated
115+
- A background process will build a new Mango index on an existing database
116+
- There are specific index limits mentioned in the Index Limits section.
117+
118+
Index limitations aside, this design preserves all of the existing API options
119+
for working with CouchDB documents.
120+
121+
## Applications and Modules affected
122+
123+
The `mango` application will be modified to work with FoundationDB
124+
125+
## HTTP API additions
126+
127+
When querying any of the `_index` endpoints an extra field, `build_status`, will be added to the index definition.
128+
The `build_status` will either be `building` or `active`.
129+
130+
## HTTP API deprecations
131+
132+
None,
133+
134+
# Security Considerations
135+
136+
None have been identified.
137+
138+
# References
139+
140+
[Original mailing list discussion](https://lists.apache.org/thread.html/b614d41b72d98c7418aa42e5aa8e3b56f9cf1061761f912cf67b738a@%3Cdev.couchdb.apache.org%3E)
141+
142+
# Acknowledgements
143+
144+
thanks to following in participating in the design discussion
145+
146+
- @kocolosk
147+
- @willholley
148+
- @janl
149+
- @alexmiller-apple

0 commit comments

Comments
 (0)