[ 
https://issues.apache.org/jira/browse/PHOENIX-3534?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16540256#comment-16540256
 ] 

ASF GitHub Bot commented on PHOENIX-3534:
-----------------------------------------

Github user twdsilva commented on a diff in the pull request:

    https://github.com/apache/phoenix/pull/303#discussion_r201739480
  
    --- Diff: 
phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
 ---
    @@ -1809,180 +2256,97 @@ public void createTable(RpcController controller, 
CreateTableRequest request,
             } catch (Throwable t) {
                 logger.error("createTable failed", t);
                 ProtobufUtil.setControllerException(controller,
    -                    
ServerUtil.createIOException(SchemaUtil.getTableName(schemaName, tableName), 
t));
    +                    ServerUtil.createIOException(fullTableName, t));
             }
         }
     
    +   private void dropChildMetadata(byte[] schemaName, byte[] tableName, 
byte[] tenantIdBytes)
    +                   throws IOException, SQLException, 
ClassNotFoundException {
    +           TableViewFinderResult childViewsResult = new 
TableViewFinderResult();
    +           findAllChildViews(tenantIdBytes, schemaName, tableName, 
childViewsResult);
    +           if (childViewsResult.hasViews()) {
    +                   for (TableInfo viewInfo : 
childViewsResult.getResults()) {
    +                           byte[] viewTenantId = viewInfo.getTenantId();
    +                           byte[] viewSchemaName = 
viewInfo.getSchemaName();
    +                           byte[] viewName = viewInfo.getTableName();
    +                           Properties props = new Properties();
    +                           if (viewTenantId != null && viewTenantId.length 
!= 0)
    +                                   
props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, 
Bytes.toString(viewTenantId));
    +                           try (PhoenixConnection connection = 
QueryUtil.getConnectionOnServer(env.getConfiguration())
    +                                           
.unwrap(PhoenixConnection.class)) {
    +                                   MetaDataClient client = new 
MetaDataClient(connection);
    +                                   org.apache.phoenix.parse.TableName 
viewTableName = org.apache.phoenix.parse.TableName
    +                                                   
.create(Bytes.toString(viewSchemaName), Bytes.toString(viewName));
    +                                   client.dropTable(
    +                                                   new 
DropTableStatement(viewTableName, PTableType.VIEW, false, true, true));
    +                           }
    +                   }
    +           }
    +   }
    +
         private boolean execeededIndexQuota(PTableType tableType, PTable 
parentTable) {
             return PTableType.INDEX == tableType && 
parentTable.getIndexes().size() >= maxIndexesPerTable;
         }
    -    
    -    private void findAllChildViews(Region region, byte[] tenantId, PTable 
table,
    -            TableViewFinder result, long clientTimeStamp, int 
clientVersion) throws IOException, SQLException {
    -        TableViewFinder currResult = findChildViews(region, tenantId, 
table, clientVersion, false);
    -        result.addResult(currResult);
    -        for (ViewInfo viewInfo : currResult.getViewInfoList()) {
    -            byte[] viewtenantId = viewInfo.getTenantId();
    -            byte[] viewSchema = viewInfo.getSchemaName();
    -            byte[] viewTable = viewInfo.getViewName();
    -            byte[] tableKey = SchemaUtil.getTableKey(viewtenantId, 
viewSchema, viewTable);
    -            ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(tableKey);
    -            PTable view = loadTable(env, tableKey, cacheKey, 
clientTimeStamp, clientTimeStamp, clientVersion);
    -            if (view == null) {
    -                logger.warn("Found orphan tenant view row in 
SYSTEM.CATALOG with tenantId:"
    -                        + Bytes.toString(tenantId) + ", schema:"
    -                        + Bytes.toString(viewSchema) + ", table:"
    -                        + Bytes.toString(viewTable));
    -                continue;
    -            }
    -            findAllChildViews(region, viewtenantId, view, result, 
clientTimeStamp, clientVersion);
    -        }
    -    }
    -        
    -    // TODO use child link instead once splittable system catalog 
(PHOENIX-3534) is implemented
    -    // and we have a separate table for links.
    -    private TableViewFinder findChildViews_deprecated(Region region, 
byte[] tenantId, PTable table, byte[] linkTypeBytes, boolean stopAfterFirst) 
throws IOException {
    -        byte[] schemaName = table.getSchemaName().getBytes();
    -        byte[] tableName = table.getTableName().getBytes();
    -        boolean isMultiTenant = table.isMultiTenant();
    -        Scan scan = new Scan();
    -        // If the table is multi-tenant, we need to check across all 
tenant_ids,
    -        // so we can't constrain the row key. Otherwise, any views would 
have
    -        // the same tenantId.
    -        if (!isMultiTenant) {
    -            byte[] startRow = ByteUtil.concat(tenantId, 
QueryConstants.SEPARATOR_BYTE_ARRAY);
    -            byte[] stopRow = ByteUtil.nextKey(startRow);
    -            scan.setStartRow(startRow);
    -            scan.setStopRow(stopRow);
    -        }
    -        SingleColumnValueFilter linkFilter = new 
SingleColumnValueFilter(TABLE_FAMILY_BYTES, LINK_TYPE_BYTES, CompareOp.EQUAL, 
linkTypeBytes);
    -        SingleColumnValueFilter tableTypeFilter = new 
SingleColumnValueFilter(TABLE_FAMILY_BYTES, TABLE_TYPE_BYTES,
    -                CompareOp.EQUAL, 
PTableType.VIEW.getSerializedValue().getBytes());
    -        tableTypeFilter.setFilterIfMissing(false);
    -        linkFilter.setFilterIfMissing(true);
    -        byte[] suffix = 
ByteUtil.concat(QueryConstants.SEPARATOR_BYTE_ARRAY, SchemaUtil
    -                .getPhysicalHBaseTableName(schemaName, tableName, 
table.isNamespaceMapped())
    -                .getBytes());
    -        SuffixFilter rowFilter = new SuffixFilter(suffix);
    -        List<Filter> filters = 
Lists.<Filter>newArrayList(linkFilter,tableTypeFilter,rowFilter);
    -        if (stopAfterFirst) {
    -            filters.add(new PageFilter(1));
    -        }
    -        FilterList filter = new FilterList(filters);
    -        scan.setFilter(filter);
    -        scan.addColumn(TABLE_FAMILY_BYTES, LINK_TYPE_BYTES);
    -        scan.addColumn(TABLE_FAMILY_BYTES, TABLE_TYPE_BYTES);
    -        scan.addColumn(TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
    -        
    -        // Original region-only scanner modified due to PHOENIX-1208
    -        // RegionScanner scanner = region.getScanner(scan);
    -        // The following *should* work, but doesn't due to HBASE-11837
    -        // TableName systemCatalogTableName = 
region.getTableDesc().getTableName();
    -        // HTableInterface hTable = env.getTable(systemCatalogTableName);
    -        // These deprecated calls work around the issue
    -        try (HTableInterface hTable = 
ServerUtil.getHTableForCoprocessorScan(env,
    -            region.getTableDesc().getTableName().getName())) {
    -            boolean allViewsInCurrentRegion = true;
    -            int numOfChildViews = 0;
    -            List<ViewInfo> viewInfoList = Lists.newArrayList();
    -            try (ResultScanner scanner = hTable.getScanner(scan)) {
    -                for (Result result = scanner.next(); (result != null); 
result = scanner.next()) {
    -                    numOfChildViews++;
    -                    ImmutableBytesWritable ptr = new 
ImmutableBytesWritable();
    -                    ResultTuple resultTuple = new ResultTuple(result);
    -                    resultTuple.getKey(ptr);
    -                    byte[] key = ptr.copyBytes();
    -                    if (checkTableKeyInRegion(key, region) != null) {
    -                        allViewsInCurrentRegion = false;
    -                    }
    -                    byte[][] rowKeyMetaData = new byte[3][];
    -                    getVarChars(result.getRow(), 3, rowKeyMetaData);
    -                    byte[] viewTenantId = 
rowKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
    -                    byte[] viewSchemaName = 
rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
    -                    byte[] viewName = 
rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
    -                    viewInfoList.add(new ViewInfo(viewTenantId, 
viewSchemaName, viewName));
    -                }
    -                TableViewFinder tableViewFinderResult = new 
TableViewFinder(viewInfoList);
    -                if (numOfChildViews > 0 && !allViewsInCurrentRegion) {
    -                    tableViewFinderResult.setAllViewsNotInSingleRegion();
    -                }
    -                return tableViewFinderResult;
    +
    +    private void findAncestorViewsOfIndex(byte[] tenantId, byte[] 
schemaName, byte[] indexName,
    +            TableViewFinderResult result, boolean isNamespaceMapped) 
throws IOException {
    +        try (Table hTable =
    +                env.getTable(SchemaUtil.getPhysicalTableName(
    +                    PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, 
env.getConfiguration()))) {
    +            TableViewFinderResult currentResult =
    +                    ViewFinder.findParentViewofIndex(hTable, tenantId, 
schemaName, indexName);
    +            if (currentResult.getResults().size() == 1) {
    +                result.addResult(currentResult);
    +                TableInfo tableInfo = currentResult.getResults().get(0);
    +                findAncestorViews(tableInfo.getTenantId(), 
tableInfo.getSchemaName(),
    +                    tableInfo.getTableName(), result, isNamespaceMapped);
                 }
    +            // else this is an index on a regular table and so we don't 
need to combine columns
             }
         }
         
    -    private TableViewFinder findChildViews_4_11(Region region, byte[] 
tenantId, byte[] schemaName, byte[] tableName, boolean stopAfterFirst) throws 
IOException {
    -        Scan scan = new Scan();
    -        byte[] startRow = SchemaUtil.getTableKey(tenantId, schemaName, 
tableName);
    -        byte[] stopRow = ByteUtil.nextKey(startRow);
    -        scan.setStartRow(startRow);
    -        scan.setStopRow(stopRow);
    -        SingleColumnValueFilter linkFilter = new 
SingleColumnValueFilter(TABLE_FAMILY_BYTES, LINK_TYPE_BYTES, CompareOp.EQUAL, 
CHILD_TABLE_BYTES);
    -        Filter filter = linkFilter;
    -        linkFilter.setFilterIfMissing(true);
    -        if (stopAfterFirst) {
    -            filter = new FilterList(linkFilter, new PageFilter(1));
    -        }
    -        scan.setFilter(filter);
    -        scan.addColumn(TABLE_FAMILY_BYTES, LINK_TYPE_BYTES);
    -        scan.addColumn(TABLE_FAMILY_BYTES, PARENT_TENANT_ID_BYTES);
    -        
    -        // Original region-only scanner modified due to PHOENIX-1208
    -        // RegionScanner scanner = region.getScanner(scan);
    -        // The following *should* work, but doesn't due to HBASE-11837
    -        // TableName systemCatalogTableName = 
region.getTableDesc().getTableName();
    -        // HTableInterface hTable = env.getTable(systemCatalogTableName);
    -        // These deprecated calls work around the issue
    -        try (HTableInterface hTable = 
ServerUtil.getHTableForCoprocessorScan(env,
    -            region.getTableDesc().getTableName().getName())) {
    -            boolean allViewsInCurrentRegion = true;
    -            int numOfChildViews = 0;
    -            List<ViewInfo> viewInfoList = Lists.newArrayList();
    -            try (ResultScanner scanner = hTable.getScanner(scan)) {
    -                for (Result result = scanner.next(); (result != null); 
result = scanner.next()) {
    -                    numOfChildViews++;
    -                    ImmutableBytesWritable ptr = new 
ImmutableBytesWritable();
    -                    ResultTuple resultTuple = new ResultTuple(result);
    -                    resultTuple.getKey(ptr);
    -                    byte[] key = ptr.copyBytes();
    -                    if (checkTableKeyInRegion(key, region) != null) {
    -                        allViewsInCurrentRegion = false;
    -                    }
    -                    byte[][] rowViewKeyMetaData = new byte[5][];
    -                    getVarChars(result.getRow(), 5, rowViewKeyMetaData);
    -                    byte[] viewTenantId = 
rowViewKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX];
    -                    byte[] viewSchemaName = 
SchemaUtil.getSchemaNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes();
    -                    byte[] viewName = 
SchemaUtil.getTableNameFromFullName(rowViewKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]).getBytes();
    -                    viewInfoList.add(new ViewInfo(viewTenantId, 
viewSchemaName, viewName));
    -                }
    -                TableViewFinder tableViewFinderResult = new 
TableViewFinder(viewInfoList);
    -                if (numOfChildViews > 0 && !allViewsInCurrentRegion) {
    -                    tableViewFinderResult.setAllViewsNotInSingleRegion();
    -                }
    -                return tableViewFinderResult;
    +    private void findAncestorViews(byte[] tenantId, byte[] schemaName, 
byte[] tableName,
    +            TableViewFinderResult result, boolean isNamespaceMapped) 
throws IOException {
    +        try (Table hTable =
    +                env.getTable(SchemaUtil.getPhysicalTableName(
    +                    PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, 
env.getConfiguration()))) {
    +            ViewFinder.findAllRelatives(hTable, tenantId, schemaName, 
tableName,
    +                LinkType.PARENT_TABLE, result);
    +            if (!isNamespaceMapped || schemaName.length==0) {
    +                // the child->parent link is overwritten by the 
child->physical table link for first
    +                // level children of base table when namespace mapping is 
disabled or if the parent
    +                // table doesn't have a schema as both the parent table 
name and physical table name
    +                // are the same.
    +                // When namespace mapping is enabled the physical table 
name is of the form S:T
    +                // while the table name is of the form S.T so we need to 
query for the
    +                // PHYSICAL_TABLE link
    --- End diff --
    
    We are only rewriting the PARENT->CHILD links (removing them from 
SYSTEM.CATALOG and recreating them in the new SYSTEM.CHILD_LINK table). The 
PHYSICAL_TABLE link overwriting the PARENT_TABLE link happens in the 
CHILD->PARENT links. 


> Support multi region SYSTEM.CATALOG table
> -----------------------------------------
>
>                 Key: PHOENIX-3534
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-3534
>             Project: Phoenix
>          Issue Type: Bug
>            Reporter: James Taylor
>            Assignee: Thomas D'Silva
>            Priority: Major
>             Fix For: 5.0.0, 4.15.0
>
>         Attachments: PHOENIX-3534.patch
>
>
> Currently Phoenix requires that the SYSTEM.CATALOG table is single region 
> based on the server-side row locks being held for operations that impact a 
> table and all of it's views. For example, adding/removing a column from a 
> base table pushes this change to all views.
> As an alternative to making the SYSTEM.CATALOG transactional (PHOENIX-2431), 
> when a new table is created we can do a lazy cleanup  of any rows that may be 
> left over from a failed DDL call (kudos to [~lhofhansl] for coming up with 
> this idea). To implement this efficiently, we'd need to also do PHOENIX-2051 
> so that we can efficiently find derived views.
> The implementation would rely on an optimistic concurrency model based on 
> checking our sequence numbers for each table/view before/after updating. Each 
> table/view row would be individually locked for their change (metadata for a 
> view or table cannot span regions due to our split policy), with the sequence 
> number being incremented under lock and then returned to the client.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to