[ https://issues.apache.org/jira/browse/PHOENIX-4010?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16099311#comment-16099311 ]
ASF GitHub Bot commented on PHOENIX-4010: ----------------------------------------- Github user JamesRTaylor commented on a diff in the pull request: https://github.com/apache/phoenix/pull/268#discussion_r129186906 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java --- @@ -303,73 +318,84 @@ public TaskExecutionMetricsHolder getTaskExecutionMetric() { * @throws SQLException * @throws IllegalStateException if hashed table cannot be removed on any region server on which it was added */ - private void removeServerCache(final byte[] cacheId, Set<HRegionLocation> servers) throws SQLException { - ConnectionQueryServices services = connection.getQueryServices(); - Throwable lastThrowable = null; - TableRef cacheUsingTableRef = cacheUsingTableRefMap.get(Bytes.mapKey(cacheId)); - final PTable cacheUsingTable = cacheUsingTableRef.getTable(); - byte[] tableName = cacheUsingTableRef.getTable().getPhysicalName().getBytes(); - HTableInterface iterateOverTable = services.getTable(tableName); - try { - List<HRegionLocation> locations = services.getAllTableRegions(tableName); - Set<HRegionLocation> remainingOnServers = new HashSet<HRegionLocation>(servers); - /** - * Allow for the possibility that the region we based where to send our cache has split and been - * relocated to another region server *after* we sent it, but before we removed it. To accommodate - * this, we iterate through the current metadata boundaries and remove the cache once for each - * server that we originally sent to. - */ - if (LOG.isDebugEnabled()) {LOG.debug(addCustomAnnotations("Removing Cache " + cacheId + " from servers.", connection));} - for (HRegionLocation entry : locations) { - if (remainingOnServers.contains(entry)) { // Call once per server - try { + private void removeServerCache(final ServerCache cache, Set<HRegionLocation> servers) throws SQLException { + HTableInterface iterateOverTable = null; + final byte[] cacheId = cache.getId(); + try { + List<byte[]> keys = cache.getKeys(); + ConnectionQueryServices services = connection.getQueryServices(); + Throwable lastThrowable = null; + TableRef cacheUsingTableRef = cacheUsingTableRefMap.get(Bytes.mapKey(cacheId)); + final PTable cacheUsingTable = cacheUsingTableRef.getTable(); + byte[] tableName = cacheUsingTableRef.getTable().getPhysicalName().getBytes(); + iterateOverTable = services.getTable(tableName); + + List<HRegionLocation> locations = services.getAllTableRegions(tableName); + Set<HRegionLocation> remainingOnServers = new HashSet<HRegionLocation>(servers); --- End diff -- Instead of Set<HRegionLocation> can we change this to Set<ServerName>? It'd make it more clear IMHO > Hash Join cache may not be send to all regionservers when we have stale HBase > meta cache > ---------------------------------------------------------------------------------------- > > Key: PHOENIX-4010 > URL: https://issues.apache.org/jira/browse/PHOENIX-4010 > Project: Phoenix > Issue Type: Bug > Reporter: Ankit Singhal > Assignee: Ankit Singhal > Fix For: 4.12.0 > > Attachments: PHOENIX-4010.patch, PHOENIX-4010_v1.patch, > PHOENIX-4010_v2.patch, PHOENIX-4010_v2_rebased_1.patch, > PHOENIX-4010_v2_rebased.patch > > > If the region locations changed and our HBase meta cache is not updated then > we might not be sending hash join cache to all region servers hosting the > regions. > ConnectionQueryServicesImpl#getAllTableRegions > {code} > boolean reload =false; > while (true) { > try { > // We could surface the package projected > HConnectionImplementation.getNumberOfCachedRegionLocations > // to get the sizing info we need, but this would require a > new class in the same package and a cast > // to this implementation class, so it's probably not worth > it. > List<HRegionLocation> locations = Lists.newArrayList(); > byte[] currentKey = HConstants.EMPTY_START_ROW; > do { > HRegionLocation regionLocation = > connection.getRegionLocation( > TableName.valueOf(tableName), currentKey, reload); > locations.add(regionLocation); > currentKey = regionLocation.getRegionInfo().getEndKey(); > } while (!Bytes.equals(currentKey, HConstants.EMPTY_END_ROW)); > return locations; > {code} > Skipping duplicate servers in ServerCacheClient#addServerCache > {code} > List<HRegionLocation> locations = > services.getAllTableRegions(cacheUsingTable.getPhysicalName().getBytes()); > int nRegions = locations.size(); > > ..... > if ( ! servers.contains(entry) && > keyRanges.intersectRegion(regionStartKey, > regionEndKey, > cacheUsingTable.getIndexType() == > IndexType.LOCAL)) { > // Call RPC once per server > servers.add(entry); > {code} > For eg:- Table âTâ has two regions R1 and R2 originally hosted on > regionserver RS1. > while Phoenix/Hbase connection is still active, R2 is transitioned to RS2 , > but stale meta cache will still give old region locations i.e R1 and R2 on > RS1 and when we start copying hash table, we copy for R1 and skip R2 as they > are hosted on same regionserver. so, the query on a table will fail as it > will unable to find hash table cache on RS2 for processing regions R2. -- This message was sent by Atlassian JIRA (v6.4.14#64029)