Description
Overview
As reported in SOLR-7384, when send deleteById request to Solr with ImplicitDocRouter, Solr fails to delete the document with the following error.
org.apache.solr.common.SolrException: missing _version_ on update from leader
This issue is related to SOLR-5890, which solved the issue about deleting documents with the implicit router. Unfortunately, this change left one bug in JavaBinUpdateRequestCodec that it forgets to restore version during unmarshal if _route_ is set.
Long version = (Long) params.get(UpdateRequest.VER); if (params.containsKey(ShardParams._ROUTE_)) updateRequest.deleteById(entry.getKey(), (String) params.get(ShardParams._ROUTE_)); else updateRequest.deleteById(entry.getKey(), version);
Note that, since this code refers _route_ parameter from properties of UpdateRequest, this error doesn't occur if you use _route_ request parameter (like /update?_route_=foo) instead.
How to reproduce
1. start solr cloud with default configuration.
$ ./bin/solr start -e cloud
2. create new collection (named test here) with implicit router.
$ curl 'http://localhost:8983/solr/admin/collections?action=CREATE&name=test&router.name=implicit&shards=shard1,shard2&maxShardsPerNode=2&replicationFactor=2'
3. send add and delete document requests.
// add a document "id=foo" to shard1 $ curl 'http://localhost:8983/solr/test/update?commit=true&_route_=shard1' -H 'Content-Type: text/xml' --data-binary '<add><doc><field name="id">foo</field></doc></add>' // delete the document by using "_route_" request parameter (this is OK) $ curl 'http://localhost:8983/solr/test/update?commit=true&_route_=shard1' -H 'Content-Type: text/xml' --data-binary '<delete><id>foo</id></delete>' // add a document "id=foo" to shard1 again $ curl 'http://localhost:8983/solr/test/update?commit=true&_route_=shard1' -H 'Content-Type: text/xml' --data-binary '<add><doc><field name="id">foo</field></doc></add>' // delete the document by using "_route_" attribute (this raises the error mentioned above) $ curl 'http://localhost:8983/solr/test/update?commit=true' -H 'Content-Type: text/xml' --data-binary '<delete><id _route_="shard1">foo</id></delete>'
4. stop solr cloud
$ ./bin/solr stop -all
How to fix
We can fix this issue by restoring UpdateRequest with version correctly like the following code:
Long version = (Long) params.get(UpdateRequest.VER); if (params.containsKey(ShardParams._ROUTE_)) updateRequest.deleteById(entry.getKey(), (String) params.get(ShardParams._ROUTE_), version); else updateRequest.deleteById(entry.getKey(), version);