KingbaseES例程_普通表在线转分区表(基于触发器)
KingbaseES例程_普通表在线转分区表
概述
普通表转分区表,使用视图的替换式触发器,以路由方式,实现在线转移数据。
数据准备
/*普通大表*/
create table tab_single
as
select id, (random() * 100)::int + 1 c1, md5(id::text) name
from generate_series(1, 1e7) id;
alter table tab_single add primary key (id);
/*表结构一样的分区表*/
create table tab_part
( like tab_single )
partition by list (c1)
;
select format($$ create table tab_part_%s partition of tab_part for values in ( %s ) $$, id, id)
from generate_series(1, 100) id \gexec
/*分区表可以创建查询所需的索引*/
create index idx_tab_part_id on tab_part(id);
/*创建合并视图,作为操作入口*/
create or replace view tab_view as
select *
from tab_single
union all
select *
from tab_part;
/*视图不可更新*/
update tab_view
set name = 'a'
where id = 1;
[55000] ERROR: cannot update view "tab_view" 详细:Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable. 建议:To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.
通过触发器实现视图更新
通用函数
通用的触发器函数:
- 函数的第一个参数是单表名
- 函数的第二个参数是分区表名
create or replace function ftg_tab_view()
returns trigger
parallel safe volatile
language plpgsql
as
$$
declare
sqlsta text;
tabsngl text ;--单表名
tabpart text; --分区表名
begin
--函数的第一个参数是单表名
tabsngl := tg_argv[0];
--函数的第二个参数是分区表名
tabpart := tg_argv[1];
CASE TG_OP
WHEN 'INSERT'
THEN sqlsta := format('INSERT INTO %s select $1.*', tabpart);
execute sqlsta using new;
RETURN new;
WHEN 'DELETE'
THEN sqlsta := format('DELETE FROM %s a where row (a.*) = row ($1.*) ', tabsngl);
execute sqlsta using old;
sqlsta := format('DELETE FROM %s a where row (a.*) = row ($1.*) ', tabpart);
execute sqlsta using old;
RETURN OLD;
WHEN 'UPDATE'
THEN sqlsta := format(
'insert into %1$s select $1.* where (select count(*) cnt from %1$s a where row (a.*) = row ($1.*)) = 0',
tabpart);
execute sqlsta using new;
sqlsta := format(' delete from %1$s a where row (a.*) = row ($1.*)', tabsngl);
execute sqlsta using old;
if old <> new then
sqlsta := format('delete from %1$s a where row (a.*) = row ($1.*) and row (a.*) != row ($2.*) ',
tabpart);
execute sqlsta using old,new;
end if;
RETURN NEW;
END CASE;
end;
$$;
触发器
--单表与分区表,通过函数的参数,实现通用。
CREATE TRIGGER trg_iud_tab_view
INSTEAD OF INSERT OR UPDATE OR DELETE
ON tab_view
FOR EACH ROW
EXECUTE FUNCTION ftg_tab_view('tab_single', 'tab_part');
分步转移数据
do
$$
declare
stprow int;
chgrow int;
movrow int;
timstm timestamp;
begin
stprow := 10000; /*每步迁移10000行数据*/
chgrow := 0; /*实际影响的行*/
movrow := 0; /*累计迁移的行*/
loop
timstm := clock_timestamp();
with del as (delete from tab_single
where ctid = any (array(select ctid from tab_single limit stprow))
returning *)
insert into tab_part
select * from del;
commit;
get diagnostics chgrow = row_count;
exit when chgrow = 0;
movrow := movrow + chgrow;
raise info 'moved rows : % / % , % ms',chgrow, movrow, (date_part('sec',clock_timestamp()-timstm)*1000)::numeric(10,3);
end loop;
end;
$$
;
SHELL脚本高并发迁移数据
time seq 0 1000 | xargs -i -n1 -P10 psql -c "update tab_view set id = id where id between 10000*{}+0 and 10000*({}+1)-1"
real 2m14.988s
user 0m0.782s
sys 0m1.223s
抛弃普通表,保留分区表
/*分区表代替视图*/
do
$$
begin
drop view tab_view;
alter table tab_part
rename to tab_view;
commit;
end;
$$
;
或者
/*保留数据入口视图,删除视图的规则,修改视图定义*/
do
$$
begin
drop RULE rul_ins_tab_view TO tab_view;
drop RULE rul_del_tab_view TO tab_view;
drop RULE rul_upd_tab_view TO tab_view;
create or replace view tab_view as
select *
from tab_part;
commit;
end;
$$
;
注意
DML操作,主键值可能会出现重复,但可以通过校验语句避免。
KingbaseES例程_普通表在线转分区表(基于触发器)的更多相关文章
- Oracle在线重定义(online redefinition)--将普通表改为分区表
使用Oracle的在线重定义技术,可以将Oracle的普通表改为分区表.操作如下: STEP1:测试表是否可以在线重定义,这里以unixdev数据库的LIJIAMAN.BSTEST为例 EXEC DB ...
- Oracle表空间及分区表
(1) 表空间及分区表的概念表空间: 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应 ...
- 使用导出导入(datapump)方式将普通表切换为分区表
随着数据库数据量的不断增长,有些表须要由普通的堆表转换为分区表的模式. 有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表:使用EXCHANGE PARTITION方式来 ...
- ORACLE普通表转换成分区表
转http://mp.weixin.qq.com/s?__biz=MzAwMjkyMjEwNg==&mid=2247484761&idx=1&sn=ce080581145931 ...
- Oracle大表改为分区表及表空间切换方案
Oracle大表改为分区表及表空间切换方案 一. 背景 由于之前数据库表和索引放在一个表空间导致表空间数据文件增长太快,文件数量即将达到Oracle表空间的限制,需要对表(没有分 ...
- KingbaseES R3 读写分离集群在线扩容案例
案例说明: 1. 通过sys_basebackup创建新备库. 2. 将备库加入到Cluster nodes管理,可以用kingbase_monitor.sh一键启停. 3. 主备复制切换测试. 此次 ...
- SQL Server 2005中的分区表(三):将普通表转换成分区表(转)
在设计数据库时,经常没有考虑到表分区的问题,往往在数据表承重的负担越来越重时,才会考虑到分区方式,这时,就涉及到如何将普通表转换成分区表的问题了. 那么,如何将一个普通表转换成一个分区表 呢?说到底, ...
- Docker入门实战_正版电子书在线阅读_百度阅读
Docker入门实战_正版电子书在线阅读_百度阅读 Docker入门实战
- SQL Server 2005中的分区表(三):将普通表转换成分区表
在设计数据库时,经常没有考虑到表分区的问题,往往在数据表承重的负担越来越重时,才会考虑到分区方式,这时,就涉及到如何将普通表转换成分区表的问题了. 那么,如何将一个普通表转换成一个分区表 呢?说到底, ...
- 关于我们_ | 腕表时代watchtimes.com.cn
关于我们_ | 腕表时代watchtimes.com.cn 关于我们 腕表时代是北京兰会时光科技有限公司旗下运营的手表网站.腕表时代于2013年5月17日正式上线.秉承专业.生动.实用 ...
随机推荐
- js获取格式化日期方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 时序数据库timescaleDB安装
一:前言相关 环境:Red Hat 8.3.1-5安装程序:PostgreSQL 14.1,TimescaleDB 2.5.1,cmake3.22.1PostgreSQL编译安装需要cmake3.4以 ...
- React 组件之状态
没有什么是不可能的,只是需要找到正确的方法. 1. 什么是状态? 状态就是组件内部特有数据的载体(组件数据挂载方式),改变数据页面就会刷新,由组件自己设置和更改,也就是说由组件自己产生.维护,使用状态 ...
- 【LeetCode回溯算法#02】组合总和III
组合总和III 力扣题目链接(opens new window) 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字 ...
- Java是解释型语言么
基础概念 JVM虚拟机会将.java类文件编译成.class文件--字节码文件,这大家都知道. 代码运行时还需要将.class字节码文件翻译成机器码才能执行. 解释执行:将编译好的字节码一行一行地翻译 ...
- 【Azure 存储服务】Storage Account Blob 使用REST API如何获取磁盘大小(Content-Length), IOPS信息
问题描述 1)关于使用Rest API获取非托管磁盘信息比如获取磁盘大小 2)关于使用Rest API获取非托管磁盘信息比如iops 问题答案 #1:关于使用Rest API获取非托管磁盘信息比如获取 ...
- 【Azure 应用服务】App Services 恶意软件防护相关
问题描述 App Services 恶意软件防护相关资料,App Service是否默认开启病毒防护呢? 问题解答 App Services 默认启用了Antimalware 软件功能,Microso ...
- 【Azure 应用服务】在Azure App Service多实例的情况下,如何在应用中通过代码获取到实例名(Instance ID)呢?
问题描述 App Service开启多实例后,如何在代码中获取当前请求所真实到达的实例ID(Instance ID)呢? 问题答案 App Service 通过 环境变量的方式 显示的输出实例ID等信 ...
- 基于ads1292心电数据存储和状态显示
一 前记 ads1292芯片在专业的心电采集这块应用十分广泛.随着医疗可穿戴的发展,便携式心电测量这块前景十分广阔.基于现在的几个项目,团队在这里花费了不少精力,借此机会把这个方向打造成团队的特色之一 ...
- 基于Apollo3 Blue MCU芯片的可穿戴产品解决方案开发之健康手环源码解析
一 前记 健康手环是Apollo3 Blue的一个主打业务,也是该芯片最适合做的产品,在健康穿戴设备领域,该芯片有着对场景的透彻理解和技术的深厚积累. 二 源码分析 协议栈初始化: exactle_s ...