tiflash 执行 SQL 报错

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:

[TiDB 版本] 4.0.10

[问题描述]
表如下

CREATE TABLE `store_daily_config` (
  `dt` timestamp NOT NULL ,
  `store_id` varchar(32) NOT NULL,
  `store_rules` text NOT NULL,
  `enable_realtime` tinyint(1) NOT NULL DEFAULT '1',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`dt`,`store_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

执行如下 SQL:

SELECT count(1) FROM store_daily_config WHERE dt = (SELECT max(dt) FROM store_daily_config);

会报错

ERROR 1105 (HY000): [FLASH:Coprocessor:BadRequest] Invalid MySQL Time literal tp: MysqlTime
val: "\031\250\351\000\000\000\000\000"
sig: Unspecified
field_type {
  tp: 7
  flag: 4227
  flen: 19
  decimal: 0
  collate: 63
  charset: "binary"
}

强制走 tikv 可正常执行

查询日志,tiflash 报错如下:

[] [“DAGDriver: void DB::DAGDriver::execute() [with bool batch = true]: [FLASH:Coprocessor:BadRequest] Invalid MySQL Time literal tp: MysqlTime\nval: “\031\250\351\000\000\000\000\000”\nsig: Unspecified\nfield_type {\n tp: 7\n flag: 4227\n flen: 19\n decimal: 0\n collate: 63\n charset: “binary”\n}\n\n0. bin/tiflash/tiflash(StackTrace::StackTrace()+0x15) [0x34db7d5]\n1. bin/tiflash/tiflash(DB::TiFlashException::TiFlashException(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, DB::TiFlashError const&)+0x34) [0x3db5134]\n2. bin/tiflash/tiflash(DB::decodeLiteral(tipb::Expr const&)+0x2652) [0x70c6662]\n3. bin/tiflash/tiflash(DB::DAGExpressionAnalyzer::getActions[abi:cxx11](tipb::Expr const&, std::shared_ptrDB::ExpressionActions&, bool)+0x74) [0x711c594]\n4. bin/tiflash/tiflash(DB::DAGExpressionAnalyzer::getActions[abi:cxx11](tipb::Expr const&, std::shared_ptrDB::ExpressionActions&, bool)+0x5bc) [0x711cadc]\n5. bin/tiflash/tiflash(DB::DAGExpressionAnalyzer::appendWhere(DB::ExpressionActionsChain&, std::vector<tipb::Expr const*, std::allocator<tipb::Expr const*> > const&, std::__cxx11::basic_string<char, std::char_traits, std::allocator >&)+0xd2) [0x7121022]\n6. bin/tiflash/tiflash(DB::DAGQueryBlockInterpreter::analyzeExpressions()+0x16c) [0x7102afc]\n7. bin/tiflash/tiflash(DB::DAGQueryBlockInterpreter::executeImpl(DB::Pipeline&)+0xa6) [0x710bf26]\n8. bin/tiflash/tiflash(DB::DAGQueryBlockInterpreter::execute()+0x35) [0x710c435]\n9. bin/tiflash/tiflash(DB::InterpreterDAG::executeQueryBlock(DB::DAGQueryBlock&, std::vector<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, DB::SubqueryForSet, std::hash<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits, std::allocator > const, DB::SubqueryForSet> > >, std::allocator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, DB::SubqueryForSet, std::hash<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits, std::allocator > const, DB::SubqueryForSet> > > > >&)+0xdca) [0x70d899a]\n10. bin/tiflash/tiflash(DB::InterpreterDAG::execute()+0x77) [0x70d9237]\n11. bin/tiflash/tiflash() [0x688d820]\n12. bin/tiflash/tiflash(DB::executeQuery(DB::DAGQuerySource&, DB::Context&, bool, DB::QueryProcessingStage::Enum)+0x63) [0x688eab3]\n13. bin/tiflash/tiflash(DB::DAGDriver::execute()+0x194) [0x70be434]\n14. bin/tiflash/tiflash(DB::BatchCoprocessorHandler::execute()+0x4ba) [0x70ead4a]\n15. bin/tiflash/tiflash(DB::FlashService::BatchCoprocessor(grpc_impl::ServerContext*, coprocessor::BatchRequest const*, grpc_impl::ServerWritercoprocessor::BatchResponse)+0x6a0) [0x70a6d20]\n16. bin/tiflash/tiflash(std::_Function_handler<grpc::Status (tikvpb::Tikv::Service, grpc_impl::ServerContext*, coprocessor::BatchRequest const*, grpc_impl::ServerWritercoprocessor::BatchResponse), std::_Mem_fn<grpc::Status (tikvpb::Tikv::Service::)(grpc_impl::ServerContext*, coprocessor::BatchRequest const*, grpc_impl::ServerWritercoprocessor::BatchResponse)> >::_M_invoke(std::_Any_data const&, tikvpb::Tikv::Service&&, grpc_impl::ServerContext*&&, coprocessor::BatchRequest const*&&, grpc_impl::ServerWritercoprocessor::BatchResponse&&)+0x38) [0x7843fc8]\n17. bin/tiflash/tiflash(grpc::Status grpc::internal::CatchingFunctionHandler<grpc::internal::ServerStreamingHandler<tikvpb::Tikv::Service, coprocessor::BatchRequest, coprocessor::BatchResponse>::RunHandler(grpc::internal::MethodHandler::HandlerParameter const&)::{lambda()#1}>(grpc::internal::ServerStreamingHandler<tikvpb::Tikv::Service, coprocessor::BatchRequest, coprocessor::BatchResponse>::RunHandler(grpc::internal::MethodHandler::HandlerParameter const&)::{lambda()#1}&&)+0x53) [0x7899813]\n18. bin/tiflash/tiflash(grpc::internal::ServerStreamingHandler<tikvpb::Tikv::Service, coprocessor::BatchRequest, coprocessor::BatchResponse>::RunHandler(grpc::internal::MethodHandler::HandlerParameter const&)+0xac) [0x789996c]\n19. bin/tiflash/tiflash(grpc_impl::Server::SyncRequest::CallData::ContinueRunAfterInterception()+0x160) [0x7921070]\n20. bin/tiflash/tiflash(grpc_impl::Server::SyncRequestThreadManager::DoWork(void, bool, bool)+0x42f) [0x792262f]\n21. bin/tiflash/tiflash(grpc::ThreadManager::MainWorkLoop()+0x9a) [0x792826a]\n22. bin/tiflash/tiflash(grpc::ThreadManager::WorkerThread::Run()+0xb) [0x792834b]\n23. bin/tiflash/tiflash() [0x7c9fc32]\n24. /lib64/libpthread.so.0(+0x7e24) [0x7f0cbecfde24]\n25. /lib64/libc.so.6(clone+0x6c) [0x7f0cbe725bac]\n”] [thread_id=16942646]


若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

能否提供部分脱敏的数据,需要本地测试复现下。

数据量比较大,可能不是太方便

是直接连 TiDB 查询报错吗还是使用了其他客户端连接报错的?最好是能提供部分数据。

直连报错, 数据的话就是形如:

dt: 2020-12-21 00:00:00
store_id: 58893337
store_rules: {}
enable_realtime: 1
created_at: 2020-12-22 21:08:02

store_rules 是一个大的 json_str

您好,这是一个 TiDB 与 TiFlash 交互的 bug,具体原因是按照原有协议,Coprocessor 层不用处理 TimeStamp 类型,没有相关逻辑。而 TiDB 在此语句中意外将 TimeStamp 类型传给了 TiFlash Coprocessor,导致报错。
issue: https://github.com/pingcap/tidb/issues/22917

我们将尽快修复,因为现在 4.0.11 已经封板,预计将在 4.0.12 以及 5.0 中带入此修改。

目前可以使用
SELECT count(1) FROM store_daily_config WHERE dt = cast((SELECT max(dt) FROM store_daily_config) as datetime);
把子查询返回类型强转为 datetime 来回避此 bug。

感谢您的反馈!