背景
本文基于 StarRocks 3.1.7
大家都知道对于Starrocks来说 FE 是分 master和follower的,而只有master节点才能对元数据进行写操作。但是为什么呢?哪里有体现呢?
这其中的原因在网上是搜不到的,所以大家只知道只有master节点才能对元数据进行写操作,而哪里有体现呢
结论
每个SQL被 语法解析器 解析完后,都会带有getRedirectStatus方法,这个方法用来表明该SQL是否重定向到master节点执行,所以真实环境中,你会看到FE Master的节点的CPU会比较高
分析
我们直接定位到StmtExecutor.execute()
方法:
private RedirectStatus redirectStatus = null;
public void execute() throws Exception {
...
try (Timer ignored = Tracers.watchScope("Total")) {
redirectStatus = parsedStmt.getRedirectStatus();
这里的parsedStmt.getRedirectStatus()
方法就是用来表明该SQL是否会重定向到 FE master节点,比如说DML和DDL语句:
public abstract class DmlStmt extends StatementBase {
public static final long INVALID_TXN_ID = -1L;
private long txnId = INVALID_TXN_ID;
protected DmlStmt(NodePosition pos) {
super(pos);
}
@Override
public RedirectStatus getRedirectStatus() {
return RedirectStatus.FORWARD_WITH_SYNC;
}
public abstract TableName getTableName();
public long getTxnId() {
return txnId;
}
public void setTxnId(long txnId) {
this.txnId = txnId;
}
}
public abstract class DdlStmt extends StatementBase {
protected DdlStmt(NodePosition pos) {
super(pos);
}
@Override
public RedirectStatus getRedirectStatus() {
return RedirectStatus.FORWARD_WITH_SYNC;
}
@Override
public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
return visitor.visitDDLStatement(this, context);
}
}
这些都是RedirectStatus.FORWARD_WITH_SYN
,也就是会重定向到FE master节点。比如说一下语句都会重定向到master执行:
truncate table ..
alter table ...
create table ...
drop table ...
而后在后面的执行中会有如下判断:
if (isForwardToLeader()) {
context.setIsForward(true);
forwardToLeader();
return;
} else {
LOG.debug("no need to transfer to Leader. stmt: {}", context.getStmtId());
}
这里的方法 isForwardToLeader
调用链如下:
isForwardToLeader
||
\/
getIsForwardToLeaderOrInit
||
\/
initForwardToLeaderState
||
\/
redirectStatus.isForwardToLeader()
这里就会用到getRedirectStatus
方法返回的 redirectStatus
.