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日正式上线.秉承专业.生动.实用 ...
随机推荐
- Stream 总结
1 前言 Stream 是 Java 8 中为方便操作集合及其元素而定制的接口,它将要处理的元素集合看作一种流,对流中的元素进行过滤.排序.映射.聚合等操作.使用 Stream API,就好像使用 S ...
- HTMLElement对象
HTMLElement对象 任何HTML元素都继承于HTMLElement对象,一些元素直接实现这个接口,而另一些元素通过多层继承来实现它. 属性 从其父元素Element继承属性,并从Documen ...
- oracle FGAC(细粒度访问控制)介绍
在ORACLE中,RLS有时也叫做虚拟私有数据库(VPD)或者细粒度访问控制(FGAC). RLS由8i引进,利用这一特性我们可以对表定义安全策略(并且指明对表的操作类型),实现对用户可以看到或者修改 ...
- Detours 的使用
Detours 是一个用于在 ARM, ARM64, X86, X64 和 IA64 机器上拦截二进制函数的库. Detours 最常用来拦截应用程序中的 win32 api 调用,比如添加调试工具. ...
- 硬件开发笔记(五): 硬件开发基本流程,制作一个USB转RS232的模块(四):创建CON连接器件封装并关联原理图元器件
前言 有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了一个创建CON标准连接件封装,创建 ...
- 混合类Mixins介绍
介绍 混合类是封装了一些通用行为的基类,旨在重用代码.通常,混合类本身并没有什么用,仅扩展这种类也行不通 因为在大多数情况下,它都依赖于其它类中定义的方法和属性.通过多继承,可将混合类与其它类一起使用 ...
- 【Azure 应用服务】使用Python Azure SDK 来获取 App Service的访问限制信息(Access Restrictions)
问题描述 为Azure App Service添加访问限制,需要Python Azure SDK来实现的示例代码. 问题解答 查阅Azure App Service的官方资料,使用Python SDK ...
- 【Azure 应用服务】如何查看App Service中的私网IP地址?
问题描述 在使用App Service服务时,可以通过Azure 门户中的属性功能查看出站IP列表. 如果把App Service与虚拟网络(VNET)集成后,它就可以直接访问虚拟网络内部资源,那么如 ...
- 读 NebulaGraph源码 | 查询语句 LOOKUP 的一生
本文由社区用户 Milittle 供稿 LOOKUP 是图数据库 NebulaGraph 的一个查询语句.它依赖索引,可以查询点或者边的信息.在本文,我将着重从源码的角度解析一下 LOOKUP 语句的 ...
- 无依赖单机尝鲜 Nebula Exchange 的 SST 导入
本文尝试分享下以最小方式(单机.容器化 Spark.Hadoop.Nebula Graph),快速趟一下 Nebula Exchange 中 SST 写入方式的步骤.本文适用于 v2.5 以上版本的 ...