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日正式上线.秉承专业.生动.实用 ...
随机推荐
- 【Unity3D】绘制物体表面三角形网格
1 仅绘制三角形网格 1)创建游戏对象 创建一个空对象,重命名为 Grid,并在其下添加需要绘制网格的对象,如下: 场景显示如下: 2)添加脚本组件 GridController. ...
- linux 快速安装LAMP教程
最近学习linux,安装lamp遇到一些问题,记录下来分享一下: ------------------------------------------------------------------- ...
- thymeleaf利用fragment解决html页面间获取context-path问题
问题说明 我使用spring boot+thymeleaf做了个项目,那前台页面都是html,里面有各种api调用和路径跳转. 大家都知道这些路径不能写死,为保证任何情况下路径的正确性,一般都是这种格 ...
- 【CVE-2024-21626】容器逃逸漏洞修复
哈喽大家好,我是咸鱼. 好久不见,最近有一个很火的 CVE--runc 容器逃逸漏洞.年前的时候我们已经在测试环境进行了相关操作打算年后线上进行修复. 因为今天咸鱼才开工,所以文章也就拖到了现在 漏洞 ...
- 李宏毅2022机器学习HW3 Image Classification
Homework3 数据集下载 在本地环境下进行实验总是令人安心,但是又苦于网上找不到数据集,虽然kaggle上有数据集但是下载存在问题 于是有了一个天才的想法,间接从kaggle上下载(利用outp ...
- 从零开始学Spring Boot系列-Hello World
欢迎来到从零开始学Spring Boot的旅程!在这个系列的第二篇文章中,我们将从一个非常基础但重要的示例开始:创建一个简单的Spring Boot应用程序,并输出"Hello World& ...
- HttpURLConnection使用分析
在项目中遇到各种版本的httpClient,所以想了解一下httpClient的实现 首先查看的是JDK1.1中自带的HttpURLConnection,看一下最初的设计是怎么样的 代码分析 使用Ht ...
- 教程|在矩池云使用 Stable Diffusion web UI v1.5 模型和 ControlNet 插件
今天给大家介绍下如何在矩池云使用 Stable Diffusion web UI v1.5 模型和 Stable Diffusion ControlNet 插件. 租用机器 租用机器需要选择内存大于8 ...
- 第127篇:异步函数(async和await)练习题(异步,消息队列)
好家伙,本篇为做题思考 书接上文 题目如下: 1.请给出下列代码的输出结果,并配合"消息队列"写出相关解释 async function foo() { console.lo ...
- 【Azure 应用服务】本地Node.js部署上云(Azure App Service for Linux)遇到的三个问题解决之道
问题描述 当本地Node.js(Linux + Node.js + npm + yarn)部署上云,选择 Azure App Service for Linux 环境.但是在部署时,遇见了以下三个问题 ...