华为云用户手册

  • hll_add_agg(hll_hashval, int32 log2m, int32 log2explicit, int64 log2sparse) 描述:把哈希后的数据按照分组放到hll中, 依次指定参数log2m、log2explicit、log2sparse。log2sparse取值范围是0到14,0表示直接跳过Sparse模式。该参数可以用来设置Sparse模式的阈值大小,在数据段长度达到2log2sparse后切换为Full模式。若输入-1或者NULL,则log2sparse采用内置默认值。 返回值类型:hll 示例: 1 2 3 4 5 gaussdb=# SELECT hll_cardinality(hll_add_agg(hll_hash_text(c), NULL, 6, 10)) FROM t_data; hll_cardinality ------------------ 498.496062953313 (1 row)
  • hll_add_agg(hll_hashval, int32 log2m) 描述:把哈希后的数据按照分组放到hll中, 并指定参数log2m,取值范围是10到16。若输入-1或者NULL,则采用内置默认值。 返回值类型:hll 示例: 1 2 3 4 5 gaussdb=# SELECT hll_cardinality(hll_add_agg(hll_hash_text(c), 12)) FROM t_data; hll_cardinality ------------------ 497.965240179228 (1 row)
  • hll_add_agg(hll_hashval, int32 log2m, int32 log2explicit, int64 log2sparse, int32 duplicatecheck) 描述:把哈希后的数据按照分组放到hll中, 依次指定参数log2m、log2explicit、log2sparse、duplicatecheck,duplicatecheck取值范围是0或者1,表示是否开启该模式,默认情况下该模式会关闭。若输入-1或者NULL,则duplicatecheck采用内置默认值。 返回值类型:hll 示例: 1 2 3 4 5 gaussdb=# SELECT hll_cardinality(hll_add_agg(hll_hash_text(c), NULL, 6, 10, -1)) FROM t_data; hll_cardinality ------------------ 498.496062953313 (1 row)
  • hll_union_agg(hll) 描述:将多个hll类型数据union成一个hll。 返回值类型:hll 示例: 1 2 3 4 5 6 7 8 9 10 11 --将各组中的hll数据union成一个hll,并计算distinct值。 gaussdb=# SELECT #hll_union_agg(c) AS cardinality FROM t_a_c_hll; cardinality ------------------ 498.496062953313 (1 row) --删除表 gaussdb=# DROP TABLE t_id; gaussdb=# DROP TABLE t_data; gaussdb=# DROP TABLE t_a_c_hll; 注意:当两个或者多个hll数据结构做union的时候,必须要保证其中每一个hll里面的精度参数一样,否则将不可以进行union。同样的约束也适用于函数hll_union(hll,hll)。
  • hll_add_agg(hll_hashval, int32 log2m, int32 log2explicit) 描述:把哈希后的数据按照分组放到hll中,依次指定参数log2m、log2explicit。 log2explicit取值范围是0到12,0表示直接跳过Explicit模式。该参数可以用来设置Explicit模式的阈值大小,在数据段长度达到2log2explicit后切换为Sparse模式或者Full模式。若输入-1或者NULL,则log2explicit采用内置默认值。 返回值类型:hll 示例: 1 2 3 4 5 gaussdb=# SELECT hll_cardinality(hll_add_agg(hll_hash_text(c), NULL, 1)) FROM t_data; hll_cardinality ------------------ 498.496062953313 (1 row)
  • hll_add_agg(hll_hashval) 描述:把哈希后的数据按照分组放到hll中。 返回值类型:hll 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 --准备数据 gaussdb=# CREATE TABLE t_id(id int); gaussdb=# INSERT INTO t_id VALUES(generate_series(1,500)); gaussdb=# CREATE TABLE t_data(a int, c text); gaussdb=# INSERT INTO t_data SELECT mod(id,2), id FROM t_id; --创建表并指定列为hll gaussdb=# CREATE TABLE t_a_c_hll(a int, c hll); --根据a列group by对数据分组,把各组数据加到hll中 gaussdb=# INSERT INTO t_a_c_hll SELECT a, hll_add_agg(hll_hash_text(c)) FROM t_data GROUP BY a; --得到每组数据中hll的Distinct值 gaussdb=# SELECT a, #c AS cardinality FROM t_a_c_hll ORDER BY a; a | cardinality ---+------------------ 0 | 247.862354346299 1 | 250.908710610377 (2 rows)
  • date_part('field', source) 描述:date_part函数基于传统的Ingres函数实现(该函数等效于SQL标准函数extract)。 参数:field参数是一个字符串,而不是一个名称。有效的field与extract一致,详细信息请参见EXTRACT。 示例: 1 2 3 4 5 gaussdb=# SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 16 (1 row) 1 2 3 4 5 gaussdb=# SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_part ----------- 4 (1 row) 表1 用于日期/时间格式化的格式显示了可以用于格式化日期和时间值的格式。 表1 用于日期/时间格式化的格式 类别 格式 描述 小时 HH 一天的小时数(01-12) HH12 一天的小时数(01-12) HH24 一天的小时数(00-23) 分钟 MI 分钟(00-59) 秒 SS 秒(00-59) FF 微秒(000000-999999) FF1 微秒(0-9) FF2 微秒(00-99) FF3 微秒(000-999) FF4 微秒(0000-9999) FF5 微秒(00000-99999) FF6 微秒(000000-999999) SSSSS 午夜后的秒(0-86399) 上、下午 AM或A.M. 上午标识 PM或P.M. 下午标识 年 Y,YYY 带逗号的年(4和更多位) SYYYY 公元前四位年 YYYY 年(4和更多位) YYY 年的后三位 YY 年的后两位 Y 年的最后一位 IYYY ISO年(4位或更多位) IYY ISO年的最后三位 IY ISO年的最后两位 I ISO年的最后一位 RR 年的后两位(可在21世纪存储20世纪的年份) RRRR 可接收4位年或两位年。若是两位,则和RR的返回值相同,若是四位,则和YYYY相同。 BC或B.C. AD或A.D. 纪元标识。BC(公元前),AD(公元后)。 月 MONTH 全长大写月份名(空白填充为9字符) MON 大写缩写月份名(3字符) MM 月份数(01-12) RM 罗马数字的月份(I-XII ;I=JAN)(大写) 天 DAY 全长大写日期名(空白填充为9字符) DY 缩写大写日期名(3字符) DDD 一年里的日(001-366) DD 一个月里的日(01-31) D 一周里的日(1-7 ;周日是 1) 周 W 一个月里的周数(1-5)(第一周从该月第一天开始) WW 一年里的周数(1-53)(第一周从该年的第一天开始) IW ISO一年里的周数(第一个星期四在第一周里) 世纪 CC 世纪(2位)(21 世纪从 2001-01-01 开始) 儒略日 J 儒略日(自公元前 4712 年 1 月 1 日来的天数) 季度 Q 季度 在ORA兼容模式数据库中且参数a_format_version值为10c和a_format_dev_version值为s1的情况下新增用于格式化日期和时间值的模式: 表2 新增用于格式化日期和时间值的模式 类别 模式 描述 世纪 SCC 世纪标识,公元前会显示- 年 SYYYY 返回数字型年,公元前会显示- RR 返回日期的2位年份 RRRR 返回日期的4位年份 YEAR 返回字符型年 SYEAR 返回字符型年,公元前会显示- 日期格式 DL 返回指定长日期形式 DS 返回指定短日期 TS 返回指定时间格式 秒 FF7 微秒(0000000-9999990) FF8 微秒(00000000-99999900) FF9 微秒(000000000-999999000) 上表中RR计算年的规则如下: 输入的两位年份在00~49之间: 当前年份的后两位在00~49之间,返回值年份的前两位和当前年份的前两位相同。 当前年份的后两位在50~99之间,返回值年份的前两位是当前年份的前两位加1。 输入的两位年份在50~99之间: 当前年份的后两位在00~49之间,返回值年份的前两位是当前年份的前两位减1。 当前年份的后两位在50~99之间,返回值年份的前两位和当前年份的前两位相同。 此函数在ORA兼容模式数据库中且参数a_format_version值为10c和a_format_dev_version值为s1的情况下: to_date, to_timestamp函数支持FX模式(输入和模式严格对应),支持X模式(小数点)。 输入模式不能出现超过一次,表示相同信息的模式不能同时出现。如SYYYY和BC不能同时出现。 模式大小写不敏感。 建议输入和模式之间使用分隔符,否则不保证行为与O完全一致。
  • DQL/DML-DDL同分区并发 GaussDB 不支持同分区的DQL/DML-DDL并发,后触发业务会被先触发业务阻塞。 原则上,不建议用户在进行分区DDL时,同时对该分区进行DQL/DML操作,因为目标分区存在一个状态的突变过程,可能会导致业务的查询结果不符合预期。 如果由于业务模型不合理、无法剪枝等场景导致的DQL/DML和DDL作用分区有重叠时,考虑两种场景: 场景一:先触发DQL/DML,再触发DDL。DDL会被阻塞,等DQL/DML提交后再进行。 场景二:先触发DDL,再触发DQL/DML。DQL/DML会被阻塞,等DDL提交后再进行,由于分区元信息发生了变更,可能导致预期不合理。为了保证数据一致性,预期结果按照如下规则制定。 ADD分区 ADD分区会产生一个新的分区,这个新分区对期间触发的DQL/DML操作均是不可见的,无阻塞期。 DROP分区 DROP分区会将已有分区进行删除,期间触发的目标分区DQL/DML操作会被阻塞,阻塞完成后跳过对该分区的处理。 TRUNCATE分区 TRUNCATE分区会将已有分区清空数据,期间触发的目标分区DQL/DML操作会被阻塞,阻塞完成后继续对该分区进行处理。 注意期间触发的目标分区查询是查不到数据的,因为TRUNCATE操作提交后目标分区中不存有任何数据。 EXCHANGE分区 EXCHANGE分区会将一个已有分区与普通表进行交换,期间触发的目标分区DQL/DML操作会被阻塞,阻塞完成后继续对该分区进行处理,该分区的实际数据对应原普通表。 例外:如果分区表上存在GLOBAL索引,EXCHANGE命令带来UPDATE GLOBAL INDEX子句,且期间触发的分区表查询使用了GLOBAL索引,由于无法查询到交换后分区上的数据,在阻塞完成后查询业务会报错。 ERROR: partition xxxxxx does not exist on relation "xxxxxx" DETAIL: this partition may have already been dropped by cocurrent DDL operations EXCHANGE PARTITION SPLIT分区 SPLIT分区当前会阻塞全表的DQL/DML操作,当然也包括目标分区本身。SPLIT提交后,DQL/DML操作会基于SPLIT完成后的分区表结构进行。 MERGE分区 MERGE分区当前会阻塞全表的DQL/DML操作,当然也包括目标分区本身。MERGE提交后,DQL/DML操作会基于MERGE完成后的分区表结构进行。 RENAME分区 RENAME分区不会变更分区结构信息,期间触发的DQL/DML操作不会出现任何异常,但会被阻塞,直到RENAME操作提交。 MOVE分区 MOVE分区不会变更分区结构信息,期间触发的DQL/DML操作不会出现任何异常,但会被阻塞,直到MOVE操作提交。 在DQL/DML业务期间,如果对执行DQL/DML操作的分区,连续同时做多次分区DDL操作,有低概率出现报错,报错原因:分区找不到,分区已经被DDL删除。 DQL/DML-DDL同分区并发有低概率出现业务死锁或者锁超时。原因:部分DQL/DML操作只在DN施加分区锁,若和DDL在不同DN的加锁顺序不一致则有概率导致死锁/锁超时。为了避免死锁情况,可以设置GUC参数enable_partition_ddl_lowlevel_lock为off,但是会存在性能影响。
  • 常规锁设计 分区表通过表锁+分区锁两重设计,在表和分区上分别施加8个不同级别的常规锁,来保证DQL、DML、DDL并发过程中的合理行为控制。下表给出了不同级别锁的相容行为,标记为√的两种常规锁互不阻塞,可以并行。 表1 常规锁相容行为 - AC CES S_SHARE ROW_SHARE ROW_EXCLUSIVE SHARE_UPDATE_EXCLUSIVE SHARE SHARE_ROW_EXCLUSIVE EXCLUSIVE ACCESS_EXCLUSIVE ACCESS_SHARE √ √ √ √ √ √ √ × ROW_SHARE √ √ √ √ √ √ × × ROW_EXCLUSIVE √ √ √ √ × × × × SHARE_UPDATE_EXCLUSIVE √ √ √ × × × × × SHARE √ √ × × √ × × × SHARE_ROW_EXCLUSIVE √ √ × × × × × × EXCLUSIVE √ × × × × × × × ACCESS_EXCLUSIVE × × × × × × × × 分区表的不同业务最终都是作用于目标分区上,数据库会给分区表和目标分区施加不同级别的表锁+分区锁,来控制并发行为。表2给出了不同业务的锁粒度控制。其中数字1~8分别代表表1给出的ACCESS_SHARE、ROW_SHARE、ROW_EXCLUSIVE、SHARE_UPDATE_EXCLUSIVE、SHARE、SHARE_ROW_EXCLUSIVE、EXCLUSIVE、ACCESS_EXCLUSIVE这8种级别的常规锁。 表2 分区表业务锁粒度 业务模型 分区表锁级别(表锁+分区锁) SELECT 1-1 SELECT FOR UPDATE 2-2 DML业务,包括INSERT、UPDATE、DELETE、UPSERT、MERGE INTO、COPY 3-3 大部分分区DDL,包括ADD、DROP、EXCHANGE、TRUNCATE、MOVE、RENAME 4-8 CREATE INDEX(非分类索引)、REBUILD INDEX 5-5 CREATE INDEX(分类索引) 3-5 REBUILD INDEX PARTITION 1-5 ANALYZE、VACUUM 4-4 其他分区表DDL,包括SPLIT/MERGE这两种分区DDL 8-8 如果业务执行施加的表锁和分区锁均满足表1,则可以支持业务并行操作,如果表锁和分区锁有任一不相容,则二者不支持业务并行。 DDL (ADD/DROP/TRUNCATE/EXCHANGE/MOVE/RENAME) 操作对分区表施加的表锁级别受GUC参数enable_partition_ddl_lowlevel_lock控制,当GUC参数enable_partition_ddl_lowlevel_lock设置为on时,对表施加4级锁;当GUC参数enable_partition_ddl_lowlevel_lock设置为off时,对表施加8级锁。 父主题: 分区并发控制
  • 查看动态数据脱敏基本配置 设置并查看动态数据脱敏功能是否已开启。 gs_guc reload -Z coordinator -N all -I all -c "enable_security_policy=on" enable_security_policy取值为on时表示开启,取值为off时表示关闭。 gaussdb=# SHOW enable_security_policy; enable_security_policy ----------------------- on (1 row)
  • 使用规格 SMP场景下的Full Partition-wise Join的使用规格: 支持一级HASH分区表和一级RANGE分区表。 Hash分区表的分区策略完全相同是指分区键类型相同、分区数相同。 Range分区表的分区策略完全相同是指分区键类型相同、分区数相同、分区键数量相同、每个分区的边界值相同。 仅支持Stream计划。 仅支持分区键和分布键完全一致的场景。 仅支持Join算子在单DN内完成计算,即Join算子的数据不跨节点。 支持Hash Join和Merge Join。 支持Seqscan、Indexscan、Indexonlyscan、Imcvscan。其中,对于Indexscan和Indexonlyscan,只支持分区Local索引,且索引类型为BTREE或UBTREE。 相关规格继承SMP规格,不支持SMP场景下的IUD操作。 需要开启SMP功能,且设置query_dop的值大于1。
  • 使用规格 非SMP场景下的Partition-wise Join的使用规格: 只支持一级RANGE分区。 支持Hash Join、Nestloop Join、Merge Join。 只支持Inner Join。 需要设置query_dop的值为1。 由于非SMP场景下的Partition-wise Join为规则选择,所以Partition-wise Join计划可能造成性能下降,需要用户自行决定是否启用。 仅支持FQS计划。
  • Partition-wise Join Partition-wise Join是一种分区级并行的优化技术,是指在符合一定条件的情况下,将两张表之间的Join,分解为两张表中对应的两个分区之间的Join。通过并发执行、减少数据通信量等方式,提升分区表的Join查询的性能。 Partition-wise Join分为SMP场景和非SMP场景。 非SMP场景下的Partition-wise Join SMP场景下的Full Partition-wise Join 父主题: 分区表查询优化
  • 约束 解析的WAL日志级别为logical。 数据表的复制标识必须为FULL,否则UPDATE和DELETE操作涉及到的被修改行不是全字段。 WAL日志记录的数据修改操作所对应的业务表,从找回起始位置到目前不能执行VACUUM FULL操作,否则该表VACUUM FULL之前的DML操作不会被数据找回。 每条WAL日志不能超过500MB。 不支持扩容前的Xlog日志数据找回。 集群的每个分片都会生成一个结果文件,多个文件不会进行合并。 仅支持归档数据找回,且需要开启归档,若数据尚未归档,则无法通过本接口找回。 OM_Agent在下载之前会验证本地已用空间是否大于总空间的80%,如果大于则会会报错(需要额外空间用于存放解码文件),报错信息为:"no enough space left on device, available space must be greater than 20%"。 下载失败或解码失败后,都会将下载的WAL日志文件进行清理,如果清理不成功,不会强制结束程序,只会把错误信息记录到DN的日志中。 由用户传入的时间,起始时间不能超出系统表gs_txn_lsn_time的最大时间,终止时间不能超过系统表gs_txn_lsn_time的最小时间,否则将会报错。 不支持同一节点并发调用数据找回接口。 如果进行了节点替换,不支持节点替换前的数据找回。 只支持直连DN方式的数据找回。 旧版本升级提交到新版本时,如果未基线化,则需要执行基线化后才可以使用数据找回功能,且只支持对基线化后新产生的Xlog日志进行数据找回,升级前产生的Xlog日志无法解析。 默认支持1年内的数据找回,超过1年的数据将被自动清除。如需找回超过1年的数据,需在清理前调整GUC参数logical_replication_dictionary_retention_time的值。
  • 使用步骤 逻辑解码特性需提前设置GUC参数wal_level为logical,该参数需要重启生效。 gs_guc set -Z datanode -D $node_dir -c "wal_level = logical" 其中,$node_dir为数据库节点路径,用户可根据实际情况替换。 以具有REPLICATION权限的用户登录 GaussDB数据库 主节点,使用如下命令连接数据库。 gsql -U user1 -W password -d db1 -p 16000 -r 其中,user1为用户名,password为密码,db1为需要连接的数据库名称,16000为数据库端口号,用户可根据实际情况替换。 创建名称为slot1的逻辑复制槽。 1 2 3 4 5 gaussdb=# SELECT * FROM pg_create_logical_replication_slot('slot1', 'mppdb_decoding'); slotname | xlog_position ----------+--------------- slot1 | 0/3764C788 (1 row) 在数据库中创建Package。 1 2 3 4 5 6 gaussdb=# CREATE OR REPLACE PACKAGE ldp_pkg1 IS var1 int:=1; --公有变量 var2 int:=2; PROCEDURE testpro1(var3 int); --公有存储过程,可以被外部调用 END ldp_pkg1; / 读取复制槽slot1解码结果,可通过JDBC接口或者pg_logical_slot_peek_changes推进复制槽。 逻辑解码选项请参见逻辑解码选项和新增控制参数。 并行解码中,在JDBC接口中改变参数decode_style可以决定解码格式: 通过配置选项decode-style,指定解码格式。其取值为char型的字符'j'、't'或'b',分别代表JSON格式、TEXT格式及二进制格式。 1 2 3 4 5 6 7 gaussdb=# SELECT data FROM pg_logical_slot_peek_changes('slot1', NULL, NULL, 'enable-ddl-decoding', 'true', 'enable-ddl-json-format', 'false') WHERE data not like 'BEGIN%' AND data not like 'COMMIT%' AND data not like '%dbe_pldeveloper.gs_source%'; data -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"TDDL":"CREATE OR REPLACE PACKAGE public.ldp_pkg1 AUTHID CURRENT_USER IS var1 int:=1; --公有变量\n var2 int:=2;\n PROCEDURE testpro1(var3 int); --公有存储过程,可以被外部调用\nEND ldp_pkg1; \n /"} (1 row) 删除逻辑复制槽slot1,删除package ldp_pkg1。 1 2 3 4 5 6 7 8 9 gaussdb=# SELECT * FROM pg_drop_replication_slot('slot1'); pg_drop_replication_slot -------------------------- (1 row) gaussdb=# DROP PACKAGE ldp_pkg1; NOTICE: drop cascades to function public.testpro1(integer) DROP PACKAGE
  • 解码格式 JSON格式 对于输入的DDL语句,SQL引擎解析器会通过语法、词法分析将其分解为解析树,解析树节点中包含了DDL的全部信息,并且执行器会根据解析树内容,执行系统元信息的修改。在执行器执行完成之后,便可以获取到DDL操作数据对象的search_path。本特性在执行器执行成功之后,对解析树信息以及执行器结果进行反解析,以还原出DDL原语句的全部信息。反解析的方式可以分解整个DDL语句,以方便输出JSON格式的DDL,用以适配异构数据库场景。 CREATE TABLE语句在经过词法、语法分析之后,得到对应的CreateStmt解析树节点,节点中包含了表信息、列信息、分布式信息(DistributeBy结构体)、分区信息(PartitionState结构)等。通过反解析后,可输出的JSON格式如下: {"JDDL":{"fmt":"CREATE %{persistence}s TABLE %{if_not_exists}s %{identity}D %{table_elements}s %{with_clause}s %{compression}s","identity":{"object_name":"test_create_table_a","schema_name":"public"},"compression":"NOCOMPRESS","persistence":"","with_clause":{"fmt":"WITH (%{with:, }s)","with":[{"fmt":"%{label}s = %{value}L","label":{"fmt":"%{label}I","label":"orientation"},"value":"row"},{"fmt":"%{label}s = %{value}L","label":{"fmt":"%{label}I","label":"compression"},"value":"no"}]},"if_not_exists":"","table_elements":{"fmt":"(%{elements:, }s)","elements":[{"fmt":"%{name}I %{column_type}T","name":"a","column_type":{"typmod":"","typarray":false,"type_name":"int4","schema_name":"pg_catalog"}}]}}} 可以看到,JSON格式中包含对象的search_path,其中的identity键标识schema为public,表名为test_create_table_a,其中%{persistence}s对应的字段如下,此SQL语句不含此字段所以为空。 [ [ GLOBAL | LOCAL ] [ TEMPORARY | TEMP ] | UN LOG GED ] %{if_not_exists}s对应SQL语句中的字段,不含此字段所以为空: [ IF NOT EXISTS ] %{identity}D对应SQL语句中的字段: table_name %{table_elements}s对应SQL语句中的字段: (column_name data_type) %{with_clause}s对应SQL语句中的字段: [ WITH ( {storage_parameter = value} [, ... ] ) ] %{compression}s对应SQL语句中的字段: [ COMPRESS | NOCOMPRESS ] decode-style指定格式 输出的格式由decode-style参数控制,如当decode-style='j'时,输出格式如下: {"TDDL":"CREATE TABLE public.test_create_table_a (a pg_catalog.int4) WITH (orientation = 'row', compression = 'no') NOCOMPRESS"} 其中语句中也包含Schema名称。
  • 接口设计 新增控制参数 新增逻辑解码控制参数,用于控制DDL的反解析流程以及输出形式。可通过JDBC接口或者pg_logical_slot_peek_changes开启。 enable-ddl-decoding:默认false,不开启DDL语句的逻辑解码;值为true时,开启DDL语句的逻辑解码。 enable-ddl-json-format:默认false,传送TEXT格式的DDL反解析结果;值为true时,传送JSON格式的DDL反解析结果。 新增GUC参数 enable_logical_replication_ddl:默认为ON,ON状态下,逻辑复制可支持DDL,否则,不支持DDL。只有当ON状态下,才会对DDL执行结果进行反解析,并生成DDL的WAL日志。否则,不反解析也不生成WAL日志。 enable_logical_replication_ddl的开关日志,以证明是否是用户修改了该参数导致逻辑解码不支持DDL。 新增日志 新增DDL日志xl_logical_ddl_message,其类型为RM_LOGICALDDLMSG_ID。其定义如下: 名称 类型 意义 db_id OID 数据库ID rel_id OID 表ID csn CommitSeqNo CS N快照 cid CommandId Command ID tag_type NodeTag DDL类型 message_size Size 日志内容长度 filter_message_size Size 日志中白名单过滤信息长度 message char * DDL内容
  • 功能描述 数据库在执行DML的时候,存储引擎会生成对应的DML日志,用于进行恢复,对这些DML日志进行解码,即可还原对应的DML语句,生成逻辑日志。而对于DDL语句,数据库并不记录DDL原语句的日志,而是记录DDL语句涉及的系统表的DML日志。DDL种类多样、语法复杂,逻辑复制要支持DDL语句,通过这些系统表的DML日志来解码原DDL语句是非常困难的。新增DDL日志记录原DDL信息,并在解码时通过DDL日志可以得到DDL原语句。 在DDL语句执行过程中,SQL引擎解析器会对原语句进行语法、词法解析,并生成解析树(不同的DDL语法会生成不同类型的解析树,解析树中包含DDL语句的全部信息)。随后,执行器通过这些信息执行对应操作,生成、修改对应元信息。 本节通过新增DDL日志的方式,来支持逻辑解码DDL,其内容由解析器结果(解析树)以及执行器结果生成,并在执行器执行完成后生成该日志。 从语法树反解析出DDL,DDL反解析能够将DDL命令转换为JSON格式的语句,并提供必要的信息在目标位置重建DDL命令。与原始DDL命令字符串相比,使用DDL反解析的好处包括: 解析出来的每个数据库对象都带有Schema,因此如果使用不同的search_path,也不会有歧义。 结构化的JSON和格式化的输出能支持异构数据库。如果用户使用的是不同的数据库版本,并且存在某些DDL语法差异,需要在应用之前解决这些差异。 反解析输出的结果是规范化后的形式,结果与用户输入等价,不保证完全相同,例如: 示例1:在函数体中没有单引号'时,函数体的分隔符$$会被解析为单引号'。 原始SQL语句: CREATE FUNCTION func(a INT) RETURNS INT AS $$ BEGIN a:= a+1; CREATE TABLE test(col1 INT); INSERT INTO test VALUES(1); DROP TABLE test; RETURN a; END; $$ LANGUAGE plpgsql; 反解析结果: CREATE FUNCTION public.func ( IN a pg_catalog.int4 ) RETURNS pg_catalog.int4 LANGUAGE plpgsql VOLATILE CALLED ON NULL INPUT SECURITY INVOKER COST 100 AS ' BEGIN a:= a+1; CREATE TABLE test(col1 INT); INSERT INTO test VALUES(1); DROP TABLE test; RETURN a; END; '; 示例3:“ALTER INDEX "Alter_Index_Index" REBUILD PARTITION "CA_ADDRESS_SK_index2"”会被反解析为“REINDEX INDEX public."Alter_Index_Index" PARTITION "CA_ADDRESS_SK_index2"”。 示例4:创建/修改范围分区表,START END语法格式均解码转化为LESS THAN语句: gaussdb=# CREATE TABLE test_create_table_partition2 (c1 INT, c2 INT) PARTITION BY RANGE (c2) ( PARTITION p1 START(1) END(1000) EVERY(200) , PARTITION p2 END(2000), PARTITION p3 START(2000) END(2500), PARTITION p4 START(2500), PARTITION p5 START(3000) END(5000) EVERY(1000) ); 会被反解析为: gaussdb=# CREATE TABLE test_create_table_partition2 (c1 INT, c2 INT) PARTITION BY RANGE (c2) ( PARTITION p1_0 VALUES LESS THAN ('1'), PARTITION p1_1 VALUES LESS THAN ('201'), PARTITION p1_2 VALUES LESS THAN ('401'), PARTITION p1_3 VALUES LESS THAN ('601'), PARTITION p1_4 VALUES LESS THAN ('801'), PARTITION p1_5 VALUES LESS THAN ('1000'), PARTITION p2 VALUES LESS THAN ('2000'), PARTITION p3 VALUES LESS THAN ('2500'), PARTITION p4 VALUES LESS THAN ('3000'), PARTITION p5_1 VALUES LESS THAN ('4000'), PARTITION p5_2 VALUES LESS THAN ('5000') );
  • 规格约束 逻辑解码支持DDL规格: 纯DDL逻辑解码性能标准环境下约为100MB/S,DDL/DML混合事务逻辑解码性能标准环境下约为100MB/S。 开启此功能后(设置wal_level=logical且enable_logical_replication_ddl=on),对DDL语句影响性能下降小于15%。 解码通用约束(串行和并行): 不支持解码本地临时对象的DDL操作。 不支持FOREIGN TABLE场景的DDL解码。 alter table add column的default值不支持stable类型和volatile类型的函数;create table和alter table的column的check表达式不支持stable类型和volatile类型的函数;alter table如果有多条子语句,只要其中一条子语句存在上述两种情况,则该条alter table整条语句不反解析。 gaussdb=# ALTER TABLE tbl_28 ADD COLUMN b1 TIMESTAMP DEFAULT NOW(); -- 's' NOT DEPARSE gaussdb=# ALTER TABLE tbl_28 ADD COLUMN b2 INT DEFAULT RANDOM(); -- 'v' NOT DEPARSE gaussdb=# ALTER TABLE tbl_28 ADD COLUMN b3 INT DEFAULT ABS(1); -- 'i' DEPARSE 不支持分布式CREATE MATERIALIZED VIEW的DDL解码。 不支持CREATE/ALTER/DROP VIEW、COMMENT ON VIEW的DDL解码。 不支持REINDEX DATABASE/SYSTEM的DDL解码。 不支持视图上触发器相关的DDL解码。 不支持CONCURRENTLY相关语句的DDL解码。 创建对象时语句中存在IF NOT EXISTS时,如果对象已存在,则不进行解码。删除对象时语句中存在IF EXISTS时,如果对象不存在,则不进行解码。 不对ALTER PACKAGE COMPILE语句进行解码,但会解码实例化内容中包含的DDL/DML语句。如果PACKAGE里没有DDL或DML部分的实例化内容,则alter package compile会被逻辑解码忽略。 仅支持本版本之前版本的商用DDL语法,以下SQL语句不支持逻辑解码。 创建行存表,设置ILM策略。 原始SQL语句: gaussdb=# CREATE TABLE IF NOT EXISTS tb3 (c1 int) with (storage_type=USTORE,ORIENTATION=ROW) ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER 7 day OF NO MODIFICATION; 反解析结果: gaussdb=# CREATE TABLE IF NOT EXISTS public.tb3 (c1 pg_catalog.int4) WITH (storage_type = 'ustore', orientation = 'row', compression = 'no') NOCOMPRESS; 逻辑解码不支持DDL(DCL)/DML混合事务,混合事务中DDL之后的DML解码不支持。 -- 均不反解析,DCL为不支持语句故不解析,DML处于DCL之后也不反解析 gaussdb=# BEGIN; gaussdb=# GAINT ALL PRIVILEGES to u01; gaussdb=# INSERT INTO test1(col1) values(1); gaussdb=# COMMIT; -- 只反解析第一句和第三句SQL语句 gaussdb=# BEGIN; gaussdb=# CREATE TABLE mix_tran_t4(id int); gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# CREATE TABLE mix_tran_t5(id int); gaussdb=# COMMIT; -- 只反解析第一句和第二句SQL语句 gaussdb=# BEGIN; gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# CREATE TABLE mix_tran_t6(id int); gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# COMMIT; -- 全反解析 gaussdb=# BEGIN; gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# CREATE TABLE mix_tran_t7(id int); gaussdb=# CREATE TABLE mix_tran_t8(id int); gaussdb=# COMMIT; -- 只反解析第一句和第三句SQL语句 gaussdb=# BEGIN; gaussdb=# CREATE TABLE mix_tran_t7(id int); gaussdb=# CREATE TYPE compfoo AS (f1 int, f2 text); gaussdb=# CREATE TABLE mix_tran_t8(id int); gaussdb=# COMMIT; -- 全反解析 gaussdb=# BEGIN; gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# COMMIT; -- 只反解析第一句SQL语句 gaussdb=# BEGIN; gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# CREATE TYPE compfoo AS (f1 int, f2 text); gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# COMMIT; -- 只反解析第一句和第三句SQL语句 gaussdb=# BEGIN; gaussdb=# INSERT INTO mix_tran_t4 VALUES(111); gaussdb=# CREATE TYPE compfoo AS (f1 int, f2 text); gaussdb=# CREATE TABLE mix_tran_t9(id int); gaussdb=# COMMIT; 逻辑解码语句CREATE TABLE AS SELECT、SELECT INTO和CREATE TABLE AS仅能解码出CREATE TABLE语句,暂不支持解码INSERT语句。 对于CTAS创建的表,仍会解码其ALTER和DROP语句。 示例: 原始SQL语句: CREATE TABLE IF NOT EXISTS tb35_2 (c1 int) with (storage_type=USTORE,ORIENTATION=ROW); INSERT INTO tb35_2 VALUES (6); CREATE TABLE tb35_1 with (storage_type=USTORE,ORIENTATION=ROW) AS SELECT * FROM tb35_2; 最后一句SQL语句反解析结果: CREATE TABLE public.tb35_1 (c1 pg_catalog.int4) WITH (storage_type = 'ustore', orientation = 'row', compression = 'no') NOCOMPRESS; 执行存储过程/函数/高级包时,若其本身包含DDL/DML混合事务或者其本身与同事务内其他语句组成DDL/DML混合事务,则按照混合事务原则执行解码。 逻辑解码不支持账本数据库功能,创建账本数据库的DDL语句解码结果中会包含hash列。 原始语句: CREATE SCHEMA blockchain_schema WITH BLOCKCHAIN; CREATE TABLE blockchain_schema.blockchain_table(mes int); 解码结果: CREATE SCHEMA blockchain_schema WITH BLOCKCHAIN; CREATE TABLE blockchain_schema.blockchain_table (mes pg_catalog.int4, hash_a1d895 pg_catalog.hash16); -- 此语句无法在目标端回放。 需要在目标端手动关闭blockchain_schema的防篡改属性后,才可以正常回放,此时目标端的blockchain_table等同于一张普通表,再次执行DML命令可以正常回放。 SQL命令: ALTER SCHEMA blockchain_schema WITHOUT BLOCKCHAIN; CREATE TABLE blockchain_schema.blockchain_table (mes pg_catalog.int4, hash_a1d895 pg_catalog.hash16); MYSQL兼容模式不支持ALTER SCHEMA schema_name WITHOUT/WITH BLOCKCHAIN语法反解析。 串行逻辑解码支持DDL特有约束: sql_decoding插件不支持JSON格式的DDL。
  • 使用file_fdw 创建服务器对象:CREATE SERVER。 创建用户映射:CREATE USER MAPPING。 创建外表:CREATE FOREIGN TABLE。 外表的表结构需要与指定的文件的数据保持一致。 对外表做查询操作,写操作不被允许。 删除外表:DROP FOREIGN TABLE。 删除用户映射:DROP USER MAPPING。 删除服务器对象:DROP SERVER。
  • 维护窗口参数配置 RETENTION_TIME:评估与压缩记录的保留时长,单位天,默认值30。用户可根据自己存储容量自行调节。 EXECUTION_INTERVAL:评估任务的执行频率,单位分钟,默认值15。用户可根据自己维护窗口期间业务与资源情况调节。该参数与ABS_JOBLIMIT相互影响。单日单线程最大可产生的I/O为WIND_DURATION/EXECUTION_INTERVAL*JOB_SIZELIMIT。 JOB_SIZELIMIT:控制单个压缩Job可以处理的最大字节数,单位兆,默认值1024。压缩带宽约为100MB/秒,每个压缩Job限制I/O为1GB时,最多10秒完成。用户可根据自己业务闲时情况以及需要压缩的数据量自行调节。 ABS_JOBLIMIT:控制一次评估最多生成多少个压缩Job。用户可根据自己设置策略的分区及表数量自己调节。建议最大不超过10,可以使用“select count(*) from gs_adm_ilmobjects where enabled = true”命令查询。 POLICY_TIME:控制判定冷行的条件单位是天还是秒,秒仅用来做测试用。取值为:ILM_POLICY_IN_SECONDS或ILM_POLICY_IN_DAYS(默认值)。 WIND_DURATION:维护窗口持续时长,单位分钟,默认240分钟(4小时)。维护窗口默认从北京时间22点开始持续240分钟,用户可根据自己业务闲时情况自行调节。 BLOCK_LIMITS:控制实例级的行存压缩速率上限,默认是40,取值范围是0到10000(0表示不限制),单位是block/ms,表示每毫秒最多压缩多少个block。速率上限计算方法:BLOCK_LIMITS*1000*BLOCKSIZE,以默认值40为例,其速率上限为:40*1000*8KB=320000KB/s。 ENABLE_META_COMPRESSION:是否开启header压缩,默认为0,取值范围为0(关闭)和1(开启)。用户可根据自己的实际情况来进行开启或关闭。 SAMPLE_MIN:常量编码和等值编码采样步长最小值,默认为10,取值范围[1, 100],支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 SAMPLE_MAX:常量编码和等值编码采样步长最大值,默认为10,取值范围[1, 100],支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 CONST_PRIO:常量编码优先级,默认为40,取值范围[0, 100],100表示关闭常量编码,支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 CONST_THRESHOLD:常量编码阈值,默认为90,取值范围[1, 100],表示一列常量值的占比超过该阈值时进行常量编码,支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 EQVALUE_PRIO:等值编码优先级,默认为60,取值范围[0, 100],100表示关闭等值编码,支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 EQVALUE_THRESHOLD:等值编码阈值,默认为80,取值范围[1, 100],表示两列数据的等值比例超过该阈值时进行等值编码,支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 ENABLE_DELTA_ENCODE_SWITCH:差值编码开关,默认为1,支持小数输入,0表示关闭,1表示开启,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 LZ4_COMPRESSION_LEVEL:lz4压缩等级,默认为0,取值范围[0, 16],支持小数输入,小数会自动向下取整。用户可根据自己的实际情况来设置具体值。 ENABLE_LZ4_PARTIAL_DECOMPRESSION:部分解压开关,默认为1,支持小数输入,0表示关闭,1表示开启,小数会自动向下取整。用户可根据自己的实际情况来进行开启或关闭。 示例分析: EXECUTION_INTERVAL:15 JOB_SIZELIMIT:10240 WIND_DURATION:240 BLOCK_LIMITS:0 此配置下单表分区在一个维护窗口期间可完成240/15*10240MB=160GB数据的评估压缩。压缩带宽为100MB/秒,实际压缩仅耗时160GB/(100MB/秒)=27分钟。其他时间对业务无影响。用户可根据自己业务闲时可支配给压缩的时长来调节参数。 父主题: 数据生命周期管理-OLTP表压缩
  • 特性规格 TPCC只开启策略、不开调度对原有业务无影响。 TPCC不开启压缩策略对原有业务无影响。 TPCC.bmsql_order_line设置ILM策略(只识别完成派送的订单为冷行)不调度,TPmC劣化不高于2%(56核CPU370GB内存+3TB SSD硬盘,350GB SharedBuffer)。 TPCC.bmsql_order_line设置ILM策略(只识别完成派送的订单为冷行)后台默认参数调度时,TPmC劣化不高于5%(56核CPU370GB内存+3TB SSD硬盘,350GB SharedBuffer)。 单线程ILM Job带宽约100MB/秒(56核CPU370GB内存+3TB SSD硬盘,350GB SharedBuffer)。 度量方式:根据执行压缩的开始时间和结束时间以及压缩的页面个数计算带宽。 get查询访问压缩数据比非压缩数据性能劣化,驱动侧不高于10%,plsql侧不高于15%(32MB SharedBuffer,6万页面数据)。 multi-get查询访问压缩数据比非压缩数据性能劣化,驱动侧不高于30%,plsql侧不高于40%(32MB SharedBuffer,6万页面数据)。 table-scan查询访问压缩数据比非压缩数据性能劣化,驱动侧不高于30%,plsql侧不高于40%(32MB SharedBuffer,6万页面数据)。 TPCH.lineitem表压缩比(全冷行)不小于2:1。 对于TPC-C的Orderline表,以及TPC-H的Lineitem、Orders、Customer、Part表的测试表明,数值型字段较多时,压缩率高于LZ4和ZLIB;而文本型字段较多时,压缩率介于LZ类和LZ+Huffman组合类的压缩算法之间。 父主题: 数据生命周期管理-OLTP表压缩
  • 特性约束 不支持系统表、内存表、全局临时表、本地临时表和序列表,不支持Ustore段页式表,不支持unlogged表,不支持压缩toast数据。 仅在ORA兼容模式、PG模式以及B兼容模式下有效。 Ustore不支持编解码,压缩率低于Astore。 普通表开启压缩时,扩容空间预留需按照解压后的大小评估。 扩容期间不支持压缩调度。 扩容前请确认当前是否有正在执行的压缩任务,如果有的话,要么等待压缩任务结束,要么执行DBE_ILM.STOP_ILM或DBE_ILM_ADMIN.DISABLE_ILM停掉,扩容完成后再执行DBE_ILM_ADMIN.ENABLE_ILM开启。 由于当前版本新增了部分解压特性,会导致部分极小的表在判断压缩收益时不通过,从而不进行压缩。但此前没有部分解压的版本可以压缩。例如:单表单字段int1类型的数据从当前版本开始无法进行压缩。 父主题: 数据生命周期管理-OLTP表压缩
  • 问题分析 在开启并行回放或串行回放的情况下(查询GUC参数recovery_parse_workers和recovery_max_workers均是1为串行回放;recovery_parse_workers是1,recovery_max_workers大于1为并行回放),备机的查询线程在做索引扫描时,会先对索引页面加读锁,每当扫到一个元组时会去判可见性。如果该元组对应的事务处于committing状态,需要等待该事务提交后再判断。而备机上的事务提交是依赖日志回放线程推进的,这个过程中会对索引页面进行修改,因此需要加锁。查询线程在等待过程中会释放索引页面的锁,否则会出现查询线程等待回放线程进行事务提交,而回放线程在等待查询线程释放锁。 该报错仅出现在查询与回放都需要访问同一个索引页面的场景下,查询线程在释放锁并等待事务结束过程中,访问的页面出现被修改的情况。具体流程图如下图1所示: 备机查询在扫到committing状态的元组时,需要等待事务提交是因为事务提交的顺序与产生日志的顺序可能是乱序的。例如主机上tx_1的事务比tx_2先提交,而备机上tx_1的commit日志在tx_2的commit日志之后回放,按照事务提交顺序来看tx_1对tx_2应当是可见的,所以需要等待事务提交。 备机查询在扫描索引页面时,发现页面元组数量(包含死元组)发生变化后不可重试,是因为在扫描时可能为正向或反向扫描,而举例来说页面发生分裂后一部分元组移动到右页面,在反向扫描的情况下即使重试只能向左扫描读取,无法再保证结果的正确性,并且由于无法分辨发生分裂或者插入,所以不可重试。 图1 问题分析
  • 常用视图工具 视图类型 类型 功能描述 使用场景 函数名称 解析 全类型 用于解析指定表页面,并返回存放解析内容的路径。 查看页面信息。 查看元组(非用户数据)信息。 页面或者元组损坏。 元组可见性问题。 校验报错问题。 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范围之内的xLog日志,并返回存放解析内容的路径。可以通过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存储引擎
  • 语法示例 -- 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (0 rows) gaussdb=# DROP TABLE IF EXISTS flashtest; NOTICE: table "flashtest" does not exist, skipping 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (0 rows) --创建表flashtest gaussdb=# CREATE TABLE IF NOT EXISTS flashtest(id int, name text) with (storage_type = ustore); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --插入数据 gaussdb=# INSERT INTO flashtest VALUES(1, 'A'); INSERT 0 1 gaussdb=# SELECT * FROM flashtest; id | name ----+------ 1 | A (1 row) --DROP表flashtest gaussdb=# DROP TABLE IF EXISTS flashtest; DROP TABLE --查看回收站,删除的表被放入回收站 gaussdb=# SELECT * FROM gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecs n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------ --+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 18591 | 12737 | 18585 | BIN$31C14EB4899$9737$0==$0 | flashtest | d | 0 | 79352606 | 2023-09-13 20:01:28.640664+08 | 79352595 | 7935259 5 | 2200 | 10 | 0 | 18585 | t | t | 225492 | 225492 | 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 | (2 rows) --查看表flashtest,表不存在 gaussdb=# SELECT * FROM flashtest; ERROR: relation "flashtest" does not exist LINE 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (0 rows) -- PURGE INDEX index_name; -- gaussdb=# DROP TABLE IF EXISTS flashtest; NOTICE: table "flashtest" does not exist, skipping DROP TABLE --创建表flashtest gaussdb=# CREATE TABLE IF NOT EXISTS flashtest(id int, name text) WITH (storage_type = ustore); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --为表flashtest创建索引flashtest_index gaussdb=# CREATE INDEX flashtest_index ON flashtest(id); CREATE INDEX --查看flashtest表的基本信息 gaussdb=# \d+ flashtest Table "public.flashtest" Column | Type | Modifiers | Storage | Stats target | Description --------+---------+-----------+----------+--------------+------------- id | integer | | plain | | name | text | | extended | | Indexes: "flashtest_index" ubtree (id) WITH (storage_type=USTORE) TABLESPACE pg_default Has OIDs: no Distribute By: HASH(id) Location Nodes: ALL DATANODES Options: orientation=row, storage_type=ustore, compression=no, segment=off,toast.storage_type=ustore, toast.toast_storage_type=enhanced_toast --DROP表 gaussdb=# DROP TABLE IF EXISTS flashtest; DROP TABLE --查看回收站 gaussdb=# SELECT * FROM gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecs n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------ --+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 18648 | 12737 | 18641 | BIN$31C14EB48D1$9A85$0==$0 | flashtest | d | 0 | 79354509 | 2023-09-13 20:40:11.360638+08 | 79354506 | 7935450 8 | 2200 | 10 | 0 | 18641 | t | t | 226642 | 226642 | 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 | 7935450 8 | 2200 | 10 | 0 | 18647 | f | t | 0 | 0 | (3 rows) --PURGE索引flashtest_index gaussdb=# PURGE INDEX flashtest_index; PURGE INDEX --查看回收站,回收站中的索引flashtest_index被删除 gaussdb=# SELECT * FROM gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecs n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------ --+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 18648 | 12737 | 18641 | BIN$31C14EB48D1$9A85$0==$0 | flashtest | d | 0 | 79354509 | 2023-09-13 20:40:11.360638+08 | 79354506 | 7935450 8 | 2200 | 10 | 0 | 18641 | t | t | 226642 | 226642 | 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 | (2 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (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, skipping DROP TABLE --创建表flashtest gaussdb=# CREATE TABLE IF NOT EXISTS flashtest(id int, name text) with (storage_type = ustore); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --插入数据 gaussdb=# INSERT INTO flashtest VALUES(1, 'A'); INSERT 0 1 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 | rcychangecs n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------ --+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 18658 | 12737 | 18652 | BIN$31C14EB48DC$9B2B$0==$0 | flashtest | d | 0 | 79354760 | 2023-09-13 20:47:57.075907+08 | 79354753 | 7935475 3 | 2200 | 10 | 0 | 18652 | t | t | 226824 | 226824 | 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 | (2 rows) --查看表,表不存在 gaussdb=# SELECT * FROM flashtest; ERROR: relation "flashtest" does not exist LINE 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (0 rows) --DROP表 gaussdb=# DROP TABLE IF EXISTS flashtest; DROP TABLE gaussdb=# SELECT * FROM flashtest; ERROR: relation "flashtest" does not exist LINE 1: SELECT * FROM flashtest; ^ --查看回收站,表被放入回收站 gaussdb=# SELECT * FROM gs_recyclebin; rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcy changecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+------------------------------+--------------+---------+---------------+-------------------------------+--------------+---- ----------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 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表,表名用回收站中的rcyname gaussdb=# 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (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 | rcy changecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+------------------------------+--------------+---------+---------------+-------------------------------+--------------+---- ----------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 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 exist LINE 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 exist LINE 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (0 rows) -- TIMECAPSULE TABLE { table_name } TO BEFORE TRUNCATE -- gaussdb=# DROP TABLE IF EXISTS flashtest; NOTICE: table "flashtest" does not exist, skipping DROP TABLE --创建表flashtest gaussdb=# CREATE TABLE IF NOT EXISTS flashtest(id int, name text) WITH (storage_type = ustore); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --插入数据 gaussdb=# INSERT INTO flashtest VALUES(1, 'A'); INSERT 0 1 gaussdb=# 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 | rcychangecs n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------ --+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 18703 | 12737 | 18697 | BIN$31C14EB4909$9E4C$0==$0 | flashtest | t | 0 | 79356608 | 2023-09-13 21:24:42.819863+08 | 79356606 | 7935660 6 | 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 | (2 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 | rcychangecs n | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64 | rcybucket -----------+---------+----------+------------------------------+----------------------+--------------+---------+---------------+-------------------------------+--------------+------------ --+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------+----------- 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 | 7935660 6 | 2200 | 10 | 0 | 18704 | t | t | 0 | 227928 | (2 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 | rcybucket -----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+-------------- -+----------------+---------------+-------------+--------------+----------------+----------- (0 rows)
  • 相关语法 删除表 DROP TABLE table_name [PURGE] 清理回收站对象 PURGE { TABLE { table_name } | INDEX { index_name } | RECYCLEBIN } 闪回被删除的表 TIMECAPSULE TABLE { table_name } TO BEFORE DROP [RENAME TO new_tablename] 截断表 TRUNCATE TABLE { table_name } [ PURGE ] 闪回截断的表 TIMECAPSULE TABLE { table_name } TO BEFORE TRUNCATE
  • 参数说明 DROP/TRUNCATE TABLE table_name PURGE 默认将表数据放入回收站中,PURGE直接清理。 PURGE RECYCLEBIN 表示清理回收站对象。 TO BEFORE DROP 使用这个子句检索回收站中已删除的表及其子对象。 可以指定原始用户指定的表的名称,或对象删除时数据库分配的系统生成名称。 回收站中系统生成的对象名称是唯一的。因此,如果指定系统生成名称,那么数据库检索指定的对象。使用“select * from gs_recyclebin;”语句查看回收站中的内容。 在指定了用户指定的名称且回收站中包含多个该名称的对象的情况下,数据库检索回收站中最近移动的对象,如果想要检索更早版本的表,可以执行如下操作: 指定你想要检索的表的系统生成名称。 执行TIMECAPSULE TABLE ... TO BEFORE DROP语句,直到你要检索的表。 恢复DROP表时,只恢复基表名,其他子对象名均保持回收站对象名。用户可根据需要,执行DDL命令手工调整子对象名。 回收站对象不支持DML、DCL、DDL等写操作,不支持DQL查询操作(后续支持)。 闪回点和当前点之间,执行过修改表结构或影响物理结构的语句,闪回失败。执行过DDL的表进行闪回操作报错:“ERROR:The table definition of %s has been changed. ”。涉及namespace、表名改变等操作的DDL执行闪回操作报错: ERROR: recycle object %s desired does not exist; 开启enable_recyclebin参数,启用回收站时,如果表上有truncate trigger、truncate表时,无法触发trigger。 RENAME TO 为从回收站中检索的表指定一个新名称。 TO BEFORE TRUNCATE 闪回到TRUNCATE之前。
  • 背景信息 闪回DROP:可以恢复意外删除的表,从回收站(recyclebin)中恢复被删除的表及其附属结构如索引、表约束等。闪回drop是基于回收站机制,通过还原回收站中记录的表的物理文件,实现已drop表的恢复。 闪回TRUNCATE:可以恢复误操作或意外被进行truncate的表,从回收站中恢复被truncate的表及索引的物理数据。闪回truncate基于回收站机制,通过还原回收站中记录的表的物理文件,实现已truncate表的恢复。
  • 使用示例 gaussdb=# DROP TABLE IF EXISTS "public".flashtest; NOTICE: table "flashtest" does not exist, skipping DROP TABLE --创建表 gaussdb=# CREATE TABLE "public".flashtest (col1 INT,col2 TEXT) with(storage_type=ustore); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'col1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --查询csn gaussdb=# SELECT int8in(xidout(next_csn)) FROM gs_get_next_xid_csn(); int8in ---------- 79352065 79352065 79352065 79352065 79352065 79352065 (6 rows) --查询当前的时间戳 gaussdb=# SELECT now(); now ------------------------------- 2023-09-13 19:46:34.102863+08 (1 row) --查看表flashtest 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 6 gaussdb=# SELECT * FROM flashtest; col1 | col2 ------+--------- 3 | INSERT3 1 | INSERT1 2 | INSERT2 4 | INSERT4 5 | INSERT5 6 | INSERT6 (6 rows) --闪回表至特定csn gaussdb=# TIMECAPSULE TABLE flashtest TO CSN 79352065; TimeCapsule Table gaussdb=# SELECT * FROM flashtest; col1 | col2 ------+------ (0 rows) gaussdb=# SELECT now(); now ------------------------------- 2023-09-13 19:52:21.551028+08 (1 row) --插入数据 gaussdb=# INSERT INTO flashtest VALUES(1,'INSERT1'),(2,'INSERT2'),(3,'INSERT3'),(4,'INSERT4'),(5,'INSERT5'),(6,'INSERT6'); INSERT 0 6 gaussdb=# 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 Table gaussdb=# 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 6 gaussdb=# 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 20:54:00.641506'; ERROR: The specified timestamp is invalid. gaussdb=# SELECT * FROM flashtest; col1 | col2 ------+------ 3 | INSERT3 6 | INSERT6 1 | INSERT1 2 | INSERT2 4 | INSERT4 5 | INSERT5 (6 rows) gaussdb=# DROP TABLE IF EXISTS "public".flashtest; DROP TABLE
共100000条
提示

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