单击“SQL操作 > SQL窗口”,执行如下命令,创建存储过程。
确认存储过程中指定的数据库存在,如不存在,请首先创建数据库并导入数据。
DELIMITER //
CREATE PROCEDURE archive_table_non_first_partition(
IN dbName VARCHAR(64) -- 输入参数:指定数据库名称
)
BEGIN
-- ===================== 所有DECLARE必须放在最开头 =====================
-- 1. 声明变量
DECLARE tableName VARCHAR(64); -- 存储表名
DECLARE partitionName VARCHAR(64); -- 存储分区名
DECLARE done INT DEFAULT 0; -- 游标循环结束标记
DECLARE partitionCount INT DEFAULT 0;-- 单个表的分区总数
DECLARE partitionIndex INT DEFAULT 0;-- 分区遍历索引(用于跳过首个分区)
-- 2. 声明所有游标(提前集中声明,避免语法错误)
-- 游标1:获取指定数据库下的所有分区表
DECLARE cur_partition_tables CURSOR FOR
SELECT DISTINCT t.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES t
INNER JOIN INFORMATION_SCHEMA.PARTITIONS p
ON t.TABLE_SCHEMA = p.TABLE_SCHEMA
AND t.TABLE_NAME = p.TABLE_NAME
WHERE t.TABLE_SCHEMA = dbName
AND t.TABLE_TYPE = 'BASE TABLE'
AND p.PARTITION_NAME IS NOT NULL -- 筛选分区表
ORDER BY t.TABLE_NAME;
-- 游标2:获取单个分区表的所有分区(按创建顺序排序)
DECLARE cur_partitions CURSOR FOR
SELECT PARTITION_NAME
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = dbName
AND TABLE_NAME = tableName
AND PARTITION_NAME IS NOT NULL
ORDER BY PARTITION_ORDINAL_POSITION;
-- 游标3:获取指定数据库下的所有无分区表
DECLARE cur_non_partition_tables CURSOR FOR
SELECT t.TABLE_NAME
FROM information_schema.TABLES t
WHERE t.TABLE_SCHEMA = dbName
AND t.TABLE_TYPE = 'BASE TABLE'
AND NOT EXISTS ( -- 排除分区表
SELECT 1
FROM information_schema.PARTITIONS p
WHERE p.TABLE_SCHEMA = t.TABLE_SCHEMA
AND p.TABLE_NAME = t.TABLE_NAME
AND p.PARTITION_NAME IS NOT NULL
);
-- 3. 声明游标结束处理程序(仅需声明一次)
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- ===================== 第一部分:处理分区表(非首个分区) =====================
-- 步骤1:遍历所有分区表
OPEN cur_partition_tables;
partition_table_loop: LOOP
FETCH cur_partition_tables INTO tableName;
IF done = 1 THEN
LEAVE partition_table_loop;
END IF;
-- 重置变量,统计当前表的分区总数
SET done = 0;
SET partitionIndex = 0;
SELECT COUNT(DISTINCT PARTITION_NAME) INTO partitionCount
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = dbName
AND TABLE_NAME = tableName
AND PARTITION_NAME IS NOT NULL;
-- 跳过只有1个分区的表(无非首个分区可处理)
IF partitionCount <= 1 THEN
ITERATE partition_table_loop;
END IF;
-- 步骤2:遍历当前分区表的所有分区
OPEN cur_partitions;
partition_loop: LOOP
FETCH cur_partitions INTO partitionName;
IF done = 1 THEN
LEAVE partition_loop;
END IF;
-- 跳过首个分区
SET partitionIndex = partitionIndex + 1;
IF partitionIndex = 1 THEN
ITERATE partition_loop;
END IF;
-- 拼接并执行分区级归档SQL
SET @sql = CONCAT(
'call dbms_schs.make_io_transfer(\'start\', \'',
dbName, '\', \'', tableName, '\', \'', partitionName, '\', \'\', \'obs\')'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP partition_loop;
CLOSE cur_partitions;
END LOOP partition_table_loop;
CLOSE cur_partition_tables;
-- ===================== 第二部分:处理无分区表 =====================
-- 重置结束标记(避免继承上一轮游标状态)
SET done = 0;
-- 步骤1:遍历所有无分区表
OPEN cur_non_partition_tables;
non_partition_table_loop: LOOP
FETCH cur_non_partition_tables INTO tableName;
IF done = 1 THEN
LEAVE non_partition_table_loop;
END IF;
-- 拼接并执行无分区表归档SQL(修复参数顺序,和分区表保持一致)
SET @sql = CONCAT(
'call dbms_schs.make_io_transfer(\'start\', \'',
dbName, '\', \'', tableName, '\', \'\', \'\', \'obs\')'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP non_partition_table_loop;
CLOSE cur_non_partition_tables;
END //
DELIMITER ;
执行存储过程,查看冷数据归档信息。
sys.schs_show_all(database, table, partion)是TaurusDB内置的存储过程,三个参数分别表示库名、表名和分区名。
- 如果不指定表名和分区名,则表示查询该库下的所有归档表。
- 如果不指定分区名,则表示查询特定表的所有归档分区。
例如:
- 查询某个实例上所有冷表
CALL sys.schs_show_all( "", "", "");
- 查询库名为test的所有冷分区或者冷表
CALL sys.schs_show_all( "test", "", "");
- 查询库名为test,表名为table1的冷分区或者冷表情况
CALL sys.schs_show_all( "test", "table1", "");
因为TaurusDB冷热分离特性不支持归档分区表的首个分区,因此,表t1_p的首个分区p0,表t2_p的首个(即唯一)分区p0和表order_info的首个分区p_Beijing未进行归档。
下面以test库为示例:
call sys.schs_show_all('test', '', '');
当status列显示为FINISH时,表示分区表归档成功。
