Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add METADATA_READ and METADATA_WRITE blocks #9203

Merged
merged 1 commit into from Apr 23, 2015

Conversation

tlrx
Copy link
Member

@tlrx tlrx commented Jan 8, 2015

While looking at #3703, it looks like the usage of 'read_only' is a bit confusing.

The documentation stipulates:

index.blocks.read_only
Set to true to have the index read only, false to allow writes and metadata changes.

Actually, it blocks all write operations (creating, indexing or deleting a document) but also all read/write operations on index metadata. This can lead to confusion because subsequent 'indices exists' requests will return an undocumented 403 Forbidden response code where one could expect a 200 OK (as reported in #3703). Same for 'type exists' and 'alias exists' requests.

Similar issues have been reported:

But several API calls returns a 403 when at least one index of the cluster has 'index.blocks.read_only' set to true:

DELETE /_all

POST /library/book/1
{
  "title": "Elasticsearch: the definitive guide"
}

POST /movies/dvd/1
{
  "title": "Elasticsearch: the movie"
}

PUT /library/_settings
{
  "index": {
    "blocks.read_only": true
  }
}

The following calls will return 403 / "ClusterBlockException[blocked by: [FORBIDDEN/5/index read-only (api)];]":

HEAD /library
HEAD /library/book
HEAD /_all/dvd

GET /library/_settings
GET /library/_mappings
GET /library/_warmers
GET /library/_aliases

GET /_settings
GET /_aliases
GET /_mappings
GET /_cat/indices

I agree to @imotov's comment (see #5876 (comment)) and I think we should split the METADATA blocks in METADATA_READ & METADATA_WRITE blocks. This way the 'read_only' setting will block all write operations and metadata updates but the metadata will still be available.

This is a first step before updating all other actions then removing METADATA block completely.

Closes #3703
Closes #10521
Closes #10522
Related to #8102

@tlrx tlrx added the review label Jan 8, 2015
@tlrx
Copy link
Member Author

tlrx commented Jan 19, 2015

@imotov @s1monw Can you have a look please? :)

jdeniau added a commit to jdeniau/Elastica that referenced this pull request Jan 21, 2015
@tlrx
Copy link
Member Author

tlrx commented Jan 26, 2015

For what I've seen:
index.blocks.read_only: if true, blocks index writes and metadata reads/writes
index.blocks.read: if true, blocks index reads and allows metadata reads/writes
index.blocks.write: if true, blocks index writes and allows metadata reads/writes

With this behavior, it's not possible to block index writes + metadata writes and allows index reads + metadata reads at the same time.

@kimchy can you have a look please? Specially regarding your comment #5876 (comment) . I find this change useful but maybe it's just me.

@kimchy
Copy link
Member

kimchy commented Feb 24, 2015

looking at this change, won't it be confusing to have METADATA (which is deprecated) and METADATA_READ + METADATA_WRITE while METADATA is still used across the codebase?

I mean, I think we should either remove all usages of METADATA from the codebase, and only parse it for backward comp and resulting in 2 blocks MD_READ+MD_WRITE, and then go over all the places we use it, and use the equivalent MD_READ or MD_WRITE?

@s1monw
Copy link
Contributor

s1monw commented Mar 24, 2015

@tlrx are you picking this up again?

@tlrx
Copy link
Member Author

tlrx commented Mar 24, 2015

@s1monw yes, I asked @javanna to give me his opinion

@s1monw s1monw assigned javanna and unassigned imotov Mar 24, 2015
@javanna
Copy link
Member

javanna commented Mar 24, 2015

I confirm, it's on my list :)

indices.exists:
index: test_index_ro

- is_true: ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you remind me what this assertion does? do we really need it here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's needed to check the result of the previous 'indices.exists' request.

From here:

 is_true: '' means the response had no body but the client returned true (caused by 200)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright thanks :)

@javanna
Copy link
Member

javanna commented Mar 25, 2015

looks good, I left a few comments. I do agree with @kimchy on moving the whole codebase to the new blocks and maintain the old one only for bw comp, where METADATA just gets translated to METADATA_READ and METADATA_WRITE. That would isolate the bw comp aspect even more.

@javanna javanna removed the review label Mar 25, 2015

public static final EnumSet<ClusterBlockLevel> ALL = EnumSet.of(READ, WRITE, METADATA);
/**
* After 1.5.0 METADATA has been splitted into two distincts cluster block levels
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be more precise on the version, cause it's not clear if it is from 1.5.1 or 1.6.0.

@@ -121,11 +121,11 @@ protected GroupShardsIterator shards(ClusterState clusterState, OptimizeRequest

@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, OptimizeRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am always getting confused by this one and refresh. Shouldn't this be WRITE and not METADATA_WRITE? We don't really change any metadata here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think optimize should be WRITE. It is an administrative type action, you aren't actually passing data, just telling the system to do something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

METADATA_READ then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I updated this block I supposed that users want to block refresh/optimize actions on a read only cluster so I set METADATA_WRITE. Anyway I don't have a strong opinion on this and METADATA_READ is fine to me since it will still be blockable with the index.blocks.metadata setting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it is write because the cluster is changing (an action is happening in the background), and metadata because it is not changing data (it is changing the underlying storage, but from the user perspective the data is not changing).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have strong feelings about it. I just find it confusing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we agree on letting METADATA_WRITE ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on keeping it METADATA_WRITE

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this is confusing. Given how we classified operations in this PR, I think this one is more under metadata_write than metadata_read. We might need to adress this confusion at some point though (same with snapshots). So +1 on leaving METADATA_WRITE.

@imotov
Copy link
Contributor

imotov commented Apr 10, 2015

Left a couple of comments. Otherwise LGTM.

@imotov imotov removed their assignment Apr 10, 2015
@tlrx
Copy link
Member Author

tlrx commented Apr 13, 2015

Thanks @imotov and @javanna for your reviews. I made few changes according to your last comments.

Concerning #8102 I think it should be the subject of a dedicated pull request... I'd like to know more how restoring an index works when blocks are enabled and moving the cluster state from metadata to custom is not so simple I guess? Since this pull request doesn't change the current behavior I think it could be merged as it.

@@ -131,7 +131,7 @@ public void readFrom(StreamInput in) throws IOException {
final int len = in.readVInt();
ArrayList<ClusterBlockLevel> levels = new ArrayList<>();
for (int i = 0; i < len; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we changed the serialization code for this class, would it be possible to write a small unit test that verifies it? We already have similar *RequestTests#testSerialization tests that randomize the version and make sure that everything is fine.

@imotov
Copy link
Contributor

imotov commented Apr 16, 2015

@tlrx Sorry, missed the restore one the last time around. Otherwise, I think it's good.

@tlrx
Copy link
Member Author

tlrx commented Apr 17, 2015

@javanna I just added the test, can you please have a look? @imotov no worries, thanks for your review.

I added another check on WRITE block on the empty "" index in the TransportRestoreSnapshotAction. I think that there's no need to check for WRITE block for the indices specified in the request as @javanna suggested in this comment because the indices are necessarily in closed state and so WRITE are de facto blocked.

Version fromVersion = randomVersion();
Version toVersion = randomVersion();

ClusterBlockLevel[] blockLevels = ALL_CLUSTER_BLOCK_LEVELS;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterBlockLevel.values() ? don't think we need the constant

@javanna
Copy link
Member

javanna commented Apr 21, 2015

The new serialization test looks good, left a couple of minor comments. When you backport to 1.x, can you double check that our existing bw comp tests already cover some potential bw comp problems here (e.g. ClusterBlocks gets serialized and everything is fine)? We didn't write a specific bw comp test but only a unit test for serialization, I think this is enough but I didn't verify it.

Other than that LGTM.

@javanna
Copy link
Member

javanna commented Apr 22, 2015

LGTM @tlrx thanks!!!

This commit splits the current ClusterBlockLevel.METADATA into two disctins ClusterBlockLevel.METADATA_READ and ClusterBlockLevel.METADATA_WRITE blocks. It allows to make a distinction between
an operation that modifies the index or cluster metadata and an operation that does not change any metadata.

Before this commit, many operations where blocked when the cluster was read-only: Cluster Stats, Get Mappings, Get Snapshot, Get Index Settings, etc. Now those operations are allowed even when
the cluster or the index is read-only.

Related to elastic#8102, elastic#2833

Closes elastic#3703
Closes elastic#5855
Closes elastic#10521
Closes elastic#10522
@tlrx tlrx force-pushed the blocks-metadata-read-write branch from 2d8f854 to adc0807 Compare April 23, 2015 13:20
@tlrx tlrx merged commit adc0807 into elastic:master Apr 23, 2015
@kevinkluge kevinkluge removed the review label Apr 23, 2015
@tlrx
Copy link
Member Author

tlrx commented Apr 23, 2015

This pr has been merged in master and 1.x. For this latest branch I added *BlocksTests for the IndicesStatus and DeleteMapping operations which are removed in master branch.

There's a bwc test for cluster state updates but it doesn't use any blocks. I'll add it one in a dedicated pull request.

Thanks again @javanna and @imotov for your very helpful reviews.

tlrx added a commit to tlrx/elasticsearch that referenced this pull request Apr 24, 2015
This commit removes the deprecated ClusterBlockLevel.METADATA, replaced in elastic#9203 with METADATA_READ and METADATA_WRITE.
tlrx added a commit to tlrx/elasticsearch that referenced this pull request Apr 28, 2015
This commit removes the deprecated ClusterBlockLevel.METADATA, replaced in elastic#9203 with METADATA_READ and METADATA_WRITE.
@tlrx tlrx deleted the blocks-metadata-read-write branch April 28, 2015 12:58
@clintongormley clintongormley changed the title Internal: Add METADATA_READ and METADATA_WRITE blocks Add METADATA_READ and METADATA_WRITE blocks May 29, 2015
@clintongormley clintongormley added :Distributed/Distributed A catch all label for anything in the Distributed Area. If you aren't sure, use this one. and removed :Cluster labels Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed/Distributed A catch all label for anything in the Distributed Area. If you aren't sure, use this one. >enhancement v1.6.0 v2.0.0-beta1
Projects
None yet
8 participants