Skip to content

Commit b03ecc6

Browse files
authored
Merge pull request #267 from oceanbase/cherry-pick-32534b65-to-hbase_2.0.0-alpha4-20250708_154757
Cherry-pick: add test case for disable-before-delete-table; fix cases
2 parents 7ca35cf + 76ed51a commit b03ecc6

File tree

2 files changed

+174
-49
lines changed

2 files changed

+174
-49
lines changed

src/main/java/com/alipay/oceanbase/hbase/util/OHAdmin.java

Lines changed: 109 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,56 @@
4949
import java.util.concurrent.Future;
5050
import java.util.regex.Pattern;
5151

52+
import static com.alipay.oceanbase.rpc.protocol.payload.ResultCodes.*;
53+
5254
public class OHAdmin implements Admin {
5355
private boolean aborted = false;
5456
private final OHConnectionImpl connection;
5557
private final Configuration conf;
5658

59+
@FunctionalInterface
60+
private interface ExceptionHandler {
61+
void handle(int errorCode, TableName tableName) throws IOException;
62+
}
63+
64+
private Throwable getRootCause(Throwable e) {
65+
Throwable cause = e.getCause();
66+
while(cause != null && cause.getCause() != null) {
67+
cause = cause.getCause();
68+
}
69+
return cause;
70+
}
71+
72+
private void handleTimeoutException(Exception e) throws TimeoutIOException {
73+
if (e.getCause() instanceof ObTableTransportException
74+
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
75+
throw new TimeoutIOException(e.getCause());
76+
}
77+
}
78+
79+
private void handleObTableException(Exception e, TableName tableName, ExceptionHandler exceptionHandler) throws IOException {
80+
if (e instanceof IOException) {
81+
handleTimeoutException(e);
82+
}
83+
84+
Throwable cause = getRootCause(e);
85+
86+
if (cause instanceof ObTableException) {
87+
int errCode = ((ObTableException) cause).getErrorCode();
88+
try {
89+
exceptionHandler.handle(errCode, tableName);
90+
} catch (RuntimeException re) {
91+
throw re;
92+
}
93+
}
94+
95+
if (e instanceof IOException) {
96+
throw (IOException) e;
97+
} else {
98+
throw new IOException(e);
99+
}
100+
}
101+
57102
OHAdmin(OHConnectionImpl connection) {
58103
this.connection = connection;
59104
this.conf = connection.getConfiguration();
@@ -91,10 +136,7 @@ public boolean tableExists(TableName tableName) throws IOException {
91136
return executor.tableExists(tableName.getNameAsString());
92137
} catch (Exception e) {
93138
// try to get the original cause
94-
Throwable cause = e.getCause();
95-
while (cause != null && cause.getCause() != null) {
96-
cause = cause.getCause();
97-
}
139+
Throwable cause = getRootCause(e);
98140
if (cause instanceof ObTableException) {
99141
int errCode = ((ObTableException) cause).getErrorCode();
100142
// if the original cause is database_not_exist, means namespace in tableName does not exist
@@ -103,7 +145,11 @@ public boolean tableExists(TableName tableName) throws IOException {
103145
return false;
104146
}
105147
}
106-
throw e;
148+
if (e instanceof IOException) {
149+
throw (IOException) e;
150+
} else {
151+
throw new IOException(e);
152+
}
107153
}
108154
}
109155

@@ -184,14 +230,14 @@ public HTableDescriptor getTableDescriptor(TableName tableName) throws TableNotF
184230
try {
185231
return executor.getTableDescriptor();
186232
} catch (IOException e) {
187-
if (e.getCause() instanceof ObTableTransportException
188-
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
189-
throw new TimeoutIOException(e.getCause());
190-
} else if (e.getCause().getMessage().contains("OB_TABLEGROUP_NOT_EXIST")) {
191-
throw new TableNotFoundException(tableName);
192-
} else {
193-
throw e;
194-
}
233+
handleObTableException(e, tableName, (errCode, argTableName) -> {
234+
if (errCode == OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode) {
235+
throw new TableNotFoundException(argTableName);
236+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
237+
throw new NamespaceNotFoundException(argTableName.getNamespaceAsString());
238+
}
239+
});
240+
throw e; // should never reach
195241
}
196242
}
197243

@@ -205,14 +251,14 @@ public TableDescriptor getDescriptor(TableName tableName) throws IOException {
205251
try {
206252
return executor.getTableDescriptor();
207253
} catch (IOException e) {
208-
if (e.getCause() instanceof ObTableTransportException
209-
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
210-
throw new TimeoutIOException(e.getCause());
211-
} else if (e.getCause().getMessage().contains("OB_TABLEGROUP_NOT_EXIST")) {
212-
throw new TableNotFoundException(tableName);
213-
} else {
214-
throw e;
215-
}
254+
handleObTableException(e, tableName, (errCode, argTableName) -> {
255+
if (errCode == OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode) {
256+
throw new TableNotFoundException(argTableName);
257+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
258+
throw new NamespaceNotFoundException(argTableName.getNamespaceAsString());
259+
}
260+
});
261+
throw e; // should never reach
216262
}
217263
}
218264

@@ -225,12 +271,13 @@ public void createTable(TableDescriptor tableDescriptor) throws IOException {
225271
try {
226272
executor.createTable(tableDescriptor, null);
227273
} catch (IOException e) {
228-
if (e.getCause() instanceof ObTableTransportException
229-
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
230-
throw new TimeoutIOException(e.getCause());
231-
} else {
232-
throw e;
233-
}
274+
handleObTableException(e, tableDescriptor.getTableName(), (errCode, tableName) -> {
275+
if (errCode == OB_KV_HBASE_TABLE_EXISTS.errorCode) {
276+
throw new TableExistsException(tableName.getNameAsString());
277+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
278+
throw new NamespaceNotFoundException(tableName.getNameAsString());
279+
}
280+
});
234281
}
235282
}
236283

@@ -260,12 +307,15 @@ public void deleteTable(TableName tableName) throws IOException {
260307
try {
261308
executor.deleteTable(tableName.getNameAsString());
262309
} catch (IOException e) {
263-
if (e.getCause() instanceof ObTableTransportException
264-
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
265-
throw new TimeoutIOException(e.getCause());
266-
} else {
267-
throw e;
268-
}
310+
handleObTableException(e, tableName, (errCode, argTableName) -> {
311+
if (errCode == OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode) {
312+
throw new TableNotFoundException(argTableName);
313+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
314+
throw new NamespaceNotFoundException(argTableName.getNamespaceAsString());
315+
} else if (errCode == OB_KV_TABLE_NOT_DISABLED.errorCode) {
316+
throw new TableNotDisabledException(argTableName);
317+
}
318+
});
269319
}
270320
}
271321

@@ -304,12 +354,13 @@ public void enableTable(TableName tableName) throws IOException {
304354
try {
305355
executor.enableTable(tableName.getNameAsString());
306356
} catch (IOException e) {
307-
if (e.getCause() instanceof ObTableTransportException
308-
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
309-
throw new TimeoutIOException(e.getCause());
310-
} else {
311-
throw e;
312-
}
357+
handleObTableException(e, tableName, (errCode, argTableName) -> {
358+
if (errCode == OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode) {
359+
throw new TableNotFoundException(argTableName);
360+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
361+
throw new NamespaceNotFoundException(argTableName.getNamespaceAsString());
362+
}
363+
});
313364
}
314365
}
315366

@@ -343,12 +394,13 @@ public void disableTable(TableName tableName) throws IOException {
343394
try {
344395
executor.disableTable(tableName.getNameAsString());
345396
} catch (IOException e) {
346-
if (e.getCause() instanceof ObTableTransportException
347-
&& ((ObTableTransportException) e.getCause()).getErrorCode() == TransportCodes.BOLT_TIMEOUT) {
348-
throw new TimeoutIOException(e.getCause());
349-
} else {
350-
throw e;
351-
}
397+
handleObTableException(e, tableName, (errCode, argTableName) -> {
398+
if (errCode == OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode) {
399+
throw new TableNotFoundException(argTableName);
400+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
401+
throw new NamespaceNotFoundException(argTableName.getNamespaceAsString());
402+
}
403+
});
352404
}
353405
}
354406

@@ -747,7 +799,18 @@ public Map<byte[], RegionLoad> getRegionLoad(ServerName serverName, TableName ta
747799
tableName, connectionConf);
748800
OHRegionLoadExecutor executor = new OHRegionLoadExecutor(tableName.getNameAsString(),
749801
tableClient);
750-
return executor.getRegionLoad();
802+
try {
803+
return executor.getRegionLoad();
804+
} catch (Exception e) {
805+
handleObTableException(e, tableName, (errCode, argTableName) -> {
806+
if (errCode == OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode) {
807+
throw new TableNotFoundException(argTableName.getNameAsString());
808+
} else if (errCode == OB_KV_HBASE_NAMESPACE_NOT_FOUND.errorCode) {
809+
throw new NamespaceNotFoundException(argTableName.getNamespaceAsString());
810+
}
811+
});
812+
throw e; // should never reach
813+
}
751814
}
752815

753816
@Override

src/test/java/com/alipay/oceanbase/hbase/OHTableAdminInterfaceTest.java

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,14 @@ public void testAdminEnDisableTable() throws Exception {
475475
e.printStackTrace();
476476
throw e;
477477
} finally {
478+
if (admin.isTableEnabled(TableName.valueOf("test_en_dis_tb"))) {
479+
admin.disableTable(TableName.valueOf("test_en_dis_tb"));
480+
}
478481
admin.deleteTable(TableName.valueOf("test_en_dis_tb"));
479482
assertFalse(admin.tableExists(TableName.valueOf("test_en_dis_tb")));
483+
if (admin.isTableEnabled(TableName.valueOf("en_dis", "test"))) {
484+
admin.disableTable(TableName.valueOf("en_dis", "test"));
485+
}
480486
admin.deleteTable(TableName.valueOf("en_dis", "test"));
481487
assertFalse(admin.tableExists(TableName.valueOf("en_dis", "test")));
482488
}
@@ -684,7 +690,7 @@ public void testRegionLoad() throws Exception {
684690
regionLoadMap = admin.getRegionLoad(ServerName.valueOf("localhost,1,1"), TableName.valueOf(non_part_tablegroup));
685691
cost = System.currentTimeMillis() - start;
686692
System.out.println("get region load time usage: " + cost + "ms, tablegroup: " + non_part_tablegroup);
687-
assertEquals(3, regionLoadMap.size());
693+
assertEquals(1, regionLoadMap.size());
688694
} catch (Exception e) {
689695
e.printStackTrace();
690696
throw e;
@@ -726,11 +732,20 @@ public void testAdminDeleteTable() throws Exception {
726732
assertTrue(admin.tableExists(TableName.valueOf("test_del_tb")));
727733
IOException thrown = assertThrows(IOException.class,
728734
() -> {
735+
if (admin.isTableEnabled(TableName.valueOf("tablegroup_not_exists"))) {
736+
admin.disableTable(TableName.valueOf("tablegroup_not_exists"));
737+
}
729738
admin.deleteTable(TableName.valueOf("tablegroup_not_exists"));
730739
});
731740
Assert.assertTrue(thrown.getCause() instanceof ObTableException);
732741
Assert.assertEquals(ResultCodes.OB_KV_HBASE_TABLE_NOT_EXISTS.errorCode, ((ObTableException) thrown.getCause()).getErrorCode());
742+
if (admin.isTableEnabled(TableName.valueOf("del_tb", "test"))) {
743+
admin.disableTable(TableName.valueOf("del_tb", "test"));
744+
}
733745
admin.deleteTable(TableName.valueOf("del_tb", "test"));
746+
if (admin.isTableEnabled(TableName.valueOf("test_del_tb"))) {
747+
admin.disableTable(TableName.valueOf("test_del_tb"));
748+
}
734749
admin.deleteTable(TableName.valueOf("test_del_tb"));
735750
assertFalse(admin.tableExists(TableName.valueOf("del_tb", "test")));
736751
assertFalse(admin.tableExists(TableName.valueOf("test_del_tb")));
@@ -1507,6 +1522,9 @@ public void testCreateTableInjectError() throws Exception {
15071522
if (admin.tableExists(TableName.valueOf(tableName))) {
15081523
setErrSimPoint(ErrSimPoint.EN_DELETE_HTABLE_CF_FINISH_ERR, false);
15091524
setErrSimPoint(ErrSimPoint.EN_DELETE_HTABLE_SKIP_CF_ERR, false);
1525+
if (admin.isTableEnabled(TableName.valueOf(tableName))) {
1526+
admin.disableTable(TableName.valueOf(tableName));
1527+
}
15101528
admin.deleteTable(TableName.valueOf(tableName));
15111529
}
15121530
}
@@ -1570,6 +1588,9 @@ public void testHbaseDDLException() throws Exception {
15701588
} catch (Exception e) {
15711589
Assert.assertEquals(e.getClass(), TableExistsException.class);
15721590
} finally {
1591+
if (admin.isTableEnabled(TableName.valueOf("t1"))) {
1592+
admin.disableTable(TableName.valueOf("t1"));
1593+
}
15731594
admin.deleteTable(TableName.valueOf("t1"));
15741595
}
15751596

@@ -1589,6 +1610,9 @@ public void testHbaseDDLException() throws Exception {
15891610
} catch (Exception e) {
15901611
Assert.assertEquals(e.getClass(), TableNotDisabledException.class);
15911612
} finally {
1613+
if (admin.isTableEnabled(TableName.valueOf("t1"))) {
1614+
admin.disableTable(TableName.valueOf("t1"));
1615+
}
15921616
admin.deleteTable(TableName.valueOf("t1"));
15931617
}
15941618

@@ -1620,6 +1644,9 @@ public void testHbaseDDLException() throws Exception {
16201644
} catch (Exception e) {
16211645
Assert.assertEquals(e.getClass(), TableExistsException.class);
16221646
} finally {
1647+
if (admin.isTableEnabled(TableName.valueOf("t1"))) {
1648+
admin.disableTable(TableName.valueOf("t1"));
1649+
}
16231650
admin.deleteTable(TableName.valueOf("t1"));
16241651
}
16251652

@@ -1639,6 +1666,9 @@ public void testHbaseDDLException() throws Exception {
16391666
} catch (Exception e) {
16401667
Assert.assertEquals(e.getClass(), TableNotDisabledException.class);
16411668
} finally {
1669+
if (admin.isTableEnabled(TableName.valueOf("t1"))) {
1670+
admin.disableTable(TableName.valueOf("t1"));
1671+
}
16421672
admin.deleteTable(TableName.valueOf("t1"));
16431673
}
16441674

@@ -1651,6 +1681,9 @@ public void testHbaseDDLException() throws Exception {
16511681
} catch (Exception e) {
16521682
Assert.assertEquals(e.getClass(), TableNotEnabledException.class);
16531683
} finally {
1684+
if (admin.isTableEnabled(TableName.valueOf("t1"))) {
1685+
admin.disableTable(TableName.valueOf("t1"));
1686+
}
16541687
admin.deleteTable(TableName.valueOf("t1"));
16551688
}
16561689

@@ -1671,8 +1704,8 @@ public void testCreateDropTableGroup() throws Exception {
16711704
Connection connection = ConnectionFactory.createConnection(conf);
16721705
Admin admin = connection.getAdmin();
16731706
java.sql.Connection conn = ObHTableTestUtil.getConnection();
1674-
java.sql.Connection sysConn = ObHTableTestUtil.getSysConnection();
1675-
String tenantName = "mysql";
1707+
java.sql.Connection sysConn = ObHTableTestUtil.getSysTenantConnection();
1708+
String tenantName = FULL_USER_NAME.split("@")[1].split("#")[0];
16761709

16771710
byte[] tableName = Bytes.toBytes("test_create_drop_tg_helper");
16781711
byte[] cf1 = Bytes.toBytes("cf1");
@@ -1693,6 +1726,9 @@ public void testCreateDropTableGroup() throws Exception {
16931726

16941727
// 1. open err EN_DELETE_HTABLE_SKIP_CF_ERR, will skip delete cf table when delete hbase table
16951728
// and the subsequent delete htable operations will return OB_TABLEGROUP_NOT_EMPTY
1729+
if (admin.isTableEnabled(TableName.valueOf(tableName))) {
1730+
admin.disableTable(TableName.valueOf(tableName));
1731+
}
16961732
setErrSimPoint(ErrSimPoint.EN_DELETE_HTABLE_SKIP_CF_ERR, true);
16971733
ObHTableTestUtil.executeIgnoreExpectedErrors(() -> admin.deleteTable(TableName.valueOf(tableName)), "OB_TABLEGROUP_NOT_EMPTY");
16981734
assertTrue("Table should still exist after delete error injection",
@@ -1718,6 +1754,9 @@ public void testCreateDropTableGroup() throws Exception {
17181754
executeSQL(conn, "drop database if exists db_test_create_drop_tg_helper", true);
17191755
executeSQL(sysConn, String.format("alter tenant %s set default tablegroup = null", tenantName), true);
17201756
if (admin.tableExists(TableName.valueOf(tableName))) {
1757+
if (admin.isTableEnabled(TableName.valueOf(tableName))) {
1758+
admin.disableTable(TableName.valueOf(tableName));
1759+
}
17211760
setErrSimPoint(ErrSimPoint.EN_DELETE_HTABLE_SKIP_CF_ERR, false);
17221761
admin.deleteTable(TableName.valueOf(tableName));
17231762
}
@@ -1815,4 +1854,27 @@ public void testDDLStmtStr() throws Exception {
18151854
}
18161855
}
18171856
}
1857+
1858+
@Test
1859+
public void testDropEnabledTableFail() throws Exception {
1860+
Configuration conf = ObHTableTestUtil.newConfiguration();
1861+
Connection connection = ConnectionFactory.createConnection(conf);
1862+
Admin admin = connection.getAdmin();
1863+
1864+
byte[] tableName = Bytes.toBytes("test_drop_enabled_table_fail");
1865+
byte[] cf1 = Bytes.toBytes("cf1");
1866+
HColumnDescriptor hcd1 = new HColumnDescriptor(cf1);
1867+
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
1868+
htd.addFamily(hcd1);
1869+
try {
1870+
admin.createTable(htd);
1871+
admin.deleteTable(TableName.valueOf(tableName));
1872+
fail();
1873+
} catch (Exception e) {
1874+
assertTrue(true);
1875+
}
1876+
admin.disableTable(TableName.valueOf(tableName));
1877+
admin.deleteTable(TableName.valueOf(tableName));
1878+
Assert.assertFalse(admin.tableExists(TableName.valueOf(tableName)));
1879+
}
18181880
}

0 commit comments

Comments
 (0)