Skip to content

Commit 181cbca

Browse files
committed
Merge branch 'master' into secondary_part_rebase_master2
2 parents ba79298 + 26a5f56 commit 181cbca

File tree

13 files changed

+849
-110
lines changed

13 files changed

+849
-110
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Import the dependency for your maven project:
1818
<dependency>
1919
<groupId>com.oceanbase</groupId>
2020
<artifactId>obkv-table-client</artifactId>
21-
<version>1.4.0</version>
21+
<version>1.4.1</version>
2222
</dependency>
2323
```
2424

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.oceanbase</groupId>
66
<artifactId>obkv-table-client</artifactId>
7-
<version>1.4.1-SNAPSHOT</version>
7+
<version>1.4.3-SNAPSHOT</version>
88

99
<name>${project.groupId}:${project.artifactId}</name>
1010
<description>OceanBase JavaClient for TableApi</description>

src/main/java/com/alipay/oceanbase/rpc/ObTableClient.java

Lines changed: 157 additions & 76 deletions
Large diffs are not rendered by default.

src/main/java/com/alipay/oceanbase/rpc/exception/ObTableEntryRefreshException.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
package com.alipay.oceanbase.rpc.exception;
1919

2020
public class ObTableEntryRefreshException extends ObTableException {
21+
22+
private boolean connectInactive = false;
2123

2224
/*
2325
* Ob table entry refresh exception.
@@ -52,7 +54,15 @@ public ObTableEntryRefreshException(String message) {
5254
public ObTableEntryRefreshException(String message, Throwable cause) {
5355
super(message, cause);
5456
}
57+
58+
public ObTableEntryRefreshException(String message, Throwable cause, boolean connectInactive) {
59+
super(message, cause);
60+
this.connectInactive = connectInactive;
61+
}
5562

63+
public boolean isConnectInactive() {
64+
return connectInactive;
65+
}
5666
/*
5767
* Ob table entry refresh exception.
5868
*/

src/main/java/com/alipay/oceanbase/rpc/location/LocationUtil.java

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public class LocationUtil {
6060
.getLogger(LocationUtil.class);
6161
static {
6262
ParserConfig.getGlobalInstance().setSafeMode(true);
63+
loadJdbcDriver();
6364
}
6465

6566
private static final String OB_VERSION_SQL = "SELECT /*+READ_CONSISTENCY(WEAK)*/ OB_VERSION() AS CLUSTER_VERSION;";
@@ -325,22 +326,24 @@ private static String formatObServerUrl(ObServerAddr obServerAddr, long connectT
325326
*/
326327
private static Connection getMetaRefreshConnection(String url, ObUserAuth sysUA)
327328
throws ObTableEntryRefreshException {
328-
loadJdbcDriver();
329329

330330
try {
331331
return DriverManager.getConnection(url, sysUA.getUserName(), sysUA.getPassword());
332332
} catch (Exception e) {
333333
RUNTIME.error(LCD.convert("01-00005"), e.getMessage(), e);
334-
throw new ObTableEntryRefreshException("fail to connect meta server", e);
334+
// Since the JDBC connection fails here, it is likely that the server has crashed or scaling down.
335+
// Therefore, we need to set the Inactive flag of the ObTableEntryRefreshException to true.
336+
// This allows the upper-layer retry mechanism to catch this exception and immediately refresh the metadata.
337+
throw new ObTableEntryRefreshException("fail to connect meta server", e, true /* connect inactive */);
335338
}
336339
}
337340

338341
private static void loadJdbcDriver() {
339342
try {
340343
Class.forName("com.mysql.cj.jdbc.Driver");
341344
return;
342-
} catch (ClassNotFoundException e) {
343-
RUNTIME.info("Class 'com.mysql.cj.jdbc.Driver' not found, "
345+
} catch (ClassNotFoundException ignored) {
346+
RUNTIME.debug("Class 'com.mysql.cj.jdbc.Driver' not found, "
344347
+ "try to load legacy driver class 'com.mysql.jdbc.Driver'");
345348
}
346349

@@ -430,9 +433,15 @@ private static TableEntry callTableEntryRefresh(ObServerAddr obServerAddr, Table
430433
} else {
431434
RUNTIME.error(LCD.convert("01-00007"), url, key, e);
432435
}
433-
throw new ObTableEntryRefreshException(format(
434-
"fail to refresh table entry from remote url=%s, key=%s, message=%s", url, key,
435-
e.getMessage()), e);
436+
if (e instanceof ObTableEntryRefreshException) {
437+
throw new ObTableEntryRefreshException(format(
438+
"fail to refresh table entry from remote url=%s, key=%s, message=%s", url, key,
439+
e.getMessage()), e, ((ObTableEntryRefreshException) e).isConnectInactive());
440+
} else {
441+
throw new ObTableEntryRefreshException(format(
442+
"fail to refresh table entry from remote url=%s, key=%s, message=%s", url, key,
443+
e.getMessage()), e.getCause());
444+
}
436445
} finally {
437446
try {
438447
if (null != connection) {
@@ -571,6 +580,10 @@ public static String loadTableNameWithGroupName(final ServerRoster serverRoster,
571580
RUNTIME.error("callTableEntryNameWithPriority meet exception", e);
572581
serverRoster.downgradePriority(addr);
573582
throw e;
583+
} catch (ObTableEntryRefreshException e) {
584+
RUNTIME.error("callTableEntryNameWithPriority meet exception", e);
585+
throw new ObTableEntryRefreshException(format(
586+
"fail to get table name from remote url=%s, key=%s", url, key), e, e.isConnectInactive());
574587
} catch (Exception e) {
575588
throw new ObTableNotExistException(format(
576589
"fail to get table name from remote url=%s, key=%s", url, key), e);
@@ -797,12 +810,19 @@ private static TableEntry getTableEntryFromRemote(Connection connection, TableEn
797810
}
798811
}
799812
}
813+
} catch (SQLException e) {
814+
// cannot execute sql, maybe some of the observers have been killed
815+
RUNTIME.error(LCD.convert("01-00010"), key, e.getMessage());
816+
throw new ObTableEntryRefreshException("fail to get partition location entry from remote", e, true);
800817
} catch (ObTableNotExistException e) {
801818
// avoid to refresh meta for ObTableNotExistException
802819
RUNTIME.error("getTableEntryFromRemote meet exception", e);
803820
throw e;
804821
} catch (Exception e) {
805822
RUNTIME.error(LCD.convert("01-00009"), key, e);
823+
if (e instanceof ObTableEntryRefreshException) {
824+
throw e;
825+
}
806826
throw new ObTableEntryRefreshException(format(
807827
"fail to get table entry from remote, key=%s", key), e);
808828
} finally {
@@ -924,6 +944,10 @@ public static TableEntry getTableEntryLocationFromRemote(Connection connection,
924944
rs = ps.executeQuery();
925945
getPartitionLocationFromResultSetByTablet(tableEntry, rs, partitionEntry, tabletId,
926946
withLsId);
947+
} catch (SQLException e) {
948+
// cannot execute sql, maybe some of the observers have been killed
949+
RUNTIME.error(LCD.convert("01-00010"), key, tableEntry, e.getMessage());
950+
throw new ObTableEntryRefreshException("fail to get partition location entry from remote", e, true);
927951
} catch (Exception e) {
928952
RUNTIME.error(LCD.convert("01-00010"), key, tableEntry, e);
929953
throw new ObTablePartitionLocationRefreshException(format(
@@ -973,6 +997,9 @@ public static TableEntry getTableEntryLocationFromRemote(Connection connection,
973997
}
974998
rs = ps.executeQuery();
975999
partitionEntry = getPartitionLocationFromResultSet(tableEntry, rs, partitionEntry);
1000+
} catch (SQLException e) {
1001+
RUNTIME.error(LCD.convert("01-00010"), key, partitionNum, tableEntry, e);
1002+
throw new ObTableEntryRefreshException("fail to get partition location entry from remote", e, true);
9761003
} catch (Exception e) {
9771004
RUNTIME.error(LCD.convert("01-00010"), key, partitionNum, tableEntry, e);
9781005
throw new ObTablePartitionLocationRefreshException(format(
@@ -1019,8 +1046,13 @@ public static Long getTableIdFromRemote(ObServerAddr obServerAddr, ObUserAuth sy
10191046
+ " table_id from remote");
10201047
}
10211048
} catch (Exception e) {
1022-
throw new ObTableEntryRefreshException("fail to get " + tableName
1023-
+ " table_id from remote", e);
1049+
if (e instanceof ObTableEntryRefreshException) {
1050+
throw new ObTableEntryRefreshException(format(
1051+
"fail to get " + tableName + " table_id from remote", e), e, ((ObTableEntryRefreshException) e).isConnectInactive());
1052+
} else {
1053+
throw new ObTableEntryRefreshException(format(
1054+
"fail to get " + tableName + " table_id from remote", e), e);
1055+
}
10241056
} finally {
10251057
try {
10261058
if (null != rs) {
@@ -1058,10 +1090,18 @@ public static ObIndexInfo getIndexInfoFromRemote(ObServerAddr obServerAddr, ObUs
10581090
} else {
10591091
throw new ObTableEntryRefreshException("index is not exist");
10601092
}
1093+
} catch (SQLException e) {
1094+
// cannot execute sql, maybe some of the observers have been killed
1095+
RUNTIME.error(LCD.convert("01-00010"), indexTableName, e.getMessage());
1096+
throw new ObTableEntryRefreshException("fail to get index info from remote", e, true);
10611097
} catch (Exception e) {
1062-
throw new ObTableEntryRefreshException(format(
1063-
"fail to get index info from remote, indexTableName: %s, error message: %s",
1064-
indexTableName, e.getMessage()), e);
1098+
if (e instanceof ObTableEntryRefreshException) {
1099+
throw new ObTableEntryRefreshException(format(
1100+
"fail to get index info from remote, indexTableName: %s, error message: %s", indexTableName, e.getMessage()), e, ((ObTableEntryRefreshException) e).isConnectInactive());
1101+
} else {
1102+
throw new ObTableEntryRefreshException(format(
1103+
"fail to get index info from remote, indexTableName: %s, error message: %s", indexTableName, e.getMessage()), e);
1104+
}
10651105
} finally {
10661106
try {
10671107
if (null != rs) {
@@ -1079,7 +1119,8 @@ public static ObIndexInfo getIndexInfoFromRemote(ObServerAddr obServerAddr, ObUs
10791119

10801120
private static void fetchFirstPart(Connection connection, TableEntry tableEntry,
10811121
ObPartFuncType obPartFuncType)
1082-
throws ObTablePartitionInfoRefreshException {
1122+
throws ObTablePartitionInfoRefreshException,
1123+
SQLException {
10831124
String tableName = "";
10841125
TableEntryKey key = tableEntry.getTableEntryKey();
10851126
if (key != null) {
@@ -1127,6 +1168,8 @@ private static void fetchFirstPart(Connection connection, TableEntry tableEntry,
11271168
tableEntry.getPartitionInfo().setPartTabletIdMap(
11281169
parseFirstPartKeyHash(rs, tableEntry));
11291170
}
1171+
} catch (SQLException e) {
1172+
throw e;
11301173
} catch (Exception e) {
11311174
RUNTIME.error(LCD.convert("01-00011"), tableEntry, obPartFuncType, e);
11321175

@@ -1149,7 +1192,8 @@ private static void fetchFirstPart(Connection connection, TableEntry tableEntry,
11491192

11501193
private static void fetchSubPart(Connection connection, TableEntry tableEntry,
11511194
ObPartFuncType subPartFuncType)
1152-
throws ObTablePartitionInfoRefreshException {
1195+
throws ObTablePartitionInfoRefreshException,
1196+
SQLException {
11531197
String tableName = "";
11541198
TableEntryKey key = tableEntry.getTableEntryKey();
11551199
if (key != null) {
@@ -1196,6 +1240,8 @@ private static void fetchSubPart(Connection connection, TableEntry tableEntry,
11961240
tableEntry.getPartitionInfo().setPartTabletIdMap(
11971241
parseSubPartKeyHash(rs, tableEntry));
11981242
}
1243+
} catch (SQLException e) {
1244+
throw e;
11991245
} catch (Exception e) {
12001246
RUNTIME.error(LCD.convert("01-00012"), tableEntry, subPartFuncType, e);
12011247
throw new ObTablePartitionInfoRefreshException(format(
@@ -1476,7 +1522,8 @@ private static ReplicaLocation buildReplicaLocation(ResultSet rs) throws SQLExce
14761522
}
14771523

14781524
private static void fetchPartitionInfo(Connection connection, TableEntry tableEntry)
1479-
throws ObTablePartitionInfoRefreshException {
1525+
throws ObTablePartitionInfoRefreshException,
1526+
SQLException {
14801527
PreparedStatement pstmt = null;
14811528
ResultSet rs = null;
14821529
ObPartitionInfo info = null;
@@ -1499,6 +1546,8 @@ private static void fetchPartitionInfo(Connection connection, TableEntry tableEn
14991546
logger.info("get part info from remote info:{}", JSON.toJSON(info));
15001547
}
15011548
tableEntry.setPartitionInfo(info);
1549+
} catch (SQLException e) {
1550+
throw e;
15021551
} catch (Exception e) {
15031552
RUNTIME.error(LCD.convert("01-00014"), tableEntry);
15041553
RUNTIME.error("fail to get part info from remote");

src/main/java/com/alipay/oceanbase/rpc/protocol/payload/impl/ObObjType.java

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,12 +1664,130 @@ public ObObjMeta getDefaultObjMeta() {
16641664
public Comparable parseToComparable(Object o, ObCollationType ct) {
16651665
throw new FeatureNotSupportedException("ObBitType is not supported .");
16661666
}
1667-
};
1667+
},
16681668
/*
16691669
ObEnumType(36)
16701670
ObSetType(37)
1671-
ObMaxType // invalid type, or count of obj type
1671+
...
16721672
*/
1673+
ObMySQLDateType(52) {
1674+
/*
1675+
* Encode.
1676+
*/
1677+
@Override
1678+
public byte[] encode(Object obj) {
1679+
return Serialization.encodeVi32((int) ((Date) obj).getTime());
1680+
}
1681+
1682+
/*
1683+
* Decode.
1684+
*/
1685+
@Override
1686+
public Object decode(ByteBuf buf, ObCollationType type) {
1687+
return new Date(Serialization.decodeVi32(buf) * 1000L);
1688+
}
1689+
1690+
/*
1691+
* Get encoded size.
1692+
*/
1693+
@Override
1694+
public int getEncodedSize(Object obj) {
1695+
return Serialization.getNeedBytes((int) ((Date) obj).getTime());
1696+
}
1697+
1698+
/*
1699+
* Get default obj meta.
1700+
*/
1701+
@Override
1702+
public ObObjMeta getDefaultObjMeta() {
1703+
return new ObObjMeta(this, ObCollationLevel.CS_LEVEL_NUMERIC,
1704+
ObCollationType.CS_TYPE_BINARY, (byte) 10);
1705+
}
1706+
1707+
/*
1708+
* Parse to comparable.
1709+
*/
1710+
@Override
1711+
public Date parseToComparable(Object o, ObCollationType ct)
1712+
throws IllegalArgumentException,
1713+
FeatureNotSupportedException {
1714+
1715+
if (o instanceof Date) {
1716+
return (Date) o;
1717+
}
1718+
1719+
if (o instanceof String) {
1720+
return TimeUtils.strToDate((String) o);
1721+
}
1722+
1723+
if (o instanceof ObVString) {
1724+
return TimeUtils.strToDate(((ObVString) o).getStringVal());
1725+
}
1726+
1727+
if (o instanceof Long) {
1728+
return new Date((Long) o);
1729+
}
1730+
1731+
throw new IllegalArgumentException("ObMySQLDateType can not parseToComparable argument:" + o);
1732+
}
1733+
},
1734+
ObMySQLDateTimeType(53) {
1735+
/*
1736+
* Encode.
1737+
*/
1738+
@Override
1739+
public byte[] encode(Object obj) {
1740+
// Date do not have timezone, when we use getTime, system will recognize it as our system timezone and transform it into UTC Time, which will changed the time.
1741+
// We should add back the lose part.
1742+
long targetTs = ((Date) obj).getTime()
1743+
+ OffsetDateTime.now().getOffset().getTotalSeconds() * 1000L;
1744+
return Serialization.encodeVi64(targetTs * 1000L);
1745+
}
1746+
1747+
/*
1748+
* Decode.
1749+
*/
1750+
@Override
1751+
public Object decode(ByteBuf buf, ObCollationType type) {
1752+
return new Date(Serialization.decodeVi64(buf) / 1000L
1753+
- OffsetDateTime.now().getOffset().getTotalSeconds() * 1000L);
1754+
}
1755+
1756+
/*
1757+
* Get encoded size.
1758+
*/
1759+
@Override
1760+
public int getEncodedSize(Object obj) {
1761+
return Serialization.getNeedBytes(((Date) obj).getTime() * 1000L);
1762+
}
1763+
1764+
/*
1765+
* Get default obj meta.
1766+
*/
1767+
@Override
1768+
public ObObjMeta getDefaultObjMeta() {
1769+
// scale set into 6 means microSecond
1770+
return new ObObjMeta(this, ObCollationLevel.CS_LEVEL_NUMERIC,
1771+
ObCollationType.CS_TYPE_BINARY, (byte) 6);
1772+
}
1773+
1774+
/*
1775+
* Parse to comparable.
1776+
*/
1777+
@Override
1778+
public Date parseToComparable(Object o, ObCollationType ct)
1779+
throws IllegalArgumentException,
1780+
FeatureNotSupportedException {
1781+
if (o instanceof String) {
1782+
return TimeUtils.strToDate((String) o);
1783+
}
1784+
return (Date) o;
1785+
}
1786+
};
1787+
/*
1788+
ObMaxType // invalid type, or count of obj type
1789+
*/
1790+
16731791
private int value;
16741792
private static Map<Integer, ObObjType> map = new HashMap<Integer, ObObjType>();
16751793

0 commit comments

Comments
 (0)