Apache Doris 0.15.3升级至1.1.5避坑实用总结

概述:

Apache Doris 从0.15到1.1.5属于一个大版本升级,部分语法和使用方式也发生了较大的变化,本文除前期兼容性调研(可以通过官网查到到一部分兼容性问题)已知问题外,生产环境正式升级之后遇到的突发问题进行整理总结,作为一个避坑指南,后期也会不定期更新。

正文:

1.ODBC驱动兼容性问题:

升级到1.0及以上版本后会出现ODBC版本兼容性问题,具体报错信息如下:
Apache Doris 0.15.3升级至1.1.5避坑实用总结_第1张图片

这个报错官网也有说明,具体原因不再赘述了,需要注意的是只要是从1.0以下版本升级到1.0及以上版本的,都会出现这个问题。解决方案可以分为以下几种:

  • 重新安装新的ODBC驱动包。具体安装流程可以参考:Doris升级至1.0发行版后MySQL ODBC 不可用解决方案。
  • 修改SQL语句,将ODBC外表替换成OLAP表。

以上2种方案,都可以解决目前遇到的问题,但具体分析来看:

  • Doris官网已经明确说过,1.2版本以后将不会再维护ODBC外表了,同时通过实际生产中的应用来看,ODBC的性能和稳定性与OLAP表相差甚远,很难满足快速响应需求;

  • 如果重新安装ODBC驱动包,以前的ODBC表也没办法再使用,需要利用新的驱动重新创建ODBC,返工成本高;

    综上所述,修改SQL语句才是持久化的调整方式。

2.ODBC开启向量化导致BE停机:

如果升级之前SQL中出现了ODBC外表和OLAP表关联查询,开启向量化引擎之后,会导致BE节点挂掉。附上一个异常样例SQL:

SELECT
	`text1`,
	`text2`,
	`text3`,
	`text4` 
FROM
	test1.ods_odbc_mapping 
WHERE
	DATE_FORMAT( text1, '%Y-%m-%d' ) >= DATE_SUB( CURDATE(), INTERVAL 35 DAY ) 
	AND concat( text2, text3, text4 ) NOT IN (
	SELECT
		concat( text5, '00000000000', text3, text4 ) 
FROM
	test2.ods_olap_delta ) 

具体be.out堆栈日志信息如下:

F0704 12:58:53.773236 185790 column_vector.cpp:210] Parameters start = 0, length = 1024, are out of bound in ColumnVector<T>::insert_range_from method (data.size() = 0).
[root@gaia-pro-bigdata-be01 log]# vim be.out.bak

start time: Mon Jul 3 21:39:37 CST 2023
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0703 21:39:37.529274 452701 env.cpp:46] Env init successfully.
F0704 12:58:53.773236 185790 column_vector.cpp:210] Parameters start = 0, length = 1024, are out of bound in ColumnVector<T>::insert_range_from method (data.size() = 0).
    @     0x55f96e8131fa  doris::PlanFragmentExecutor::get_vectorized_internal()
    @     0x55f96e8177bd  doris::PlanFragmentExecutor::open_vectorized_internal()
    @     0x55f96e81926f  doris::PlanFragmentExecutor::open()
    @     0x7f47096f3dd5  start_thread
    @     0x7f4709a05ead  __clone
    @              (nil)  (unknown)
*** Query id: 0-0 ***
*** Aborted at 1688446733 (unix time) try "date -d @1688446733" if you are using GNU date ***
start time: Mon Jul 3 21:39:37 CST 2023
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0703 21:39:37.529274 452701 env.cpp:46] Env init successfully.
F0704 12:58:53.773236 185790 column_vector.cpp:210] Parameters start = 0, length = 1024, are out of bound in ColumnVector<T>::insert_range_from method (data.size() = 0).
    @     0x55f96e8131fa  doris::PlanFragmentExecutor::get_vectorized_internal()
    @     0x55f96e8177bd  doris::PlanFragmentExecutor::open_vectorized_internal()
    @     0x55f96e81926f  doris::PlanFragmentExecutor::open()
    @     0x7f47096f3dd5  start_thread
    @     0x7f4709a05ead  __clone
    @              (nil)  (unknown)
*** Query id: 0-0 ***
*** Aborted at 1688446733 (unix time) try "date -d @1688446733" if you are using GNU date ***
*** SIGABRT unkown detail explain (@0x6e85d) received by PID 452701 (TID 0x7f460dec9700) from PID 452701; stack trace: ***
 0# doris::signal::(anonymous namespace)::FailureSignalHandler(int, siginfo_t*, void*) at /mnt/disk2/ygl/code/github/apache-doris/be/src/common/signal_handler.h:428
 1# 0x00007F470993E280 in /lib64/libc.so.6
 2# gsignal in /lib64/libc.so.6
 3# abort in /lib64/libc.so
 .6
 4# 0x000055F96E01EAFE in /soft/apache-doris-be-1.1.5-bin-x86_64/lib/doris_be
 5# 0x000055F97046E32D in /soft/apache-doris-be-1.1.5-bin-x86_64/lib/doris_be
 6# google::LogMessage::SendToLog() in /soft/apache-doris-be-1.1.5-bin-x86_64/lib/doris_be
 7# google::LogMessage::Flush() in /soft/apache-doris-be-1.1.5-bin-x86_64/lib/doris_be
 8# google::LogMessageFatal::~LogMessageFatal() in /soft/apache-doris-be-1.1.5-bin-x86_64/lib/doris_be
 9# doris::vectorized::ColumnVector::insert_range_from(doris::vectorized::IColumn const&, unsigned long, unsigned long) at /mnt/disk2/ygl/code/github/apache-doris/be
/src/vec/columns/column_vector.cpp:21810# doris::vectorized::HashJoinNode::_build_output_block(doris::vectorized::Block*, doris::vectorized::Block*) at /mnt/disk2/ygl/code/github/apache-doris/be/src/vec/exec/j
oin/vhash_join_node.cpp:147611# doris::vectorized::HashJoinNode::get_next(doris::RuntimeState*, doris::vectorized::Block*, bool*) at /mnt/disk2/ygl/code/github/apache-doris/be/src/vec/exec/join/vhash
_join_node.cpp:104712# doris::PlanFragmentExecutor::get_vectorized_internal(doris::vectorized::Block**) at /mnt/disk2/ygl/code/github/apache-doris/be/src/runtime/plan_fragment_executor.cpp:3
5213# doris::PlanFragmentExecutor::open_vectorized_internal() at /mnt/disk2/ygl/code/github/apache-doris/be/src/runtime/plan_fragment_executor.cpp:301
14# doris::PlanFragmentExecutor::open() at /mnt/disk2/ygl/code/github/apache-doris/be/src/runtime/plan_fragment_executor.cpp:259
15# doris::FragmentExecState::execute() at /mnt/disk2/ygl/code/github/apache-doris/be/src/runtime/fragment_mgr.cpp:249
16# doris::FragmentMgr::_exec_actual(std::shared_ptr, std::function) at /mnt/disk2/ygl/code/github/apache-do
ris/be/src/runtime/fragment_mgr.cpp:48717# std::_Function_handler, std::function
(doris::PlanFragmentExecutor*)>))(std::shared_ptr<doris::FragmentExecState>, std::function<void (doris::PlanFragmentExecutor*)>)> >::_M_invoke(std::_Any_data const&) at /mnt/disk2/ygl/installs/ldbtools/include/c++/11/bits/std_function.h:29118# doris::ThreadPool::dispatch_thread() at /mnt/disk2/ygl/code/github/apache-doris/be/src/util/threadpool.cpp:578
19# doris::Thread::supervise_thread(void*) at /mnt/disk2/ygl/code/github/apache-doris/be/src/util/thread.cpp:407
20# start_thread in /lib64/libpthread.so.0
21# __clone in /lib64/libc.so.6

从BE端源码insert_range_from这个方法判断,可能是因为data.size()为空,进入到if判断后,输出了从be.out中看到的日志信息Parameters start = 0, length = 1024, are out of bound in ColumnVector::insert_range_from method (data.size() = 0).,但程序并没有返回,而是继续执行memcpy这个内存拷贝方法,导致操作系统内存分配异常,然后Aborted掉这个进程导致的,但至于为什么内存拷贝会出现异常,这个就没有继续深入追踪了。
Apache Doris 0.15.3升级至1.1.5避坑实用总结_第2张图片
解决方案:

  • 关闭向量化引擎。需要注意的是,Doris 1.1.5版本向量化引擎默认是关闭状态,但在1.2版本以后,向量化引擎是默认开启的;
  • 修改SQL语句,将ODBC外表替换成OLAP表。

综合来看,向量化引擎是Doris的一个重大功能,它能极致提高查询性能,为了快速响应需求,在实际业务中肯定是要开启的,我们不可能因为使用ODBC外表而放弃向量化引擎,因此最优的解决方案就是修改SQL语句,将SQL中的ODBC外表替换掉。

3.语法变更:

在1.0版本以下时,如果要查看一个表的所有tablet,我们常用的语法是show tablet from table,但在1.0及以后的版本中,该语法发生了变化,如果还是继续使用旧的语法会出现以下报错:

mysql> show tablet from ods_test_delta\G;
ERROR 1105 (HY000): errCode = 2, detailMessage = Syntax error in line 1:
show tablet from  ods_test_delta
            ^
Encountered: FROM
Expected

mysql> 

解决方案:

使用新的查看语法show tablets from table即可。

mysql> show tablets from test_cdc_sink\G;
*************************** 1. row ***************************
               TabletId: 3944055
              ReplicaId: 3944056
              BackendId: 10003
             SchemaHash: -1
                Version: 1
      LstSuccessVersion: 1
       LstFailedVersion: -1
          LstFailedTime: NULL
          LocalDataSize: 0
         RemoteDataSize: 0
               RowCount: 0
                  State: NORMAL
LstConsistencyCheckTime: NULL
           CheckVersion: -1
           VersionCount: 1
               PathHash: -1
                MetaUrl: http://172.0.0.1:8040/api/meta/header/3944055
       CompactionStatus: http://172.0.0.1:8040/api/compaction/show?tablet_id=3944055
4.CHAR类型字段隐士转换问题:

在1.0以下版本中,如果OLAP表中的字段是char类型,在使用in过滤数据时,如果in里面的过滤条件是数值类型,是可以执行的;但在1.0及以后的版本,如果in里面继续使用数值类型,会报类型转换异常detailMessage = can not cast from origin type TINYINT to target type=CHAR(2),具体测试参考如下:

##建表语句
CREATE TABLE `ods_test_in_delta` (
  `id` INT NULL COMMENT 'id',
  `name` varchar(500) NULL COMMENT 'name',
  `age` int NULL COMMENT 'age',
  `address` varchar(500) NULL COMMENT 'address',
  `status` char(2) NULL COMMENT 'status',
  `ranke` varchar(1) NULL COMMENT 'ranke',
  `grade` TINYINT(1) NULL COMMENT 'grade'
) ENGINE=OLAP
UNIQUE KEY(`id`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 3",
"in_memory" = "false",
"storage_format" = "V2",
"disable_auto_compaction" = "false"
);

##插入语句
insert into ods_test_in_delta(id,name,age,address,status,ranke,grade) VALUES(1,"张三",28,"西安","1","1",1);
insert into ods_test_in_delta(id,name,age,address,status,ranke,grade) VALUES(2,"李四",21,"上海","2","2",6);
insert into ods_test_in_delta(id,name,age,address,status,ranke,grade) VALUES(3,"王二",22,"北京","1","3",2);
insert into ods_test_in_delta(id,name,age,address,status,ranke,grade) VALUES(4,"麻子",18,"天津","3","6",1);
insert into ods_test_in_delta(id,name,age,address,status,ranke,grade) VALUES(5,"横七",56,"济南","4","4",3);
insert into ods_test_in_delta(id,name,age,address,status,ranke,grade) VALUES(6,"竖八",47,"杭州","5","5",4);
  • case 1: status字段类型为char,根据status in (1,3,5),会出现报错:
mysql> SELECT * from ods_test_in_delta  where status in (1,3,5)\G;
ERROR 1105 (HY000): errCode = 2, detailMessage = can not cast from origin type TINYINT to target type=CHAR(2)
ERROR: 
No query specified

mysql> 
  • case2 :grade 字段类型为tinyint,根据grade in ("1","3","2"),可以正常查询出结果:
mysql> SELECT * from ods_test_in_delta  where grade in ("1","3","2");
+------+--------+------+---------+--------+-------+-------+
| id   | name   | age  | address | status | ranke | grade |
+------+--------+------+---------+--------+-------+-------+
|    1 | 张三   |   28 | 西安    | 1      | 1     |     1 |
|    3 | 王二   |   22 | 北京    | 1      | 3     |     2 |
|    4 | 麻子   |   18 | 天津    | 3      | 6     |     1 |
|    5 | 横七   |   56 | 济南    | 4      | 4     |     3 |
+------+--------+------+---------+--------+-------+-------+
4 rows in set (0.01 sec)

mysql>
  • case3 :ranke 字段类型为varchar,根据 ranke in (2,3,5),可以正常查询出结果:
mysql> SELECT * from ods_test_in_delta where ranke in (2,3,5); 
+------+--------+------+---------+--------+-------+-------+
| id   | name   | age  | address | status | ranke | grade |
+------+--------+------+---------+--------+-------+-------+
|    2 | 李四   |   21 | 上海    | 2      | 2     |     6 |
|    3 | 王二   |   22 | 北京    | 1      | 3     |     2 |
|    6 | 竖八   |   47 | 杭州    | 5      | 5     |     4 |
+------+--------+------+---------+--------+-------+-------+
3 rows in set (0.01 sec)

mysql> 

从以上3个case 可以看出,1.0以上版本兼容了 varcharint之间的隐士转换,但对char类型没有做类型转换。遇到这种情况,只能提高SQL书写规范,尽量减少这种类型转换的需求。

总结:

通过本次从0.15升级到1.1.5版本的过程中来看,因为前期也做了大量兼容性调研工作,所以升级工作整体还是比较顺利的,但升级过后也遇到以上这些问题在调研过程中并没有涉及到。目前已知问题中,除了ODBCOLAP关联会导致BE节点down机外,暂时还没有发现其他比较严重的问题,所以大家在升级Apache Doris时还是要做好前提兼容性调研的工作,避免出现不可控异常导致生产环境瘫痪,后续如果有新的版本兼容问题,也会持续更新。

换的需求。

总结:

通过本次从0.15升级到1.1.5版本的过程中来看,因为前期也做了大量兼容性调研工作,所以升级工作整体还是比较顺利的,但升级过后也遇到以上这些问题在调研过程中并没有涉及到。目前已知问题中,除了ODBCOLAP关联会导致BE节点down机外,暂时还没有发现其他比较严重的问题,所以大家在升级Apache Doris时还是要做好前提兼容性调研的工作,避免出现不可控异常导致生产环境瘫痪,后续如果有新的版本兼容问题,也会持续更新。

你可能感兴趣的:(apache,大数据,big,data)