华为云用户手册

  • 闪回恢复 闪回恢复功能是数据库恢复技术的一环,可以有选择性的撤销一个已提交事务的影响,将数据从人为不正确的操作中进行恢复。在采用闪回技术之前,只能通过备份恢复、PITR等手段找回已提交的数据库修改,恢复时长需要数分钟甚至数小时。采用闪回技术后,通过闪回Drop和闪回Truncate恢复已提交的数据库Drop/Truncate的数据,只需要秒级,而且恢复时间和数据库大小无关。 Astore引擎暂不支持闪回功能。 备机不支持闪回操作。 用户可以根据需要开启闪回功能,开启后会带来一定的性能劣化。 闪回查询 闪回表 闪回DROP/TRUNCATE 父主题: Ustore存储引擎
  • 使用示例 gaussdb=# drop TABLE IF EXISTS "public".flashtest;NOTICE: table "flashtest" does not exist, skippingDROP TABLE--创建表flashtestgaussdb=# CREATE TABLE "public".flashtest (col1 INT,col2 TEXT) with(storage_type=ustore);CREATE TABLE--查询csngaussdb=# select int8in(xidout(next_csn)) from gs_get_next_xid_csn(); int8in ---------- 79352065(1 rows)--查询当前时间戳gaussdb=# select now(); now ------------------------------- 2023-09-13 19:46:34.102863+08(1 row)gaussdb=# SELECT * FROM flashtest; col1 | col2 ------+------(0 rows)--插入数据gaussdb=# INSERT INTO flashtest VALUES(1,'INSERT1'),(2,'INSERT2'),(3,'INSERT3'),(4,'INSERT4'),(5,'INSERT5'),(6,'INSERT6');INSERT 0 6gaussdb=# SELECT * FROM flashtest; col1 | col2 ------+--------- 3 | INSERT3 6 | INSERT6 1 | INSERT1 2 | INSERT2 4 | INSERT4 5 | INSERT5(6 rows)--闪回表至特定的时间戳gaussdb=# TIMECAPSULE TABLE flashtest TO TIMESTAMP to_timestamp ('2023-09-13 19:52:21.551028', 'YYYY-MM-DD HH24:MI:SS.FF');TimeCapsule Tablegaussdb=# SELECT * FROM flashtest; col1 | col2 ------+------(0 rows)gaussdb=# select now(); now ------------------------------- 2023-09-13 19:54:00.641506+08(1 row)--插入数据gaussdb=# INSERT INTO flashtest VALUES(1,'INSERT1'),(2,'INSERT2'),(3,'INSERT3'),(4,'INSERT4'),(5,'INSERT5'),(6,'INSERT6');INSERT 0 6gaussdb=# SELECT * FROM flashtest; col1 | col2 ------+--------- 3 | INSERT3 6 | INSERT6 1 | INSERT1 2 | INSERT2 4 | INSERT4 5 | INSERT5(6 rows)--闪回表至特定的时间戳gaussdb=# TIMECAPSULE TABLE flashtest TO TIMESTAMP '2023-09-13 19:54:00.641506';TimeCapsule Tablegaussdb=# SELECT * FROM flashtest; col1 | col2 ------+------(0 rows)gaussdb=# drop TABLE IF EXISTS "public".flashtest;DROP TABLE
  • 对二级分区表删除一级分区 使用ALTER TABLE DROP PARTITION可以删除二级分区表的一个一级分区,这个行为可以作用在一级分区策略为RANGE或者LIST的情况。数据库会将这个一级分区,以及一级分区下的所有二级分区都删除。 例如,通过指定分区名删除二级分区表range_list_sales的一级分区date_202005,并更新Global索引。 ALTER TABLE range_list_sales DROP PARTITION date_202005 UPDATE GLOBAL INDEX; 或者,通过指定分区值来删除二级分区表range_list_sales中('2020-05-08')所对应的一级分区。由于不带UPDATE GLOBAL INDEX子句,执行该命令后Global索引会失效。 ALTER TABLE range_list_sales DROP PARTITION FOR ('2020-05-08'); 当二级分区表只有一个一级分区时,不支持通过ALTER TABLE DROP PARTITION命令删除一级分区。 当二级分区表的一级分区策略为HASH时,不支持通过ALTER TABLE DROP PARTITION命令删除一级分区。 父主题: 删除分区
  • 背景信息 闪回DROP:可以恢复意外删除的表,从回收站(recyclebin)中恢复被删除的表及其附属结构如索引、表约束等。闪回drop是基于回收站机制,通过还原回收站中记录的表的物理文件,实现已drop表的恢复。 闪回TRUNCATE:可以恢复误操作或意外被进行truncate的表,从回收站中恢复被truncate的表及索引的物理数据。闪回truncate基于回收站机制,通过还原回收站中记录的表的物理文件,实现已truncate表的恢复。
  • 分区表动态剪枝 对于检索条件中存在带有变量的分区表查询语句,由于优化器阶段无法获取用户的绑定参数,因此优化器阶段仅能完成indexscan、bitmapindexscan、indexonlyscan等算子检索条件的解析,后续会在执行器阶段获得绑定参数后,完成分区筛选。算子包含的检索条件中需要至少包含一个分区键字段,对于含有多个分区键的分区表,包含任意分区键子集即可。目前分区表动态剪枝仅支持PBE(Prepare/Bind/Execute)场景和参数化路径场景。 PBE动态剪枝 参数化路径动态剪枝 父主题: 分区剪枝
  • 语法示例 -- PURGE TABLE table_name; -- --查看回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)gaussdb=# drop table if EXISTS flashtest;NOTICE: table "flashtest" does not exist, skippingDROP TABLEgaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)--创建表flashtestgaussdb=# create table if not EXISTS flashtest(id int, name text) with (storage_type = ustore);CREATE TABLE--插入数据gaussdb=# insert into flashtest values(1, 'A');INSERT 0 1gaussdb=# select * from flashtest; id | name ----+------ 1 | A(1 row)--DROP表flashtestgaussdb=# drop table if EXISTS flashtest;DROP TABLE--查看回收站,删除的表被放入回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18591 | 12737 | 18585 | BIN$31C14EB4899$9737$0==$0 | flashtest | d | 0 | 79352606 | 2023-09-13 20:01:28.640664+08 | 79352595 | 79352595 | 2200 | 10 | 0 | 18585 | t | t | 225492 | 225492 18591 | 12737 | 18590 | BIN$31C14EB489E$12D1B978==$0 | pg_toast_18585_index | d | 3 | 79352606 | 2023-09-13 20:01:28.64093+08 | 79352595 | 79352595 | 99 | 10 | 0 | 18590 | f | f | 0 | 0 18591 | 12737 | 18588 | BIN$31C14EB489C$12D1BF60==$0 | pg_toast_18585 | d | 2 | 79352606 | 2023-09-13 20:01:28.641018+08 | 0 | 0 | 99 | 10 | 0 | 18588 | f | f | 225492 | 225492(3 rows)--查看表flashtest,表不存在gaussdb=# select * from flashtest;ERROR: relation "flashtest" does not existLINE 1: select * from flashtest; ^--PURGE表,将回收站中的表删除gaussdb=# PURGE TABLE flashtest;PURGE TABLE--查看回收站,回收站中的表被删除gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)-- PURGE INDEX index_name; --gaussdb=# drop table if EXISTS flashtest;NOTICE: table "flashtest" does not exist, skippingDROP TABLE--创建表flashtestgaussdb=# create table if not EXISTS flashtest(id int, name text) with (storage_type = ustore);CREATE TABLE--为表flashtest创建索引flashtest_indexgaussdb=# create index flashtest_index on flashtest(id);CREATE INDEX--DROP表gaussdb=# drop table if EXISTS flashtest;DROP TABLE--查看回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18648 | 12737 | 18641 | BIN$31C14EB48D1$9A85$0==$0 | flashtest | d | 0 | 79354509 | 2023-09-13 20:40:11.360638+08 | 79354506 | 79354508 | 2200 | 10 | 0 | 18641 | t | t | 226642 | 226642 18648 | 12737 | 18646 | BIN$31C14EB48D6$12E230B8==$0 | pg_toast_18641_index | d | 3 | 79354509 | 2023-09-13 20:40:11.361034+08 | 79354506 | 79354506 | 99 | 10 | 0 | 18646 | f | f | 0 | 0 18648 | 12737 | 18644 | BIN$31C14EB48D4$12E236A0==$0 | pg_toast_18641 | d | 2 | 79354509 | 2023-09-13 20:40:11.36112+08 | 0 | 0 | 99 | 10 | 0 | 18644 | f | f | 226642 | 226642 18648 | 12737 | 18647 | BIN$31C14EB48D7$9A85$0==$0 | flashtest_index | d | 1 | 79354509 | 2023-09-13 20:40:11.361246+08 | 79354508 | 79354508 | 2200 | 10 | 0 | 18647 | f | t | 0 | 0(4 rows)--PURGE索引flashtest_indexgaussdb=# PURGE index flashtest_index;PURGE INDEX--查看回收站,回收站中的索引flashtest_index被删除gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18648 | 12737 | 18641 | BIN$31C14EB48D1$9A85$0==$0 | flashtest | d | 0 | 79354509 | 2023-09-13 20:40:11.360638+08 | 79354506 | 79354508 | 2200 | 10 | 0 | 18641 | t | t | 226642 | 226642 18648 | 12737 | 18646 | BIN$31C14EB48D6$12E230B8==$0 | pg_toast_18641_index | d | 3 | 79354509 | 2023-09-13 20:40:11.361034+08 | 79354506 | 79354506 | 99 | 10 | 0 | 18646 | f | f | 0 | 0 18648 | 12737 | 18644 | BIN$31C14EB48D4$12E236A0==$0 | pg_toast_18641 | d | 2 | 79354509 | 2023-09-13 20:40:11.36112+08 | 0 | 0 | 99 | 10 | 0 | 18644 | f | f | 226642 | 226642(3 rows)-- PURGE RECYCLEBIN ----PURGE回收站gaussdb=# PURGE RECYCLEBIN;PURGE RECYCLEBIN--查看回收站,回收站被清空gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)-- TIMECAPSULE TABLE { table_name } TO BEFORE DROP [RENAME TO new_tablename] --gaussdb=# drop table if EXISTS flashtest;NOTICE: table "flashtest" does not exist, skippingDROP TABLE--创建表flashtestgaussdb=# create table if not EXISTS flashtest(id int, name text) with (storage_type = ustore);CREATE TABLE--插入数据gaussdb=# insert into flashtest values(1, 'A');INSERT 0 1gaussdb=# select * from flashtest; id | name ----+------ 1 | A(1 row)--DROP表gaussdb=# drop table if EXISTS flashtest;DROP TABLE--查看回收站,表被放入回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18658 | 12737 | 18652 | BIN$31C14EB48DC$9B2B$0==$0 | flashtest | d | 0 | 79354760 | 2023-09-13 20:47:57.075907+08 | 79354753 | 79354753 | 2200 | 10 | 0 | 18652 | t | t | 226824 | 226824 18658 | 12737 | 18657 | BIN$31C14EB48E1$12E45E00==$0 | pg_toast_18652_index | d | 3 | 79354760 | 2023-09-13 20:47:57.076129+08 | 79354753 | 79354753 | 99 | 10 | 0 | 18657 | f | f | 0 | 0 18658 | 12737 | 18655 | BIN$31C14EB48DF$12E46400==$0 | pg_toast_18652 | d | 2 | 79354760 | 2023-09-13 20:47:57.07621+08 | 0 | 0 | 99 | 10 | 0 | 18655 | f | f | 226824 | 226824(3 rows)--查看表,表不存在gaussdb=# select * from flashtest;ERROR: relation "flashtest" does not existLINE 1: select * from flashtest; ^--闪回drop表gaussdb=# timecapsule table flashtest to before drop;TimeCapsule Table--查看表,表被恢复到drop之前gaussdb=# select * from flashtest; id | name ----+------ 1 | A(1 row)--查看回收站,回收站中的表被删除gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)--DROP表gaussdb=# drop table if EXISTS flashtest;DROP TABLEgaussdb=# select * from flashtest;ERROR: relation "flashtest" does not existLINE 1: select * from flashtest; ^--查看回收站,表被放入回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+------------------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18664 | 12737 | 18652 | BIN$31C14EB48DC$9B4E$0==$0 | flashtest | d | 0 | 79354845 | 2023-09-13 20:49:17.762977+08 | 79354753 | 79354753 | 2200 | 10 | 0 | 18652 | t | t | 226824 | 226824 18664 | 12737 | 18657 | BIN$31C14EB48E1$12E680A8==$0 | BIN$31C14EB48E1$12E45E00==$0 | d | 3 | 79354845 | 2023-09-13 20:49:17.763271+08 | 79354753 | 79354753 | 99 | 10 | 0 | 18657 | f | f | 0 | 0 18664 | 12737 | 18655 | BIN$31C14EB48DF$12E68698==$0 | BIN$31C14EB48DF$12E46400==$0 | d | 2 | 79354845 | 2023-09-13 20:49:17.763343+08 | 0 | 0 | 99 | 10 | 0 | 18655 | f | f | 226824 | 226824(3 rows)--闪回drop表,表名用回收站中的rcynamegaussdb=# timecapsule table "BIN$31C14EB48DC$9B4E$0==$0" to before drop;TimeCapsule Table--查看回收站,回收站中的表被删除gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)gaussdb=# select * from flashtest; id | name ----+------ 1 | A(1 row)--DROP表gaussdb=# drop table if EXISTS flashtest;DROP TABLE--查看回收站,表被放入回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+------------------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18667 | 12737 | 18652 | BIN$31C14EB48DC$9B8D$0==$0 | flashtest | d | 0 | 79354943 | 2023-09-13 20:52:14.525946+08 | 79354753 | 79354753 | 2200 | 10 | 0 | 18652 | t | t | 226824 | 226824 18667 | 12737 | 18657 | BIN$31C14EB48E1$1320B4F0==$0 | BIN$31C14EB48E1$12E680A8==$0 | d | 3 | 79354943 | 2023-09-13 20:52:14.526319+08 | 79354753 | 79354753 | 99 | 10 | 0 | 18657 | f | f | 0 | 0 18667 | 12737 | 18655 | BIN$31C14EB48DF$1320BAE0==$0 | BIN$31C14EB48DF$12E68698==$0 | d | 2 | 79354943 | 2023-09-13 20:52:14.526423+08 | 0 | 0 | 99 | 10 | 0 | 18655 | f | f | 226824 | 226824(3 rows)--查看表,表不存在gaussdb=# select * from flashtest;ERROR: relation "flashtest" does not existLINE 1: select * from flashtest; ^--闪回drop表,并重命名表gaussdb=# timecapsule table flashtest to before drop rename to flashtest_rename;TimeCapsule Table--查看原表,表不存在gaussdb=# select * from flashtest;ERROR: relation "flashtest" does not existLINE 1: select * from flashtest; ^--查看重命名后的表,表存在gaussdb=# select * from flashtest_rename; id | name ----+------ 1 | A(1 row)--查看回收站,回收站中的表被删除gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)--drop表gaussdb=# drop table if EXISTS flashtest_rename;DROP TABLE--清空回收站gaussdb=# PURGE RECYCLEBIN;PURGE RECYCLEBIN--查看回收站,回收站被清空gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)-- TIMECAPSULE TABLE { table_name } TO BEFORE TRUNCATE --gaussdb=# drop table if EXISTS flashtest;NOTICE: table "flashtest" does not exist, skippingDROP TABLE--创建表flashtestgaussdb=# create table if not EXISTS flashtest(id int, name text) with (storage_type = ustore);CREATE TABLE--插入数据gaussdb=# insert into flashtest values(1, 'A');INSERT 0 1gaussdb=# select * from flashtest; id | name ----+------ 1 | A(1 row)--truncate表gaussdb=# truncate table flashtest;TRUNCATE TABLE--查看回收站,表的数据被放入回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18703 | 12737 | 18697 | BIN$31C14EB4909$9E4C$0==$0 | flashtest | t | 0 | 79356608 | 2023-09-13 21:24:42.819863+08 | 79356606 | 79356606 | 2200 | 10 | 0 | 18697 | t | t | 227927 | 227927 18703 | 12737 | 18700 | BIN$31C14EB490C$132FE3F0==$0 | pg_toast_18697 | t | 2 | 79356608 | 2023-09-13 21:24:42.820358+08 | 0 | 0 | 99 | 10 | 0 | 18700 | f | f | 227927 | 227927 18703 | 12737 | 18702 | BIN$31C14EB490E$132FEA40==$0 | pg_toast_18697_index | t | 3 | 79356608 | 2023-09-13 21:24:42.821012+08 | 79356606 | 79356606 | 99 | 10 | 0 | 18702 | f | f | 0 | 0(3 rows)--查看表,表中的数据为空gaussdb=# select * from flashtest; id | name ----+------(0 rows)--闪回truncate表gaussdb=# timecapsule table flashtest to before truncate;TimeCapsule Table--查看表,表中的数据被恢复gaussdb=# select * from flashtest; id | name ----+------ 1 | A(1 row)--查看回收站gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+---------------- 18703 | 12737 | 18702 | BIN$31C14EB490E$132FFC38==$0 | pg_toast_18697_index | t | 3 | 79356610 | 2023-09-13 21:24:42.872654+08 | 79356606 | 79356606 | 99 | 10 | 0 | 18708 | f | f | 0 | 0 18703 | 12737 | 18700 | BIN$31C14EB490C$13300228==$0 | pg_toast_18697 | t | 2 | 79356610 | 2023-09-13 21:24:42.872732+08 | 0 | 0 | 99 | 10 | 0 | 18706 | f | f | 0 | 227928 18703 | 12737 | 18697 | BIN$31C14EB4909$9E4D$0==$0 | flashtest | t | 0 | 79356610 | 2023-09-13 21:24:42.872792+08 | 79356606 | 79356606 | 2200 | 10 | 0 | 18704 | t | t | 0 | 227928(3 rows)--drop表gaussdb=# drop table if EXISTS flashtest;DROP TABLE--清空回收站gaussdb=# PURGE RECYCLEBIN;PURGE RECYCLEBIN--查看回收站,回收站被清空gaussdb=# select * from gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------(0 rows)
  • 事务提交 隐式事务。单条DML/DDL语句自动触发隐式事务,这种事务没有显式的事务块控制语句(START TRANSACTION/BEGIN/COMMIT/END),DML语句结束后自动提交。 显式事务。显式事务由显式的START TRANSACTION/BEGIN语句控制事务的开始,由COMMIT/END语句控制事务的提交。 子事务必须存在于显式事务或存储过程中,由SAVEPOINT语句控制子事务开始,由RELEASE SAVEPOINT语句控制子事务结束。如果一个事务在提交时还存在未释放的子事务,该事务提交前会先执行子事务的提交,所有子事务提交完毕后才会进行父事务的提交。 Ustore支持读已提交隔离级别。语句在执行开始时,获取当前系统的 CS N作为当前语句的查询CSN。整个语句的可见结果由语句开始那一刻决定,不受后续其他事务修改影响。Ustore中read committed默认是保持一致性读的。Ustore也支持标准的2PC事务。 父主题: Ustore事务模型
  • 分区(分区子表、子分区) 分区表中实际保存数据的表,对应的entry通常保存在pg_partition中,各个子分区的parentid作为外键关联其分区母表在pg_class表中的oid列。 示例1:t1_hash为一个一级分区表: gaussdb=# CREATE TABLE t1_hash (c1 INT, c2 INT, c3 INT)PARTITION BY HASH(c1)( PARTITION p0, PARTITION p1, PARTITION p2, PARTITION p3, PARTITION p4, PARTITION p5, PARTITION p6, PARTITION p7, PARTITION p8, PARTITION p9);--查询t1_hash分区类型gaussdb=# SELECT oid, relname, parttype FROM pg_class WHERE relname = 't1_hash'; oid | relname | parttype-------+---------+---------- 16685 | t1_hash | p (1 row)--查询t1_hash的分区信息gaussdb=# SELECT oid, relname, parttype, parentid FROM pg_partition WHERE parentid = 16685; oid | relname | parttype | parentid-------+---------+----------+---------- 16688 | t1_hash | r | 16685 16689 | p0 | p | 16685 16690 | p1 | p | 16685 16691 | p2 | p | 16685 16692 | p3 | p | 16685 16693 | p4 | p | 16685 16694 | p5 | p | 16685 16695 | p6 | p | 16685 16696 | p7 | p | 16685 16697 | p8 | p | 16685 16698 | p9 | p | 16685(11 rows)--删除t1_hash,清理示例gaussdb=# DROP TABLE t1_hash; 父主题: 基本概念
  • UB-tree增删改查 Insert操作:UB-tree的插入逻辑基本不变,只需增加索引插入时直接获取事务信息填写xmin字段。 Delete操作:UB-tree额外增加了索引删除流程,索引删除主要步骤与插入相似,获取事务信息填写xmax字段(B-tree索引不维护版本信息,不需要删除操作),同时更新页面上的active_tuple_count,若active_tuple_count被减为0,则尝试页面回收。 Update操作:对于Ustore而言,数据更新对UB-tree索引列的操作也与Astore有所不同,数据更新包含两种情况:索引列和非索引列更新,下图给出了UB-tree在数据发生更新时的处理。 上图展示UB-tree在索引列和非索引列更新的差异: 在非索引列更新的情况下,索引不发生任何变化,index tuple仍指向第一次插入的data tuple,Uheap不会插入新的data tuple,而是修改当下data tuple并将历史数据存入Undo中。 在索引列更新的情况下,UB-tree也会插入新的index tuple,但是会指向同一个data linepointer和同一个data tuple,扫描旧版本的数据则需要从Undo中读取。 Scan操作:用户在读取数据时,可通过使用索引扫描加速,UB-tree支持索引数据的多版本管理及可见性检查,索引层的可见性检查使得索引扫描(Index Scan)及仅索引扫描(IndexOnly Scan)性能有所提升。 对于索引扫描: 若索引列包含所有扫描列(IndexOnly Scan),则通过扫描条件在索引上进行二分查找,找到符合条件元组即可返回数据。 若索引列不包含所有扫描列(Index Scan),则通过扫描条件在索引上进行二分查找,找到符合条件元组的TID,再通过TID到数据表上查找对应的数据元组。如下图所示。 父主题: Index
  • 事务回滚 回滚是在事务运行的过程中发生了故障等异常情形下,事务不能继续执行,系统需要将事务中已完成的修改操作进行撤销。Astore、UB-tree没有回滚段,自然没有这个专门的回滚动作。Ustore为了性能考虑,它的回滚流程结合了同步、异步与页内即时回滚3种形式。 同步回滚。 有三种情况会触发事务的同步回滚: 事务块中的ROLLBACK关键字会触发同步回滚。 事务运行过程中如果发生ERROR级别报错,此时的COMMIT关键字与ROLLBACK功能相同,也会触发同步回滚。 事务运行过程中如果发生FATAL/PANIC级别报错,在线程退出前会尝试将该线程绑定的事务进行一次同步回滚。 异步回滚。同步回滚失败或者在系统宕机后再次重启时,会由Undo回收线程为未回滚完成的事务发起异步回滚任务,立即对外提供服务。由异步回滚任务发起线程undo launch负责拉起异步回滚工作线程undo worker,再由异步回滚工作线程实际执行回滚任务。undo launch线程最多可以同时拉起5个undo worker线程。 页面级回滚。当事务需要回滚但还未回滚到本页面时,如果其他事务需要复用该事务所占用的TD,就会在复用前对该事务在本页面的所有修改执行页面级回滚。页面级回滚只负责回滚事务在本页面的修改,不涉及其他页面。 Ustore子事务的回滚由ROLLBACK TO SAVEPOINT语句控制,子事务回滚后父事务可以继续运行,子事务的回滚不影响父事务的事务状态。如果一个事务在回滚时还存在未释放的子事务,该事务回滚前会先执行子事务的回滚,所有子事务回滚完毕后才会进行父事务的回滚。 父主题: Ustore事务模型
  • 工具函数示例 pg_get_tabledef获取分区表的定义,入参可以为表的oid或者表名。 SELECT pg_get_tabledef('test_range_pt'); pg_get_tabledef -------------------------------------------------------------------- SET search_path = public; + CREATE TABLE test_range_pt ( + a integer, + b integer, + c integer + ) + WITH (orientation=row, compression=no) + PARTITION BY RANGE (a) + ( + PARTITION p1 VALUES LESS THAN (2000) TABLESPACE pg_default, + PARTITION p2 VALUES LESS THAN (3000) TABLESPACE pg_default, + PARTITION p3 VALUES LESS THAN (4000) TABLESPACE pg_default, + PARTITION p4 VALUES LESS THAN (5000) TABLESPACE pg_default, + PARTITION p5 VALUES LESS THAN (MAXVALUE) TABLESPACE pg_default+ ) + ENABLE ROW MOVEMENT;(1 row) pg_stat_get_partition_tuples_hot_updated返回给定分区id的分区热更新元组数的统计。 在分区p1中插入10条数据并更新,统计分区p1的热更新元组数。 INSERT INTO test_range_pt VALUES(generate_series(1,10),1,1);INSERT 0 10SELECT pg_stat_get_partition_tuples_hot_updated(49294);pg_stat_get_partition_tuples_hot_updated------------------------------------------0(1 row)UPDATE test_range_pt SET b = 2;UPDATE 10SELECT pg_stat_get_partition_tuples_hot_updated(49294);pg_stat_get_partition_tuples_hot_updated------------------------------------------10(1 row)
  • 静态编译架构 从整个数据库服务的组成构架来看,存储引擎向上对接SQL引擎,为SQL引擎提供或接收标准化的数据格式(元组或向量数组);存储引擎向下对接存储介质,按照特定的数据组织方式,以页面、压缩单元(Compress Unit)或其他形式为单位,通过存储介质提供的特定接口,对存储介质中的数据完成读、写操作。 GaussDB Kernel通过静态编译使数据库专业人员可以为特定的应用程序需求选择专用的存储引擎。为了减少对执行引擎的干扰,提供行存访问接口层TableAM,用来屏蔽底层行存引擎带来的差异,使得不同行存引擎可以分别独立演进。如下图所示。 在此基础之上,存储引擎通过日志系统提供数据的持久化和可靠性能力。通过并发控制(事务)系统保证同时执行的、多个读写操作之间的原子性、一致性和隔离性,通过索引系统提供对特定数据的加速寻址和查询能力,通过主备复制系统提供整个数据库服务的高可用能力。 行存引擎主要面向OLTP(OnLine Transaction Processing)类业务应用场景,适合高并发、小数据量的单点或小范围数据读写操作。行存引擎向上为SQL引擎提供元组形式的读写接口,向下以页面为单位通过可扩展的介质管理器对存储介质进行读写操作,并通过页面粒度的共享缓冲区来优化读写操作的效率。对于读写并发操作,采用多版本并发控制(MVCC,Multi-Version Concurrency Control);对于写写并发操作,采用基于两阶段锁协议(2PL,Two-Phase Locking)的悲观并发控制(PCC,Pessimistic Concurrency Control)。当前,行存引擎默认的介质管理器采用磁盘文件系统接口,后续可扩展支持块设备等其他类型的存储介质。GaussDB Kernel行存引擎可以选择基于Append update 的Astore或基于In-place update的Ustore。 父主题: 存储引擎体系架构概述
  • 前置建表相关信息 前置建表: CREATE TABLE test_range_pt (a INT, b INT, c INT)PARTITION BY RANGE (a)( PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN (3000), PARTITION p3 VALUES LESS THAN (4000), PARTITION p4 VALUES LESS THAN (5000), PARTITION p5 VALUES LESS THAN (MAXVALUE))ENABLE ROW MOVEMENT; 查看分区表oid SELECT oid FROM pg_class WHERE relname = 'test_range_pt'; oid------- 49290(1 row) 查看分区信息 SELECT oid,relname,parttype,parentid,boundaries FROM pg_partition WHERE parentid = 49290; oid | relname | parttype | parentid | boundaries-------+---------------+----------+----------+------------ 49293 | test_range_pt | r | 49290 | 49294 | p1 | p | 49290 | {2000} 49295 | p2 | p | 49290 | {3000} 49296 | p3 | p | 49290 | {4000} 49297 | p4 | p | 49290 | {5000} 49298 | p5 | p | 49290 | {NULL}(6 rows) 创建索引 CREATE INDEX idx_range_a ON test_range_pt(a) LOCAL;CREATE INDEX--查看分区索引oidSELECT oid FROM pg_class WHERE relname = 'idx_range_a'; oid------- 90250(1 row) 查看索引分区信息 SELECT oid,relname,parttype,parentid,boundaries,indextblid FROM pg_partition WHERE parentid = 90250; oid | relname | parttype | parentid | boundaries | indextblid-------+----------+----------+----------+------------+------------ 90255 | p5_a_idx | x | 90250 | | 49298 90254 | p4_a_idx | x | 90250 | | 49297 90253 | p3_a_idx | x | 90250 | | 49296 90252 | p2_a_idx | x | 90250 | | 49295 90251 | p1_a_idx | x | 90250 | | 49294(5 rows)
  • 对范围分区表分割分区 使用ALTER TABLE SPLIT PARTITION可以对范围分区表分割分区。 例如,假设范围分区表range_sales的分区date_202001定义范围为['2020-01-01', '2020-02-01')。可以指定分割点'2020-01-16'将分区date_202001分割为两个分区,并更新Global索引。 ALTER TABLE range_sales SPLIT PARTITION date_202001 AT ('2020-01-16') INTO( PARTITION date_202001_p1, --第一个分区上界是'2020-01-16' PARTITION date_202001_p2 --第二个分区上界是'2020-02-01') UPDATE GLOBAL INDEX; 或者,不指定分割点,将分区date_202001分割为多个分区,并更新Global索引。 ALTER TABLE range_sales SPLIT PARTITION date_202001 INTO( PARTITION date_202001_p1 VALUES LESS THAN ('2020-01-11'), PARTITION date_202001_p2 VALUES LESS THAN ('2020-01-21'), PARTITION date_202001_p3 --第三个分区上界是'2020-02-01')UPDATE GLOBAL INDEX; 又或者,通过指定分区值而不是指定分区名来分割分区。 ALTER TABLE range_sales SPLIT PARTITION FOR ('2020-01-15') AT ('2020-01-16') INTO( PARTITION date_202001_p1, --第一个分区上界是'2020-01-16' PARTITION date_202001_p2 --第二个分区上界是'2020-02-01') UPDATE GLOBAL INDEX; 若对MAXVALUE分区进行分割,前面几个分区不能申明MAXVALUE范围,最后一个分区会继承MAXVALUE分区范围。 父主题: 分割分区
  • 对*-LIST二级分区表分割二级分区 使用ALTER TABLE SPLIT SUBPARTITION可以对*-LIST二级分区表分割二级分区。 例如,假设*-LIST二级分区表hash_list_sales的二级分区product2_channel2的定义范围为DEFAULT。可以指定分割点将其分割为两个分区,并更新Global索引。 ALTER TABLE hash_list_sales SPLIT SUBPARTITION product2_channel2 VALUES ('6', '7', '8', '9') INTO( SUBPARTITION product2_channel2_p1, --第一个分区范围是('6', '7', '8', '9') SUBPARTITION product2_channel2_p2 --第二个分区范围是DEFAULT) UPDATE GLOBAL INDEX; 或者,不指定分割点,将分区product2_channel2分割为多个分区,并更新Global索引。 ALTER TABLE hash_list_sales SPLIT SUBPARTITION product2_channel2 INTO( SUBPARTITION product2_channel2_p1 VALUES ('6', '7', '8'), SUBPARTITION product2_channel2_p2 VALUES ('9', '10'), SUBPARTITION product2_channel2_p3 --第三个分区范围是DEFAULT) UPDATE GLOBAL INDEX; 又或者,通过指定分区值而不是指定分区名来分割分区。 ALTER TABLE hash_list_sales SPLIT SUBPARTITION FOR (1200, '6') VALUES ('6', '7', '8', '9') INTO( SUBPARTITION product2_channel2_p1, --第一个分区范围是('6', '7', '8', '9') SUBPARTITION product2_channel2_p2 --第二个分区范围是DEFAULT) UPDATE GLOBAL INDEX; 若对DEFAULT分区进行分割,前面几个分区不能申明DEFAULT范围,最后一个分区会继承DEFAULT分区范围。 父主题: 分割分区
  • 对二级分区表清空二级分区 使用ALTER TABLE TRUNCATE SUBPARTITION可以清空二级分区表的一个二级分区。 例如,通过指定分区名清空二级分区表range_list_sales的二级分区date_202005_channel1,并更新Global索引。 ALTER TABLE range_list_sales TRUNCATE SUBPARTITION date_202005_channel1 UPDATE GLOBAL INDEX; 或者,通过指定分区值来清空二级分区表range_list_sales中('2020-05-08', '0')所对应的二级分区。由于不带UPDATE GLOBAL INDEX子句,执行该命令后Global索引会失效。 ALTER TABLE range_list_sales TRUNCATE SUBPARTITION FOR ('2020-05-08', '0'); 父主题: 清空分区
  • Local索引分区重建/不可用 使用ALTER INDEX PARTITION可以设置Local索引分区是否可用。 使用ALTER TABLE MODIFY PARTITION可以设置分区表上指定分区的所有索引分区是否可用。这个语法如果作用于二级分区表的一级分区,数据库会将这个一级分区下的所有二级分区均进行设置。 使用ALTER TABLE MODIFY SUBPARTITION可以设置二级分区表上指定二级分区的所有索引分区是否可用。 例如,假设分区表range_sales上存在两张Local索引range_sales_idx1和range_sales_idx2,假设其在分区date_202001上对应的索引分区名分别为range_sales_idx1_part1和range_sales_idx2_part1。 下面给出了维护分区表分区索引的语法: 可以通过如下命令设置分区date_202001上的所有索引分区均不可用。 ALTER TABLE range_sales MODIFY PARTITION date_202001 UNUSABLE LOCAL INDEXES; 或者通过如下命令单独设置分区date_202001上的索引分区range_sales_idx1_part1不可用。 ALTER INDEX range_sales_idx1 MODIFY PARTITION range_sales_idx1_part1 UNUSABLE; 可以通过如下命令重建分区date_202001上的所有索引分区。 ALTER TABLE range_sales MODIFY PARTITION date_202001 REBUILD UNUSABLE LOCAL INDEXES; 或者通过如下命令单独重建分区date_202001上的索引分区range_sales_idx1_part1。 ALTER INDEX range_sales_idx1 REBUILD PARTITION range_sales_idx1_part1; 假设二级分区表list_range_sales上存在两张Local索引list_range_sales_idx1和list_range_sales_idx2,表下有一级分区channel1,其下属二级分区有channel1_product1、channel1_product2、channel1_product3,二级分区channel1_product1上对应的索引分区名分别为channel1_product1_idx1和channel1_product1_idx2。 下面给出了维护二级分区表一级分区索引的语法: 可以通过如下命令设置分区channel1下属二级分区的所有索引分区均不可用,包括二级分区channel1_product1、channel1_product2、channel1_product3。 ALTER TABLE list_range_sales MODIFY PARTITION channel1 UNUSABLE LOCAL INDEXES; 可以通过如下命令重建分区channel1下属二级分区的所有索引分区。 ALTER TABLE list_range_sales MODIFY PARTITION channel1 REBUILD UNUSABLE LOCAL INDEXES; 下面给出了维护二级分区表二级分区索引的语法: 可以通过如下命令单独设置二级分区channel1_product1上的所有索引分区均不可用。 ALTER TABLE list_range_sales MODIFY SUBPARTITION channel1_product1 UNUSABLE LOCAL INDEXES; 可以通过如下命令重建二级分区channel1_product1上的所有索引分区。 ALTER TABLE list_range_sales MODIFY SUBPARTITION channel1_product1 REBUILD UNUSABLE LOCAL INDEXES; 或者通过如下命令单独设置二级分区channel1_product1上的索引分区channel1_product1_idx1不可用。 ALTER INDEX list_range_sales_idx1 MODIFY PARTITION channel1_product1_idx1 UNUSABLE; 通过如下命令单独重建二级分区channel1_product1上的索引分区channel1_product1_idx1。 ALTER INDEX list_range_sales_idx1 REBUILD PARTITION channel1_product1_idx1; 父主题: 分区表索引重建/不可用
  • 对列表分区表分割分区 使用ALTER TABLE SPLIT PARTITION可以对列表分区表分割分区。 例如,假设列表分区表list_sales的分区channel2定义范围为('6', '7', '8', '9')。可以指定分割点('6', '7')将分区channel2分割为两个分区,并更新Global索引。 ALTER TABLE list_sales SPLIT PARTITION channel2 VALUES ('6', '7') INTO( PARTITION channel2_1, --第一个分区范围是('6', '7') PARTITION channel2_2 --第二个分区范围是('8', '9')) UPDATE GLOBAL INDEX; 或者,不指定分割点,将分区channel2分割为多个分区,并更新Global索引。 ALTER TABLE list_sales SPLIT PARTITION channel2 INTO( PARTITION channel2_1 VALUES ('6'), PARTITION channel2_2 VALUES ('8'), PARTITION channel2_3 --第三个分区范围是('7', '9'))UPDATE GLOBAL INDEX; 又或者,通过指定分区值而不是指定分区名来分割分区。 ALTER TABLE list_sales SPLIT PARTITION FOR ('6') VALUES ('6', '7') INTO( PARTITION channel2_1, --第一个分区范围是('6', '7') PARTITION channel2_2 --第二个分区范围是('8', '9')) UPDATE GLOBAL INDEX; 若对DEFAULT分区进行分割,前面几个分区不能申明DEFAULT范围,最后一个分区会继承DEFAULT分区范围。 父主题: 分割分区
  • 向二级分区表新增一级分区 使用ALTER TABLE ADD PARTITION可以在二级分区表中新增一个一级分区,这个行为可以作用在一级分区策略为RANGE或者LIST的情况。如果这个新增一级分区下申明了二级分区定义,则数据库会根据定义创建对应的二级分区;如果这个新增一级分区下没有申明二级分区定义,则数据库会自动创建一个默认的二级分区。 例如,对二级分区表range_list_sales新增一个一级分区,并在下面创建四个二级分区。 ALTER TABLE range_list_sales ADD PARTITION date_202005 VALUES LESS THAN ('2020-06-01') TABLESPACE tb1( SUBPARTITION date_202005_channel1 VALUES ('0', '1', '2'), SUBPARTITION date_202005_channel2 VALUES ('3', '4', '5') TABLESPACE tb2, SUBPARTITION date_202005_channel3 VALUES ('6', '7'), SUBPARTITION date_202005_channel4 VALUES ('8', '9')); 或者对二级分区表range_list_sales只进行新增一级分区操作。 ALTER TABLE range_list_sales ADD PARTITION date_202005 VALUES LESS THAN ('2020-06-01') TABLESPACE tb1; 上面这种行为与如下SQL语句等价。 ALTER TABLE range_list_sales ADD PARTITION date_202005 VALUES LESS THAN ('2020-06-01') TABLESPACE tb1( SUBPARTITION date_202005_channel1 VALUES (DEFAULT)); 当二级分区表的一级分区策略为HASH时,不支持通过ALTER TABLE ADD PARTITION命令新增一级分区。 父主题: 新增分区
  • 示例 创建表 gaussdb=# CREATE TABLE web_returns_p2( ca_address_sk INTEGER NOT NULL , ca_address_id CHARACTER(16) NOT NULL , ca_street_number CHARACTER(10) , ca_street_name CHARACTER VARYING(60) , ca_street_type CHARACTER(15) , ca_suite_number CHARACTER(10) , ca_city CHARACTER VARYING(60) , ca_county CHARACTER VARYING(30) , ca_state CHARACTER(2) , ca_zip CHARACTER(10) , ca_country CHARACTER VARYING(20) , ca_gmt_offset NUMERIC(5,2) , ca_location_type CHARACTER(20))PARTITION BY RANGE (ca_address_sk)( PARTITION P1 VALUES LESS THAN(5000), PARTITION P2 VALUES LESS THAN(10000), PARTITION P3 VALUES LESS THAN(15000), PARTITION P4 VALUES LESS THAN(20000), PARTITION P5 VALUES LESS THAN(25000), PARTITION P6 VALUES LESS THAN(30000), PARTITION P7 VALUES LESS THAN(40000), PARTITION P8 VALUES LESS THAN(MAXVALUE))ENABLE ROW MOVEMENT; 创建索引 创建分区表LOCAL索引tpcds_web_returns_p2_index1,不指定索引分区的名称。 gaussdb=# CREATE INDEX tpcds_web_returns_p2_index1 ON web_returns_p2 (ca_address_id) LOCAL; 当结果显示为如下信息,则表示创建成功。 CREATE INDEX 创建分区表LOCAL索引tpcds_web_returns_p2_index2,并指定索引分区的名称。 gaussdb=# CREATE TABLESPACE example2 LOCATION '/home/omm/example2';gaussdb=# CREATE TABLESPACE example3 LOCATION '/home/omm/example3';gaussdb=# CREATE TABLESPACE example4 LOCATION '/home/omm/example4';gaussdb=# CREATE INDEX tpcds_web_returns_p2_index2 ON web_returns_p2 (ca_address_sk) LOCAL( PARTITION web_returns_p2_P1_index, PARTITION web_returns_p2_P2_index TABLESPACE example3, PARTITION web_returns_p2_P3_index TABLESPACE example4, PARTITION web_returns_p2_P4_index, PARTITION web_returns_p2_P5_index, PARTITION web_returns_p2_P6_index, PARTITION web_returns_p2_P7_index, PARTITION web_returns_p2_P8_index) TABLESPACE example2; 当结果显示为如下信息,则表示创建成功。 CREATE INDEX 创建分区表GLOBAL索引tpcds_web_returns_p2_global_index。 gaussdb=# CREATE INDEX tpcds_web_returns_p2_global_index ON web_returns_p2 (ca_street_number) GLOBAL; 当结果显示为如下信息,则表示创建成功。 CREATE INDEX 修改索引分区的表空间 修改索引分区web_returns_p2_P2_index的表空间为example1。 gaussdb=# ALTER INDEX tpcds_web_returns_p2_index2 MOVE PARTITION web_returns_p2_P2_index TABLESPACE example1; 当结果显示为如下信息,则表示修改成功。 ALTER INDEX –修改索引分区web_returns_p2_P3_index的表空间为example2。 gaussdb=# ALTER INDEX tpcds_web_returns_p2_index2 MOVE PARTITION web_returns_p2_P3_index TABLESPACE example2; 当结果显示为如下信息,则表示修改成功。 ALTER INDEX 重命名索引分区 执行如下命令对索引分区web_returns_p2_P8_index重命名web_returns_p2_P8_index_new。 gaussdb=# ALTER INDEX tpcds_web_returns_p2_index2 RENAME PARTITION web_returns_p2_P8_index TO web_returns_p2_P8_index_new; 当结果显示为如下信息,则表示重命名成功。 ALTER INDEX 查询索引 执行如下命令查询系统和用户定义的所有索引。 gaussdb=# SELECT RELNAME FROM PG_CLASS WHERE RELKIND='i' or RELKIND='I'; 执行如下命令查询指定索引的信息。 gaussdb=# \di+ tpcds_web_returns_p2_index2 删除索引 gaussdb=# DROP INDEX tpcds_web_returns_p2_index1; 当结果显示为如下信息,则表示删除成功。 DROP INDEX 清理以上示例 --清理示例gaussdb=# DROP TABLE web_returns_p2;
  • 二级分区 二级分区(Sub Partition,也叫组合分区)是基本数据分区类型的组合,将表通过一种数据分布方法进行分区,然后使用第二种数据分布方式将每个分区进一步细分为子分区。给定分区的所有子分区表示数据的逻辑子集。常见的二级分区组合如下所示: Range-Range Range-List Range-Hash List-Range List-List List-Hash Hash-Range Hash-List Hash-Hash 示例如下: --Range-Rangegaussdb=# CREATE TABLE t_range_range ( c1 INT, c2 INT, c3 INT)PARTITION BY RANGE (c1) SUBPARTITION BY RANGE (c2) ( PARTITION p1 VALUES LESS THAN (10) ( SUBPARTITION p1sp1 VALUES LESS THAN (5), SUBPARTITION p1sp2 VALUES LESS THAN (10) ), PARTITION p2 VALUES LESS THAN (20) ( SUBPARTITION p2sp1 VALUES LESS THAN (15), SUBPARTITION p2sp2 VALUES LESS THAN (20) ));gaussdb=# DROP TABLE t_range_range;--Range-Listgaussdb=# CREATE TABLE t_range_list ( c1 INT, c2 INT, c3 INT)PARTITION BY RANGE (c1) SUBPARTITION BY LIST (c2) ( PARTITION p1 VALUES LESS THAN (10) ( SUBPARTITION p1sp1 VALUES (1, 2), SUBPARTITION p1sp2 VALUES (3, 4) ), PARTITION p2 VALUES LESS THAN (20) ( SUBPARTITION p2sp1 VALUES (1, 2), SUBPARTITION p2sp2 VALUES (3, 4) ));gaussdb=# DROP TABLE t_range_list;--Range-Hashgaussdb=# CREATE TABLE t_range_hash ( c1 INT, c2 INT, c3 INT)PARTITION BY RANGE (c1) SUBPARTITION BY HASH (c2) SUBPARTITIONS 2( PARTITION p1 VALUES LESS THAN (10), PARTITION p2 VALUES LESS THAN (20));gaussdb=# DROP TABLE t_range_hash;--List-Rangegaussdb=# CREATE TABLE t_list_range ( c1 INT, c2 INT, c3 INT)PARTITION BY LIST (c1) SUBPARTITION BY RANGE (c2) ( PARTITION p1 VALUES (1, 2) ( SUBPARTITION p1sp1 VALUES LESS THAN (5), SUBPARTITION p1sp2 VALUES LESS THAN (10) ), PARTITION p2 VALUES (3, 4) ( SUBPARTITION p2sp1 VALUES LESS THAN (5), SUBPARTITION p2sp2 VALUES LESS THAN (10) ));gaussdb=# DROP TABLE t_list_range;--List-Listgaussdb=# CREATE TABLE t_list_list ( c1 INT, c2 INT, c3 INT)PARTITION BY LIST (c1) SUBPARTITION BY LIST (c2) ( PARTITION p1 VALUES (1, 2) ( SUBPARTITION p1sp1 VALUES (1, 2), SUBPARTITION p1sp2 VALUES (3, 4) ), PARTITION p2 VALUES (3, 4) ( SUBPARTITION p2sp1 VALUES (1, 2), SUBPARTITION p2sp2 VALUES (3, 4) ));gaussdb=# DROP TABLE t_list_list;--List-Hashgaussdb=# CREATE TABLE t_list_hash ( c1 INT, c2 INT, c3 INT)PARTITION BY LIST (c1) SUBPARTITION BY HASH (c2) SUBPARTITIONS 2( PARTITION p1 VALUES (1, 2), PARTITION p2 VALUES (3, 4));gaussdb=# DROP TABLE t_list_hash;--Hash-Rangegaussdb=# CREATE TABLE t_hash_range ( c1 INT, c2 INT, c3 INT)PARTITION BY HASH (c1) PARTITIONS 2SUBPARTITION BY RANGE (c2) ( PARTITION p1 ( SUBPARTITION p1sp1 VALUES LESS THAN (5), SUBPARTITION p1sp2 VALUES LESS THAN (10) ), PARTITION p2 ( SUBPARTITION p2sp1 VALUES LESS THAN (5), SUBPARTITION p2sp2 VALUES LESS THAN (10) ));gaussdb=# DROP TABLE t_hash_range;--Hash-Listgaussdb=# CREATE TABLE t_hash_list ( c1 INT, c2 INT, c3 INT)PARTITION BY HASH (c1) PARTITIONS 2SUBPARTITION BY LIST (c2) ( PARTITION p1 ( SUBPARTITION p1sp1 VALUES (1, 2), SUBPARTITION p1sp2 VALUES (3, 4) ), PARTITION p2 ( SUBPARTITION p2sp1 VALUES (1, 2), SUBPARTITION p2sp2 VALUES (3, 4) ));gaussdb=# DROP TABLE t_hash_list;--Hash-Hashgaussdb=# CREATE TABLE t_hash_hash ( c1 INT, c2 INT, c3 INT)PARTITION BY HASH (c1) PARTITIONS 2SUBPARTITION BY HASH (c2) SUBPARTITIONS 2( PARTITION p1, PARTITION p2);gaussdb=# DROP TABLE t_hash_hash; Interval分区看成是范围分区的一种特殊形式,目前不支持二级分区场景中定义Interval分区。 二级分区表的一级分区和二级分区分区键均只支持1列。 父主题: 分区策略
  • 范围分区 范围分区(Range Partition)根据为每个分区建立的分区键的值范围将数据映射到分区。范围分区是生产系统中最常见的分区类型,通常在以时间维度(Date、Time Stamp)描述数据场景中使用。范围分区有两种语法格式,示例如下: VALUES LESS THAN的语法格式 对于从句是VALUE LESS THAN的语法格式,范围分区策略的分区键最多支持16列。 单列分区键示例如下: gaussdb=# CREATE TABLE range_sales_single_key( product_id INT4 NOT NULL, customer_id INT4 NOT NULL, time DATE, channel_id CHAR(1), type_id INT4, quantity_sold NUMERIC(3), amount_sold NUMERIC(10,2))PARTITION BY RANGE (time)( PARTITION date_202001 VALUES LESS THAN ('2020-02-01'), PARTITION date_202002 VALUES LESS THAN ('2020-03-01'), PARTITION date_202003 VALUES LESS THAN ('2020-04-01'), PARTITION date_202004 VALUES LESS THAN ('2020-05-01'));--清理示例gaussdb=# DROP TABLE range_sales_single_key; 其中date_202002表示2020年2月的分区,将包含分区键值从2020年2月1日到2020年2月29日的数据。 每个分区都有一个VALUES LESS子句,用于指定分区的非包含上限。大于或等于该分区键的任何值都将添加到下一个分区。除第一个分区外,所有分区都具有由前一个分区的VALUES LESS子句指定的隐式下限。可以为最高分区定义MAXVALUE关键字,MAXVALUE表示一个虚拟无限值,其排序高于分区键的任何其他可能值,包括空值。 多列分区键示例如下: gaussdb=# CREATE TABLE range_sales( c1 INT4 NOT NULL, c2 INT4 NOT NULL, c3 CHAR(1))PARTITION BY RANGE (c1,c2)( PARTITION p1 VALUES LESS THAN (10,10), PARTITION p2 VALUES LESS THAN (10,20), PARTITION p3 VALUES LESS THAN (20,10));gaussdb=# INSERT INTO range_sales VALUES(9,5,'a');gaussdb=# INSERT INTO range_sales VALUES(9,20,'a');gaussdb=# INSERT INTO range_sales VALUES(9,21,'a');gaussdb=# INSERT INTO range_sales VALUES(10,5,'a');gaussdb=# INSERT INTO range_sales VALUES(10,15,'a');gaussdb=# INSERT INTO range_sales VALUES(10,20,'a');gaussdb=# INSERT INTO range_sales VALUES(10,21,'a');gaussdb=# INSERT INTO range_sales VALUES(11,5,'a');gaussdb=# INSERT INTO range_sales VALUES(11,20,'a');gaussdb=# INSERT INTO range_sales VALUES(11,21,'a');gaussdb=# SELECT * FROM range_sales PARTITION (p1); c1 | c2 | c3----+----+---- 9 | 5 | a 9 | 20 | a 9 | 21 | a 10 | 5 | a(4 rows)gaussdb=# SELECT * FROM range_sales PARTITION (p2); c1 | c2 | c3----+----+---- 10 | 15 | a(1 row)gaussdb=# SELECT * FROM range_sales PARTITION (p3); c1 | c2 | c3----+----+---- 10 | 20 | a 10 | 21 | a 11 | 5 | a 11 | 20 | a 11 | 21 | a(5 rows)--清理示例gaussdb=# DROP TABLE range_sales; 多列分区的分区规则如下: 从第一列开始比较。 如果插入的值当前列小于分区当前列边界值,则直接插入。 如果插入的当前列等于分区当前列的边界值,则比较插入值的下一列与分区下一列边界值的大小。 如果插入的当前列大于分区当前列的边界值,则换下一个分区进行比较。 START END语法格式 对于从句是START END语法格式,范围分区策略的分区键最多支持1列。 示例如下: -- 创建表空间gaussdb=# CREATE TABLESPACE startend_tbs1 LOCATION '/home/omm/startend_tbs1';gaussdb=# CREATE TABLESPACE startend_tbs2 LOCATION '/home/omm/startend_tbs2';gaussdb=# CREATE TABLESPACE startend_tbs3 LOCATION '/home/omm/startend_tbs3';gaussdb=# CREATE TABLESPACE startend_tbs4 LOCATION '/home/omm/startend_tbs4';-- 创建临时schemagaussdb=# CREATE SCHEMA tpcds;gaussdb=# SET CURRENT_SCHEMA TO tpcds;-- 创建分区表,分区键是integer类型gaussdb=# CREATE TABLE tpcds.startend_pt (c1 INT, c2 INT)TABLESPACE startend_tbs1PARTITION BY RANGE (c2) ( PARTITION p1 START(1) END(1000) EVERY(200) TABLESPACE startend_tbs2, PARTITION p2 END(2000), PARTITION p3 START(2000) END(2500) TABLESPACE startend_tbs3, PARTITION p4 START(2500), PARTITION p5 START(3000) END(5000) EVERY(1000) TABLESPACE startend_tbs4)ENABLE ROW MOVEMENT;-- 查看分区表信息gaussdb=# SELECT relname, boundaries, spcname FROM pg_partition p JOIN pg_tablespace t ON p.reltablespace=t.oid and p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; relname | boundaries | spcname-------------+------------+--------------- p1_0 | {1} | startend_tbs2 p1_1 | {201} | startend_tbs2 p1_2 | {401} | startend_tbs2 p1_3 | {601} | startend_tbs2 p1_4 | {801} | startend_tbs2 p1_5 | {1000} | startend_tbs2 p2 | {2000} | startend_tbs1 p3 | {2500} | startend_tbs3 p4 | {3000} | startend_tbs1 p5_1 | {4000} | startend_tbs4 p5_2 | {5000} | startend_tbs4 startend_pt | | startend_tbs1(12 rows)--清理示例gaussdb=# DROP TABLE tpcds.startend_pt;DROP TABLEgaussdb=# DROP SCHEMA tpcds;DROP SCHEMA 父主题: 分区策略
  • 常用视图工具 视图类型 类型 功能描述 使用场景 函数名称 解析 全类型 用于解析指定表页面,并返回存放解析内容的路径。 查看页面信息。 查看元组(非用户数据)信息。 页面或者元组损坏。 元组可见性问题。 校验报错问题。 gs_parse_page_bypath 索引回收队列(URQ) 用于解析UB-tree索引回收队列关键信息。 UB-tree索引空间膨胀。 UB-tree索引空间回收异常。 校验报错问题。 gs_urq_dump_stat 回滚段(Undo) 用于解析指定Undo Record的内容,不包含旧版本元组的数据。 undo空间膨胀。 undo回收异常。 回滚异常。 日常巡检。 校验报错。 可见性判断异常。 修改参数。 gs_undo_dump_record 用于解析指定事务生成的所有Undo Record,不包含旧版本元组的数据。 gs_undo_dump_xid 用于解析指定UndoZone中所有Transaction Slot信息。 gs_undo_translot_dump_slot 用于解析指定事务对应Transaction Slot信息,包括事务XID和该事务生成的Undo Record范围. gs_undo_translot_dump_xid 用于解析指定Undo Zone的元信息,显示Undo Record和Transaction Slot指针使用情况。 gs_undo_meta_dump_zone 用于解析指定Undo Zone对应Undo Space的元信息,显示Undo Record文件使用情况。 gs_undo_meta_dump_spaces 用于解析指定Undo Zone对应Slot Space的元信息,显示Transaction Slot文件使用情况。 gs_undo_meta_dump_slot 用于解析数据页和数据页上数据的所有历史版本,并返回存放解析内容的路径。 gs_undo_dump_parsepage_mv 预写日志 (WAL) 用于解析指定LSN范围之内的X LOG 日志,并返回存放解析内容的路径。可以通过pg_current_xlog_location()获取当前XLOG位置。 WAL日志出错。 日志回放出错。 页面损坏。 gs_xlogdump_lsn 用于解析指定XID的XLOG日志,并返回存放解析内容的路径。可以通过txid_current()获取当前事务ID。 gs_xlogdump_xid 用于解析指定表页面对应的日志,并返回存放解析内容的路径。 gs_xlogdump_tablepath 用于解析指定表页面和表页面对应的日志,并返回存放解析内容的路径。可以看做一次执行gs_parse_page_bypath和gs_xlogdump_tablepath。该函数执行的前置条件是表文件存在。如果想查看已删除的表的相关日志,请直接调用gs_xlogdump_tablepath。 gs_xlogdump_parsepage_tablepath 统计 回滚段(Undo) 用于显示Undo模块的统计信息,包括Undo Zone使用情况、Undo链使用情况、Undo模块文件创建删除情况和Undo模块参数设置推荐值。 Undo空间膨胀。 Undo资源监控。 gs_stat_undo 预写日志 (WAL) 用于统计预写日志(WAL)写盘时的内存状态表内容。 WAL写/刷盘监控。 WAL写/刷盘hang住。 gs_stat_wal_entrytable 用于统计预写日志(WAL)刷盘状态、位置统计信息。 gs_walwriter_flush_position 用于统计预写日志(WAL)写刷盘次数频率、数据量以及刷盘文件统计信息。 gs_walwriter_flush_stat 校验 堆表/索引 用于离线校验表或者索引文件磁盘页面数据是否异常。 页面损坏或者元组损坏。 可见性问题。 日志回放出错问题。 ANALYZE VERIFY 用于校验当前实例当前库物理文件是否存在丢失。 文件丢失。 gs_verify_data_file 索引回收队列(URQ) 用于校验UB-tree索引回收队列(潜在队列/可用队列/单页面)数据是否异常。 UB-tree索引空间膨胀。 UB-tree索引空间回收异常。 gs_verify_urq 回滚段(Undo) 用于离线校验Undo Record数据是否存在异常。 Undo Record异常或者损坏。 可见性问题。 回滚出错或者异常。 gs_verify_undo_record 用于离线校验Transaction Slot数据是否存在异常。 Undo Record异常或者损坏。 可见性问题。 回滚出错或者异常。 gs_verify_undo_slot 用于离线校验Undo元信息数据是否存在异常。 因Undo meta引起的节点无法启动问题。 Undo空间回收异常。 Snapshot too old问题。 gs_verify_undo_meta 修复 堆表/索引/Undo文件 用于基于备机修复主机丢失的物理文件。 堆表/索引/Undo文件丢失。 gs_repair_file 堆表/索引/Undo页面 用于校验并基于备机修复主机受损页面。 堆表/索引/Undo页面损坏。 gs_verify_and_tryrepair_page 用于基于备机页面直接修复主机页面。 gs_repair_page 用于基于偏移量对页面的备份进行字节修改。 gs_edit_page_bypath 用于将修改后的页面覆盖写入到目标页面。 gs_repair_page_bypath 回滚段(Undo) 用于重建Undo元信息,如果校验发现Undo元信息没有问题则不重建。 Undo元信息异常或者损坏。 gs_repair_undo_byzone 索引回收队列(URQ) 用于重建UB-tree索引回收队列。 索引回收队列异常或者损坏。 gs_repair_urq 父主题: Ustore存储引擎
  • 怎么配置回滚段大小 一般情况下回滚段大小的参数使用默认值即可。为了达到最佳性能,部分场景下可调整回滚段大小的相关参数,具体场景与设置方法如下。 保留给定时间内的历史版本数据。 当使用闪回或者支撑问题定位时,通常希望保留更多历史版本数据,此时需要修改undo_retention_time。undo_retention_time默认值是0,取值范围为 0~3天。 调整的推荐值为900s,需要注意的是,undo_retention_time的取值越大,对业务的影响除了Undo空间占用增多,也会造成数据空间膨胀,进一步影响数据扫描更新性能。当不使用闪回或者希望减少历史旧版本的磁盘空间占用时,需要将undo_retention_time调小来达到最佳性能。可以通过如下方法选择更适合自己业务模型的取值。 查询guc参数undo_space_limit_size,查询视图gs_stat_undo,获取近期undo空间平均增长速度avg_space_increse_speed与当前undo占用空间curr_used_undo_size,计算undo_retention_time的建议值new_val = 0.5 * (undo_space_limit_size * 0.8 - curr_used_undo_size) / avg_space_increse_speed。 保留给定空间大小的历史版本数据。 如果业务中存在长事务或大事务可能导致Undo空间膨胀时,需要将undo_space_limit_size调大,undo_space_limit_size默认值为256GB,取值范围为800MB~16TB。 在磁盘空间允许的条件下,推荐undo_space_limit_size设置翻倍。同时undo_space_limit_size的取值越大则占用磁盘空间越大,可能降低性能。如果查询gs_stat_undo()的curr_used_undo_size发现不存在Undo空间膨胀,可以恢复为原值。 调整undo_space_limit_size后可相应提高单事务平均占用undo空间undo_limit_size_per_transaction的取值,undo_limit_size_per_transaction取值范围为2MB~16TB,默认值为32GB。设置时建议undo_limit_size_per_transaction不超过undo_space_limit_size,即单事务Undo分配空间阈值不大于Undo总空间阈值。 为了更准确设置该参数来达到最佳性能,建议采用如下方式进行计算。 undo_space_limit_size:查询视图gs_stat_undo,获取近期undo空间平均增长速度avg_space_increse_speed和curr_used_undo_size,计算undo_space_limit_size的建议值new_val = 86400 * 30 * avg_space_increse_speed + curr_used_undo_size。 undo_limit_size_per_transaction:查询gs_stat_undo(),获取单事务最大占用undo空间max_xact_space(503.2版本中扩展该列),建议该参数调整后不小于new_val = 10 * max_xact_space。 历史版本的保留参数的调整优先级。 在undo_retention_time、undo_space_limit_size、undo_limit_size_per_transaction中,先触发的空间阈值会先进行约束限制。 例如:Undo强制回收阈值参数undo_space_limit_size设置为1GB,Undo旧版本保留时间undo_retention_time为900s,如果900s内产生的历史版本数据不足1GB*0.8,则按照900s进行回收限制;否则按照1GB*0.8进行回收限制。遇到该情况时,如果磁盘空闲空间充足,则上调undo_space_limit_size,如果磁盘空闲空间紧缺,则下调undo_retention_time。 父主题: Ustore的最佳实践
  • 使用Ustore的优势 最新版本和历史版本分离存储,相比Astore扫描范围小。去除Astore的HOT chain,非索引列/索引列更新,Heap均可原位更新,ROWID可保持不变。历史版本可批量回收,对最新版本空间膨胀友好。 大并发更新同一行的场景,Ustore的原位更新机制保证了元组ROWID稳定,先到先得,更新时延相对稳定。 不依赖Vacuum进行旧版本清理。Index与Heap解耦,可独立清理,IO平稳度较好。 支持闪回功能。 不过,Ustore DML除修改数据页面,同时也需要修改Undo,更新操作开销会稍大一些。此外单条Tuple扫描开销由于需要复制(Astore返回指针)也会大一些。
  • 对二级分区表移动二级分区 使用ALTER TABLE MOVE SUBPARTITION可以对二级分区表移动二级分区。 例如,通过指定分区名将二级分区表range_list_sales的分区date_202001_channel1移动到表空间tb1中。 ALTER TABLE range_list_sales MOVE SUBPARTITION date_202001_channel1 TABLESPACE tb1; 或者,通过指定分区值将二级分区表range_list_sales中('2020-01-08', '0')所对应的分区移动到表空间tb1中。 ALTER TABLE range_list_sales MOVE SUBPARTITION FOR ('2020-01-08', '0') TABLESPACE tb1; 父主题: 移动分区
  • 对间隔分区表分割分区 对间隔分区表分割分区的命令与范围分区表相同。 对间隔分区表的间隔分区完成分割分区操作之后,源分区之前的间隔分区会变成范围分区。 例如,创建如下间隔分区表,并插入数据新增三个分区sys_p1、sys_p2、sys_p3。 CREATE TABLE interval_sales( prod_id NUMBER(6), cust_id NUMBER, time_id DATE, channel_id CHAR(1), promo_id NUMBER(6), quantity_sold NUMBER(3), amount_sold NUMBER(10, 2))PARTITION BY RANGE (TIME_ID) INTERVAL ('1 MONTH')( PARTITION date_2015 VALUES LESS THAN ('2016-01-01'), PARTITION date_2016 VALUES LESS THAN ('2017-01-01'), PARTITION date_2017 VALUES LESS THAN ('2018-01-01'), PARTITION date_2018 VALUES LESS THAN ('2019-01-01'), PARTITION date_2019 VALUES LESS THAN ('2020-01-01'));INSERT INTO interval_sales VALUES (263722,42819872,'2020-07-09','E',432072,213,17); --新增分区sys_p1INSERT INTO interval_sales VALUES (345724,72651233,'2021-03-05','A',352451,146,9); --新增分区sys_p2INSERT INTO interval_sales VALUES (153241,65143129,'2021-05-07','H',864134,89,34); --新增分区sys_p3 如果对分区sys_p2进行分割,则会将分区sys_p1变为范围分区,分区范围下界值从依赖间隔分区值变成依赖前一个分区的上界值,也就是分区范围从['2020-07-01', '2020-08-01')变成['2020-01-01', '2020-08-01');分区sys_p3依然为间隔分区,其分区范围为['2021-05-01', '2021-06-01')。 父主题: 分割分区
  • 对二级分区表重命名二级分区 使用ALTER TABLE RENAME SUBPARTITION可以对二级分区表重命名二级分区。 例如,通过指定分区名将二级分区表range_list_sales的分区date_202001_channel1重命名。 ALTER TABLE range_list_sales RENAME SUBPARTITION date_202001_channel1 TO date_202001_channelnew; 或者,通过指定分区值将二级分区表range_list_sales中('2020-01-08', '0')所对应的分区重命名。 ALTER TABLE range_list_sales RENAME SUBPARTITION FOR ('2020-01-08', '0') TO date_202001_channelnew; 父主题: 重命名分区
  • 存储规格 数据表最大列数不能超过1600列。 Ustore表(不含toast情况)最大Tuple长度不能超过(8192 - MAXALIGN(56 + init_td * 26 + 4)), 其中MAXALIGN表示8字节对齐。当插入数据长度超过阈值时,用户会收到元组长度过长无法插入的报错。其中init_td对于Tuple长度的影响如下: 表init_td数量为最小值2时,Tuple长度不能超过8192 - MAXALIGN(56+2*26+4) = 8080B。 表init_td数量为默认值4时,Tuple长度不能超过8192 - MAXALIGN(56+4*26+4) = 8024B。 表init_td数量为最大值128时,Tuple长度不能超过8192 - MAXALIGN(56+128*26+4) = 4800B。 init_td取值范围[2, 128],默认值4。单页面支持的最大并发不超过128个。 索引最大列数不能超过32列。全局分区索引最大列数不能超过31列。 索引元组长度不能超过(8192 - MAXALIGN(28 + 3 * 4 + 3 * 10) - MAXALIGN(42))/3, 其中MAXALIGN表示8字节对齐。当插入数据长度超过阈值时,用户会收到索引元组长度过长无法插入的报错,其中索引页头为28B,行指针为4B,元组CTID+INFO标记位为10B,页尾为42B。 回滚段容量最大支持16TB。 父主题: Ustore特性与规格
  • 使用Ustore进行测试 创建Ustore表 使用CREATE TABLE语句创建Ustore表。 gaussdb=# CREATE TABLE ustore_table(a INT PRIMARY KEY, b CHAR (20)) WITH (STORAGE_TYPE=USTORE);NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "ustore_table_pkey" for table "ustore_table"CREATE TABLEgaussdb=# \d+ ustore_tableTable "public.ustore_table"Column | Type | Modifiers | Storage | Stats target | Description--------+---------------+-----------+----------+--------------+-------------a | integer | not null | plain | |b | character(20) | | extended | |Indexes:"ustore_table_pkey" PRIMARY KEY, ubtree (a) WITH (storage_type=USTORE) TABLESPACE pg_defaultHas OIDs: noOptions: orientation=row, storage_type=ustore, compression=no 为Ustore表创建索引 Ustore当前仅支持B-tree类型的多版本索引,在一些场景中,为了区别于Astore的B-tree索引,也会将Ustore表的多版本B-tree索引称为UB-tree(Ustore B-tree,UB-tree介绍详见Index章节)。用户可以参照以下方式使用CREATE INDEX语句为Ustore表的 “a” 属性创建一个UB-tree索引。 Ustore表不指定创建索引类型,默认创建的是UB-tree索引: gaussdb=# CREATE INDEX UB-tree_index ON ustore_table(a);CREATE INDEXgaussdb=# \d+ ustore_tableTable "public.ustore_table"Column | Type | Modifiers | Storage | Stats target | Description--------+---------------+-----------+----------+--------------+-------------a | integer | not null | plain | |b | character(20) | | extended | |Indexes:"ustore_table_pkey" PRIMARY KEY, ubtree (a) WITH (storage_type=USTORE) TABLESPACE pg_default"ubtree_index" ubtree (a) WITH (storage_type=USTORE) TABLESPACE pg_defaultHas OIDs: noOptions: orientation=row, storage_type=ustore, compression=no 父主题: Ustore简介
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全