DDL常见问题

本文将介绍PolarDB-X DDL常见问题。

PolarDB-X 2.0数据库数量超限 32个,需要增加怎么办?

您可以使用高权限账户连接数据库执行SET GLOBAL MAX_LOGICAL_DB_COUNT=64; 即可。

PolarDB-X 2.0异常DDL如何确认?

具体可参考一下语句进行修改:

SHOW FULL DDL; 
SHOW FULL physical_processlist WHERE info !='';

PolarDB-X批量插入操作,一次能插入的最大行记录?

您可以根据以下内容评估:

  • 存储容量计算原则

    • InnoDB引擎下,INT(4 Byte)、BIGINT(8 Byte)、DECIMAL(4 Byte)、DATETIME(8 Byte).

    • VARCHAR(N):UTF8字符集按3字节,UTF8MB44字节。

    • 特殊字段需单独评估:TEXT/BLOB/LONGTEXT等大对象类型。例如:某些字符类型设计也不合理,例如Group_ID设置为VRACHAR(1024)其实该字段只存储了一个数字0,按照单行最大存储进行预估。

      示例假设某表单行各字段加总后,最大占用存储空间为:8+8+8+8+8+8+255+255+255+1024+4+64+8=1913 字节。根据PolarDB-X CN计算层的16M批量插入方式,建议如下:

      • 按照1M计算,(1024*1024)/1913 ≈ 548。因此建议单批插入条数控制在500条以内,以避免超出限制。

      • 那么16M下,500*16=8000条,当max_allowed_packet=16M时,单次批量插入8000条数据是相对合理且安全的范围。

      综上,实际批量插入条数应结合单行实际字节占用和max_allowed_packet参数合理预估,在保证性能和安全的前提下,选择合适的批量插入条数。

  • 其他影响插入性能因素:

    • InnoDB缓冲池(buffer_pool)大小。

    • 磁盘IOPS能力、网络带宽(分布式数据库场景)。

    • Redo日志缓冲区(innodb_log_buffer_size)刷盘机制。

  • 参数设置建议

    • 建议您调整max_allowed_packet参数到最大值。

    • 建议将innodb_log_buffer_size调整到 32M~128M 之间,并通过多次测试找出最佳的插入响应时间。合理设置该参数,可以避免InnoDB在事务提交前频繁进行日志刷盘操作,从而提升事务处理性能。

PolarDB-X执行DDL报错:[ERR_REPARTITION_TABLE_WITH_GSI] can not alter table repartition when gsi table is not public?

问题原因:

GSI索引的状态不正确,您可以使用SHOW GLOBAL INDEX FROM xxx;来进一步确认索引状态。只有PUBLIC、ABSENT这两个状态才支持对目标表操作DDL,其他状态表示GSI索引还在创建中,不能进行其他DDL操作。

解决方案:

  1. 先执行SHOW DDL;看下是否有残留的DDL操作阻塞。

  2. 如有残留的DDL操作,您可以先等待DDL操作结束。如果SHOW GLOBAL INDEX状态并非PUBLICABSENT,可以考虑CANCEL DDL JOB_ID;取消GSI的创建。然后重新执行需要的DDL操作。

    image

PolarDB-X 2.0中执行DDL出现报错:Tablefind incorrect column xxx/Out of range value for column xxx/Data too Long for column xxx

若一个字段的类型为DECIMAL(10, 0) ,则其可以存储最大9位的整数(小数部分为0)。执行DDL后,字段类型为DECIMAL(5, 4),则可以存储最多1位整数和4位小数。 此时,如果原DECIMAL(10, 0)列中有任何大于等于10的整数,执行DDL就会报错。

PolarDB-X中执行ALTER TABLE MODIFY/CHANGE COLUMN语句出现部分分片更新失败的情况,应如何处理?

PolarDB-X中分为2种方式处理:正向执行反向执行。

示例

  1. 创建以下表结构,并插入一些记录:

    CREATE TABLE `t1` (
     `id` bigint(20) NOT NULL AUTO_INCREMENT,
     `c2` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`)
    ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
    PARTITION BY KEY(`id`)
    PARTITIONS 32;
    
    INSERT INTO t1 VALUES (1, "1");
    INSERT INTO t1 VALUES (2, "abc");
  2. 此时在严格的SQL_MODE模式下,对t1表做⼀个MODIFY COLUMNDDL,将c2列由varchar变更成数字类型:

    SET sql_mode="strict_trans_tables"; 
    ALTER TABLE t1 MODIFY COLUMN c2 INT;
  3. 由于某个分⽚包含"abc"这样的⾮法值,所以在严格的SQL_MODE模式下,这个分⽚会变更失败。此时DDL报错:

    ...Not all physical DDLs have been executed successfully: 32 expected, 31 done, 1 failed...Incorrect integer value...

以上示例场景,PolarDB-X是无法自动处理的,处理方式参考如下:

  • 正向执行:修复执⾏失败的分⽚的数据,并继续此DDL,则称为正向执⾏。

  • 反向执行:若有些业务⽆法修改已有的⾮法数据,需要将已经执⾏成功的分⽚改回去,则称为反向执⾏。

正向执行

  1. 修正⾮法的数据:根据DDL修正表中的非法值,例如:

    UPDATE t1 SET c2=0 WHERE id=2;
  2. 执行SHOW DDL获取执⾏失败的DDLJOB_ID

    --------------------+----------------+---------------+----------+--------------+-----------+--------------------------+--------------------------+-----------------+----------------------------+------------------------------+----------------------+-----------------------+---------------+
    | JOB_ID            |OBJECT_SCHEMA   |  OBJECT_NAME  | ENGINE   |  DDL_TYPE    |  STATE    |  TOTAL_BACKFILL_PROGRESS | CURRENT_PHY_DDL_PROGRESS |   PROGRESS      |    START_TIME              |     END_TIME                 |     ELAPSED_TIME(MS)|      PHY_PROCESS      |    CANCELABLE |
    --------------------+----------------+---------------+----------+--------------+-----------+--------------------------+--------------------------+-----------------+----------------------------+------------------------------+----------------------+-----------------------+--------------+
    | 166113736846543257|    testdb      |      t1       |  DAG     |  ALTER_TABLE |  PAUSED   |  --                      |      96%                 |        33%      |    2023-11-14 14:01:11:585 |     2023-11-14 14:01:11:910  |        3325          |                       |     false    |
    --------------------+----------------+---------------+----------+--------------+-----------+--------------------------+--------------------------+-----------------+----------------------------+------------------------------+----------------------+-----------------------+--------------+
  3. 继续执⾏此DDL:

    CONTINUE DDL 1661145277907759104;

反向执行

说明

反向执行仅适用于ALTER TABLE MODIFY COLUMN出现分片级部分成功/部分失败的异常场景,使用限制如下:

  • PolarDB-X实例的5.4.18版本中提供此场景下的⾃动回滚能⼒,推荐您升级至该版本及以上版本。

  • 仅适⽤于PolarDB-X 2.0实例。

  • ALTER语句中仅包含变更列类型的操作,不包括改名等操作。

  • 必须是部分分⽚成功,部分分⽚失败,不包括全部成功或者全部失败的场景。也即报错中需要有类似信息32 expected, 31 done, 1 failed,failed数需要⼤于0,并且⼩于expected数。

  • 执⾏算法没有指定使⽤OMC(DDL语句中显式设定了ALGORITHM=OMC才会使⽤OMC,没有指定则没有使⽤)。

  1. 执行SHOW DDL获取执⾏失败的DDLJOB_ID

    --------------------+----------------+---------------+----------+--------------+-----------+--------------------------+--------------------------+-----------------+----------------------------+------------------------------+----------------------+-----------------------+---------------+
    | JOB_ID            |OBJECT_SCHEMA   |  OBJECT_NAME  | ENGINE   |  DDL_TYPE    |  STATE    |  TOTAL_BACKFILL_PROGRESS | CURRENT_PHY_DDL_PROGRESS |   PROGRESS      |    START_TIME              |     END_TIME                 |     ELAPSED_TIME(MS)|      PHY_PROCESS      |    CANCELABLE |
    --------------------+----------------+---------------+----------+--------------+-----------+--------------------------+--------------------------+-----------------+----------------------------+------------------------------+----------------------+-----------------------+--------------+
    | 166113736846543257|    testdb      |      t1       |  DAG     |  ALTER_TABLE |  PAUSED   |  --                      |      96%                 |        33%      |    2023-11-14 14:01:11:585 |     2023-11-14 14:01:11:910  |        3325          |                       |     false    |
    --------------------+----------------+---------------+----------+--------------+-----------+--------------------------+--------------------------+-----------------+----------------------------+------------------------------+----------------------+-----------------------+--------------+
  2. 取消当前DDL任务:

    DELETE FROM metadb.ddl_engine WHERE job_id=166113736846543257;
     
    DELETE FROM metadb.ddl_engine_task WHERE job_id=166113736846543257;
    说明

    注意,此步骤需要⾼权限账号执⾏。

  3. 取消后,执行SHOW DDL查看已⽆此任务。

  4. 请注意,此时该表处于不⼀致状态,务必及时处理,CHECK TABLE可以观察到:

    CHECK TABLE t1; 
    +----------------------+-------+----------+--------------------------------+----------------------------------------------------------------+ 
    | TABLE                | OP    | MSG_TYPE | MSG_TEXT                                                                                        | 
    +----------------------+-------+----------+-------------------------------- ----------------------------------------------------------------+ 
    |testdb.t1:Topology    | check | Error    | Table 'testdb_P00001_GROUP.t1 _EZ5p_00010' find incorrect columns 'c2', please recreate table   |                                           | 
    |testdb.t1:Columns     | check | Error    | Table 'testdb_P00000_GROUP.t1 _EZ5p_00000' find incorrect columns 'c2', please recreate table   | 
    +----------------------+-------+----------+-------------------------------- ----------------------------------------------------------------+ 
    2 rows in set (0.03 sec)
  5. 执⾏反向ALTER TABLE语句:

    ALTER TABLE t1 MODIFY COLUMN c2 varchar(16);
    说明

    此时也可以将列修改为其他类型,未必是原始类型,例如,若将字段从varchar(16)缩减为varchar(12)失败,可直接尝试调整为varchar(14),无需先恢复原始长度。

  6. 再次进行CHECK TABLE。此时,表已处于⼀致的状态:

    CHECK TABLE t1; 
    +--------------------+-------+----------+------------+ 
    | TABLE              | OP    | MSG_TYPE | MSG_TEXT   | 
    +----------------------+-------+----------+----------+ 
    | testdb.t1:Topology | CHECK | status   | OK         | 
    | testdb.t1:Columns  | CHECK | status   | OK         | 
    +--------------------+-------+----------+------------+ 
    2 rows in set (0.02 sec)