[
https://issues.apache.org/jira/browse/PHOENIX-4849?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16595765#comment-16595765
]
Lars Hofhansl commented on PHOENIX-4849:
----------------------------------------
Thanks [~jamestaylor]!
Agree on the comment :) Will add that.
In this particular case the RPC right now happens anyway... See
FromCompiler.getResolverForQuery(...) -> SingleTableColumnResolver.init(...) >
createTableRef(...). If the mutating and query tables are the same it already
does the RPC (see alwaysHitServer variable there). Maybe that's an unintended
left over from the past, but is it happening right now. Since it's only
happening for UPSERT SELECT and then only if used on the same table, perf wise
that is acceptable, I think.
I also think staying as close to the HBase model as possible good also. Getting
rid of the ChunkedResultIterator was a great step in that direction, a further
step is to let queries through that do not need to be scoped to a region. So
this is special for UPSERT SELECT into the same table only!
Lemme try the OFFSET case.
I see on passing back the right timestamp if/when the exception occurs. That's
a good idea!
I wonder though... Won't the timestamp have moved forward on the server if
there have been UPSERTs in between? I see no way to get the correct *old* for
timestamp at the same the SELECT started. At the time of the exception it
already is too late (the split happened, some data got inserted), only the
client starting the overall query can know that. Or is there some way to do
that? I can get the timestamps of the edits of the split region, but that's not
good enough, right?
Alternatively...
We also can just decide not to handle UPSERT SELECT for same tables special in
any way and allow the UPSERT to see partial updates if/when there're splits,
and not set a timestamp at all. It's not wrong from an HBase view point, just
unexpected. That is certainly a valid option as well. In that case we let
simple SELECTs pass without forcing them into a region always.
> UPSERT SELECT fails with stale region boundary exception after a split
> ----------------------------------------------------------------------
>
> Key: PHOENIX-4849
> URL: https://issues.apache.org/jira/browse/PHOENIX-4849
> Project: Phoenix
> Issue Type: Bug
> Reporter: Akshita Malhotra
> Assignee: Lars Hofhansl
> Priority: Major
> Attachments: PHOENIX-4849-complete-1.4.txt, PHOENIX-4849-fix.txt,
> PHOENIX-4849-v2.patch, PHOENIX-4849-v3.patch, PHOENIX-4849.patch
>
>
> UPSERT SELECT throws a StaleRegionBoundaryCacheException immediately after a
> split. On the other hand, an upsert followed by a select for example works
> absolutely fine
> org.apache.phoenix.schema.StaleRegionBoundaryCacheException: ERROR 1108
> (XCL08): Cache of region boundaries are out of date.
> at
> org.apache.phoenix.exception.SQLExceptionCode$14.newException(SQLExceptionCode.java:365)
> at
> org.apache.phoenix.exception.SQLExceptionInfo.buildException(SQLExceptionInfo.java:150)
> at
> org.apache.phoenix.util.ServerUtil.parseRemoteException(ServerUtil.java:183)
> at
> org.apache.phoenix.util.ServerUtil.parseServerExceptionOrNull(ServerUtil.java:167)
> at
> org.apache.phoenix.util.ServerUtil.parseServerException(ServerUtil.java:134)
> at
> org.apache.phoenix.iterate.ScanningResultIterator.next(ScanningResultIterator.java:153)
> at
> org.apache.phoenix.iterate.TableResultIterator.next(TableResultIterator.java:228)
> at
> org.apache.phoenix.iterate.LookAheadResultIterator$1.advance(LookAheadResultIterator.java:47)
> at
> org.apache.phoenix.iterate.LookAheadResultIterator.init(LookAheadResultIterator.java:59)
> at
> org.apache.phoenix.iterate.LookAheadResultIterator.peek(LookAheadResultIterator.java:73)
> at
> org.apache.phoenix.iterate.SerialIterators$SerialIterator.nextIterator(SerialIterators.java:187)
> at
> org.apache.phoenix.iterate.SerialIterators$SerialIterator.currentIterator(SerialIterators.java:160)
> at
> org.apache.phoenix.iterate.SerialIterators$SerialIterator.peek(SerialIterators.java:218)
> at
> org.apache.phoenix.iterate.ConcatResultIterator.currentIterator(ConcatResultIterator.java:100)
> at
> org.apache.phoenix.iterate.ConcatResultIterator.next(ConcatResultIterator.java:117)
> at
> org.apache.phoenix.iterate.DelegateResultIterator.next(DelegateResultIterator.java:44)
> at
> org.apache.phoenix.iterate.LimitingResultIterator.next(LimitingResultIterator.java:47)
> at org.apache.phoenix.jdbc.PhoenixResultSet.next(PhoenixResultSet.java:805)
> at
> org.apache.phoenix.compile.UpsertCompiler.upsertSelect(UpsertCompiler.java:219)
> at
> org.apache.phoenix.compile.UpsertCompiler$ClientUpsertSelectMutationPlan.execute(UpsertCompiler.java:1292)
> at org.apache.phoenix.jdbc.PhoenixStatement$2.call(PhoenixStatement.java:408)
> at org.apache.phoenix.jdbc.PhoenixStatement$2.call(PhoenixStatement.java:391)
> at org.apache.phoenix.call.CallRunner.run(CallRunner.java:53)
> at
> org.apache.phoenix.jdbc.PhoenixStatement.executeMutation(PhoenixStatement.java:390)
> at
> org.apache.phoenix.jdbc.PhoenixStatement.executeMutation(PhoenixStatement.java:378)
> at
> org.apache.phoenix.jdbc.PhoenixPreparedStatement.execute(PhoenixPreparedStatement.java:173)
> at
> org.apache.phoenix.jdbc.PhoenixPreparedStatement.execute(PhoenixPreparedStatement.java:183)
> at
> org.apache.phoenix.end2end.UpsertSelectAfterSplitTest.upsertSelectData1(UpsertSelectAfterSplitTest.java:109)
> at
> org.apache.phoenix.end2end.UpsertSelectAfterSplitTest.testUpsertSelect(UpsertSelectAfterSplitTest.java:59)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
> at
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> at
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
> at
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> at
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
> at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
> at
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
> at
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
> at
> com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
> at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)