PHOENIX-2915 Dropping of Index can still leave some non-replayed writes in WAL
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/a747b459 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/a747b459 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/a747b459 Branch: refs/heads/4.x-HBase-1.0 Commit: a747b459a15ed271f536b1b08fab416eb5f03fb7 Parents: 5a5da14 Author: Ankit Singhal <ankitsingha...@gmail.com> Authored: Fri Jun 10 16:26:08 2016 +0530 Committer: Ankit Singhal <ankitsingha...@gmail.com> Committed: Fri Jun 10 16:26:08 2016 +0530 ---------------------------------------------------------------------- .../query/ConnectionQueryServicesImpl.java | 58 +++++++++++++------- 1 file changed, 39 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/a747b459/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java index c6d8683..b51be5d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java @@ -1530,7 +1530,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement } @Override - public MetaDataMutationResult dropTable(final List<Mutation> tableMetaData, final PTableType tableType, final boolean cascade) throws SQLException { + public MetaDataMutationResult dropTable(final List<Mutation> tableMetaData, final PTableType tableType, + final boolean cascade) throws SQLException { byte[][] rowKeyMetadata = new byte[3][]; SchemaUtil.getVarChars(tableMetaData.get(0).getRow(), rowKeyMetadata); byte[] tenantIdBytes = rowKeyMetadata[PhoenixDatabaseMetaData.TENANT_ID_INDEX]; @@ -1565,18 +1566,14 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement case TABLE_ALREADY_EXISTS: ReadOnlyProps props = this.getProps(); boolean dropMetadata = props.getBoolean(DROP_METADATA_ATTRIB, DEFAULT_DROP_METADATA); + PTable table = result.getTable(); if (dropMetadata) { + flushParentPhysicalTable(table); dropTables(result.getTableNamesToDelete()); } invalidateTables(result.getTableNamesToDelete()); if (tableType == PTableType.TABLE) { - boolean isNamespaceMapped = result.getTable().isNamespaceMapped(); - byte[] physicalName; - if (!isNamespaceMapped) { - physicalName = SchemaUtil.getTableNameAsBytes(schemaBytes, tableBytes); - } else { - physicalName = TableName.valueOf(schemaBytes, tableBytes).getName(); - } + byte[] physicalName = table.getPhysicalName().getBytes(); long timestamp = MetaDataUtil.getClientTimeStamp(tableMetaData); ensureViewIndexTableDropped(physicalName, timestamp); ensureLocalIndexTableDropped(physicalName, timestamp); @@ -1589,6 +1586,25 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement return result; } + /* + * PHOENIX-2915 while dropping index, flush data table to avoid stale WAL edits of indexes 1. Flush parent table if + * dropping view has indexes 2. Dropping table indexes 3. Dropping view indexes + */ + private void flushParentPhysicalTable(PTable table) throws SQLException { + byte[] parentPhysicalTableName = null; + if (PTableType.VIEW == table.getType()) { + if (!table.getIndexes().isEmpty()) { + parentPhysicalTableName = table.getPhysicalName().getBytes(); + } + } else if (PTableType.INDEX == table.getType()) { + PTable parentTable = getTable(null, table.getParentName().getString(), HConstants.LATEST_TIMESTAMP); + parentPhysicalTableName = parentTable.getPhysicalName().getBytes(); + } + if (parentPhysicalTableName != null) { + flushTable(parentPhysicalTableName); + } + } + @Override public MetaDataMutationResult dropFunction(final List<Mutation> functionData, final boolean ifExists) throws SQLException { byte[][] rowKeyMetadata = new byte[2][]; @@ -1660,31 +1676,35 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement private void ensureViewIndexTableCreated(PName tenantId, byte[] physicalIndexTableName, long timestamp, boolean isNamespaceMapped) throws SQLException { - PTable table; String name = Bytes .toString(SchemaUtil.getParentTableNameFromIndexTable(physicalIndexTableName, MetaDataUtil.VIEW_INDEX_TABLE_PREFIX)) .replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR); - + PTable table = getTable(tenantId, name, timestamp); + ensureViewIndexTableCreated(table, timestamp, isNamespaceMapped); + } + + private PTable getTable(PName tenantId, String fullTableName, long timestamp) throws SQLException { + PTable table; try { PMetaData metadata = latestMetaData; if (metadata == null) { throwConnectionClosedException(); } - table = metadata.getTableRef(new PTableKey(tenantId, name)).getTable(); - if (table.getTimeStamp() >= timestamp) { // Table in cache is newer than client timestamp which shouldn't be the case + table = metadata.getTableRef(new PTableKey(tenantId, fullTableName)).getTable(); + if (table.getTimeStamp() >= timestamp) { // Table in cache is newer than client timestamp which shouldn't be + // the case throw new TableNotFoundException(table.getSchemaName().getString(), table.getTableName().getString()); } } catch (TableNotFoundException e) { - byte[] schemaName = Bytes.toBytes(SchemaUtil.getSchemaNameFromFullName(name)); - byte[] tableName = Bytes.toBytes(SchemaUtil.getTableNameFromFullName(name)); - MetaDataMutationResult result = this.getTable(null, schemaName, tableName, HConstants.LATEST_TIMESTAMP, timestamp); + byte[] schemaName = Bytes.toBytes(SchemaUtil.getSchemaNameFromFullName(fullTableName)); + byte[] tableName = Bytes.toBytes(SchemaUtil.getTableNameFromFullName(fullTableName)); + MetaDataMutationResult result = this.getTable(null, schemaName, tableName, HConstants.LATEST_TIMESTAMP, + timestamp); table = result.getTable(); - if (table == null) { - throw e; - } + if (table == null) { throw e; } } - ensureViewIndexTableCreated(table, timestamp, isNamespaceMapped); + return table; } private void ensureViewIndexTableCreated(PTable table, long timestamp, boolean isNamespaceMapped)