61.6. 版本发布 13.8-23.1

61.6.1. 新增功能
61.6.2. 优化
61.6.3. 兼容性

版本发布日期:. 2023年3月30日

61.6.1. 新增功能

  • 当内存被分配时出现内存不足问题,添加详细信息和提示。

  • LightDB 支持 Kubernetes(K8S) 的高可用部署。 核心模块包括 LightDB-patroni 镜像和 LightDB-operator 镜像。 LightDB-patroni 镜像包含 LightDBPatroni,以支持容器中的高可用部署。 LightDB-operator 镜像用于在 Kubernetes 中管理 LightDB 集群。

  • 新增 guc 参数 lightdb_server_version_num 用于标识 LightDB 版本号。 此值无法在会话级别下进行修改,需在 lightdb.conf 配置文件中进行设置。 请参见 SHOW

    显示 LightDB 服务器版本号:

    SHOW lightdb_server_version_num;
     lightdb_server_version_num 
    ----------------------------
     220400
    (1 row)
    

  • 新增扩展 lt_sql_inspect,用于定义事务时段、拦截和审计交易期间执行的危险 SQL 和命令。 请参见 lt_sql_inspect

61.6.2. 优化

lt_probackup 支持分布式优化。 请参见 lt_distributed_probackup

  • 在脚本中添加了分布式备份 ID。

  • 您可以通过分布式备份 ID 查看备份的总体状态。

61.6.3. 兼容性

61.6.3.1.  MySQL 兼容

  • 支持函数 substrsubstring。 请参见 function

    例如:

    lightdb@postgres=# create database test_createdb_mysql with lightdb_syntax_compatible_type mysql;
    CREATE DATABASE
    lightdb@postgres=# \c test_createdb_mysql
    You are now connected to database "test_createdb_mysql" as user "lightdb".
    lightdb@test_createdb_mysql=# select substr('sadadertyui',-3,3) FROM DUAL;
     substr 
    --------
     yui
    (1 row)
    

  • 支持 MySQL 的除法,包括整数除以整数,除以 0 等操作。 请参见 MySQL兼容函数

    例如:

    lightdb@test_createdb_mysql=# select 4/0;
    WARNING:  division by zero
     ?column? 
    ----------
             
    (1 row)
    lightdb@test_createdb_mysql=# select 4/1;
          ?column?      
    --------------------
     4.0000000000000000
    (1 row)
    

  • 支持 str_to_date 函数。 请参见 MySQL兼容函数

    • 不支持使用变量绑定的 Prepare Statements。

    • 由于使用 Julian 日来表示时间,无法表示非法日期 1999-00-00。

    • lightdb_sql_mode 的值为 no_zero_date 时,返回的值为空字符串,而非 NULL。

    • 报告非法日期错误,使用 LightDB 的错误报告逻辑。

    例如:

    select str_to_date('2022/09/10 11,13,13', '%Y/%m/%d %h,%i,%s');
          str_to_date     
    ---------------------
      2022-09-10 11:13:13
    (1 row)
    

  • 支持 @ 变量。 请参见 User Variable

    • 如果变量未初始化,则变量的类型为 text

    • 如果变量类型为 floatfloat8,则存储类型为 float8

    • 如果变量的值是 integer 类型(smallintbigintint ), 则存储类型为 bigint

    • 如果变量的类型是 numeric,则存储类型为 numeric

    • 如果变量的类型是其他类型,则变量类型为 text

    用户变量写作 @var_name,其中变量名 var_name 必须是标识符或关键字。如果您将其引用为标识符,var_name 将被视为列名(例如,@"my-var")。 @var_name 和 @ var_name 是不同的。@var_name 是用户变量表达式,@ var_name 是列 var_name 的绝对值。

    lightdb@test=# select @c1 := 5;
     @c1 
    -----
       5
    (1 row)
    
    lightdb@test=# SELECT c1, @c1, @ c1 FROM t;
     c1 | @c1 | ?column? 
    ----+-----+----------
      0 |   5 |        0
      1 |   5 |        1
    (2 rows)
    

  • 支持在查询时指定索引,仅支持语法。 force index 强制使用指定的索引; ignore index 忽略指定的索引。 请参见 SELECT

        -- multiple index
        select * from lt_test_mysql_ddl use index(pk_lt_test_mysql_ddl,uk_lt_test_mysql_ddl);
        select * from lt_test_mysql_ddl force index(pk_lt_test_mysql_ddl,uk_lt_test_mysql_ddl);
        select * from lt_test_mysql_ddl ignore index(pk_lt_test_mysql_ddl,uk_lt_test_mysql_ddl);
    
        -- multiple table join
        select * from lt_test_mysql_ddl a use index for order by(primary) join b using(id);
        select * from lt_test_mysql_ddl a force index for order by(pk_lt_test_mysql_ddl) join b using(id);
        select * from lt_test_mysql_ddl a ignore index for order by(primary,pk_lt_test_mysql_ddl) join b using(id);
        select * from lt_test_mysql_ddl a ignore index for order by(pk_lt_test_mysql_ddl) join b using(id);
       
  • 支持在创建表时指定 enginecollatecharacter set comment 等属性, 其中 enginecomment 仅支持语法。 兼容反引号( '' )和 tinyint 类型兼容。 请参见 Integer Types

  • 支持 duplicate key update 语法,当 PRIMARY KEYUNIQU 约束被违反时,进行更新操作,反之亦然。 请参见 ON DUPLICATE KEY UPDATE

    INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=t1.c+1;
    
    UPDATE t1 SET c=c+1 WHERE a=1;
          
  • 支持 replace into 语法,当 PRIMARY KEYUNIQU 约束被违反时, 先删除旧元组,然后插入新元组。 请参见 REPLACE INTO

    lightdb@testdb=# REPLACE INTO test VALUES (1, 'Old name', '18');
    INSERT 0 1
    
    lightdb@testdb=# REPLACE INTO test VALUES (1, 'New name');
    INSERT 0 1
    
    lightdb@testdb=# SELECT * FROM test;
     id |       name       | age 
    ----+------------------+-----
      1 | New name         |   0
    (1 row)
    

61.6.3.2.  Oracle 兼容

  • 添加了 no_unnestpq_distribute 优化提示。 请参阅 lt_hint_plan

    no_unnest 优化提示。

    lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 where exists(select * from test2 where test1.key1=test2.key1);
                   QUERY PLAN               
    ----------------------------------------
     Hash Join
       Hash Cond: (test1.key1 = test2.key1)
       ->  Seq Scan on test1
       ->  Hash
             ->  HashAggregate
                   Group Key: test2.key1
                   ->  Seq Scan on test2
    (7 rows)
    lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 where exists(select/*+no_unnest*/ * from test2 where test1.key1=test2.key1);
                           QUERY PLAN                        
    ---------------------------------------------------------
     Seq Scan on test1 @"lt#1"
       Filter: (alternatives: SubPlan 1 or hashed SubPlan 2)
       SubPlan 1
         ->  Seq Scan on test2 @"lt#0"
               Filter: (test1.key1 = key1)
       SubPlan 2
         ->  Seq Scan on test2 test2_1 @"lt#0"
    (7 rows)
    

    pq_distribute 优化提示。

    lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
    lightdb@lt_test-# EXPLAIN (COSTS false) SELECT /*+ leading(t1 t2) hashjoin(t1 t2)*/ * FROM t1 join t2 on t1.id=t2.id;
                        QUERY PLAN                     
    ---------------------------------------------------
     Gather
       Workers Planned: 3
       ->  Parallel Hash Join
             Hash Cond: (t1.id = t2.id)
             ->  Parallel Seq Scan on t1 @"lt#0"
             ->  Parallel Hash
                   ->  Parallel Seq Scan on t2 @"lt#0"
    (7 rows)
    lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
    lightdb@lt_test-# EXPLAIN (COSTS false) select/*+leading(t1 t2) hashjoin(t1 t2) pq_distribute(t2 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
                     QUERY PLAN                  
    ---------------------------------------------
     Gather
       Workers Planned: 3
       ->  Hash Join
             Hash Cond: (t1.id = t2.id)
             ->  Parallel Seq Scan on t1 @"lt#0"
             ->  Hash
                   ->  Seq Scan on t2 @"lt#0"
    (7 rows)
    

  • 支持 Oraclecreate user ( CREATE USER) 语法; 支持级联删除用户 ( DROP USER) 和 grant 语句 (详见 示例)。

    例如:

       CREATE USER user_name IDENTIFIED BY passwd DEFAULT TABLESPACE dt_space TEMPORARY TABLESPACE tt_space;
       DROP USER user_name CASCADE;
       GRANT CONNECT TO HS_SES;
       GRANT RESOURCE TO HS_SES;
       GRANT UNLIMITED TABLESPACE TO HS_SES;
    

  • 支持全局临时表。 详情请参见 兼容性

    • 支持Oracle全局临时会话表。

    • 支持Oracle全局临时事务表。

    创建一个会话级别的全局临时表。

      CREATE GLOBAL TEMPORARY TABLE gtt_session(id number,ename varchar(15)) ON COMMIT PRESERVE ROWS;
      

    创建一个事务级别的全局临时表。

      CREATE GLOBAL TEMPORARY TABLE gtt_transaction(id number,ename varchar(15)) ON COMMIT DELETE ROWS;
      

  • 自动创建一个与数据库同名的用户, 自动创建的同名用户在所创建的数据库中具有createconnecttemporarylogin权限, 该功能不能在分布式系统中使用。 详情请参见 CREATE DATABASE

    lightdb@postgres=# create database testdb with lightdb_syntax_compatible_type oracle;
    NOTICE:  auto create user "testdb" success
    CREATE DATABASE
    
  • 当可支持变量类型声明的长度时, 它可以支持字符或字节,当单位目前为字符时, 仅支持语法。 详情请参见 orafce

        create table hs_es(id int, name varchar2(10 byte));
        create table hs_lt(id int, name varchar2(10 char));
       
  • 增加导入工具 ltldr,与 sqlldr 工具兼容。 通过控制文件将数据从指定表导入数据库, 可以同时导入多个表。 对于使用 sqlldr 工具导入数据的业务, 具有天然的优势。

  • 兼容 DBMS_UTILITY 内置包 format_error_backtrace 函数, 仅记录 PlorasSQL 执行错误的最新记录, 使用此函数可以查看错误位置。 详情请参见 支持 DBMS_UTILITY 内置包 format_error_backtrace

    使用 DBMS_UTILITY.format_error_backtrace 函数,例如:

    create or replace procedure pr_error_code_test1 is
        v_backtrace    varchar(1000);
        v_error        varchar(1000); 
    begin
    
        INSERT INTO test_error_stack values (2);
        INSERT INTO test_error_stack values (1);
        commit;
        exception when others then
        insert into t_errlog(operate_error_msg) select to_char(DBMS_UTILITY.format_error_backtrace);
        commit;
        rollback;
        end pr_error_code_test1;
    /
    
    select select to_char(DBMS_UTILITY.format_error_backtrace)
        

  • pl/sql 支持存储过程使用未装饰的返回参数和返回 null。 返回 null 函数用于终止存储过程。 详情请参见 从存储过程返回

    create or replace procedure p_fmt_post_update_cash
    (
      p_src_system  varchar2 DEFAULT '0',
      p_init_date   number DEFAULT 0, 
      p_company_no  varchar2 DEFAULT '0',
      o_return_msg  out varchar2, 
      o_return_code out integer
    ) as
      v_init_date         int := 0;
    begin
      if v_init_date = 0 then
        o_return_code := 1;
        o_return_msg  := '请输入正确的校验日期';
    	return;
      end if;
     end;
    /