Compare commits

...

376 Commits

Author SHA1 Message Date
opengauss-bot 18b260d9e1
!1711 【轻量级 PR】:修复pg_recvlogical工具-I选项不生效的问题
Merge pull request !1711 from pengjiong/N/A
2022-05-13 10:50:32 +00:00
opengauss-bot 862293c3c9
!1713 【bugfix】合入主线修复hot_standby_feedback关闭后,xmin不推进的问题
Merge pull request !1713 from li_jianqiu/2.0.0
2022-04-30 01:38:26 +00:00
li_jianqiu e8b6faf915 【bugfix】修复hot_standby_feedback关闭后,xmin不推进的问题 2022-04-30 01:38:46 +08:00
opengauss-bot 4c803975b9
!1712 【bugfix】修复hot_standby_feedback关闭后,xmin不推进的问题
Merge pull request !1712 from li_jianqiu/2.0.0
2022-04-29 12:38:32 +00:00
li_jianqiu d2e069125e 修复hot_standby_feedback关闭后,xmin不推进的问题 2022-04-29 19:23:44 +08:00
pengjiong 7f1dc2b79f
test 2022-04-29 09:39:39 +00:00
opengauss-bot 07ad2fc0b2
!1687 change version to 2.0.3
Merge pull request !1687 from zhangxubo/2.0.0
2022-04-21 11:36:10 +00:00
opengauss-bot c7dddf6ace
!1686 修复逻辑复制内存泄露的问题
Merge pull request !1686 from pengjiong/2.0/0
2022-04-21 11:18:08 +00:00
opengauss-bot 91b3e149f9
!1681 修改gs_guc reload内存越界产生core
Merge pull request !1681 from mujinqiang/guc
2022-04-21 11:09:24 +00:00
mjq c6c3b2c722 修改gs_guc和主备同步参数备份文件名相同导致同时读写同一个文件产生中间态,导致core
修改local_syscache为usess
2022-04-21 17:32:40 +08:00
zhang_xubo 2c3bc6a56b change version to 2.0.3 2022-04-21 17:29:10 +08:00
TotaJ 40c7176f03 Fix mem leak. 2022-04-21 17:10:56 +08:00
opengauss-bot b7fcc134ae
!1662 回合master代码,添加guc参数num_internal_lock_partitions, 进行锁分区的配置
Merge pull request !1662 from 周斌/lock_2.0.0
2022-04-02 10:42:42 +00:00
opengauss-bot b03341beb0
!1658 [feature] 回合gauss解决分区表的4个issue
Merge pull request !1658 from 周斌/partation_first
2022-04-02 10:27:14 +00:00
justbk bf712a1cc6 apply lock modify 2022-04-02 18:16:51 +08:00
justbk e03e4cfbfe fix start_end_every for partition 2022-04-02 11:14:38 +08:00
z00513495 b9bd5888a7 fix partition table relhasindex 2022-04-02 11:11:15 +08:00
opengauss-bot 0db9f3ea1e
!1655 回滚pg_stat_get_wal_senders的升级与gs_guc设置参数出错
Merge pull request !1655 from 胡正超/revert202
2022-04-01 03:37:51 +00:00
gentle_hu 21d976ed18 revert upgrade of pg_stat_get_wal_senders() 2022-04-01 10:44:33 +08:00
opengauss-bot 787eaed932
!1647 【bugfix】解决分区表autovacuum时已达到清理阈值但没有自动清理
Merge pull request !1647 from li_jianqiu/2.0.0
2022-03-31 09:01:17 +00:00
li_jianqiu 80052edd8e 删除空格 2022-03-31 16:17:35 +08:00
li_jianqiu c0bee891b0 加入宏隔离分布式 2022-03-31 15:39:14 +08:00
li_jianqiu 9d5e7f9044 解决分区表达到清理阈值后,没有自动vacuum的问题 2022-03-30 17:49:42 +08:00
opengauss-bot a3584e3a2e
!1642 提升分区表逻辑解码性能
Merge pull request !1642 from pengjiong/logical_decode_perf_parttable
2022-03-29 14:02:14 +00:00
ZigSmith 62b1943825 添加guc参数num_internal_lock_partitions, 进行锁分区的配置 2022-03-29 19:27:36 +08:00
TotaJ 6206f03d67 Enhance logical decoding performance for partition table. 2022-03-29 19:22:00 +08:00
opengauss-bot de396a512b
!1640 修改local_syscache_threshold参数为SIGHUP级别,可通过reload生效
Merge pull request !1640 from 杨皓/2.0.0-trunk
2022-03-29 06:24:47 +00:00
yanghao dc4dc6a870 change local_syscache_threshold to SIGHUP level 2022-03-29 11:09:16 +08:00
opengauss-bot 213b7432ef
!1634 【bugfix】修复高并发下不能创建新连接,数据库hang住问题。
Merge pull request !1634 from li_jianqiu/2.0.0
2022-03-29 03:04:11 +00:00
li_jianqiu 56422b713a 【bugfix】从应用端看连接数并没有达到1W最大连接数,但是数据库堆栈中存在13800个线程,也不能创建新连接,数据库hang住。 2022-03-28 18:55:39 +08:00
opengauss-bot dfb522b74f
!1559 支持备机build出新的备机
Merge pull request !1559 from 熊小军/2.0.0
2022-03-26 07:44:26 +00:00
opengauss-bot 34ad8af43f
!1629 修复逻辑复制core问题,同步master分支的修改
Merge pull request !1629 from pengjiong/relmap4k
2022-03-26 02:51:34 +00:00
TotaJ 0d77d960a4 Fix logical core. 2022-03-26 10:03:32 +08:00
opengauss-bot e1fc374ae4
!1610 change version to 2.0.2
Merge pull request !1610 from zhangxubo/2.0.0_version
2022-03-21 09:36:03 +00:00
zhang_xubo 839a6b4801 update version to 2.0.2 2022-03-21 15:02:07 +08:00
opengauss-bot c81a284cad
!1606 回合relmap文件支持4K代码
Merge pull request !1606 from pengjiong/relmap4k
2022-03-21 01:14:31 +00:00
TotaJ cc6b8bc62d relmap file support 4K version. 2022-03-18 21:13:00 +08:00
opengauss-bot f927083841
!1565 【BUGFIX】 修复两次备份、生成snapshot IO高与打印-no free slot等问题
Merge pull request !1565 from li_jianqiu/2.0.0
2022-03-10 02:09:59 +00:00
xiong_xjun 9313d708ce standby full build standby 2022-03-09 21:03:55 +08:00
li_jianqiu c420fde60e 解决编译错误 2022-03-07 17:54:24 +08:00
li_jianqiu e78e3c4eff 【BUGFIX】解决WDR snapshot生成过程中IO高的问题 2022-03-07 16:10:59 +08:00
li_jianqiu 38d7c01fac 【gs_probackup】【BUGFIX】修复PGDATA目录下的表空间,两次备份问题 2022-03-07 15:36:40 +08:00
li_jianqiu e001cbee91 主要内容:not assign stmt handle at DN slave mode
主要逻辑:instr  stmt thread is not running on slave node, so we can check the pid of instr stmt thread, then can assign(or not) stmt handle when the pid is not zero(or zero)
2022-03-07 11:10:20 +08:00
opengauss-bot ef7949c398
!1527 修复gs_guc/reload方式设置分组同步复制参数失败
Merge pull request !1527 from 胡正超/anyxfix
2022-02-28 03:07:34 +00:00
opengauss-bot 7344c83601
!1536 notify 支持指定为cascade standby
Merge pull request !1536 from 刘春/2.0.0
2022-02-24 09:26:23 +00:00
liuchun 7ffe72acb5 notify 支持指定cascade standby 2022-02-24 15:59:16 +08:00
gentle_hu 29340beb1d fix gs_guc reload any x 2022-02-16 19:57:49 +08:00
opengauss-bot 1db5ddc8f9
!1508 【轻量级PR】在release打包文件中,添加libzstd库文件
Merge pull request !1508 from zhangxubo/2.0.0
2022-02-16 01:51:49 +00:00
zhang_xubo e4e060ec84 add libzstd librarys in release file 2022-02-15 16:15:09 +08:00
opengauss-bot 55986704fc
!1499 pg_probackup数据页完整性校验
Merge pull request !1499 from 薛蒙恩/gs_probackup_checksum_200
2022-02-11 02:47:36 +00:00
opengauss-bot abcdefd4a3
!1499 pg_probackup数据页完整性校验
Merge pull request !1499 from 薛蒙恩/gs_probackup_checksum_200
2022-02-11 02:47:36 +00:00
opengauss-bot ee99c06af3
!1472 支持any x分组组合同步复制协议
Merge pull request !1472 from 胡正超/anyx
2022-02-10 02:03:14 +00:00
xue_meng_en bbff7b4f8a probackup checksum open, support data checksum check
Author: lwx843928 <liyifeng9@huawei.com>
Date:   Fri Jan 21 09:46:16 2022 +0800

    probackup checksum open

    Offering: GaussDB Kernel

    More detail: probackup checksum open, support data checksum check

    merged from liyifeng
2022-01-28 15:08:31 +08:00
gentle_hu e5a91d0c00 support any x 2022-01-24 22:03:19 +08:00
opengauss-bot ce5358b2dc
!1469 修复数据目录名被修改再恢复后gaussdb无法stop的问题
Merge pull request !1469 from Cross-罗/cannot_stop
2022-01-21 09:02:07 +00:00
opengauss-bot 7ed416426a
!1483 修复twophasecleaner内存泄漏
Merge pull request !1483 from maxiang/twophase2
2022-01-20 08:36:39 +00:00
luozihao ebd0d53b9a fixed the bug that database cannot stop 2022-01-20 15:54:39 +08:00
Xiao__Ma 83d10255b7 修复twophasecleaner内存泄漏 2022-01-19 15:04:42 +08:00
opengauss-bot c3b98cd084
!1392 修复视图时间戳出错的问题
Merge pull request !1392 from Cross-罗/new_view
2022-01-18 13:13:15 +00:00
opengauss-bot f5e1bf0ef7
!1449 [修复缺陷master同步到2.0.0分支] gs_probackup远程备份的时候,环境变量分离下,加载不到lib库
Merge pull request !1449 from zhangxubo/2.0.0
2022-01-05 15:42:49 +00:00
zhang_xubo 80e06757ad gs_probackup远程备份且环境变量分离下,加载不到lib库。增加 --remote-libpath配置项导入 2022-01-04 22:06:56 +08:00
opengauss-bot 3bfba81357 !1402 修复switchover时新主机core的bug
Merge pull request !1402 from Cross-罗/switchover_core
2021-12-25 03:37:30 +00:00
opengauss-bot 839880b73e !1424 回合路径生成唯一索引优先,多列主键选择率估算错误,enable_indexscan无法禁止索引扫描,修正索引代价模型
Merge pull request !1424 from zhengxue/2.0.0_dev
2021-12-24 02:41:13 +00:00
shirley_zhengx 82d949068d fix conflict 2021-12-24 10:36:49 +08:00
opengauss-bot f14f8188c4 !1425 index代价高估导致走bitmapscan
Merge pull request !1425 from Cross-罗/index_cost
2021-12-24 01:47:37 +00:00
luozihao f615b8d514 index代价高估导致走bitmapscan 2021-12-24 09:24:30 +08:00
opengauss-bot 30c77fb771 !1426 增加join行数估算时候对类型转换函数的支持
Merge pull request !1426 from Cross-罗/join_row
2021-12-23 14:24:26 +00:00
opengauss-bot 3f10a35464 !1423 修复分区表执行并发update时结果不一致的问题
Merge pull request !1423 from zhangzhijing/2.0.0
2021-12-23 14:19:15 +00:00
opengauss-bot 2eed7552d4 !1420 修复视图pg_replication_slots中归档槽的restart_lsn概率性显示为0的bug
Merge pull request !1420 from Cross-罗/branch1
2021-12-23 06:27:37 +00:00
luozihao e642f9d5f8 增加join行数估算时候对类型转换函数的支持 2021-12-23 11:59:06 +08:00
zhangzhijingMY a2c22701a8 回退逻辑复制修改 2021-12-22 17:45:21 +08:00
shirley_zhengx 424b1c0b79 回合路径生唯一索引优先,多列主键选择率估算错误,无法禁止索引扫描,修正索引代价模型 2021-12-22 15:17:45 +08:00
zhangzhijingMY a2faea7d96 代码回合2.0.0 2021-12-22 09:38:40 +08:00
luozihao ec386db397 修复switchover备升主新主机core的bug 2021-12-21 17:42:30 +08:00
luozihao 112023186b 修复快速删除、创建归档槽导致归档线程未正确重启的bug 2021-12-21 16:44:36 +08:00
opengauss-bot ee30a37bb3 !1382 对pgarch_chooseWalsnd的流程进行优化
Merge pull request !1382 from Cross-罗/retry
2021-12-09 12:29:20 +00:00
opengauss-bot 556aad463c !1381 fixed the bug that gs_om cannot stop the cluster
Merge pull request !1381 from Cross-罗/cluster_stop
2021-12-09 12:28:54 +00:00
luozihao f2c925df9a 修复时间戳出错导致日期显示出错的问题 2021-12-08 19:44:23 +08:00
opengauss-bot be4a969aa5 !1391 修复新增系统函数不可用问题
Merge pull request !1391 from Cross-罗/new_view
2021-12-08 03:10:20 +00:00
luozihao 66b956bfce 修复新增系统函数不可用问题 2021-12-07 15:43:44 +08:00
opengauss-bot e72573a4c3 !1389 fix gs_probackup sort core dump
Merge pull request !1389 from 刘春/2.0
2021-12-06 11:13:51 +00:00
l00280231 2a1399e97b fix gs_probackup sort core dump 2021-12-06 18:03:17 +08:00
luozihao 7eef88d8dd 对pgarch_chooseWalsnd的流程进行优化 2021-12-04 14:22:08 +08:00
luozihao 940fc12903 fixed the bug that gs_om cannot stop the cluster 2021-12-04 11:04:44 +08:00
opengauss-bot 9c3c898e52 !1373 解决升级bug
Merge pull request !1373 from Cross-罗/upgrade
2021-12-03 08:20:09 +00:00
opengauss-bot 06112da4c6 !1364 解决归档流程会因为备机不存在对应的xlog文件而卡住的bug
Merge pull request !1364 from Cross-罗/my_own_2_0
2021-12-03 02:13:04 +00:00
luozihao 40ee83640d 修复升级bug 2021-11-27 21:11:35 +08:00
luozihao 3290af6a23 解决归档流程会因为备机不存在对应的xlog文件而卡住的bug 2021-11-25 09:50:12 +08:00
opengauss-bot 87139aeb02 !1367 提供视图查看当前是哪台备机在做归档
Merge pull request !1367 from Cross-罗/new_view
2021-11-24 13:02:26 +00:00
luozihao 7ef4caf5bb 提供视图查看当前是哪台备机在做归档 2021-11-24 20:09:01 +08:00
opengauss-bot 881c689aec !1365 【轻量级 PR】:修复版本号设置不准确的bug
Merge pull request !1365 from Cross-罗/N/A
2021-11-23 11:26:08 +00:00
Cross-罗 5bc68d9c1c 修复版本号设置不准确的bug
作为PR:的补充,此处版本号应再+1,因为再PR:上错误地把版本号也回退了,会导致从旧备机归档方案升级到新备机归档方案但未提交时仍然能够创建归档槽
2021-11-22 08:25:04 +00:00
opengauss-bot d251f7caeb !1361 优化备机归档日志打印频率
Merge pull request !1361 from Cross-罗/my_own_2_0
2021-11-19 08:57:48 +00:00
opengauss-bot 78af441670 !1363 新增版本控制,在版本号比备机归档版本的版本号要小的时候不允许创建归档槽
Merge pull request !1363 from Cross-罗/version_ctl
2021-11-19 01:29:28 +00:00
luozihao 91d2dfd761 为归档槽的创建增加版本控制 2021-11-18 21:14:45 +08:00
luozihao f53ea60351 优化日志打印频率 2021-11-17 15:34:52 +08:00
opengauss-bot 61cd9e6bcc !1360 修复逻辑解码bug
Merge pull request !1360 from Cross-罗/my_own_2_0
2021-11-16 13:30:17 +00:00
luozihao 497cca8886 修复逻辑解码的bug 2021-11-16 19:58:58 +08:00
opengauss-bot d5b6f9ebc5 !1357 修复catchup时丢失xlog的bug
Merge pull request !1357 from Cross-罗/my_own_2_0
2021-11-16 02:56:14 +00:00
luozihao d52064490d 修复catchup时丢失未归档xlog的bug 2021-11-16 09:50:51 +08:00
opengauss-bot b66511e9a9 !1354 【轻量级 PR】:修复initLastTaskLsn函数中restart_lsn不更新的bug
Merge pull request !1354 from Cross-罗/N/A
2021-11-11 11:06:36 +00:00
Cross-罗 179ecce641 update src/gausskernel/process/postmaster/pgarch.cpp. 2021-11-10 09:51:42 +00:00
opengauss-bot 05641397b1 !1349 修复全异步备归档丢数据的bug
Merge pull request !1349 from Cross-罗/my_own_2_0
2021-11-09 13:22:37 +00:00
luozihao e7d541bc7a 修复全异步备归档丢数据的bug 2021-11-09 19:31:40 +08:00
opengauss-bot 2e6a0bd5e6 !1344 修复归档槽的bug
Merge pull request !1344 from Cross-罗/my_new_2
2021-11-08 07:24:14 +00:00
opengauss-bot 426a5ef54f !1339 对发送的归档lsn做进一步限制,防止发送错误的lsn
Merge pull request !1339 from Cross-罗/my_own_2_0
2021-11-05 06:53:45 +00:00
luozihao 75bce00aed 修复归档槽的bug 2021-11-05 11:28:52 +08:00
opengauss-bot 3830e90d8b !1341 【轻量级 PR】:限制归档复制槽只能有0或1个,在已有归档复制槽的情况下不允许创建
Merge pull request !1341 from Cross-罗/N/A
2021-11-05 02:35:43 +00:00
luozihao 7be46e0e8c 进一步完善对将要发送的lsn的合法性校验 2021-11-05 10:31:51 +08:00
Cross-罗 34909bdaa7 限制归档复制槽只能有0或1个,在已有归档复制槽的情况下不允许创建 2021-11-04 10:23:09 +00:00
opengauss-bot f6d2a542b3 !1336 完善备机归档复制槽刷盘步骤
Merge pull request !1336 from Cross-罗/my_own_2_0
2021-11-03 11:49:31 +00:00
luozihao e54711814b 完善备机归档复制槽刷盘步骤 2021-11-03 17:42:10 +08:00
opengauss-bot 69a8bb769b !1331 修复initLastTaskLsn在集群重启后无法正确初始化归档起点的问题
Merge pull request !1331 from Cross-罗/my_own_2_0
2021-11-02 07:29:06 +00:00
luozihao a10f3f8702 修复initLastTaskLsn在集群重启后无法正确初始化归档起点的问题 2021-11-02 12:02:29 +08:00
opengauss-bot 2e14ad8b05 !1330 在备机build的过程中不允许主机发送归档消息
Merge pull request !1330 from Cross-罗/my_own_2_0
2021-11-01 09:30:57 +00:00
luozihao e5295761b5 在备机build的过程中不允许发送归档信息 2021-11-01 14:48:54 +08:00
opengauss-bot 82f41211b8 !1317 合入备机归档新方案
Merge pull request !1317 from Cross-罗/my_own_2_0
2021-10-26 13:08:14 +00:00
luozihao 518f8250d6 new solution of standby archive 2021-10-26 19:38:02 +08:00
opengauss-bot 66e71ca295 !1314 回退备机归档代码
Merge pull request !1314 from Cross-罗/my_own_2_0
2021-10-20 01:45:50 +00:00
luozihao d31aeb6bbf rollback standby archive 2021-10-19 09:31:58 +08:00
opengauss-bot e3d719e68d !1264 修正日志归档打印信息
Merge pull request !1264 from mujinqiang/mjq200
2021-09-26 09:05:37 +00:00
opengauss-bot 868c3193d7 !1267 禁用备机归档
Merge pull request !1267 from Cross-罗/my_own_2_0
2021-09-12 02:52:25 +00:00
luozihao aedb48e7e1 禁用备机归档 2021-09-12 10:02:04 +08:00
mujinqiang 960b1f040c update src/gausskernel/process/postmaster/pgarch.cpp.
修正日志归档打印日志信息
2021-09-10 11:08:48 +00:00
opengauss-bot 86e8c7686d !1263 I496VN修复
Merge pull request !1263 from Cross-罗/my_own_2_0
2021-09-09 14:43:26 +00:00
luo_zihao5524 8725ceff6e I496VN修复 2021-09-09 22:06:38 +08:00
opengauss-bot f13767aa88 !1262 gs_probackup对应walsender的超时时间改为至少30分钟,确保备份不因超时而失败
Merge pull request !1262 from LiHeng/2.0.0
2021-09-09 13:51:55 +00:00
LiHeng a75fa7ba38 set wal_sender_timeout >= 30minutes for gs_probackup 2021-09-09 21:09:43 +08:00
opengauss-bot 53e0a7b5e3 !1261 【bugfix】解决一主多同步备下一同步备异常退出时主机业务阻塞的问题
Merge pull request !1261 from chenxiaobin/2.0.0
2021-09-08 15:50:44 +00:00
chenxiaobin19 107dbfc873 wake up other walsenders to release workers when walsender exits. 2021-09-08 22:16:39 +08:00
opengauss-bot 24cdd19cb5 !1256 修复OOM逃生手段中相关问题
Merge pull request !1256 from 杨皓/2.0.0
2021-09-07 09:41:36 +00:00
yanghao d32dfbacaa fix problem for oom flee 2021-09-07 15:15:41 +08:00
opengauss-bot 9716e5359e !1255 修复备机归档中确认起点效率低引起归档错误的bug
Merge pull request !1255 from Cross-罗/my_own_2_0
2021-09-07 03:32:43 +00:00
luozihao 1498872c34 修复备机xlog归档起点的bug,并进行代码和日志打印优化 2021-09-07 10:56:05 +08:00
opengauss-bot 4997aaa735 !1252 gs_guc增加对min_dynamic_memory的支持
Merge pull request !1252 from 杨皓/2.0.0
2021-09-06 08:45:27 +00:00
yanghao 1b3a1e41a4 support min_dynamic_memory in gs_guc 2021-09-06 15:59:29 +08:00
opengauss-bot 0c2e6e7098 !1250 增加数据库出现OOM时的逃生手段
Merge pull request !1250 from 杨皓/2.0.0
2021-09-04 07:48:36 +00:00
opengauss-bot 4631ea876e !1249 回滚事务计数不再包括逻辑解码线程
Merge pull request !1249 from LiHeng/2.0.0
2021-09-03 08:44:36 +00:00
yanghao d1c210cdc0 add method to clean idle connection while oom 2021-09-03 16:32:12 +08:00
LiHeng 1f6e6c2638 walsender for logical decoding will not count rollback transaction 2021-09-03 14:53:36 +08:00
opengauss-bot bb0fd6ca83 !1206 修复两个memcheck检测到的内存越界访问问题
Merge pull request !1206 from gentle_hu/2.0.0
2021-08-31 07:45:59 +00:00
opengauss-bot d5227f5f65 !1242 逻辑解码snapshot增强
Merge pull request !1242 from maxiang/snapshot-2.0
2021-08-28 10:41:16 +00:00
Xiao__Ma 6adcc36fc6 enhance snapshot 2021-08-28 17:43:46 +08:00
opengauss-bot 50aee20da9 !1218 split分区、merge分区时同时复制reloptions 同步代码至2.0.0分支
Merge pull request !1218 from 吴岳川/partition2
2021-08-23 06:34:19 +00:00
opengauss-bot 631cc42d1e !1222 修复gs_probackup增量备份数据不完整
Merge pull request !1222 from LiHeng/2.0.0
2021-08-15 03:06:46 +00:00
LiHeng 53395ca206 fix invalid blocknum for incremental backup 2021-08-14 22:51:17 +08:00
wuyuechuan 5eb44eed53 add partition reloptions when split partition or merge partition 2021-08-13 12:17:23 +08:00
opengauss-bot 78c42f2a25 !1209 修复内存泄漏问题
Merge pull request !1209 from maxiang/memory-2
2021-08-12 09:55:53 +00:00
opengauss-bot 3bec247d73 !1215 Fix issue: handle combined scenario of 'order' and '*' in single query index advisor
Merge pull request !1215 from liuly/2.0.0
2021-08-11 06:47:50 +00:00
liuly 0a8e37b025 Fix issue: Fix bugs on the index advisor: handle combined scenario of 'order' and '*' in single query index advisor 2021-08-10 18:53:35 +08:00
opengauss-bot b8c6463548 !1210 修复普通用户查询get_local_active_session()时,在对null数组赋值时未适配列的问题
Merge pull request !1210 from 周雄佳/zxj2.0.0
2021-08-10 09:28:08 +00:00
zhouxiongjia 1453860560 fix a core problem 2021-08-10 16:03:10 +08:00
Xiao__Ma e1b9418050 fix memory leakage 2021-08-10 14:30:39 +08:00
gentle_hu e08739048f fix memcheck issue: 1 to_number(), 2 core of spliting hash partition by range-gram 2021-08-10 09:46:50 +08:00
opengauss-bot d6ed737bc7 !1203 [同步PR] 同步master分支中多个已合并的PR 到2.0分支
Merge pull request !1203 from cchen676/late20
2021-08-07 08:15:15 +00:00
Song Rongrong 52f0789fb8 upsert 2021-08-06 20:07:36 +08:00
jackchenchenchen de8703b2fc fix: the SIGUSR2 flag bit is reset to False when a thead exists and interrupts are interrupted 2021-08-06 20:07:36 +08:00
LiHeng 903c81598e 修复线程池flag长跳转,导致其他session无法获取锁,hang 2021-08-06 20:07:36 +08:00
lanchunyi 23ce4e04b4 修复fd泄漏问题 2021-08-06 20:07:36 +08:00
joker 71f3e152a4 Fix probackup to point node and cluster can not be start 2021-08-06 20:07:36 +08:00
Xiao__Ma e8f21ffeb1 buf 2021-08-06 20:07:36 +08:00
liyifeng_seu 4708c83460 update src/bin/pg_probackup/pgut.cpp.
修复probackup内存泄露问题
2021-08-06 20:07:36 +08:00
liyifeng_seu 76ee161a69 update src/bin/pg_probackup/pg_probackup.cpp.
修复probackup内存泄露问题
2021-08-06 20:07:36 +08:00
liyifeng_seu f27365b926 update src/bin/pg_basebackup/pg_basebackup.cpp.
修复basebackup的内存泄露问题
2021-08-06 20:07:36 +08:00
nwen 08f2655e39 no massage returned, when GUC is set in the init session if thread pool 2021-08-06 20:07:36 +08:00
nwen 3dfa80b335 secure compilation 2021-08-06 20:07:36 +08:00
flyly fa702eb6c3 fix core 2021-08-06 20:07:36 +08:00
flyly 9bb33c2a4b 解决:【业务范畴:分布式】【测试类型:压力长稳】【测试活动:专项】【专项名称:压力长稳】【环境:裸机】执行TPCC+混合DDL、DML业务,CN产生hang 2021-08-06 20:07:36 +08:00
LiHeng 080c54c9da 修复主机drop表同时全量build后,备机数据目录比主机大问题 2021-08-06 20:07:35 +08:00
LiHeng 561ba0ebcd 添加内存屏障,保证读取的变量是当前最新值 2021-08-06 20:07:35 +08:00
LiHeng a7e92ffd28 fix threadpool 2021-08-06 20:07:35 +08:00
cchen676 14fc938f54 fix xlog recycle when start 2021-08-06 20:07:35 +08:00
herui d40098a5e2 fix percentile thread consumes 7% cpu when no user workload running 2021-08-06 20:07:35 +08:00
lijianfeng 34f457d2aa bug fix for heap-use-after-free in check_statement_stat_level 2021-08-06 20:07:35 +08:00
wangzhenzhen d470ef5f50 修复子事务里内存报错core问题 2021-08-06 20:07:35 +08:00
Xiao__Ma c1a69126a5 vacuum 2021-08-06 20:07:35 +08:00
Li Bingchen 53480bc2e4 FixIssue: fix slow_sql mismatch while behavior_compat_options = -1 2021-08-06 20:07:35 +08:00
wangtq 52f2f17864 prevent bitmapscan using global indexes while searching only local partitions 2021-08-06 20:07:35 +08:00
wangtq 893dc25515 fix jdbc端查询point数值报错 2021-08-06 20:07:35 +08:00
aaronwell f3ac0f81ec gs_rewind 2021-08-06 20:07:35 +08:00
cchen676 ed81aff7ea fix add bufferinvaild jug 2021-08-06 20:07:32 +08:00
yanghao 74a53a08c2 fix CreateRestartPoint core not correct in extreme rto 2021-08-06 19:17:56 +08:00
wangxin fd31bfbba6 report_iud_time函数中try catch跳转后锁队列混乱 2021-08-06 19:17:31 +08:00
wangxin 1a20907a0c fix shared_buffers设置极小时,淘汰策略ring size为0 2021-08-06 19:17:11 +08:00
dengxuyue 34830974d0 add smgrnblock cache and revert logical of block exist in
smgr/md
2021-08-06 19:16:47 +08:00
dengxuyue 0d1a224b9b fix switchover & stop walreceiver exit abnormal 2021-08-06 19:16:07 +08:00
mujinqiang f9ccb7f333 reaperall时进入exitpostmaster导致core 2021-08-06 19:15:39 +08:00
mujinqiang 17198aede1 合入增加build完成后数据flush落盘 2021-08-06 19:15:11 +08:00
opengauss-bot 0399758403 !1134 增加dn停止时通知逻辑解码线程退出的逻辑
Merge pull request !1134 from maxiang/logical2
2021-08-06 08:14:17 +00:00
opengauss-bot 1e1deb8ccb !1136 优化清理临时表流程,弃用工具gs_clean,改为在内核操作
Merge pull request !1136 from maxiang/clean2
2021-08-06 08:02:55 +00:00
opengauss-bot 29b6e0ae0b !1164 Fix issue: Fix bugs on the index advisor: single query index advisor reports out of memory
Merge pull request !1164 from liuly/2.0.0
2021-08-06 07:44:39 +00:00
maxiang f973f66c91 Merge branch '2.0.0' of gitee.com:opengauss/openGauss-server into clean2 2021-08-06 03:00:13 +00:00
maxiang 8b911a9ecc update src/common/backend/utils/init/miscinit.cpp. 2021-08-06 02:51:43 +00:00
opengauss-bot f7c9c74e94 !1197 回合master PR 1111 修复分区表并发update问题
Merge pull request !1197 from cchen676/late20
2021-08-06 01:36:39 +00:00
dengxuyue 7dfaa30b61 Fixed partition table concurrent update issue 2021-08-05 19:16:22 +08:00
liuly da0810db73 handle warning 2021-08-05 08:46:12 +00:00
liuly 1fcee7bded handle warning 2021-08-05 07:38:56 +00:00
opengauss-bot 8105a88efc !1149 支持cgroup
Merge pull request !1149 from gentle_hu/2.0.0
2021-08-05 07:11:10 +00:00
opengauss-bot 853f28b007 !1147 delete unused variable 'idx'
Merge pull request !1147 from chenxiaobin/2.0.0
2021-08-05 06:20:06 +00:00
liuly 8fa6f5d266 Fix issue: Fix bugs on the index advisor: single query index advisor reports out of memory 2021-08-04 06:34:56 +00:00
gentle_hu 530c4f9295 fix cgroup 2021-08-04 14:21:34 +08:00
opengauss-bot 18b92d0179 !1156 Fix issue: Fix bugs on the index advisor: repair log extraction function
Merge pull request !1156 from liuly/2.0.0
2021-08-04 06:19:59 +00:00
liuly afc8573e0c Fix bugs on the index advisor: repair log extraction function 2021-08-03 12:31:45 +00:00
liuly cb7199ad10 Fix issue: Fix bugs on the index advisor: repair log extraction function 2021-08-03 11:50:29 +00:00
opengauss-bot 08ff95ceac !1150 Fix issue: Fix bugs on the index advisor: String overlength related bugs
Merge pull request !1150 from liuly/2.0.0
2021-08-03 11:30:54 +00:00
opengauss-bot 2cb242dea4 !1114 修复分区表并发访问,锁冲突导致的系统hang
Merge pull request !1114 from 杨皓/lock2
2021-08-03 07:36:23 +00:00
opengauss-bot 07cf79cd4c !1115 修复反复对分区表执行split、merge后,执行vacuum freeze pg_partition报错的问题
Merge pull request !1115 from 杨皓/vacuum2
2021-08-03 07:35:11 +00:00
opengauss-bot ae0bba2497 !1112 修复普通表的数据迁移到分区报错,压缩标记有定义的时候,把它置为NOCOMPRESS
Merge pull request !1112 from maxiang/parse-2.0.0
2021-08-03 07:33:26 +00:00
opengauss-bot b270c85d0d !1113 全局分区索引适配支持ANALYZE VERIFY FAST
Merge pull request !1113 from mujinqiang/mjq200
2021-08-03 07:32:43 +00:00
maxiang e929c3d736 update src/common/backend/utils/init/postinit.cpp. 2021-08-03 07:26:20 +00:00
maxiang 47a29a6549 update src/gausskernel/process/postmaster/twophasecleaner.cpp. 2021-08-03 07:25:16 +00:00
flyly e16bcf5447 Fix issue: Fix bugs on the index advisor: String overlength related bugs 2021-08-03 11:49:04 +08:00
chenxiaobin19 a9b1ed440b delete unused variable 'idx' 2021-08-02 14:18:41 +08:00
Xiao__Ma 2f0096bbf4 clean 2021-07-31 09:49:41 +08:00
opengauss-bot bf913706f4 !1139 Fix issue: Fix a bug on the index advisor: Repair log extraction
Merge pull request !1139 from liuly/2.0.0
2021-07-29 12:40:53 +00:00
flyly 01aa74162a Fix issue: Fix a bug on the index advisor: Repair log extraction 2021-07-29 19:51:29 +08:00
opengauss-bot 47c987f3ab !1132 修复bypass执行带setMaxRows报错
Merge pull request !1132 from maxiang/bypass2
2021-07-29 11:17:44 +00:00
Xiao__Ma 597e454f8e logical 2021-07-29 15:37:57 +08:00
Xiao__Ma 3ec8df390c bypass 2021-07-29 15:36:32 +08:00
opengauss-bot 2f1e988b6f !1129 Update index advisor: Index recommendation function enhancement
Merge pull request !1129 from liuly/2.0.0
2021-07-29 01:47:54 +00:00
flyly b8b38213df Index recommendation function enhancement 2021-07-28 20:04:26 +08:00
opengauss-bot c5661c88a9 !1033 fix gpc bug and optimize gpc performance
Merge pull request !1033 from gentle_hu/2.0.0
2021-07-27 12:41:51 +00:00
opengauss-bot a189abd40e !1116 分区表交换分区时,如果指定verbose会报错
Merge pull request !1116 from ShineStarStar/2.0.0
2021-07-26 13:05:26 +00:00
gentle_hu c6b1e6dd61 fix gpc compare searchpath problem 2021-07-26 10:19:17 +08:00
wangxin 6a6d31e033 verbose报错 2021-07-23 14:35:57 +08:00
yanghao 9daeecabab fix partition table get lock hang 2021-07-23 10:07:39 +08:00
yanghao fa1c39017d Fixed the vacuum freeze issue caused by partition split and merge for a long time. 2021-07-23 10:06:45 +08:00
mujinqiang 7825074686 全局分区索引适配支持ANALYZE VERIFY FAST 2021-07-23 10:02:20 +08:00
opengauss-bot 4cae2a598f !1086 同步[PR 1085 PR 1061] 到2.0分支
Merge pull request !1086 from cchen676/new2.0
2021-07-21 09:46:05 +00:00
cchen676 af29fcb32c fix issue 恢复pg_dw_single文件时跳过了对索引为0位置的数据页面的处理 2021-07-21 16:15:28 +08:00
Xiao__Ma be3daf9735 parse 2021-07-21 15:38:31 +08:00
opengauss-bot ee41b69791 !1095 修改此处判断HA端口方式,isLocalport接口在走AF_UNIX协议时不生效
Merge pull request !1095 from mujinqiang/mjq200
2021-07-20 06:58:46 +00:00
mujinqiang be03869079 改此处判断HA端口方式,isLocalport接口在走AF_UNIX协议时不生效 2021-07-17 11:26:56 +08:00
opengauss-bot 009f101444 !1092 Fix issue: Fix a bug on the index advisor: Repair log extraction to identify database information
Merge pull request !1092 from liuly/2.0.0
2021-07-15 11:47:42 +00:00
flyly 6c642dfb0f bugfix:Repair log extraction 2021-07-15 18:03:00 +08:00
opengauss-bot cf68d6850f !1090 Update index advisor:support python driver and Index recommended lightweight deployment
Merge pull request !1090 from liuly/2.0.0
2021-07-15 08:48:29 +00:00
flyly 48a1e97eb6 Update index recommendation code 2021-07-15 15:35:32 +08:00
opengauss-bot 1e38a0e8ac !1082 同步[PR 1081 wdr snapshot更新统计信息]到2.0分支
Merge pull request !1082 from cchen676/new2.0
2021-07-12 12:31:03 +00:00
LiHeng ba1300e7bb report wdr snapshot table statistics 2021-07-12 17:44:04 +08:00
opengauss-bot 71eae51f51 !1078 修复备机超大事物解码无法正常推进问题
Merge pull request !1078 from maxiang/2.0.0
2021-07-12 09:37:33 +00:00
opengauss-bot 217801b8e6 !1080 回合unique_sql自动淘汰特性到2.0.0分支
Merge pull request !1080 from TotaJ/test_2
2021-07-12 07:39:37 +00:00
TotaJ 7f68b9106d Change unique_sql_clean_ratio to SIGHUP level. 2021-07-09 17:04:55 +08:00
xue_meng_en 942963ce99 支持uniqueSQL自动淘汰
修复bug

修复bug

修复bug

修改检视意见
2021-07-09 17:04:37 +08:00
TotaJ eb8a201dd8 Fix unique sql bug. 2021-07-09 17:04:01 +08:00
Xiao__Ma 137f9e27da logical 2021-07-09 10:07:49 +08:00
opengauss-bot 8145a970b8 !1074 skip the explain sql when recording in the unique sql view
Merge pull request !1074 from lishifu/2.0.0
2021-07-08 08:24:08 +00:00
lishifu_db 8908b5b686 skip the explain sql 2021-07-08 15:30:49 +08:00
opengauss-bot e55fe34bd1 !1067 RAS:UCE故障感知修改函数入口以及退出方式
Merge pull request !1067 from Ricardo_Cui/2.0.0
2021-07-03 06:44:16 +00:00
opengauss-bot 934ede745f !1068 回合master分支的部分PR
Merge pull request !1068 from cchen676/new2.0
2021-07-03 02:23:01 +00:00
movead a0b573df19 fix issue that receive thread has no chance to send a feedback 2021-07-02 17:40:07 +08:00
movead 132ecf4dfb issue when gs_probackup backup from standby,and if pg_stop_backup return invalid lsn then backup faild after timeout 2021-07-02 17:39:48 +08:00
ashnah de938b0876 add RESUME_INTERRUPTS before throw 2021-07-02 17:39:32 +08:00
ashnah ffa89332fd modify build error 2021-07-02 17:39:22 +08:00
ashnah 71dc7a8d23 use holdinterrupt instead of block signal 2021-07-02 17:39:10 +08:00
ashnah 65f0c17ba0 Fix the problem of deadlock when shutting down 2021-07-02 17:38:51 +08:00
Hemny 75b48e5d5d 备机连接可以走非HA端口,根据配置中的连接信息决定 2021-07-02 17:38:25 +08:00
Hemny 0cd2b0be96 修复 使用replication协议连接监听端口后,数据库stop失败的问题
openGauss中,replication协议不能用线程池的线程。
如果数据库启用了线程池,并且出现用户操作失误使用了replication协议工具连接监听端口,连接失败后造成工作线程直接退出,引起gs_ctl stop停库失败。

现在直接在连接数据库时限制如果线程池模式下,replication工具只能通过HA端口连接数据库。
2021-07-02 17:38:10 +08:00
opengauss-bot 830c7b65c5 !1064 逻辑日志解析时多版本读元信息
Merge pull request !1064 from maxiang/2.0.0
2021-07-02 09:27:54 +00:00
Ricaro.Cui df7ce14ac5 add enableIncrementalCheckpoint condition 2021-07-02 12:16:21 +08:00
Ricaro.Cui 5833a6ade8 add sigmask 2021-07-02 10:53:11 +08:00
maxiang 186ec1e3d6 update src/common/backend/catalog/pg_partition.cpp. 2021-07-02 02:28:10 +00:00
Ricaro.Cui 9e08c03365 RAS:UCE 2021-07-01 20:26:06 +08:00
Xiao__Ma 9b22bbca66 logical 2021-06-30 15:57:37 +08:00
opengauss-bot e7466a0ba5 !1060 Add GUC track_stmt_parameter to record a statement with parameters
Merge pull request !1060 from wangtq/2.0.0
2021-06-30 06:37:11 +00:00
wangtq 161392ce01 feat (WDR): add GUC track_stmt_parameter to record a statement with parameters 2021-06-29 15:39:33 +08:00
wangtianqing 00464751 fc0bd72f7c fix (xtuner): fix the importing for logging 2021-06-29 15:39:33 +08:00
opengauss-bot 4d9e5c3995 !1055 同步lsn check例外场景:truncate之后再init出来的page,不做检查
Merge pull request !1055 from mujinqiang/recuess
2021-06-28 12:03:33 +00:00
mujinqiang 1de15e5767 lsn check例外场景:truncate之后再init出来的page,不做检查 2021-06-26 17:20:16 +08:00
opengauss-bot 2f6663e0a8 !1046 Fixed the bug that a memory leak occurs when archiving is enabled on the standby node.
Merge pull request !1046 from Cross-罗/patch_branch
2021-06-22 14:16:37 +00:00
luozihao d7db88e63c 修复开启备机归档时内存泄漏的bug 2021-06-22 20:54:13 +08:00
opengauss-bot ed0ed87142 !1043 将全局变量relfilenode_skey改为session级,修复逻辑复制问题
Merge pull request !1043 from maxiang/2.0.0
2021-06-18 17:23:58 +08:00
maxiang 68bb7f6db4 update src/include/knl/knl_session.h. 2021-06-18 16:52:18 +08:00
Li Bingchen e16a7dc8e6 session 2021-06-18 15:39:35 +08:00
opengauss-bot f571ec39a4 !1040 fixbug for index_advisor: field value length
Merge pull request !1040 from oohlala/2.0.0
2021-06-18 11:32:18 +08:00
z00574602 14575e716e fixbug for index_advisor: field value length 2021-06-17 19:40:31 +08:00
gentle_hu 5801e94cb5 fix gpc bug and optimize gpc performance 2021-06-17 09:56:36 +08:00
opengauss-bot ea09eb38b3 !1026 RAS:基于4p pro的故障感知
Merge pull request !1026 from Ricardo_Cui/2.0.0
2021-06-16 15:44:03 +08:00
opengauss-bot 06a67d97c8 !942 【轻量级 PR】:update src/gausskernel/dbmind/tools/predictor/python/model.py.
Merge pull request !942 from 宋清怡/N/A
2021-06-15 14:55:19 +08:00
opengauss-bot 8c0b5d2d25 !1018 Fix issue: Fix some bugs on the xtuner
Merge pull request !1018 from wangtq/2.0.0
2021-06-13 14:50:41 +08:00
Racardo.Cui fe108e5081 RAS:基于4P pro的UCE故障感知 2021-06-11 11:11:49 +08:00
wangtq 6bf1fb2f9c fix (xtuner): change import form and simplify neural network 2021-06-07 15:00:14 +08:00
opengauss-bot d2cc245629 !1014 Fix issue: Fix a bug on the index advisor: handling of missing parts of join on scene
Merge pull request !1014 from liuly/2.0.0
2021-06-07 10:45:43 +08:00
flyly 54c9ee660f Fix issue: Fix a bug on the index advisor: handling of missing parts of join on scene 2021-06-04 11:32:39 +08:00
opengauss-bot 86c7b50454 !1012 charry-pick: 增加memory peak facility,
Merge pull request !1012 from gentle_hu/2.0.0
2021-06-03 20:20:35 +08:00
zankyfun4 974d93ac1a add peak memory information for query 2021-06-03 19:52:52 +08:00
opengauss-bot d97c0e8a59 !1010 解决自动化测试时由于多线程并发调用init_gauss_cluster_config导致coredump
Merge pull request !1010 from cchen676/new2.0
2021-06-02 19:32:45 +08:00
cchen676 2ed6eb7e73 fix up 自动化连跑时多线程并发调用init_gauss_cluster_config导致coredump 2021-06-02 15:52:01 +08:00
opengauss-bot cfb2309a2f !1007 fix core about gs_guc reload
Merge pull request !1007 from zhengxue/2.0.0
2021-06-01 20:39:57 +08:00
shirley_zhengx f60dd06e4e fix core
fix core about gs_guc reload
2021-06-01 19:56:30 +08:00
opengauss-bot eda1e7a059 !1006 update server version to 2.0.1
Merge pull request !1006 from zhangxubo/2.0.1
2021-06-01 19:48:00 +08:00
opengauss-bot ae9a04a7d7 !995 gs_collector收集plan信息时候,缺少gs_plan_simulator.sh脚本
Merge pull request !995 from zhangxubo/2.0.0
2021-06-01 14:02:21 +08:00
zhangxubo 1512d8c2b2 update version to 2.0.1 2021-05-31 17:09:09 +08:00
opengauss-bot 8aa97848db !999 optimizer for signal block in threadpool
Merge pull request !999 from 杨皓/2.0.0
2021-05-31 09:52:17 +08:00
opengauss-bot 37ce2f004c !1003 极致RTO优化
Merge pull request !1003 from 赵文浩/2.0.0
2021-05-31 09:51:21 +08:00
opengauss-bot e8cfcb6913 !1001 修复JDBC连接备机解码,lsn回推问题
Merge pull request !1001 from maxiang/2.0.0
2021-05-29 18:10:51 +08:00
zhaowenhao 29cda19e0a 极致RTO优化 2021-05-29 15:41:01 +08:00
maxiang 6f90fd61ef update src/gausskernel/storage/replication/logical/logical.cpp. 2021-05-29 10:18:28 +08:00
maxiang ef48e48294 update src/gausskernel/storage/replication/walsender.cpp. 2021-05-29 10:17:14 +08:00
opengauss-bot 7d89cf9b71 !994 Fix issue: Fix a bug on the index advisor: bad type casting and strengthen the hypo-index
Merge pull request !994 from liuly/2.0.0
2021-05-29 10:16:05 +08:00
opengauss-bot e2a9abadf0 !997 Update SQLDiag: Add two threshold judgments
Merge pull request !997 from wangtq/2.0.0
2021-05-28 20:11:08 +08:00
opengauss-bot 9037554735 !998 更改是否执行下一个归档任务的判断
Merge pull request !998 from Cross-罗/patch_branch
2021-05-28 19:20:41 +08:00
yanghao ea6cb7bc85 optimizer for signal block in threadpool 2021-05-28 17:27:17 +08:00
luozihao 0ef7e16c01 更改是否执行下一个归档任务的判断 2021-05-28 16:28:46 +08:00
wangtq 255f2f088d maintain (index-advisor): add two threshold judgements 2021-05-28 15:49:40 +08:00
opengauss-bot 873d312766 !980 修复备机归档bug
Merge pull request !980 from Cross-罗/patch_branch
2021-05-28 15:44:32 +08:00
liuly b0cf1b5a71 Fix issue: Fix a bug on the index advisor: bad type casting and strengthen the hypo-index 2021-05-28 15:15:24 +08:00
zhangxubo dde0db6e41 add gs_plan_simulator.sh file in package shell 2021-05-28 14:49:47 +08:00
luozihao 6884947f92 编码规范化 2021-05-28 09:44:45 +08:00
luozihao 4038da4073 fixed the bug of standby archiving 2021-05-27 14:21:53 +08:00
opengauss-bot 76d06ea404 !985 解决session退出时系统无权限访问gs_encrypted_table问题
Merge pull request !985 from Li Bingchen/2.0.0
2021-05-27 10:25:12 +08:00
opengauss-bot 93ffe79fdf !987 回合master 分区锁降级
Merge pull request !987 from 赵文浩/2.0.0
2021-05-26 17:58:49 +08:00
zhaowenhao 35a33b0477 回合master 分区锁降级 2021-05-26 16:05:49 +08:00
Li Bingchen 65328fecc4 解决session退出时系统无权限访问gs_encrypted_table问题 2021-05-26 11:07:34 +08:00
luozihao 38cbb219a4 解决编译告警问题 2021-05-24 11:08:34 +08:00
opengauss-bot 91fa7c590a !962 fix 集群内多个节点坏死,gs_dropnode无法正常执行
Merge pull request !962 from cchen676/new2.0
2021-05-20 16:32:19 +08:00
opengauss-bot 66aab91c24 !973 修复备机归档bug
Merge pull request !973 from Cross-罗/patch_branch
2021-05-20 14:39:07 +08:00
luozihao 9ce2d71763 解决新引入的备机xlog回收的bug 2021-05-20 10:36:28 +08:00
luozihao 3571af9264 修复备机归档的bug 2021-05-18 14:33:13 +08:00
opengauss-bot 710b91df67 !968 延时参数修改为保存到u_sess中
Merge pull request !968 from mujinqiang/recuess
2021-05-17 19:48:28 +08:00
mujinqiang 1eb23621ba 延时参数修改为保存到u_sess中 2021-05-17 16:18:10 +08:00
opengauss-bot 6b600011ef !959 Synchronize the bugfixes from master branch
Merge pull request !959 from wangtq/2.0.0
2021-05-17 11:33:40 +08:00
w00464751 335ad7ab79 chore (xtuner): enhance xtuner's stability and add several new features and fix some bugs
Modifications:
    fix (xtuner): easy to install dependencies
    fix (xtuner): refactor exec_statement
    fix (xtuner): change recorder to csv format and run the initial knobs
    fix (xtuner): fix the bug that shared_buffers has no round
    fix (xtuner): change round4() to return a int value and apply it to max_process_memory
    fix (xtuner): remove out default field and repalce with recommend field
    feat (xtuner): support period benchmark
    feat (xtuner): support Python version check
    feat (xtuner): support to recommend more knobs
    feat (xtuner): add a new function that can traverse all properties from Advisor
    refactor (xtuner): refactor some benchmark driver scripts
2021-05-14 16:27:19 +08:00
wangtq d30a31dc44 Revert "fix (xtuner): fix the bug that shared_buffers has no round"
This reverts commit 1afa003280.
2021-05-14 16:27:09 +08:00
cchen676 9302324edf fix issue
当配置synchronous_standby_names参数的值为和主节点不在一个AZ内的备节点时,
会报错,这个是因为guc参数检查导致,修改内核中guc相关代码去掉该检查
2021-05-14 16:08:02 +08:00
opengauss-bot aa802913dc !961 修复备机xlog归档的bug
Merge pull request !961 from Cross-罗/patch_branch
2021-05-14 14:50:15 +08:00
luozihao 98ea2c0c6d 添加相应注释 2021-05-14 12:45:07 +08:00
luozihao 79eb60ec65 优化代码结构 2021-05-14 10:38:00 +08:00
Cross-罗 2cc54fcbe0 Merge branch '2.0.0' of gitee.com:opengauss/openGauss-server into patch_branch 2021-05-13 21:40:25 +08:00
luozihao 926e3140a4 修复备机xlog归档的bug 2021-05-13 21:36:00 +08:00
wangtq 3f9b68d3b5 fix (dbmind): fix some bugs on the index-advisor and add extract_log.py 2021-05-13 20:31:41 +08:00
opengauss-bot 9ffe07c287 !957 【轻量级 PR】:修复备机归档在切换日志时可能会core的bug
Merge pull request !957 from Cross-罗/N/A
2021-05-12 20:23:08 +08:00
Cross-罗 3da699c225 修复北极归档在切换日志时可能会core的bug 2021-05-12 19:56:31 +08:00
opengauss-bot 5cf37d09a8 !954 Enable the xlog archiving function of the standby node
Merge pull request !954 from Cross-罗/archive_xlog_standby
2021-05-11 09:53:47 +08:00
luozihao 03f5c450a7 Enable the xlog archiving function of the standby node 2021-05-10 20:29:32 +08:00
opengauss-bot c8ed01893a !951 【openGauss】Fix some bugs on the index advisor
Merge pull request !951 from 宋清怡/2.0.0
2021-05-10 15:02:36 +08:00
wangtq 9d98a96424 fix (dbmind): fix some issues on index advisor 2021-05-08 10:36:57 +08:00
wangtq beb58498ea feat (dbmind): update sqldiag 2021-05-08 10:32:43 +08:00
opengauss-bot 7147032489 !946 解决备机createRestartpoint时报错current dirty page list head smaller than redo lsn
Merge pull request !946 from cchen676/new2.0
2021-05-06 19:39:55 +08:00
opengauss-bot a6bca8da91 !943 GPC适回合2.0.0分支
Merge pull request !943 from 赵文浩/2.0.0
2021-05-06 17:45:16 +08:00
cchen676 dd0d35fed5 fix 备机报错current dirty page list head smaller than redo lsn 2021-05-06 11:53:20 +08:00
opengauss-bot e7bdddbfb7 !941 [Lightweight PR]: Fix free dirty_page_queue
Merge pull request !941 from TotaJ/N/A
2021-04-30 16:46:42 +08:00
TotaJ 20c720785c fix symbol 2021-04-30 09:45:21 +08:00
TotaJ 6b05f10be4 return back IsStreamSupport 2021-04-30 09:45:04 +08:00
TotaJ 114c58d19f fix GPC bug with memoryleak and make it suitable for SQLBYPASS 2021-04-30 09:44:44 +08:00
宋清怡 0010c147ba update src/gausskernel/dbmind/tools/predictor/python/model.py. 2021-04-29 19:10:28 +08:00
opengauss-bot 9d63994ad9 !938 备机逻辑复制通知主机更新restart_lsn
Merge pull request !938 from maxiang/2.0.0
2021-04-29 17:24:48 +08:00
TotaJ f03c3fb372 Fix free dirty_page_queue 2021-04-29 17:00:56 +08:00
maxiang bc4795bde0 update src/gausskernel/process/threadpool/knl_thread.cpp. 2021-04-29 12:33:58 +08:00
Xiao__Ma 32dfafd391 restart 2021-04-29 11:56:53 +08:00
opengauss-bot a13cbeea2a !932 Fix issue: Fix some bugs on the index advisor
Merge pull request !932 from 宋清怡/2.0.0
2021-04-27 21:42:56 +08:00
wangtq 8549fe7257 fix (dbmind): fix some bugs on the index advisor 2021-04-27 20:49:59 +08:00
opengauss-bot e33dec6c43 !931 优化备机catchup时主机阻塞场景方案
Merge pull request !931 from chenxiaobin/2.0.0
2021-04-27 17:00:46 +08:00
chenxiaobin c2e37342f7 fixbug: divided by zero 2021-04-27 16:27:58 +08:00
chenxiaobin dcdd71384b optimize primary hang scenario when standby in catchup 2021-04-27 16:27:13 +08:00
opengauss-bot b071fe9f99 !924 合并提交master代码到2.0.0
Merge pull request !924 from 赵文浩/2.0.0
2021-04-27 11:12:29 +08:00
gentle_hu 360d281ceb fix selectForUpdateFusion core in fetch size case. 2021-04-23 11:55:40 +08:00
TotaJ bf32e4ae36 Fix unique sql bug. 2021-04-23 11:55:19 +08:00
opengauss-bot d2de98cea1 !922 回退代码
Merge pull request !922 from chenxiaobin/2.0.0
2021-04-22 23:42:49 +08:00
yanghao a8e142f0cb Revert "fix memory leak in pgxc_planner"
This reverts commit e50da3586d.
2021-04-22 21:09:26 +08:00
Xiao__Ma 08f2a403fa upsert 2021-04-22 21:08:13 +08:00
maxiang 30e066555e update src/gausskernel/runtime/executor/opfusion.cpp. 2021-04-22 21:08:07 +08:00
Xiao__Ma 43fd81e96a memory 2021-04-22 21:08:00 +08:00
wangxin 7674a2a9eb 修复删除正在解码的复制槽时,备机数据库停止的问题 2021-04-22 21:07:55 +08:00
wangxin 2e6258fde4 修复pbe场景下单机smp使用limit出现hang的问题 2021-04-22 21:07:50 +08:00
wangxin 440355076f 修复SystemCache清理逻辑错误的问题 2021-04-22 21:07:39 +08:00
wangxin b872b011ea 优化pg_recvlogical提示信息 2021-04-22 21:07:34 +08:00
wangxin 78f38bb9cb fixddl_pbe内存释放未置空 2021-04-22 21:07:29 +08:00
yanghao e6c44f068b sync gaussdb kernel bug-fix 2021-04-22 21:07:20 +08:00
dengxuyue 46e97fe6f8 removed unused variable 2021-04-22 21:07:14 +08:00
dengxuyue 4d60233c3b Fix inc build backup rewind find problem 2021-04-22 21:06:51 +08:00
dengxuyue 90274f363e Fix malloc 2021-04-22 21:06:45 +08:00
dengxuyue e85e79a09e Fix communiction issues 2021-04-22 21:06:40 +08:00
mujinqiang 1c05419296 回合代码fixvacuum+limit语句不退出 2021-04-22 21:06:34 +08:00
xiepy 896bdd99d9 优化gs_probackup备机备份会打印很多重复log问题 2021-04-22 21:06:27 +08:00
LiHeng 6a283ac83e add smgr cached nblocks for main fork
Avoid repeatedly calling smgrnblocks() in read query on standby.
Now, we only add cached nblocks in main fork.
2021-04-22 21:06:20 +08:00
chenxiaobin a6e46957f5 rollback 2021-04-22 15:46:52 +08:00
430 changed files with 25272 additions and 14503 deletions

View File

@ -881,6 +881,9 @@ function install_gaussdb()
fi fi
fi fi
# copy gs_plan_simulator.sh to /bin dir. it's used in gs_collector tool.
cp ${ROOT_DIR}/src/bin/gs_plan_simulator/gs_plan_simulator.sh ${BUILD_DIR}/bin/
chmod 444 ${BUILD_DIR}/bin/cluster_guc.conf chmod 444 ${BUILD_DIR}/bin/cluster_guc.conf
dos2unix ${BUILD_DIR}/bin/cluster_guc.conf > /dev/null 2>&1 dos2unix ${BUILD_DIR}/bin/cluster_guc.conf > /dev/null 2>&1

View File

@ -1,2 +1,2 @@
PRODUCT=openGauss PRODUCT=openGauss
VERSION=2.0.0 VERSION=2.0.3

View File

@ -29,6 +29,7 @@
./bin/transfer.py ./bin/transfer.py
./bin/bind_net_irq.sh ./bin/bind_net_irq.sh
./bin/setArmOptimization.sh ./bin/setArmOptimization.sh
./bin/gs_plan_simulator.sh
./bin/krb5kdc ./bin/krb5kdc
./bin/klist ./bin/klist
./bin/kinit ./bin/kinit
@ -877,6 +878,9 @@
./lib/postgresql/latin2_and_win1250.so ./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so ./lib/postgresql/euc2004_sjis2004.so
./lib/libhll.so ./lib/libhll.so
./lib/libzstd.so
./lib/libzstd.so.1
./lib/libzstd.so.1.4.4
./include/postgresql/server/postgres_ext.h ./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h ./include/postgresql/server/pg_config_os.h

View File

@ -29,6 +29,7 @@
./bin/transfer.py ./bin/transfer.py
./bin/bind_net_irq.sh ./bin/bind_net_irq.sh
./bin/setArmOptimization.sh ./bin/setArmOptimization.sh
./bin/gs_plan_simulator.sh
./bin/krb5kdc ./bin/krb5kdc
./bin/klist ./bin/klist
./bin/kinit ./bin/kinit
@ -877,6 +878,9 @@
./lib/postgresql/latin2_and_win1250.so ./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so ./lib/postgresql/euc2004_sjis2004.so
./lib/libhll.so ./lib/libhll.so
./lib/libzstd.so
./lib/libzstd.so.1
./lib/libzstd.so.1.4.4
./include/postgresql/server/postgres_ext.h ./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h ./include/postgresql/server/pg_config_os.h

View File

@ -29,6 +29,7 @@
./bin/transfer.py ./bin/transfer.py
./bin/bind_net_irq.sh ./bin/bind_net_irq.sh
./bin/setArmOptimization.sh ./bin/setArmOptimization.sh
./bin/gs_plan_simulator.sh
./bin/krb5kdc ./bin/krb5kdc
./bin/klist ./bin/klist
./bin/kinit ./bin/kinit
@ -877,6 +878,9 @@
./lib/postgresql/latin2_and_win1250.so ./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so ./lib/postgresql/euc2004_sjis2004.so
./lib/libhll.so ./lib/libhll.so
./lib/libzstd.so
./lib/libzstd.so.1
./lib/libzstd.so.1.4.4
./include/postgresql/server/postgres_ext.h ./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h ./include/postgresql/server/pg_config_os.h

View File

@ -900,7 +900,9 @@
./lib/postgresql/latin2_and_win1250.so ./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so ./lib/postgresql/euc2004_sjis2004.so
./lib/libhll.so ./lib/libhll.so
./lib/libzstd.so
./lib/libzstd.so.1
./lib/libzstd.so.1.4.4
./include/postgresql/server/postgres_ext.h ./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h ./include/postgresql/server/pg_config_os.h

View File

@ -29,6 +29,7 @@
./bin/transfer.py ./bin/transfer.py
./bin/bind_net_irq.sh ./bin/bind_net_irq.sh
./bin/setArmOptimization.sh ./bin/setArmOptimization.sh
./bin/gs_plan_simulator.sh
./bin/krb5kdc ./bin/krb5kdc
./bin/klist ./bin/klist
./bin/kinit ./bin/kinit
@ -877,6 +878,9 @@
./lib/postgresql/latin2_and_win1250.so ./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so ./lib/postgresql/euc2004_sjis2004.so
./lib/libhll.so ./lib/libhll.so
./lib/libzstd.so
./lib/libzstd.so.1
./lib/libzstd.so.1.4.4
./include/postgresql/server/postgres_ext.h ./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h ./include/postgresql/server/pg_config_os.h

View File

@ -29,6 +29,7 @@
./bin/transfer.py ./bin/transfer.py
./bin/bind_net_irq.sh ./bin/bind_net_irq.sh
./bin/setArmOptimization.sh ./bin/setArmOptimization.sh
./bin/gs_plan_simulator.sh
./bin/krb5kdc ./bin/krb5kdc
./bin/klist ./bin/klist
./bin/kinit ./bin/kinit
@ -877,6 +878,9 @@
./lib/postgresql/latin2_and_win1250.so ./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so ./lib/postgresql/euc2004_sjis2004.so
./lib/libhll.so ./lib/libhll.so
./lib/libzstd.so
./lib/libzstd.so.1
./lib/libzstd.so.1.4.4
./include/postgresql/server/postgres_ext.h ./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h ./include/postgresql/server/pg_config_os.h

View File

@ -108,7 +108,7 @@ function print_help()
} }
####################################################################### #######################################################################
##version 2.0.0 ##version 2.0.3
####################################################################### #######################################################################
function read_srv_version() function read_srv_version()
{ {

View File

@ -1781,7 +1781,7 @@ static char** get_pkey_attnames(Relation rel, int16* indnkeyatts)
indexRelation = heap_open(IndexRelationId, AccessShareLock); indexRelation = heap_open(IndexRelationId, AccessShareLock);
ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
scan = systable_beginscan(indexRelation, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey); scan = systable_beginscan(indexRelation, IndexIndrelidIndexId, true, NULL, 1, &skey);
while (HeapTupleIsValid(indexTuple = systable_getnext(scan))) { while (HeapTupleIsValid(indexTuple = systable_getnext(scan))) {
Form_pg_index index = (Form_pg_index)GETSTRUCT(indexTuple); Form_pg_index index = (Form_pg_index)GETSTRUCT(indexTuple);

View File

@ -775,11 +775,6 @@ void ExceptionalCondition(const char* conditionName, const char* errorType, cons
abort(); abort();
} }
// see to relmappper.cpp
//
#define MAX_MAPPINGS 62 /* 62 * 8 + 16 = 512 */
#define RELMAPPER_FILENAME "pg_filenode.map"
#define RELMAPPER_FILEMAGIC 0x592717 /* version ID value */
#define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */ #define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */
typedef struct PgClass_table { typedef struct PgClass_table {
@ -3179,6 +3174,35 @@ read_failed:
return result; return result;
} }
static int ReadOldVersionRelmapFile(char *buffer, FILE *fd)
{
errno_t rc;
char oldMapCache[RELMAP_SIZE_OLD];
int readByte = fread(oldMapCache, 1, RELMAP_SIZE_OLD, fd);
rc = memcpy_s(buffer, sizeof(RelMapFile), oldMapCache, MAPPING_LEN_OLDMAP_HEAD);
securec_check(rc, "\0", "\0");
rc = memcpy_s(
buffer + offsetof(RelMapFile, crc), MAPPING_LEN_TAIL, oldMapCache + MAPPING_LEN_OLDMAP_HEAD, MAPPING_LEN_TAIL);
securec_check(rc, "\0", "\0");
return readByte;
}
static void DoRelMapCrcCheck(const RelMapFile* mapfile, int32 magicNum)
{
pg_crc32 crc;
/* verify the CRC */
INIT_CRC32(crc);
if (IS_NEW_RELMAP(magicNum)) {
COMP_CRC32(crc, (char*)mapfile, offsetof(RelMapFile, crc));
} else {
COMP_CRC32(crc, (char*)mapfile, MAPPING_LEN_OLDMAP_HEAD);
}
FIN_CRC32(crc);
if (!EQ_CRC32(crc, (pg_crc32)(mapfile->crc))) {
fprintf(stdout, "WARNING: relmap crc check failed!");
}
}
static int parse_filenodemap_file(char* filename) static int parse_filenodemap_file(char* filename)
{ {
char buffer[sizeof(RelMapFile)]; char buffer[sizeof(RelMapFile)];
@ -3189,6 +3213,9 @@ static int parse_filenodemap_file(char* filename)
char* pg_class_map[MAX_PG_CLASS_ID]; char* pg_class_map[MAX_PG_CLASS_ID];
char* pg_class = NULL; char* pg_class = NULL;
int i = 0; int i = 0;
int32 magicNum;
int32 relmapSize;
int32 relmapMaxMappings;
for (i = 0; i < MAX_PG_CLASS_ID; i++) { for (i = 0; i < MAX_PG_CLASS_ID; i++) {
pg_class_map[i] = NULL; pg_class_map[i] = NULL;
@ -3203,17 +3230,34 @@ static int parse_filenodemap_file(char* filename)
fseek(fd, 0, SEEK_END); fseek(fd, 0, SEEK_END);
size = ftell(fd); size = ftell(fd);
rewind(fd); rewind(fd);
result = fread(buffer, 1, sizeof(RelMapFile), fd);
if (sizeof(RelMapFile) != result) { result = fread(&magicNum, 1, sizeof(int32), fd);
rewind(fd);
if (result != sizeof(int32)) {
fprintf(stderr, "Reading magic error");
return false;
}
if (IS_NEW_RELMAP(magicNum)) {
result = fread(buffer, 1, sizeof(RelMapFile), fd);
relmapSize = RELMAP_SIZE_NEW;
relmapMaxMappings = MAX_MAPPINGS_4K;
} else {
result = ReadOldVersionRelmapFile(buffer, fd);
relmapSize = RELMAP_SIZE_OLD;
relmapMaxMappings = MAX_MAPPINGS;
}
if ((size_t)relmapSize != result) {
fprintf(stderr, "Reading error"); fprintf(stderr, "Reading error");
return false; return false;
} }
mapfile = (RelMapFile*)buffer; mapfile = (RelMapFile*)buffer;
DoRelMapCrcCheck(mapfile, magicNum);
fprintf(stdout, "Magic number: 0x%x\n", mapfile->magic); fprintf(stdout, "Magic number: 0x%x\n", mapfile->magic);
fprintf(stdout, "Number of mappings: %u\n", mapfile->num_mappings); fprintf(stdout, "Number of mappings: %u\n", mapfile->num_mappings);
fprintf(stdout, "Mapping pairs:\n"); fprintf(stdout, "Mapping pairs:\n");
for (i = 0; i < MAX_MAPPINGS; i++) { for (i = 0; i < relmapMaxMappings; i++) {
if (0 == mapfile->mappings[i].mapoid && 0 == mapfile->mappings[i].mapfilenode) if (0 == mapfile->mappings[i].mapoid && 0 == mapfile->mappings[i].mapfilenode)
break; break;

View File

@ -86,8 +86,8 @@ Datum pg_buffercache_pages(PG_FUNCTION_ARGS)
fctx->tupdesc = BlessTupleDesc(tupledesc); fctx->tupdesc = BlessTupleDesc(tupledesc);
/* Allocate g_instance.attr.attr_storage.NBuffers worth of BufferCachePagesRec records. */ /* Allocate g_instance.attr.attr_storage.NBuffers worth of BufferCachePagesRec records. */
fctx->record = fctx->record = (BufferCachePagesRec *)palloc_huge(CurrentMemoryContext,
(BufferCachePagesRec*)palloc(sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers); sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers);
/* Set max calls and remember the user function context. */ /* Set max calls and remember the user function context. */
funcctx->max_calls = g_instance.attr.attr_storage.NBuffers; funcctx->max_calls = g_instance.attr.attr_storage.NBuffers;

View File

@ -634,7 +634,7 @@ static void exec_object_restorecon(struct selabel_handle* sehnd, Oid catalogId)
*/ */
rel = heap_open(catalogId, AccessShareLock); rel = heap_open(catalogId, AccessShareLock);
sscan = systable_beginscan(rel, InvalidOid, false, SnapshotNow, 0, NULL); sscan = systable_beginscan(rel, InvalidOid, false, NULL, 0, NULL);
while (HeapTupleIsValid(tuple = systable_getnext(sscan))) { while (HeapTupleIsValid(tuple = systable_getnext(sscan))) {
Form_pg_database datForm; Form_pg_database datForm;
Form_pg_namespace nspForm; Form_pg_namespace nspForm;

View File

@ -52,7 +52,7 @@ SUBDIRS = \
pg_controldata \ pg_controldata \
pg_resetxlog \ pg_resetxlog \
gs_guc \ gs_guc \
pgxc_clean \ gs_cgroup \
gsqlerr \ gsqlerr \
pg_basebackup \ pg_basebackup \
pg_probackup pg_probackup

View File

@ -186,6 +186,7 @@ enable_compress_hll|bool|0,0|NULL|NULL|
enable_fast_numeric|bool|0,0|NULL|Enable numeric optimize.| enable_fast_numeric|bool|0,0|NULL|Enable numeric optimize.|
enable_force_vector_engine|bool|0,0|NULL|NULL| enable_force_vector_engine|bool|0,0|NULL|NULL|
enable_global_plancache|bool|0,0|NULL|NULL| enable_global_plancache|bool|0,0|NULL|NULL|
gpc_clean_timeout|int|300,86400|NULL|NULL|
enable_twophase_commit|bool|0,0|NULL|NULL| enable_twophase_commit|bool|0,0|NULL|NULL|
enable_hashagg|bool|0,0|NULL|NULL| enable_hashagg|bool|0,0|NULL|NULL|
enable_hashjoin|bool|0,0|NULL|NULL| enable_hashjoin|bool|0,0|NULL|NULL|
@ -295,6 +296,7 @@ gtm_port4|int|1,65535|NULL|NULL|
gtm_port5|int|1,65535|NULL|NULL| gtm_port5|int|1,65535|NULL|NULL|
gtm_port6|int|1,65535|NULL|NULL| gtm_port6|int|1,65535|NULL|NULL|
gtm_port7|int|1,65535|NULL|NULL| gtm_port7|int|1,65535|NULL|NULL|
gs_clean_timeout|int|0,2147483|s|NULL|
hashagg_table_size|int|0,1073741823|NULL|NULL| hashagg_table_size|int|0,1073741823|NULL|NULL|
hba_file|string|0,0|NULL|NULL| hba_file|string|0,0|NULL|NULL|
hot_standby|bool|0,0|NULL|When hot_standby set to on, wal_level must be set to hot_standby. Otherwise it will cause the database can not be started. In the dual-system environments, hot_standby can not be set to off.| hot_standby|bool|0,0|NULL|When hot_standby set to on, wal_level must be set to hot_standby. Otherwise it will cause the database can not be started. In the dual-system environments, hot_standby can not be set to off.|
@ -345,6 +347,7 @@ wdr_snapshot_query_timeout|int|100,2147483647|s|NULL|
enable_wdr_snapshot|bool|0,0|NULL|NULL| enable_wdr_snapshot|bool|0,0|NULL|NULL|
enable_asp|bool|0,0|NULL|NULL| enable_asp|bool|0,0|NULL|NULL|
enable_stmt_track|bool|0,0|NULL|NULL| enable_stmt_track|bool|0,0|NULL|NULL|
track_stmt_parameter|bool|0,0|NULL|NULL|
asp_sample_num|int|10000,100000|NULL|NULL| asp_sample_num|int|10000,100000|NULL|NULL|
asp_sample_interval|int|1,10|s|NULL| asp_sample_interval|int|1,10|s|NULL|
asp_flush_rate|int|1,10|NULL|NULL| asp_flush_rate|int|1,10|NULL|NULL|
@ -398,6 +401,7 @@ memorypool_enable|bool|0,0|NULL|NULL|
memorypool_size|int|131072,1073741823|kB|NULL| memorypool_size|int|131072,1073741823|kB|NULL|
memory_detail_tracking|string|0,0|NULL|This parameter memory_detail_tracking only can be used in debug version. If it is set in the release version, it will lead the cluster does not work properly. Therefore, before making the settings, please make sure that the cluster version is debug.| memory_detail_tracking|string|0,0|NULL|This parameter memory_detail_tracking only can be used in debug version. If it is set in the release version, it will lead the cluster does not work properly. Therefore, before making the settings, please make sure that the cluster version is debug.|
memory_tracking_mode|enum|none,normal,executor,fullexec|NULL|NULL| memory_tracking_mode|enum|none,normal,executor,fullexec|NULL|NULL|
min_dynamic_memory|int|-1,2147483647|NULL|NULL|
minimum_pool_size|int|1,65535|NULL|NULL| minimum_pool_size|int|1,65535|NULL|NULL|
modify_initial_password|bool|0,0|NULL|NULL| modify_initial_password|bool|0,0|NULL|NULL|
most_available_sync|bool|0,0|NULL|NULL| most_available_sync|bool|0,0|NULL|NULL|
@ -480,6 +484,7 @@ standard_conforming_strings|bool|0,0|NULL|NULL|
standby_shared_buffers_fraction|real|0.1,1|NULL|NULL| standby_shared_buffers_fraction|real|0.1,1|NULL|NULL|
statement_timeout|int|0,2147483647|ms|NULL| statement_timeout|int|0,2147483647|ms|NULL|
stats_temp_directory|string|0,0|NULL|NULL| stats_temp_directory|string|0,0|NULL|NULL|
num_internal_lock_partitions|string|0,0|NULL|NULL|
stream_multiple|real|0,1.79769e+308|NULL|NULL| stream_multiple|real|0,1.79769e+308|NULL|NULL|
string_hash_compatible|bool|0,0|NULL|NULL| string_hash_compatible|bool|0,0|NULL|NULL|
enable_slow_query_log|bool|0,0|NULL|NULL| enable_slow_query_log|bool|0,0|NULL|NULL|
@ -649,7 +654,7 @@ enable_auto_explain|bool|0,0|NULL|NULL|
auto_explain_level|enum|off,log,notice|NULL|NULL| auto_explain_level|enum|off,log,notice|NULL|NULL|
cost_weight_index|real|1e-10,1e+10|NULL|NULL| cost_weight_index|real|1e-10,1e+10|NULL|NULL|
default_limit_rows|real|-100,1.79769e+308|NULL|NULL| default_limit_rows|real|-100,1.79769e+308|NULL|NULL|
sql_beta_feature|enum|sel_semi_poisson,sel_expr_instr,param_path_gen,rand_cost_opt,param_path_opt,page_est_opt,none|NULL|NULL| sql_beta_feature|enum|join_sel_with_cast_func,no_unique_index_first,sel_semi_poisson,sel_expr_instr,param_path_gen,rand_cost_opt,param_path_opt,page_est_opt,none|NULL|NULL|
xlog_idle_flushes_before_sleep|int64|0,576460752303423487|NULL|NULL| xlog_idle_flushes_before_sleep|int64|0,576460752303423487|NULL|NULL|
wal_writer_cpu|int|-1,2147483647|NULL|NULL| wal_writer_cpu|int|-1,2147483647|NULL|NULL|
wal_file_init_num|int|1,2147483647|NULL|NULL| wal_file_init_num|int|1,2147483647|NULL|NULL|
@ -658,6 +663,8 @@ max_concurrent_autonomous_transactions|int|0,262143|NULL|NULL|
sync_config_strategy|enum|all_node,only_sync_node,none_node|NULL|Synchronization strategy for configuration files between host and standby.| sync_config_strategy|enum|all_node,only_sync_node,none_node|NULL|Synchronization strategy for configuration files between host and standby.|
time_to_target_rpo|int|0,3600|NULL|NULL| time_to_target_rpo|int|0,3600|NULL|NULL|
disable_memory_protect|bool|0,0|NULL|NULL| disable_memory_protect|bool|0,0|NULL|NULL|
unique_sql_clean_ratio|real|0,0.2|NULL|NULL|
enable_auto_clean_unique_sql|bool|0,0|NULL|NULL|
[cmserver] [cmserver]
log_dir|string|0,0|NULL|NULL| log_dir|string|0,0|NULL|NULL|
log_file_size|int|0,2047|MB|NULL| log_file_size|int|0,2047|MB|NULL|

View File

@ -1696,74 +1696,6 @@ int get_nodename_number_from_nodelist(const char* namelist)
return count; return count;
} }
/*
******************************************************************************
******************************************************************************
Function : check_datanodename_value
Description : check the input datanode Name.
Input :nodeName data node name
return :true input datanode name is correct
false input datanode name is incorrect
******************************************************************************
*/
bool CheckDataNameValue(const char *datanodeName, const char *dataDir)
{
int nRet;
uint32 nodeIdx = 0;
uint32 datanodeIdx = 0;
int dnIdMaxLen = 64;
char dnId[dnIdMaxLen];
if ((datanodeName == NULL) || (*datanodeName == '\0')) {
return false;
}
dataNodeInfo *dnI = NULL;
for (datanodeIdx = 0; datanodeIdx < g_currentNode->datanodeCount; datanodeIdx++) {
dataNodeInfo *dniTmp = &(g_currentNode->datanode[datanodeIdx]);
if (strcmp(dniTmp->datanodeLocalDataPath, dataDir) == 0) {
dnI = dniTmp;
break;
}
}
if (dnI == NULL) {
write_stderr("Failed: cannot find the expected data dir\n");
return false;
}
for (nodeIdx = 0; nodeIdx < g_node_num; ++nodeIdx) {
staticNodeConfig *dest = &(g_node[nodeIdx]);
for (datanodeIdx = 0; datanodeIdx < dest->datanodeCount; ++datanodeIdx) {
dataNodeInfo *dn = &(dest->datanode[datanodeIdx]);
if (dn->datanodeId == 0 || dn->datanodeId == dnI->datanodeId) {
continue;
}
nRet = memset_s(dnId, sizeof(dnId), '\0', sizeof(dnId));
securec_check_c(nRet, "\0", "\0");
nRet = snprintf_s(
dnId, sizeof(dnId) / sizeof(char), sizeof(dnId) / sizeof(char) - 1, "dn_%4d", dn->datanodeId);
securec_check_ss_c(nRet, "\0", "\0");
if (strncmp(dnId, datanodeName,
((strlen(dnId) > strlen(datanodeName)) ? strlen(dnId) : strlen(datanodeName))) != 0) {
continue;
}
for (int peerIndex = 0; peerIndex < CM_MAX_DATANODE_STANDBY_NUM; ++peerIndex) {
peerDatanodeInfo *peerDatanode = &(dnI->peerDatanodes[peerIndex]);
if (strlen(peerDatanode->datanodePeerHAIP[0]) == 0) {
continue;
}
if (strcmp(peerDatanode->datanodePeerHAIP[0], dn->datanodeLocalHAIP[0]) == 0 &&
peerDatanode->datanodePeerHAPort == dn->datanodeLocalHAPort) {
return true;
}
}
}
}
return false;
}
/* /*
****************************************************************************** ******************************************************************************
Function : parse_datanodename_result Function : parse_datanodename_result
@ -1846,7 +1778,6 @@ char* get_AZ_value(const char* value, const char* data_dir)
char delims[] = ","; char delims[] = ",";
char* vptr = NULL; char* vptr = NULL;
char emptyvalue[] = "''"; char emptyvalue[] = "''";
int resultStatus = 0;
bool isNodeName = false; bool isNodeName = false;
if (az1 != NULL) { if (az1 != NULL) {
@ -1946,11 +1877,6 @@ char* get_AZ_value(const char* value, const char* data_dir)
if (NULL == nodenameList) { if (NULL == nodenameList) {
// try dn // try dn
resultStatus = get_nodename_list_by_AZ(az1, data_dir, &nodenameList);
PROCESS_STATUS(resultStatus);
if (nodenameList == NULL) {
goto failed;
}
len = strlen(q) + 1; len = strlen(q) + 1;
s = (char *)pg_malloc_zero(len * sizeof(char)); s = (char *)pg_malloc_zero(len * sizeof(char));
@ -1961,15 +1887,15 @@ char* get_AZ_value(const char* value, const char* data_dir)
while (vptr != NULL) { while (vptr != NULL) {
p = vptr; p = vptr;
if (!contain_nodename(nodenameList, p)) { if (CheckDataNameValue(p, data_dir) == false) {
goto failed; goto failed;
} }
vptr = strtok_r(NULL, delims, &vouter_ptr); vptr = strtok_r(NULL, delims, &vouter_ptr);
} }
GS_FREE(s); GS_FREE(s);
len = strlen(nodenameList); nodenameList = (char *)pg_malloc_zero(len * sizeof(char));
nRet = snprintf_s(nodenameList, len + 1, len, "%s", q); nRet = snprintf_s(nodenameList, len, len - 1, "%s", q);
securec_check_ss_c(nRet, nodenameList, "\0"); securec_check_ss_c(nRet, nodenameList, "\0");
} else if ('\0' == nodenameList[0]) { } else if ('\0' == nodenameList[0]) {
(void)write_stderr("ERROR: There is no standby node name. Please make sure the value of " (void)write_stderr("ERROR: There is no standby node name. Please make sure the value of "

View File

@ -172,7 +172,7 @@ const int EQUAL_MARK_LEN = 3;
#define ADDPOINTER_SIZE 2 #define ADDPOINTER_SIZE 2
#define MAX_HOST_NAME_LENGTH 255 #define MAX_HOST_NAME_LENGTH 255
#define TEMP_PGCONF_FILE "postgresql.conf.bak" #define TEMP_PGCONF_FILE "postgresql.conf.guc.bak"
#define TEMP_CMAGENTCONF_FILE "cm_agent.conf.bak" #define TEMP_CMAGENTCONF_FILE "cm_agent.conf.bak"
#define TEMP_CMSERVERCONF_FILE "cm_server.conf.bak" #define TEMP_CMSERVERCONF_FILE "cm_server.conf.bak"
#define TEMP_GTMCONF_FILE "gtm.conf.bak" #define TEMP_GTMCONF_FILE "gtm.conf.bak"
@ -1033,6 +1033,72 @@ append_string_info(char **optLines, const char *newContext)
return optLinesResult; return optLinesResult;
} }
static void
parse_next_sync_groups(char **pgroup, char *result)
{
if (**pgroup == '\0') {
result[0] = '\0';
return;
}
char *this_group = *pgroup;
char *p = *pgroup;
while (*p != '\0' && *p != ')') p++;
while (*p != '\0' && *p != ',') p++;
if (*p == ',') {
*p = '\0';
p++;
}
*pgroup = p;
errno_t rc = snprintf_s(result, MAX_VALUE_LEN, MAX_VALUE_LEN - 1, "'%s'", this_group);
securec_check_ss_c(rc, "\0", "\0");
return;
}
static int
transform_az_name(char *config_value, char *allAZString, int allAZStringBufLen, const char *data_dir)
{
if (strcmp(config_value, "''") == 0) {
errno_t rc = strncpy_s(allAZString, allAZStringBufLen, config_value, strlen(config_value));
securec_check_c(rc, "\0", "\0");
return SUCCESS;
}
char *azString = NULL;
char *buf = allAZString;
int buflen = allAZStringBufLen;
char *allgroup = xstrdup(config_value);
char *pgrp = allgroup + 1; // trim first "'"
char this_group[MAX_VALUE_LEN] = {0x00};
allgroup[strlen(allgroup) - 1] = '\0'; // trim last "'"
parse_next_sync_groups(&pgrp, this_group);
while (this_group[0] != '\0') {
azString = get_AZ_value(this_group, data_dir);
if (NULL == azString) {
GS_FREE(allgroup);
return FAILURE;
}
int azStringLen = strlen(azString);
azString[0] = ' ';
azString[azStringLen - 1] = ',';
errno_t rc = strncpy_s(buf, buflen, azString, azStringLen);
securec_check_c(rc, "\0", "\0");
buf += azStringLen;
buflen -= azStringLen;
GS_FREE(azString);
parse_next_sync_groups(&pgrp, this_group);
}
GS_FREE(allgroup);
allAZString[0] = allAZString[strlen(allAZString) - 1] = '\'';
return SUCCESS;
}
#ifndef ENABLE_MULTIPLE_NODES #ifndef ENABLE_MULTIPLE_NODES
/******************************************************************************* /*******************************************************************************
Function : IsLastNotNullReplconninfo Function : IsLastNotNullReplconninfo
@ -1194,17 +1260,16 @@ do_gucset(const char *action_type, const char *data_dir)
// get AZ string // get AZ string
if (NULL != config_value[i]) { if (NULL != config_value[i]) {
char *azString = NULL; char allAZString[MAX_VALUE_LEN] = {0x00};
azString = get_AZ_value(config_value[i], data_dir);
if (NULL == azString) { result_status = transform_az_name(config_value[i], allAZString, MAX_VALUE_LEN, data_dir);
result_status = FAILURE; if (result_status == FAILURE) {
continue; continue;
} }
tmpAZStr = xstrdup(config_value[i]); tmpAZStr = xstrdup(config_value[i]);
GS_FREE(config_value[i]); GS_FREE(config_value[i]);
config_value[i] = xstrdup(azString); config_value[i] = xstrdup(allAZString);
GS_FREE(azString);
} }
} }

View File

@ -708,6 +708,7 @@ static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
} }
disconnect_and_exit(1); disconnect_and_exit(1);
} }
PQclear(res);
while (true) { while (true) {
if (copybuf != NULL) { if (copybuf != NULL) {
@ -886,6 +887,7 @@ static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
* Get the COPY data * Get the COPY data
*/ */
res = backup_get_result(conn); res = backup_get_result(conn);
PQclear(res);
while (1) { while (1) {
int r; int r;
@ -938,7 +940,7 @@ static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
/* /*
* All files are padded up to 512 bytes * All files are padded up to 512 bytes
*/ */
if (current_len_left < 0 || current_len_left > LLONG_MAX - 511) { if (current_len_left < 0 || current_len_left > INT_MAX - 511) {
pg_log(stderr, _("%s: the file '%s' is too big or file size is invalid\n"), progname, copybuf); pg_log(stderr, _("%s: the file '%s' is too big or file size is invalid\n"), progname, copybuf);
disconnect_and_exit(1); disconnect_and_exit(1);
} }

View File

@ -636,7 +636,7 @@ static int getOptions(const int argc, char* const* argv)
int c; int c;
int option_index; int option_index;
uint32 hi, lo; uint32 hi, lo;
while ((c = getopt_long(argc, argv, "f:F:nvd:h:o:p:U:wWP:s:S:", long_options, &option_index)) != -1) { while ((c = getopt_long(argc, argv, "f:F:nvd:h:o:p:U:wWP:s:S:I:", long_options, &option_index)) != -1) {
switch (c) { switch (c) {
/* general options */ /* general options */
case 'f': case 'f':
@ -669,9 +669,9 @@ static int getOptions(const int argc, char* const* argv)
break; break;
case 'p': case 'p':
check_env_value_c(optarg); check_env_value_c(optarg);
if (atoi(optarg) <= 0) { if (checkIsDigit(optarg) == 0) {
fprintf(stderr, _("%s: invalid port number \"%s\"\n"), progname, optarg); fprintf(stderr, _("%s: invalid port number \"%s\"\n"), progname, optarg);
return 1; exit(1);
} }
dbport = pg_strdup(optarg); dbport = pg_strdup(optarg);
break; break;
@ -736,8 +736,7 @@ static int getOptions(const int argc, char* const* argv)
fsync_interval = atoi(optarg) * 1000; fsync_interval = atoi(optarg) * 1000;
if (fsync_interval < 0) { if (fsync_interval < 0) {
fprintf(stderr, _("%s: invalid fsync interval \"%s\"\n"), progname, optarg); fsync_interval = 0;
return -1;
} }
break; break;
case 'S': case 'S':

View File

@ -709,10 +709,10 @@ bool ReceiveXlogStream(PGconn* conn, XLogRecPtr startpos, uint32 timeline, const
if (standby_message_timeout_local) { if (standby_message_timeout_local) {
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
timeout.tv_sec = CalculateCopyStreamSleeptime(local_now, timeout.tv_sec = CalculateCopyStreamSleeptime(local_now,
standby_message_timeout_local, standby_message_timeout_local / 2,
last_status); last_status);
#else #else
timeout.tv_sec = last_status + standby_message_timeout_local - local_now - 1; timeout.tv_sec = last_status + (standby_message_timeout_local / 2) - local_now - 1;
#endif #endif
if (timeout.tv_sec <= 0) if (timeout.tv_sec <= 0)
timeout.tv_sec = 1; /* Always sleep at least 1 sec */ timeout.tv_sec = 1; /* Always sleep at least 1 sec */

View File

@ -22,6 +22,7 @@
#include "knl/knl_variable.h" #include "knl/knl_variable.h"
#include "utils/timestamp.h" #include "utils/timestamp.h"
#include "streamutil.h" #include "streamutil.h"
#include "libpq/libpq-int.h"
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -138,6 +139,17 @@ static void CalculateArgCount(int *argcount)
return; return;
} }
static void CheckConnectionHost(PGconn* tmpconn)
{
if (tmpconn == NULL || tmpconn->sock < 0) {
fprintf(stderr, "failed to connect %s:%s.\n",
(dbhost == NULL) ? "Unknown" : dbhost,
(dbport == NULL) ? "Unknown" : dbport);
PQfinish(tmpconn);
exit(1);
}
}
/* /*
* Connect to the server. Returns a valid PGconn pointer if connected, * Connect to the server. Returns a valid PGconn pointer if connected,
* or NULL on non-permanent error. On permanent error, the function will * or NULL on non-permanent error. On permanent error, the function will
@ -212,10 +224,7 @@ PGconn* GetConnection(void)
* If there is too little memory even to allocate the PGconn object * If there is too little memory even to allocate the PGconn object
* and PQconnectdbParams returns NULL, we call exit(1) directly. * and PQconnectdbParams returns NULL, we call exit(1) directly.
*/ */
if (tmpconn == NULL) { CheckConnectionHost(tmpconn);
fprintf(stderr, _("%s: could not connect to server\n"), progname);
exit(1);
}
if (PQstatus(tmpconn) == CONNECTION_BAD && PQconnectionNeedsPassword(tmpconn) && dbgetpassword != -1) { if (PQstatus(tmpconn) == CONNECTION_BAD && PQconnectionNeedsPassword(tmpconn) && dbgetpassword != -1) {
dbgetpassword = 1; /* ask for password next time */ dbgetpassword = 1; /* ask for password next time */

View File

@ -295,7 +295,7 @@ static void show_version(int alls)
#ifdef ENABLE_MULTIPLE_NODES #ifdef ENABLE_MULTIPLE_NODES
printf("PostgreSQL 9.2.4\n"); printf("PostgreSQL 9.2.4\n");
#else #else
printf("openGauss 2.0.0\n"); printf("openGauss 2.0.3\n");
#endif #endif
} }

View File

@ -59,6 +59,7 @@
/* Global options */ /* Global options */
char* basedir = NULL; char* basedir = NULL;
bool isBuildFromStandby = false;
char format = 'p'; /* p(lain)/t(ar) */ char format = 'p'; /* p(lain)/t(ar) */
char* label = "gs_ctl full build"; char* label = "gs_ctl full build";
bool showprogress = true; bool showprogress = true;
@ -132,6 +133,8 @@ static int replace_node_name(char* sSrc, const char* sMatchStr, const char* sRep
static void show_full_build_process(const char* errmg); static void show_full_build_process(const char* errmg);
static void backup_dw_file(const char* target_dir); static void backup_dw_file(const char* target_dir);
void get_xlog_location(char (&xlog_location)[MAXPGPATH]); void get_xlog_location(char (&xlog_location)[MAXPGPATH]);
static void DeleteAlreadyDropedFile(const char* path, bool is_table_space);
static int DeleteUnusedFile(const char* path, unsigned int SegNo, unsigned int fileNode);
/* /*
* tblspaceDirectory is used for saving the table space directory created by * tblspaceDirectory is used for saving the table space directory created by
@ -450,6 +453,7 @@ typedef struct {
char* sysidentifier; char* sysidentifier;
int timeline; int timeline;
uint32 term; uint32 term;
bool isBuildFromStandby;
} logstreamer_param; } logstreamer_param;
static int LogStreamerMain(logstreamer_param* param) static int LogStreamerMain(logstreamer_param* param)
@ -457,7 +461,11 @@ static int LogStreamerMain(logstreamer_param* param)
int ret = 0; int ret = 0;
/* get second connection info in child process for the sake of memmory leak */ /* get second connection info in child process for the sake of memmory leak */
param->bgconn = check_and_conn(standby_connect_timeout, standby_recv_timeout, param->term); if (param->isBuildFromStandby) {
param->bgconn = check_and_conn_for_standby(standby_connect_timeout, standby_recv_timeout, param->term);
} else {
param->bgconn = check_and_conn(standby_connect_timeout, standby_recv_timeout, param->term);
}
if (param->bgconn == NULL) { if (param->bgconn == NULL) {
return 1; return 1;
} }
@ -501,6 +509,7 @@ void StartLogStreamer(
param->timeline = timeline; param->timeline = timeline;
param->sysidentifier = sysidentifier; param->sysidentifier = sysidentifier;
param->term = primaryTerm; param->term = primaryTerm;
param->isBuildFromStandby = isBuildFromStandby;
/* Convert the starting position */ /* Convert the starting position */
if (sscanf_s(startpos, "%X/%X", &hi, &lo) != 2) { if (sscanf_s(startpos, "%X/%X", &hi, &lo) != 2) {
@ -814,7 +823,7 @@ static void ReceiveAndUnpackTarFile(PGconn* conn, PGresult* res, int rownum)
/* /*
* All files are padded up to 512 bytes * All files are padded up to 512 bytes
*/ */
if (current_len_left < 0 || current_len_left > LLONG_MAX - 511) { if (current_len_left < 0 || current_len_left > INT_MAX - 511) {
pg_log(PG_WARNING, _("current_len_left is invalid\n")); pg_log(PG_WARNING, _("current_len_left is invalid\n"));
disconnect_and_exit(1); disconnect_and_exit(1);
} }
@ -1017,6 +1026,62 @@ bool CreateBuildtagFile(const char* fulltagname)
return true; return true;
} }
bool ModifyControlFile(const char* dirname)
{
ControlFileData controlFileNew;
char controlFilePath[MAXPGPATH] = {0};
size_t size = 0;
int writelen;
int fd = -1;
int ss = 0;
char* buffer = NULL;
char writeBuf[PG_CONTROL_SIZE];
errno_t errorNo = EOK;
buffer = slurpFile(dirname, "global/pg_control", &size);
if (buffer == NULL) {
pg_log(PG_WARNING, _("could not read anything from file pg_control. \n"));
disconnect_and_exit(1);
return false;
}
errorNo = memcpy_s(&controlFileNew, sizeof(ControlFileData), buffer, sizeof(ControlFileData));
securec_check_c(errorNo, "\0", "\0");
controlFileNew.state = DB_IN_ARCHIVE_RECOVERY;
INIT_CRC32C(controlFileNew.crc);
COMP_CRC32C(controlFileNew.crc, (char*)&controlFileNew, offsetof(ControlFileData, crc));
FIN_CRC32C(controlFileNew.crc);
errorNo = memset_s(writeBuf, PG_CONTROL_SIZE, 0, PG_CONTROL_SIZE);
securec_check_c(errorNo, "", "");
errorNo = memcpy_s(writeBuf, PG_CONTROL_SIZE, &controlFileNew, sizeof(ControlFileData));
securec_check_c(errorNo, "", "");
ss = snprintf_s(controlFilePath, MAXPGPATH, MAXPGPATH - 1, "%s/global/pg_control", dirname);
securec_check_ss_c(ss, "\0", "\0");
int mode = O_WRONLY | O_CREAT | PG_BINARY;
int flags = 0600;
fd = open(controlFilePath, mode, flags);
if (fd < 0) {
pg_log(PG_WARNING, ("could not open pg_control file. \n"));
disconnect_and_exit(1);
return false;
}
if (lseek(fd, 0, SEEK_SET) == -1) {
(void)close(fd);
fd = -1;
pg_log(PG_WARNING, "could not seek in target file \"%s\"\n", controlFilePath);
disconnect_and_exit(1);
return false;
}
writelen = write(fd, writeBuf, PG_CONTROL_SIZE);
if (writelen != PG_CONTROL_SIZE) {
pg_log(PG_WARNING, "could not write in target file \"%s\"\n", controlFilePath);
disconnect_and_exit(1);
return false;
}
close(fd);
return true;
}
static void BaseBackup(const char* dirname, uint32 term) static void BaseBackup(const char* dirname, uint32 term)
{ {
PGresult* res = NULL; PGresult* res = NULL;
@ -1027,6 +1092,8 @@ static void BaseBackup(const char* dirname, uint32 term)
char nodetablespacepath[MAXPGPATH] = {0}; char nodetablespacepath[MAXPGPATH] = {0};
char nodetablespaceparentpath[MAXPGPATH] = {0}; char nodetablespaceparentpath[MAXPGPATH] = {0};
char escaped_label[MAXPGPATH] = {0}; char escaped_label[MAXPGPATH] = {0};
char basePath[MAXPGPATH] = {0};
char tblspcPath[MAXPGPATH] = {0};
int i; int i;
char xlogstart[MAXFNAMELEN] = {0}; char xlogstart[MAXFNAMELEN] = {0};
char xlogend[MAXFNAMELEN] = {0}; char xlogend[MAXFNAMELEN] = {0};
@ -1056,7 +1123,11 @@ static void BaseBackup(const char* dirname, uint32 term)
get_conninfo(conf_file); get_conninfo(conf_file);
/* find a available conn */ /* find a available conn */
streamConn = check_and_conn(standby_connect_timeout, standby_recv_timeout, term); if (isBuildFromStandby) {
streamConn = check_and_conn_for_standby(standby_connect_timeout, standby_recv_timeout, term);
} else {
streamConn = check_and_conn(standby_connect_timeout, standby_recv_timeout, term);
}
if (streamConn == NULL) { if (streamConn == NULL) {
show_full_build_process("could not connect to server."); show_full_build_process("could not connect to server.");
disconnect_and_exit(1); disconnect_and_exit(1);
@ -1123,15 +1194,19 @@ static void BaseBackup(const char* dirname, uint32 term)
*/ */
(void)PQsetRwTimeout(streamConn, Max(BUILD_RW_TIMEOUT, standby_recv_timeout)); (void)PQsetRwTimeout(streamConn, Max(BUILD_RW_TIMEOUT, standby_recv_timeout));
(void)PQescapeStringConn(streamConn, escaped_label, label, sizeof(escaped_label), &i); (void)PQescapeStringConn(streamConn, escaped_label, label, sizeof(escaped_label), &i);
if (isBuildFromStandby) {
fastcheckpoint = false;
}
nRet = snprintf_s(current_path, nRet = snprintf_s(current_path,
MAXPGPATH, MAXPGPATH,
sizeof(current_path) - 1, sizeof(current_path) - 1,
"BASE_BACKUP LABEL '%s' %s %s %s %s", "BASE_BACKUP LABEL '%s' %s %s %s %s %s",
escaped_label, escaped_label,
showprogress ? "PROGRESS" : "", showprogress ? "PROGRESS" : "",
includewal && !streamwal ? "WAL" : "", includewal && !streamwal ? "WAL" : "",
fastcheckpoint ? "FAST" : "", fastcheckpoint ? "FAST" : "",
includewal ? "NOWAIT" : ""); includewal ? "NOWAIT" : "",
isBuildFromStandby ? "BUILDSTANDBY" : "");
securec_check_ss_c(nRet, "", ""); securec_check_ss_c(nRet, "", "");
if (PQsendQuery(streamConn, current_path) == 0) { if (PQsendQuery(streamConn, current_path) == 0) {
@ -1436,6 +1511,13 @@ static void BaseBackup(const char* dirname, uint32 term)
PQfinish(streamConn); PQfinish(streamConn);
streamConn = NULL; streamConn = NULL;
/* fsync all data come from source */
if (!no_need_fsync) {
show_full_build_process("starting fsync all files come from source.");
(void) fsync_pgdata(basedir);
show_full_build_process("finish fsync all files.");
}
/* delete dw file if exists, recreate it and write a page of zero */ /* delete dw file if exists, recreate it and write a page of zero */
backup_dw_file(dirname); backup_dw_file(dirname);
show_full_build_process("build dummy dw file success"); show_full_build_process("build dummy dw file success");
@ -1444,6 +1526,19 @@ static void BaseBackup(const char* dirname, uint32 term)
RENAME_BUILD_FILE(buildstart_file, builddone_file); RENAME_BUILD_FILE(buildstart_file, builddone_file);
show_full_build_process("rename build status file success"); show_full_build_process("rename build status file success");
nRet = snprintf_s(basePath, MAXPGPATH, MAXPGPATH, "%s/base", dirname);
securec_check_ss_c(nRet, "\0", "\0");
DeleteAlreadyDropedFile(basePath, false);
nRet = snprintf_s(tblspcPath, MAXPGPATH, MAXPGPATH, "%s/pg_tblspc", dirname);
securec_check_ss_c(nRet, "\0", "\0");
DeleteAlreadyDropedFile(tblspcPath, true);
if (isBuildFromStandby) {
(void)ModifyControlFile(dirname);
}
} }
/* /*
@ -1452,13 +1547,14 @@ static void BaseBackup(const char* dirname, uint32 term)
* Description : * Description :
* Notes : * Notes :
*/ */
void backup_main(char* dir, uint32 term) void backup_main(char* dir, uint32 term, bool isFromStandby)
{ {
if (dir == NULL) { if (dir == NULL) {
pg_log(PG_PRINT, "%s: parameters dir is NULL.\n", progname); pg_log(PG_PRINT, "%s: parameters dir is NULL.\n", progname);
exit(1); exit(1);
} else { } else {
basedir = dir; basedir = dir;
isBuildFromStandby = isFromStandby;
} }
/* program name */ /* program name */
progname = "gs_ctl"; progname = "gs_ctl";
@ -1949,3 +2045,110 @@ void get_xlog_location(char (&xlog_location)[MAXPGPATH])
} }
xlog_location[MAXPGPATH - 1] = '\0'; xlog_location[MAXPGPATH - 1] = '\0';
} }
static void DeleteAlreadyDropedFile(const char* path, bool is_table_space)
{
char* fileName = NULL;
char pathbuf[MAXPGPATH] = {0};
unsigned int fileNode = 0;
unsigned int spaceNode = 0;
unsigned int SegNo = 0;
unsigned int dbNode = 0;
struct stat statbuf;
struct dirent *de = NULL;
int nmatch = 0;
int res = -1;
int rc = 0;
DIR *dir = opendir(path);
while ((de = readdir(dir)) != NULL) {
/* skip entries point current dir or parent dir */
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
continue;
rc = snprintf_s(pathbuf, MAXPGPATH, MAXPGPATH - 1, "%s/%s", path, de->d_name);
securec_check_ss_c(rc, "\0", "\0");
if (lstat(pathbuf, &statbuf) != 0) {
if (errno != ENOENT) {
pg_log(PG_WARNING, _("could not lstat file or directory : %s!\n"), de->d_name);
continue;
}
}
if (S_ISDIR(statbuf.st_mode)) {
DeleteAlreadyDropedFile(pathbuf, is_table_space);
} else if (S_ISREG(statbuf.st_mode)) {
if (is_table_space) {
if ((fileName = strstr(pathbuf, "pg_tblspc/")) != NULL) {
nmatch = sscanf_s(fileName, "pg_tblspc/%u/%*[^/]/%u/%u.%u", &spaceNode,
&dbNode, &fileNode, &SegNo);
if (nmatch == 4) {
res = DeleteUnusedFile(path, SegNo, fileNode);
if (res < 0) {
(void)closedir(dir);
disconnect_and_exit(1);
}
}
}
} else {
if ((fileName = strstr(pathbuf, "base/")) != NULL) {
nmatch = sscanf_s(fileName, "base/%u/%u.%u", &dbNode, &fileNode, &SegNo);
if (nmatch == 3) {
res = DeleteUnusedFile(path, SegNo, fileNode);
if (res < 0) {
(void)closedir(dir);
disconnect_and_exit(1);
}
}
}
}
}
}
(void)closedir(dir);
}
static int DeleteUnusedFile(const char* path, unsigned int SegNo, unsigned int fileNode)
{
char firstFileName[MAXPGPATH] = {0};
char beforeFileName[MAXPGPATH] = {0};
char currentFileName[MAXPGPATH] = {0};
struct stat statbuf;
struct stat tmpStatBuf;
int rc = 0;
rc = snprintf_s(currentFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u.%u", path, fileNode, SegNo);
securec_check_ss_c(rc, "\0", "\0");
rc = snprintf_s(firstFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u", path, fileNode);
securec_check_ss_c(rc, "\0", "\0");
if (lstat(firstFileName, &statbuf) != 0) {
if (errno != ENOENT) {
pg_log(PG_WARNING, _("could not lstat file: %s!\n"), firstFileName);
return -1;
} else {
while (SegNo >= 1) {
rc = snprintf_s(currentFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u.%u", path, fileNode, SegNo);
securec_check_ss_c(rc, "\0", "\0");
if (lstat(currentFileName, &tmpStatBuf) == 0) {
pg_log(PG_DEBUG, _("the file %s should be unlink without origin file\n"), currentFileName);
unlink(currentFileName);
}
SegNo--;
}
return 0;
}
}
if (statbuf.st_size == 0) {
while (SegNo > 1) {
SegNo -= 1;
rc = snprintf_s(beforeFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%u.%u", path, fileNode, SegNo);
securec_check_ss_c(rc, "\0", "\0");
if (lstat(beforeFileName, &tmpStatBuf) != 0) {
if (errno == ENOENT) {
pg_log(PG_DEBUG, _("the file %s before file does not exist\n"), currentFileName);
unlink(currentFileName);
break;
}
}
}
}
return 0;
}

View File

@ -9,13 +9,14 @@ extern int standby_connect_timeout;
extern int standby_message_timeout; extern int standby_message_timeout;
extern char* conn_str; extern char* conn_str;
extern bool no_need_fsync;
extern pid_t process_id; extern pid_t process_id;
extern char* basedir; extern char* basedir;
extern int bgpipe[2]; extern int bgpipe[2];
extern pid_t bgchild; extern pid_t bgchild;
extern char* formatLogTime(); extern char* formatLogTime();
void backup_main(char* dir, uint32 term); void backup_main(char* dir, uint32 term, bool isFromStandby);
void backup_incremental_xlog(char* dir); void backup_incremental_xlog(char* dir);
void get_xlog_location(char (&xlog_location)[MAXPGPATH]); void get_xlog_location(char (&xlog_location)[MAXPGPATH]);
bool CreateBuildtagFile(const char* fulltagname); bool CreateBuildtagFile(const char* fulltagname);

View File

@ -57,6 +57,8 @@ int g_replication_type = -1;
#define RT_WITH_DUMMY_STANDBY 0 #define RT_WITH_DUMMY_STANDBY 0
#define RT_WITH_MULTI_STANDBY 1 #define RT_WITH_MULTI_STANDBY 1
static void walkdir(const char *path, int (*action) (const char *fname, bool isdir), bool process_symlinks);
int32 pg_atoi(const char* s, int size, int c) int32 pg_atoi(const char* s, int size, int c)
{ {
long l; long l;
@ -873,6 +875,74 @@ PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term)
return con_get; return con_get;
} }
/* check connection for standby build standby */
PGconn* check_and_conn_for_standby(int conn_timeout, int recv_timeout, uint32 term)
{
PGconn* con_get = NULL;
char repl_conninfo_str[MAXPGPATH];
ServerMode remote_mode = UNKNOWN_MODE;
int tnRet = 0;
int repl_arr_length;
int i = 0;
int parse_failed_num = 0;
for (i = 1; i < MAX_REPLNODE_NUM; i++) {
ReplConnInfo* repl_conn_info = ParseReplConnInfo(conninfo_global[i - 1], &repl_arr_length);
if (repl_conn_info == NULL) {
parse_failed_num++;
continue;
}
tnRet = memset_s(repl_conninfo_str, MAXPGPATH, 0, MAXPGPATH);
securec_check_ss_c(tnRet, "", "");
tnRet = snprintf_s(repl_conninfo_str,
sizeof(repl_conninfo_str),
sizeof(repl_conninfo_str) - 1,
"localhost=%s localport=%d host=%s port=%d "
"dbname=replication replication=true "
"fallback_application_name=gs_ctl "
"connect_timeout=%d rw_timeout=%d "
"options='-c remotetype=application'",
repl_conn_info->localhost,
repl_conn_info->localport,
repl_conn_info->remotehost,
repl_conn_info->remoteport,
conn_timeout,
recv_timeout);
securec_check_ss_c(tnRet, "", "");
free(repl_conn_info);
repl_conn_info = NULL;
con_get = PQconnectdb(repl_conninfo_str);
if (con_get != NULL && PQstatus(con_get) == CONNECTION_OK && check_remote_version(con_get, term)) {
remote_mode = get_remote_mode(con_get);
if (remote_mode == STANDBY_MODE && (g_replconn_idx == -1 || i == g_replconn_idx)) {
g_replconn_idx = i;
break;
}
} else {
if (conn_str != NULL) {
pg_log(PG_WARNING, "The given address can not been access.\n");
if (con_get != NULL) {
PQfinish(con_get);
}
exit(1);
}
}
}
if (parse_failed_num == MAX_REPLNODE_NUM - 1) {
pg_log(PG_WARNING, "Invalid value for parameter \"replconninfo\" in postgresql.conf or no correct standby.\n");
if (con_get != NULL) {
PQfinish(con_get);
}
exit(1);
}
return con_get;
}
/* /*
* Brief : @@GaussDB@@ * Brief : @@GaussDB@@
* Description : find the value of guc para according to name * Description : find the value of guc para according to name
@ -1452,3 +1522,178 @@ bool libpqRotateCbmFile(PGconn* connObj, XLogRecPtr lsn)
return ec; return ec;
} }
/*
* Issue fsync recursively on PGDATA and all its contents.
*
* We fsync regular files and directories wherever they are, but we follow
* symlinks only for pg_wal (or pg_xlog) and immediately under pg_tblspc.
* Other symlinks are presumed to point at files we're not responsible for
* fsyncing, and might not have privileges to write at all.
*
*/
void fsync_pgdata(const char *pg_data)
{
bool xlog_is_symlink = false;
char pg_xlog[MAXPGPATH] = {0};
char pg_tblspc[MAXPGPATH] = {0};
errno_t errorno = EOK;
errorno = snprintf_s(pg_xlog, MAXPGPATH, MAXPGPATH - 1, "%s/pg_xlog", pg_data);
securec_check_ss_c(errorno, "\0", "\0");
errorno = snprintf_s(pg_tblspc, MAXPGPATH, MAXPGPATH - 1, "%s/pg_tblspc", pg_data);
securec_check_ss_c(errorno, "\0", "\0");
#ifndef WIN32
{
struct stat st;
if (lstat(pg_xlog, &st) < 0) {
pg_log(PG_WARNING, _("could not stat file \"%s\": %m\n"), pg_xlog);
exit(1);
}
else if (S_ISLNK(st.st_mode))
xlog_is_symlink = true;
}
#else
if (pgwin32_is_junction(pg_xlog))
xlog_is_symlink = true;
#endif
/*
* Now we do the fsync()s in the same order.
*
* The main call ignores symlinks, so in addition to specially processing
* pg_wal if it's a symlink, pg_tblspc has to be visited separately with
* process_symlinks = true. Note that if there are any plain directories
* in pg_tblspc, they'll get fsync'd twice. That's not an expected case
* so we don't worry about optimizing it.
*/
walkdir(pg_data, fsync_fname, false);
if (xlog_is_symlink)
walkdir(pg_xlog, fsync_fname, false);
walkdir(pg_tblspc, fsync_fname, true);
}
/*
* walkdir: recursively walk a directory, applying the action to each
* regular file and directory (including the named directory itself).
*
* If process_symlinks is true, the action and recursion are also applied
* to regular files and directories that are pointed to by symlinks in the
* given directory; otherwise symlinks are ignored. Symlinks are always
* ignored in subdirectories, ie we intentionally don't pass down the
* process_symlinks flag to recursive calls.
*
* Errors are reported but not considered fatal.
*
* See also walkdir in fd.cpp, which is a backend version of this logic.
*/
static void walkdir(const char *path, int (*action) (const char *fname, bool isdir), bool process_symlinks)
{
DIR *dir;
struct dirent *de = NULL;
errno_t errorno = EOK;
dir = opendir(path);
if (dir == NULL) {
pg_log(PG_WARNING, _("could not open directory \"%s\": %m\n"), path);
return;
}
while (errno = 0, (de = readdir(dir)) != NULL) {
char subpath[MAXPGPATH * 2] = {0};
struct stat fst;
int sret;
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
continue;
if (strcmp(de->d_name, "pg_ctl.lock") == 0) {
continue;
}
errorno = snprintf_s(subpath, sizeof(subpath), sizeof(subpath) - 1, "%s/%s", path, de->d_name);
securec_check_ss_c(errorno, "\0", "\0");
if (process_symlinks)
sret = stat(subpath, &fst);
else
sret = lstat(subpath, &fst);
if (sret < 0) {
pg_log(PG_WARNING, _("could not stat file \"%s\": %m\n"), subpath);
continue;
}
if (S_ISREG(fst.st_mode))
(*action) (subpath, false);
else if (S_ISDIR(fst.st_mode))
walkdir(subpath, action, false);
}
if (errno)
pg_log(PG_WARNING, _("could not read directory \"%s\": %m\n"), path);
(void)closedir(dir);
/*
* It's important to fsync the destination directory itself as individual
* file fsyncs don't guarantee that the directory entry for the file is
* synced. Recent versions of ext4 have made the window much wider but
* it's been an issue for ext3 and other filesystems in the past.
*/
(*action) (path, true);
}
/*
* fsync_fname -- Try to fsync a file or directory
*
* Ignores errors trying to open unreadable files, or trying to fsync
* directories on systems where that isn't allowed/required. All other errors
* are fatal.
*/
int fsync_fname(const char *fname, bool isdir)
{
int fd = -1;
int flags;
int returncode;
/*
* Some OSs require directories to be opened read-only whereas other
* systems don't allow us to fsync files opened read-only; so we need both
* cases here. Using O_RDWR will cause us to fail to fsync files that are
* not writable by our userid, but we assume that's OK.
*/
flags = PG_BINARY;
if (!isdir)
flags |= O_RDWR;
else
flags |= O_RDONLY;
/*
* Open the file, silently ignoring errors about unreadable files (or
* unsupported operations, e.g. opening a directory under Windows), and
* logging others.
*/
fd = open(fname, flags, 0);
if (fd < 0) {
if (errno == EACCES || (isdir && errno == EISDIR))
return 0;
pg_log(PG_WARNING, _("could not open file \"%s\": %m\n"), fname);
return -1;
}
returncode = fsync(fd);
/*
* Some OSes don't allow us to fsync directories at all, so we can ignore
* those errors. Anything else needs to be reported.
*/
if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL))) {
pg_log(PG_WARNING, _("could not fsync file \"%s\": %m\n"), fname);
(void) close(fd);
exit(EXIT_FAILURE);
}
(void) close(fd);
return 0;
}

View File

@ -49,6 +49,7 @@ int find_gucoption(
void get_conninfo(const char* filename); void get_conninfo(const char* filename);
extern PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term = 0); extern PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term = 0);
extern PGconn* check_and_conn_for_standby(int conn_timeout, int recv_timeout, uint32 term = 0);
int GetLengthAndCheckReplConn(const char* ConnInfoList); int GetLengthAndCheckReplConn(const char* ConnInfoList);
extern int replconn_num; extern int replconn_num;
@ -60,5 +61,7 @@ extern char* pg_strdup(const char* in);
extern void pg_free(void* ptr); extern void pg_free(void* ptr);
extern void get_slot_name(char* slotname, size_t len); extern void get_slot_name(char* slotname, size_t len);
extern bool libpqRotateCbmFile(PGconn* connObj, XLogRecPtr lsn); extern bool libpqRotateCbmFile(PGconn* connObj, XLogRecPtr lsn);
extern int fsync_fname(const char *fname, bool isdir);
extern void fsync_pgdata(const char *pg_data);
#endif /* PG_BUILD_H */ #endif /* PG_BUILD_H */

View File

@ -171,6 +171,7 @@ static char switchover_file[MAXPGPATH];
static char promote_file[MAXPGPATH]; static char promote_file[MAXPGPATH];
static char primary_file[MAXPGPATH]; static char primary_file[MAXPGPATH];
static char standby_file[MAXPGPATH]; static char standby_file[MAXPGPATH];
static char cascade_standby_file[MAXPGPATH];
static char pg_ctl_lockfile[MAXPGPATH]; static char pg_ctl_lockfile[MAXPGPATH];
static char pg_conf_file[MAXPGPATH]; static char pg_conf_file[MAXPGPATH];
static FILE* lockfile = NULL; static FILE* lockfile = NULL;
@ -184,6 +185,7 @@ char gaussdb_state_file[MAXPGPATH] = {0};
static char postport_lock_file[MAXPGPATH]; static char postport_lock_file[MAXPGPATH];
static PGconn* dbConn = NULL; static PGconn* dbConn = NULL;
bool no_need_fsync = false;
pid_t process_id = 0; pid_t process_id = 0;
const int g_length_stop_char = 2; const int g_length_stop_char = 2;
@ -2146,6 +2148,10 @@ static void do_notify(uint32 term)
pgha_str[strlen("primary")] == '\0') { pgha_str[strlen("primary")] == '\0') {
notify_file = xstrdup(primary_file); notify_file = xstrdup(primary_file);
notify_mode = PRIMARY_MODE; notify_mode = PRIMARY_MODE;
} else if ((pgha_str != NULL) && 0 == strncmp(pgha_str, "cascade_standby", strlen("cascade_standby")) &&
pgha_str[strlen("cascade_standby")] == '\0') {
notify_file = xstrdup(cascade_standby_file);
notify_mode = CASCADE_STANDBY_MODE;
} else { } else {
pg_log(PG_WARNING, _(" the parameter of notify is not recognized\n")); pg_log(PG_WARNING, _(" the parameter of notify is not recognized\n"));
exit(1); exit(1);
@ -3498,8 +3504,9 @@ static void do_help(void)
(void)printf(_(" %s hotpatch [-D DATADIR] [-a ACTION] [-n NAME]\n"), progname); (void)printf(_(" %s hotpatch [-D DATADIR] [-a ACTION] [-n NAME]\n"), progname);
#endif #endif
printf(_("\nCommon options:\n")); printf(_("\nCommon options:\n"));
printf(_(" -b, --mode=MODE the mode of building the datanode.MODE can be \"full\", \"incremental\", " printf(_(" -b, --mode=MODE the mode of building the datanode or coordinator."
"\"auto\"\n")); "MODE can be \"full\", \"incremental\", "
"\"auto\", \"standby_full\"\n"));
printf(_(" -D, --pgdata=DATADIR location of the database storage area\n")); printf(_(" -D, --pgdata=DATADIR location of the database storage area\n"));
printf(_(" -s, --silent only print errors, no informational messages\n")); printf(_(" -s, --silent only print errors, no informational messages\n"));
printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n")); printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
@ -3576,7 +3583,7 @@ static void do_help(void)
#endif #endif
printf(_("\nBuild connection option:\n")); printf(_("\nBuild connection option:\n"));
printf(_(" -r, --recvtimeout=INTERVAL time that receiver waits for communication from server (in seconds)\n")); printf(_(" -r, --recvtimeout=INTERVAL time that receiver waits for communication from server (in seconds)\n"));
printf(_(" -C, connector CN/DN connect to CN for build\n")); printf(_(" -C, connector CN/DN connect to specified CN/DN for build\n"));
#if ((defined(ENABLE_MULTIPLE_NODES)) || (defined(ENABLE_PRIVATEGAUSS))) #if ((defined(ENABLE_MULTIPLE_NODES)) || (defined(ENABLE_PRIVATEGAUSS)))
printf("\nReport bugs to GaussDB support.\n"); printf("\nReport bugs to GaussDB support.\n");
@ -3785,6 +3792,8 @@ static char* get_localrole_string(ServerMode mode)
return "Primary"; return "Primary";
case STANDBY_MODE: case STANDBY_MODE:
return "Standby"; return "Standby";
case CASCADE_STANDBY_MODE:
return "Cascade Standby";
case PENDING_MODE: case PENDING_MODE:
return "Pending"; return "Pending";
default: default:
@ -3833,7 +3842,7 @@ static void do_build_stop(pgpid_t pid)
} }
do_wait = true; do_wait = true;
if (build_mode == FULL_BUILD) { if (build_mode == FULL_BUILD || build_mode == STANDBY_FULL_BUILD) {
shutdown_mode = IMMEDIATE_MODE; shutdown_mode = IMMEDIATE_MODE;
sig = SIGQUIT; sig = SIGQUIT;
do_stop(true); do_stop(true);
@ -3918,6 +3927,11 @@ static void do_build(uint32 term)
createRewindFile(pg_data); createRewindFile(pg_data);
do_incremental_build_xlog(); do_incremental_build_xlog();
} }
/* standby DN full build from standby DN */
else if (build_mode == STANDBY_FULL_BUILD) {
createRewindFile(pg_data);
do_actual_build(term);
}
} }
static void do_restore(void) static void do_restore(void)
@ -3980,7 +3994,7 @@ static void do_incremental_build(uint32 term)
/* Concate connection str to primary host for performing rewind. */ /* Concate connection str to primary host for performing rewind. */
errorno = sprintf_s(connstrSource, errorno = sprintf_s(connstrSource,
sizeof(connstrSource), sizeof(connstrSource),
"host=%s port=%s dbname=postgres application_name=gs_rewind connect_timeout=5", "host=%s port=%s dbname=postgres application_name=gs_rewind connect_timeout=5 rw_timeout=600",
(streamConn->pghost != NULL) ? streamConn->pghost : streamConn->pghostaddr, (streamConn->pghost != NULL) ? streamConn->pghost : streamConn->pghostaddr,
streamConn->pgport); streamConn->pgport);
securec_check_ss_c(errorno, "\0", "\0"); securec_check_ss_c(errorno, "\0", "\0");
@ -4165,7 +4179,11 @@ static void do_actual_build(uint32 term)
read_ssl_confval(); read_ssl_confval();
backup_main(pg_data, term); if (build_mode == STANDBY_FULL_BUILD) {
backup_main(pg_data, term, true);
} else {
backup_main(pg_data, term, false);
}
pg_log(PG_WARNING, _("build completed(%s).\n"), pg_data); pg_log(PG_WARNING, _("build completed(%s).\n"), pg_data);
@ -4174,7 +4192,7 @@ static void do_actual_build(uint32 term)
* Standby DN incremental build from Primary DN auto start. * Standby DN incremental build from Primary DN auto start.
* If connect string is not empty,CN/DN will be started by caller. * If connect string is not empty,CN/DN will be started by caller.
*/ */
if (conn_str == NULL) { if (conn_str == NULL || (build_mode == STANDBY_FULL_BUILD && conn_str != NULL)) {
/* cascade standby will use use pgha_opt directly */ /* cascade standby will use use pgha_opt directly */
if (pgha_opt == NULL || strstr(pgha_opt, "cascade_standby") == NULL) { if (pgha_opt == NULL || strstr(pgha_opt, "cascade_standby") == NULL) {
/* pg_ctl start -M standby */ /* pg_ctl start -M standby */
@ -4637,6 +4655,7 @@ int main(int argc, char** argv)
{"connect-string", required_argument, NULL, 'C'}, {"connect-string", required_argument, NULL, 'C'},
{"remove-backup", no_argument, NULL, 1}, {"remove-backup", no_argument, NULL, 1},
{"action", required_argument, NULL, 'a'}, {"action", required_argument, NULL, 'a'},
{"no-fsync", no_argument, NULL, 3},
{NULL, 0, NULL, 0}}; {NULL, 0, NULL, 0}};
int option_index; int option_index;
@ -4711,16 +4730,19 @@ int main(int argc, char** argv)
argc, argv, "a:b:cD:l:m:M:N:n:o:p:P:r:sS:t:U:wWZ:dqL:T:", long_options, &option_index)) != -1) argc, argv, "a:b:cD:l:m:M:N:n:o:p:P:r:sS:t:U:wWZ:dqL:T:", long_options, &option_index)) != -1)
#else #else
while ((c = getopt_long( while ((c = getopt_long(
argc, argv, "b:cD:l:m:M:N:o:p:P:r:sS:t:U:wWZ:dqL:T:", long_options, &option_index)) != -1) argc, argv, "b:cD:l:m:M:N:o:p:P:r:sS:t:U:wWZ:C:dqL:T:", long_options, &option_index)) != -1)
#endif #endif
#endif #endif
{ {
switch (c) { switch (c) {
case 'b': { case 'b': {
if (strcmp(optarg, "full") == 0) if (strcmp(optarg, "full") == 0) {
build_mode = FULL_BUILD; build_mode = FULL_BUILD;
else if (strcmp(optarg, "incremental") == 0) } else if (strcmp(optarg, "incremental") == 0) {
build_mode = INC_BUILD; build_mode = INC_BUILD;
} else if (strcmp(optarg, "standby_full") == 0) {
build_mode = STANDBY_FULL_BUILD;
}
break; break;
} }
case 'D': { case 'D': {
@ -4923,6 +4945,9 @@ int main(int argc, char** argv)
case 1: case 1:
clear_backup_dir = true; clear_backup_dir = true;
break; break;
case 3:
no_need_fsync = true;
break;
default: default:
/* getopt_long already issued a suitable error message */ /* getopt_long already issued a suitable error message */
do_advice(); do_advice();
@ -5094,6 +5119,8 @@ int main(int argc, char** argv)
securec_check_ss_c(ret, "\0", "\0"); securec_check_ss_c(ret, "\0", "\0");
ret = snprintf_s(standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/standby", pg_data); ret = snprintf_s(standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/standby", pg_data);
securec_check_ss_c(ret, "\0", "\0"); securec_check_ss_c(ret, "\0", "\0");
ret = snprintf_s(cascade_standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/cascade_standby", pg_data);
securec_check_ss_c(ret, "\0", "\0");
ret = snprintf_s(pg_ctl_lockfile, MAXPGPATH, MAXPGPATH - 1, "%s/pg_ctl.lock", pg_data); ret = snprintf_s(pg_ctl_lockfile, MAXPGPATH, MAXPGPATH - 1, "%s/pg_ctl.lock", pg_data);
securec_check_ss_c(ret, "\0", "\0"); securec_check_ss_c(ret, "\0", "\0");
ret = snprintf_s(pg_conf_file, MAXPGPATH, MAXPGPATH - 1, "%s/postgresql.conf", pg_data); ret = snprintf_s(pg_conf_file, MAXPGPATH, MAXPGPATH - 1, "%s/postgresql.conf", pg_data);
@ -5208,17 +5235,38 @@ int main(int argc, char** argv)
break; break;
#endif #endif
case BUILD_COMMAND: case BUILD_COMMAND:
if (conn_str != NULL) if (conn_str != NULL) {
pg_log(PG_PROGRESS, if (build_mode == FULL_BUILD) {
_("gs_ctl %s build ,datadir is %s,conn_str is \'%s\'\n"), pg_log(PG_PROGRESS,
build_mode == FULL_BUILD ? "full" : "incremental", _("gs_ctl full build ,datadir is %s,conn_str is \'%s\'\n"),
pg_data, pg_data,
conn_str); conn_str);
else } else if (build_mode == STANDBY_FULL_BUILD) {
pg_log(PG_PROGRESS, pg_log(PG_PROGRESS,
_("gs_ctl %s build ,datadir is %s\n"), _("gs_ctl standby full build ,datadir is %s,conn_str is \'%s\'\n"),
build_mode == FULL_BUILD ? "full" : "incremental", pg_data,
pg_data); conn_str);
} else {
pg_log(PG_PROGRESS,
_("gs_ctl incremental build ,datadir is %s,conn_str is \'%s\'\n"),
pg_data,
conn_str);
}
} else {
if (build_mode == FULL_BUILD) {
pg_log(PG_PROGRESS,
_("gs_ctl full build ,datadir is %s\n"),
pg_data);
} else if (build_mode == STANDBY_FULL_BUILD) {
pg_log(PG_PROGRESS,
_("gs_ctl standby full build ,datadir is %s\n"),
pg_data);
} else {
pg_log(PG_PROGRESS,
_("gs_ctl incremental build ,datadir is %s\n"),
pg_data);
}
}
if (-1 != pg_ctl_lock(pg_ctl_lockfile, &lockfile)) { if (-1 != pg_ctl_lock(pg_ctl_lockfile, &lockfile)) {
do_build(term); do_build(term);
(void)pg_ctl_unlock(lockfile); (void)pg_ctl_unlock(lockfile);

View File

@ -665,7 +665,7 @@ bool ReceiveXlogStream(PGconn* conn, XLogRecPtr startpos, uint32 timeline, const
FD_ZERO(&input_mask); FD_ZERO(&input_mask);
FD_SET(PQsocket(conn), &input_mask); FD_SET(PQsocket(conn), &input_mask);
if (standby_message_timeout) { if (standby_message_timeout) {
timeout.tv_sec = last_status + standby_message_timeout - local_now - 1; timeout.tv_sec = last_status + (standby_message_timeout / 2) - local_now - 1;
if (timeout.tv_sec <= 0) if (timeout.tv_sec <= 0)
timeout.tv_sec = 1; /* Always sleep at least 1 sec */ timeout.tv_sec = 1; /* Always sleep at least 1 sec */
timeout.tv_usec = 0; timeout.tv_usec = 0;

View File

@ -728,7 +728,7 @@ int main(int argc, char** argv)
errorMessages = ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password, false); errorMessages = ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password, false);
if (errorMessages != NULL) { if (errorMessages != NULL) {
(void)remove(filename); (void)remove(filename);
filename = NULL; GS_FREE(filename);
exit_horribly(NULL, "connection to database \"%s\" failed: %s ", exit_horribly(NULL, "connection to database \"%s\" failed: %s ",
((dbname != NULL) ? dbname : ""), errorMessages); ((dbname != NULL) ? dbname : ""), errorMessages);
} }

View File

@ -27,6 +27,10 @@
#include "file.h" #include "file.h"
#include "common/fe_memutils.h" #include "common/fe_memutils.h"
/* list of dirs which will not to be backuped
it will be backuped up in external dirs */
parray *pgdata_nobackup_dir = NULL;
static int standby_message_timeout_local = 10 ; /* 10 sec = default */ static int standby_message_timeout_local = 10 ; /* 10 sec = default */
static XLogRecPtr stop_backup_lsn = InvalidXLogRecPtr; static XLogRecPtr stop_backup_lsn = InvalidXLogRecPtr;
static XLogRecPtr stop_stream_lsn = InvalidXLogRecPtr; static XLogRecPtr stop_stream_lsn = InvalidXLogRecPtr;
@ -740,6 +744,11 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
if (external_dirs) if (external_dirs)
free_dir_list(external_dirs); free_dir_list(external_dirs);
if (pgdata_nobackup_dir) {
free_dir_list(pgdata_nobackup_dir);
}
pgdata_nobackup_dir = NULL;
/* Cleanup */ /* Cleanup */
if (backup_list) if (backup_list)
{ {
@ -786,7 +795,7 @@ pgdata_basic_setup(const ConnectionOptions conn_opt, PGNodeInfo *nodeInfo)
exclusive_backup = true; exclusive_backup = true;
} }
current.checksum_version = 0; current.checksum_version = 1;
nodeInfo->checksum_version = current.checksum_version; nodeInfo->checksum_version = current.checksum_version;
@ -1223,10 +1232,20 @@ void tryToFindCompressedWALFile(bool *file_exists, char *gz_wal_segment_path, ch
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
*file_exists = fileExists(gz_wal_segment_path, FIO_BACKUP_HOST); *file_exists = fileExists(gz_wal_segment_path, FIO_BACKUP_HOST);
if (*file_exists) if (*file_exists)
{
elog(LOG, "Found compressed WAL segment: %s", wal_segment_path); elog(LOG, "Found compressed WAL segment: %s", wal_segment_path);
if (current.from_replica)
{
elog(INFO, "Wait a few minutes to get the target LSN or the last valid record prior to the target LSN");
}
}
#endif #endif
} else { } else {
elog(LOG, "Found WAL segment: %s", wal_segment_path); elog(LOG, "Found WAL segment: %s", wal_segment_path);
if (current.from_replica)
{
elog(INFO, "Wait a few minutes to get the target LSN or the last valid record prior to the target LSN");
}
} }
} }
@ -1263,11 +1282,13 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
XLogSegNo targetSegNo; XLogSegNo targetSegNo;
char pg_wal_dir[MAXPGPATH]; char pg_wal_dir[MAXPGPATH];
char wal_segment_path[MAXPGPATH], char wal_segment_path[MAXPGPATH],
partial_file[MAXPGPATH],
*wal_segment_dir, *wal_segment_dir,
wal_segment[MAXFNAMELEN]; wal_segment[MAXFNAMELEN];
bool file_exists = false; bool file_exists = false;
uint32 try_count = 0, uint32 try_count = 0,
timeout; timeout;
int rc = 0;
const char *wal_delivery_str = (const char *)(in_stream_dir ? "streamed":"archived"); const char *wal_delivery_str = (const char *)(in_stream_dir ? "streamed":"archived");
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
@ -1301,6 +1322,8 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
join_path_components(wal_segment_path, arclog_path, wal_segment); join_path_components(wal_segment_path, arclog_path, wal_segment);
wal_segment_dir = arclog_path; wal_segment_dir = arclog_path;
} }
rc = sprintf_s(partial_file, MAXPGPATH, "%s.partial", wal_segment_path);
securec_check_ss_c(rc, "\0", "\0");
/* TODO: remove this in 3.0 (it is a cludge against some old bug with archive_timeout) */ /* TODO: remove this in 3.0 (it is a cludge against some old bug with archive_timeout) */
timeout = (instance_config.archive_timeout > 0) ? instance_config.archive_timeout : ARCHIVE_TIMEOUT_DEFAULT; timeout = (instance_config.archive_timeout > 0) ? instance_config.archive_timeout : ARCHIVE_TIMEOUT_DEFAULT;
@ -1323,6 +1346,10 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
if (!file_exists) if (!file_exists)
{ {
file_exists = fileExists(wal_segment_path, FIO_BACKUP_HOST); file_exists = fileExists(wal_segment_path, FIO_BACKUP_HOST);
if(!file_exists)
{
file_exists = fileExists(partial_file, FIO_BACKUP_HOST);
}
tryToFindCompressedWALFile(&file_exists, gz_wal_segment_path, wal_segment_path); tryToFindCompressedWALFile(&file_exists, gz_wal_segment_path, wal_segment_path);
} }
@ -2391,6 +2418,7 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
int i = 0; int i = 0;
int j = 0; int j = 0;
char *tablespace_path = NULL; char *tablespace_path = NULL;
bool in_pgdata = false;
const char *query = (const char *)"SELECT pg_catalog.pg_tablespace_location(oid) " const char *query = (const char *)"SELECT pg_catalog.pg_tablespace_location(oid) "
"FROM pg_catalog.pg_tablespace;"; "FROM pg_catalog.pg_tablespace;";
@ -2400,13 +2428,23 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
if (!res) if (!res)
elog(ERROR, "Failed to get list of tablespaces"); elog(ERROR, "Failed to get list of tablespaces");
pgdata_nobackup_dir = parray_new();
for (i = 0; i < res->ntups; i++) for (i = 0; i < res->ntups; i++)
{ {
char full_path[MAXPGPATH] = {0};
char rel_path[MAXPGPATH] = {0};
tablespace_path = PQgetvalue(res, i, 0); tablespace_path = PQgetvalue(res, i, 0);
if (strlen(tablespace_path) == 0) { if (strlen(tablespace_path) == 0) {
continue; continue;
} }
if (!is_absolute_path(tablespace_path)) {
join_path_components(rel_path, PG_RELATIVE_TBLSPC_DIR, tablespace_path);
join_path_components(full_path, instance_config.pgdata, rel_path);
tablespace_path = full_path;
}
canonicalize_path(tablespace_path); canonicalize_path(tablespace_path);
for (j = 0; j < (int)parray_num(external_list); j++) for (j = 0; j < (int)parray_num(external_list); j++)
@ -2421,6 +2459,13 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
elog(WARNING, "External directory path (-E option) \"%s\" " elog(WARNING, "External directory path (-E option) \"%s\" "
"is in tablespace directory \"%s\"", "is in tablespace directory \"%s\"",
tablespace_path, external_path); tablespace_path, external_path);
in_pgdata = path_is_prefix_of_path(instance_config.pgdata, external_path);
if (in_pgdata &&
strcmp(external_path, tablespace_path) == 0) {
char *no_backup_dir = pg_strdup(rel_path);
parray_append(pgdata_nobackup_dir, no_backup_dir);
}
} }
} }
PQclear(res); PQclear(res);
@ -2507,9 +2552,9 @@ static bool PathContainPath(const char* path1, const char* path2)
size_t path2Len = strlen(path2); size_t path2Len = strlen(path2);
if (path1Len == path2Len) { if (path1Len == path2Len) {
return false; return false;
} else if ((path2Len == (path1Len + 1)) && !IS_DIR_SEP(path2[path1Len - 1])) { } else if ((path2Len >= (path1Len + 1)) && !IS_DIR_SEP(path2[path1Len])) {
return false; return false;
} else if ((path2Len == (path1Len + 1)) && IS_DIR_SEP(path2[path1Len - 1])) { } else if ((path2Len >= (path1Len + 1)) && IS_DIR_SEP(path2[path1Len])) {
return true; return true;
} else { } else {
return false; return false;

View File

@ -215,6 +215,11 @@ ConfigOption instance_options[] =
&instance_config.remote.ssh_config, SOURCE_CMD, (OptionSource)0, &instance_config.remote.ssh_config, SOURCE_CMD, (OptionSource)0,
OPTION_REMOTE_GROUP, 0, option_get_value OPTION_REMOTE_GROUP, 0, option_get_value
}, },
{
's', 231, "remote-libpath",
&instance_config.remote.libpath, SOURCE_CMD, (OptionSource)0,
OPTION_REMOTE_GROUP, 0, option_get_value
},
{ 0 } { 0 }
}; };
@ -506,6 +511,10 @@ readInstanceConfigFile(const char *instance_name)
's', 230, "ssh-config", &instance->remote.ssh_config, SOURCE_CMD, (OptionSource)0, 's', 230, "ssh-config", &instance->remote.ssh_config, SOURCE_CMD, (OptionSource)0,
OPTION_REMOTE_GROUP, 0, option_get_value OPTION_REMOTE_GROUP, 0, option_get_value
}, },
{
's', 231, "remote-libpath", &instance->remote.libpath, SOURCE_CMD, (OptionSource)0,
OPTION_REMOTE_GROUP, 0, option_get_value
},
{ 0 } { 0 }
}; };

View File

@ -33,9 +33,90 @@ typedef struct DataPage
char data[BLCKSZ]; char data[BLCKSZ];
} DataPage; } DataPage;
uint32 CHECK_STEP = 2;
static bool get_page_header(FILE *in, const char *fullpath, BackupPageHeader* bph, static bool get_page_header(FILE *in, const char *fullpath, BackupPageHeader* bph,
pg_crc32 *crc, bool use_crc32c); pg_crc32 *crc, bool use_crc32c);
static inline uint32 pg_checksum_init(uint32 seed, uint32 value)
{
CHECKSUM_COMP(seed, value);
return seed;
}
uint32 pg_checksum_block(char* data, uint32 size)
{
uint32 sums[N_SUMS];
uint32* dataArr = (uint32*)data;
uint32 result = 0;
uint32 i, j;
/* ensure that the size is compatible with the algorithm */
Assert((size % (sizeof(uint32) * N_SUMS)) == 0);
/* initialize partial checksums to their corresponding offsets */
for (j = 0; j < N_SUMS; j += CHECK_STEP) {
sums[j] = pg_checksum_init(g_checksumBaseOffsets[j], dataArr[j]);
sums[j + 1] = pg_checksum_init(g_checksumBaseOffsets[j + 1], dataArr[j + 1]);
}
dataArr += N_SUMS;
/* main checksum calculation */
for (i = 1; i < size / (sizeof(uint32) * N_SUMS); i++) {
for (j = 0; j < N_SUMS; j += CHECK_STEP) {
CHECKSUM_COMP(sums[j], dataArr[j]);
CHECKSUM_COMP(sums[j + 1], dataArr[j + 1]);
}
dataArr += N_SUMS;
}
/* finally add in two rounds of zeroes for additional mixing */
for (j = 0; j < N_SUMS; j++) {
CHECKSUM_COMP(sums[j], 0);
CHECKSUM_COMP(sums[j], 0);
/* xor fold partial checksums together */
result ^= sums[j];
}
return result;
}
/*
* Compute the checksum for a openGauss page. The page must be aligned on a
* 4-byte boundary.
*
* The checksum includes the block number (to detect the case where a page is
* somehow moved to a different location), the page header (excluding the
* checksum itself), and the page data.
*/
uint16 pg_checksum_page(char* page, BlockNumber blkno)
{
PageHeader phdr = (PageHeader)page;
uint16 save_checksum;
uint32 checksum;
/*
* Save pd_checksum and temporarily set it to zero, so that the checksum
* calculation isn't affected by the old checksum stored on the page.
* Restore it after, because actually updating the checksum is NOT part of
* the API of this function.
*/
save_checksum = phdr->pd_checksum;
phdr->pd_checksum = 0;
checksum = pg_checksum_block(page, BLCKSZ);
phdr->pd_checksum = save_checksum;
/* Mix in the block number to detect transposed pages */
checksum ^= blkno;
/*
* Reduce to a uint16 (to fit in the pd_checksum field) with an offset of
* one. That avoids checksums of zero, which seems like a good idea.
*/
return (checksum % UINT16_MAX) + 1;
}
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
/* Implementation of zlib compression method */ /* Implementation of zlib compression method */
static int32 static int32
@ -270,7 +351,7 @@ get_checksum_errormsg(Page page, char **errormsg, BlockNumber absolute_blkno)
"page verification failed, " "page verification failed, "
"calculated checksum %u but expected %u", "calculated checksum %u but expected %u",
phdr->pd_checksum, phdr->pd_checksum,
/*pg_checksum_page(page, absolute_blkno)*/0); pg_checksum_page(page, absolute_blkno));
securec_check_ss_c(nRet, "\0", "\0"); securec_check_ss_c(nRet, "\0", "\0");
} }
@ -1428,7 +1509,7 @@ validate_one_page(Page page, BlockNumber absolute_blkno,
} }
/* Verify checksum */ /* Verify checksum */
page_st->checksum = 0;//pg_checksum_page(page, absolute_blkno); page_st->checksum = pg_checksum_page(page, absolute_blkno);
if (checksum_version) if (checksum_version)
{ {
@ -1734,7 +1815,7 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
{ {
elog(WARNING, "Invalid CRC of backup file \"%s\": %X. Expected %X", elog(WARNING, "Invalid CRC of backup file \"%s\": %X. Expected %X",
fullpath, crc, file->crc); fullpath, crc, file->crc);
//is_valid = false; is_valid = false;
} }
pg_free(headers); pg_free(headers);
@ -1789,8 +1870,10 @@ get_checksum_map(const char *fullpath, uint32 checksum_version,
if (rc == PAGE_IS_VALID) if (rc == PAGE_IS_VALID)
{ {
if (checksum_version)
checksum_map[blknum].checksum = page_st.checksum; checksum_map[blknum].checksum = ((PageHeader) read_buffer)->pd_checksum;
else
checksum_map[blknum].checksum = page_st.checksum;
checksum_map[blknum].lsn = page_st.lsn; checksum_map[blknum].lsn = page_st.lsn;
} }
} }

View File

@ -131,6 +131,7 @@ static char dir_check_file(pgFile *file, bool backup_logs);
static char check_in_tablespace(pgFile *file, bool in_tablespace); static char check_in_tablespace(pgFile *file, bool in_tablespace);
static char check_db_dir(pgFile *file); static char check_db_dir(pgFile *file);
static char check_digit_file(pgFile *file); static char check_digit_file(pgFile *file);
static char check_nobackup_dir(pgFile *file);
static void dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir, static void dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
bool exclude, bool follow_symlink, bool backup_logs, bool exclude, bool follow_symlink, bool backup_logs,
bool skip_hidden, int external_dir_num, fio_location location); bool skip_hidden, int external_dir_num, fio_location location);
@ -479,8 +480,8 @@ pgFileCompareLinked(const void *f1, const void *f2)
int int
pgFileCompareSize(const void *f1, const void *f2) pgFileCompareSize(const void *f1, const void *f2)
{ {
pgFile *f1p = (pgFile *)const_cast<void*>(f1); pgFile *f1p = *(pgFile **)f1;
pgFile *f2p = (pgFile *)const_cast<void*>(f2); pgFile *f2p = *(pgFile **)f2;
if (f1p->size > f2p->size) if (f1p->size > f2p->size)
return 1; return 1;
@ -493,7 +494,7 @@ pgFileCompareSize(const void *f1, const void *f2)
static int static int
pgCompareString(const void *str1, const void *str2) pgCompareString(const void *str1, const void *str2)
{ {
return strcmp((char *)const_cast<void*>( str1), (char *)const_cast<void*>(str2)); return strcmp(*(char **) str1, *(char **) str2);
} }
/* Compare two Oids */ /* Compare two Oids */
@ -644,6 +645,12 @@ dir_check_file(pgFile *file, bool backup_logs)
return CHECK_EXCLUDE_FALSE; return CHECK_EXCLUDE_FALSE;
} }
} }
ret = check_nobackup_dir(file);
if (ret != -1) { /* -1 means need backup */
return ret;
}
} }
/* /*
@ -719,6 +726,23 @@ if (in_tablespace)
return -1; return -1;
} }
static char check_nobackup_dir(pgFile *file)
{
char ret = -1; /* -1 means need backup */
int i = 0;
if (pgdata_nobackup_dir) {
for (i = 0; i < (int)parray_num(pgdata_nobackup_dir); i++) {
char *file_path = (char *)parray_get(pgdata_nobackup_dir, i);
/* relative tablespace path exclude */
if (strcmp(file->rel_path, file_path) == 0) {
elog(VERBOSE, "Excluding external directory content: %s", file->rel_path);
return CHECK_EXCLUDE_FALSE;
}
}
}
return ret;
}
static char check_db_dir(pgFile *file) static char check_db_dir(pgFile *file)
{ {
char ret = -1; char ret = -1;
@ -1037,7 +1061,7 @@ opt_externaldir_map(ConfigOption *opt, const char *arg)
* Enforce permissions from backup_content.control. The only * Enforce permissions from backup_content.control. The only
* problem now is with PGDATA itself. * problem now is with PGDATA itself.
* TODO: we must preserve PGDATA permissions somewhere. Is it actually a problem? * TODO: we must preserve PGDATA permissions somewhere. Is it actually a problem?
* Shouldn`t starting postgres force correct permissions on PGDATA? * Shouldn`t starting openGauss force correct permissions on PGDATA?
* *
* TODO: symlink handling. If user located symlink in PG_TBLSPC_DIR, it will * TODO: symlink handling. If user located symlink in PG_TBLSPC_DIR, it will
* be restored as directory. * be restored as directory.

View File

@ -116,6 +116,8 @@ do_add_instance(InstanceConfig *instance)
SOURCE_DEFAULT); SOURCE_DEFAULT);
config_set_opt(instance_options, &instance_config.remote.path, config_set_opt(instance_options, &instance_config.remote.path,
SOURCE_DEFAULT); SOURCE_DEFAULT);
config_set_opt(instance_options, &instance_config.remote.libpath,
SOURCE_DEFAULT);
config_set_opt(instance_options, &instance_config.remote.user, config_set_opt(instance_options, &instance_config.remote.user,
SOURCE_DEFAULT); SOURCE_DEFAULT);
config_set_opt(instance_options, &instance_config.remote.ssh_options, config_set_opt(instance_options, &instance_config.remote.ssh_options,

View File

@ -13,6 +13,8 @@
#include "parray.h" #include "parray.h"
#include "pgut.h" #include "pgut.h"
static size_t qsort_size = 100000; /* 100000 = default size */
/* members of struct parray are hidden from client. */ /* members of struct parray are hidden from client. */
struct parray struct parray
{ {
@ -191,10 +193,60 @@ parray_num(const parray *array)
return array->used; return array->used;
} }
static void HeapAdjust(void **array, size_t size, size_t index,
int(*compare)(const void *, const void *))
{
size_t parent = index;
size_t child = 2 * parent + 1; /* 2 * n + 1 :left child */
while (child < size) {
if (child + 1 < size && compare(&array[child + 1], &array[child]) > 0) {
child = child + 1;
}
if (compare(&array[child], &array[parent]) > 0) {
void *tmp = array[child];
array[child] = array[parent];
array[parent] = tmp;
} else {
break;
}
parent = child;
child = 2 * parent + 1; /* 2 * n + 1 :left child */
}
}
static void HeapPop(void **array, size_t size,
int(*compare)(const void *, const void *))
{
void *tmp = array[0];
array[0] = array[size - 1];
array[size - 1] = tmp;
HeapAdjust(array, size - 1, 0, compare);
}
static void HeapSort(void **array, size_t size,
int(*compare)(const void *, const void *))
{
for (int64 i = (size - 2) / 2; i >= 0; i--) { /* parent node:(size -2) / 2 */
HeapAdjust(array, size, i, compare);
}
for (size_t i = 0; i < size; i++) {
HeapPop(array, size - i, compare);
}
}
void void
parray_qsort(parray *array, int(*compare)(const void *, const void *)) parray_qsort(parray *array, int(*compare)(const void *, const void *))
{ {
qsort(array->data, array->used, sizeof(void *), compare); Assert(array->used < (PG_UINT64_MAX / 1024));
if (array->used <= qsort_size) {
qsort(array->data, array->used, sizeof(void *), compare);
} else {
HeapSort(array->data, array->used, compare);
}
} }
void void

View File

@ -1054,8 +1054,9 @@ static int switch_next_wal_segment(XLogReaderData *reader_data, bool *isreturn)
if (fileExists(reader_data->xlogpath, FIO_LOCAL_HOST)) if (fileExists(reader_data->xlogpath, FIO_LOCAL_HOST))
{ {
elog(LOG, "Thread [%d]: Opening WAL segment \"%s\"", if (!current.from_replica)
reader_data->thread_num, reader_data->xlogpath); elog(LOG, "Thread [%d]: Opening WAL segment \"%s\"",
reader_data->thread_num, reader_data->xlogpath);
reader_data->xlogexists = true; reader_data->xlogexists = true;
reader_data->xlogfile = fio_open(reader_data->xlogpath, reader_data->xlogfile = fio_open(reader_data->xlogpath,

View File

@ -804,6 +804,8 @@ int main(int argc, char *argv[])
*/ */
parse_backup_option_to_params(command, command_name); parse_backup_option_to_params(command, command_name);
pfree(command_name);
compress_init(); compress_init();
/* do actual operation */ /* do actual operation */

View File

@ -68,6 +68,7 @@ extern const char *PROGRAM_FULL_PATH;
#define DATABASE_MAP "database_map" #define DATABASE_MAP "database_map"
#define HEADER_MAP "page_header_map" #define HEADER_MAP "page_header_map"
#define HEADER_MAP_TMP "page_header_map_tmp" #define HEADER_MAP_TMP "page_header_map_tmp"
#define PG_RELATIVE_TBLSPC_DIR "pg_location"
/* Timeout defaults */ /* Timeout defaults */
#define ARCHIVE_TIMEOUT_DEFAULT 300 #define ARCHIVE_TIMEOUT_DEFAULT 300

View File

@ -50,6 +50,10 @@ extern int rw_timeout;
/* backup options */ /* backup options */
extern bool smooth_checkpoint; extern bool smooth_checkpoint;
/* list of dirs which will not to be backuped
it will be backuped up in external dirs */
extern parray *pgdata_nobackup_dir;
/* remote probackup options */ /* remote probackup options */
extern char* remote_agent; extern char* remote_agent;

View File

@ -613,6 +613,7 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
const char **values; const char **values;
errno_t rc = EOK; errno_t rc = EOK;
char rwtimeoutStr[12] = {0}; char rwtimeoutStr[12] = {0};
const char *malloc_port = NULL;
if (interrupted && !in_cleanup) if (interrupted && !in_cleanup)
elog(ERROR, "interrupted"); elog(ERROR, "interrupted");
@ -659,6 +660,7 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
{ {
keywords[i] = "port"; keywords[i] = "port";
values[i] = inc_dbport(port); values[i] = inc_dbport(port);
malloc_port = values[i];
i++; i++;
} }
@ -683,6 +685,10 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
{ {
free(values); free(values);
free(keywords); free(keywords);
if (malloc_port)
{
free((void *)malloc_port);
}
return tmpconn; return tmpconn;
} }
@ -700,6 +706,10 @@ PGconn* pgut_connect_replication(const char *host, const char *port,
PQfinish(tmpconn); PQfinish(tmpconn);
free(values); free(values);
free(keywords); free(keywords);
if (malloc_port)
{
free((void *)malloc_port);
}
return NULL; return NULL;
} }
} }

View File

@ -54,6 +54,9 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
{ {
PGresult *res; PGresult *res;
char start_lsn[17 + 1]; char start_lsn[17 + 1];
uint32 lsn_hi;
uint32 lsn_lo;
XLogRecPtr cur_track_lsn;
char *params[2]; char *params[2];
char *saved = NULL; char *saved = NULL;
char *blocknum_str = NULL; char *blocknum_str = NULL;
@ -63,23 +66,37 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
int blkcnt = 0; int blkcnt = 0;
BlockNumber blknum = 0; BlockNumber blknum = 0;
datapagemap_t pagemap; datapagemap_t pagemap;
int segno = -1;
char relpath[MAXPGPATH] = {0};
page_map_entry **segarrary = (page_map_entry **)pgut_malloc(sizeof(page_map_entry *) * 32000);
page_map_entry *pm_entry_seg = NULL;
errno_t rc = snprintf_s(start_lsn, sizeof(start_lsn), sizeof(start_lsn) - 1, "%X/%X", errno_t rc = snprintf_s(start_lsn, sizeof(start_lsn), sizeof(start_lsn) - 1, "%X/%X",
(uint32) (lsn >> 32), (uint32) lsn); (uint32) (lsn >> 32), (uint32) lsn);
securec_check_ss_c(rc, "\0", "\0"); securec_check_ss_c(rc, "\0", "\0");
params[0] = gs_pstrdup(start_lsn); params[0] = gs_pstrdup(start_lsn);
elog(INFO, "change bitmap start lsn location is %s", params[0]);
if (!current.from_replica) { for (;;) {
res = pgut_execute(backup_conn, "CHECKPOINT;", 0, NULL); char *temp_lsn = NULL;
PQclear(res); res = pgut_execute(backup_conn, "SELECT pg_cbm_tracked_location()", 0, NULL);
} if (PQnfields(res) != 1) {
elog(ERROR, "cannot get cbm tracked lsn location");
res = pgut_execute(backup_conn, "SELECT pg_cbm_tracked_location()", 0, NULL); }
if (PQnfields(res) != 1) { temp_lsn = pg_strdup(PQgetvalue(res, 0, 0));
elog(ERROR, "cannot get cbm tracked lsn location"); ret = sscanf_s(temp_lsn, "%X/%X", &lsn_hi, &lsn_lo);
securec_check_for_sscanf_s(ret, 2, "\0", "\0");
pfree(temp_lsn);
cur_track_lsn = ((uint64) lsn_hi) << 32 | lsn_lo;
if (cur_track_lsn >= current.start_lsn) {
break;
}
sleep(1);
PQclear(res);
} }
params[1] = gs_pstrdup(PQgetvalue(res, 0, 0)); params[1] = gs_pstrdup(PQgetvalue(res, 0, 0));
PQclear(res); PQclear(res);
elog(INFO, "change bitmap end lsn location is %s", params[1]);
res = pgut_execute(backup_conn, res = pgut_execute(backup_conn,
"SELECT path,changed_block_number,changed_block_list " "SELECT path,changed_block_number,changed_block_list "
@ -92,45 +109,74 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
elog(ERROR, "cannot get ptrack pagemapset"); elog(ERROR, "cannot get ptrack pagemapset");
/* Initialize bitmap */ /* Initialize bitmap */
pagemap.bitmap = NULL;
pagemap.bitmapsize = 0;
/* Construct database map */ /* Construct database map */
for (i = 0; i < PQntuples(res); i++) { for (i = 0; i < PQntuples(res); i++) {
page_map_entry *pm_entry = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
/* get path */ /* get path */
pm_entry->path = pgut_strdup(PQgetvalue(res, i, 0));
ret = sscanf_s(PQgetvalue(res, i, 1), "%d", &blkcnt); ret = sscanf_s(PQgetvalue(res, i, 1), "%d", &blkcnt);
securec_check_for_sscanf_s(ret, 1, "\0", "\0"); securec_check_for_sscanf_s(ret, 1, "\0", "\0");
if (blkcnt == 1) { if (blkcnt == 1) {
pagemap.bitmap = NULL;
pagemap.bitmapsize = 0;
page_map_entry *pm_entry = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
ret = sscanf_s(PQgetvalue(res, i, 2), "%u", &blknum); ret = sscanf_s(PQgetvalue(res, i, 2), "%u", &blknum);
securec_check_for_sscanf_s(ret, 1, "\0", "\0"); securec_check_for_sscanf_s(ret, 1, "\0", "\0");
datapagemap_add(&pagemap, blknum % ((BlockNumber) RELSEG_SIZE)); datapagemap_add(&pagemap, blknum % ((BlockNumber) RELSEG_SIZE));
} else { pm_entry->pagemap = (char *)pagemap.bitmap;
pm_entry->pagemapsize = pagemap.bitmapsize;
segno = blknum / ((BlockNumber) RELSEG_SIZE);
if (segno > 0 ) {
ret = snprintf_s(relpath, MAXPGPATH, MAXPGPATH - 1, "%s.%u",
PQgetvalue(res, i, 0), segno);
securec_check_ss_c(ret, "\0", "\0");
pm_entry->path = pgut_strdup(relpath);
} else {
pm_entry->path = pgut_strdup(PQgetvalue(res, i, 0));
}
if (pagemapset == NULL) {
pagemapset = parray_new();
}
parray_append(pagemapset, pm_entry);
} else if (blkcnt > 1) {
if (pagemapset == NULL) {
pagemapset = parray_new();
}
rc = memset_s(segarrary, sizeof(page_map_entry *) * 32000, 0, sizeof(page_map_entry *) * 32000);
securec_check(rc, "\0", "\0");
blocknum_str = strtok_r(PQgetvalue(res, i, 2), ", ", &saved); blocknum_str = strtok_r(PQgetvalue(res, i, 2), ", ", &saved);
while (blocknum_str != NULL) { while (blocknum_str != NULL) {
ret = sscanf_s(blocknum_str, "%u", &blknum); ret = sscanf_s(blocknum_str, "%u", &blknum);
securec_check_for_sscanf_s(ret, 1, "\0", "\0"); securec_check_for_sscanf_s(ret, 1, "\0", "\0");
segno = blknum / ((BlockNumber) RELSEG_SIZE);
if (segarrary[segno] == NULL) {
pm_entry_seg = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
segarrary[segno] = pm_entry_seg;
pagemap.bitmap = NULL;
pagemap.bitmapsize = 0;
if (segno > 0 ) {
ret = snprintf_s(relpath, MAXPGPATH, MAXPGPATH - 1, "%s.%u",
PQgetvalue(res, i, 0), segno);
securec_check_ss_c(ret, "\0", "\0");
pm_entry_seg->path = pgut_strdup(relpath);
} else {
pm_entry_seg->path = pgut_strdup(PQgetvalue(res, i, 0));
}
parray_append(pagemapset, pm_entry_seg);
} else {
pm_entry_seg = segarrary[segno];
pagemap.bitmap = (unsigned char*)pm_entry_seg->pagemap;
pagemap.bitmapsize = pm_entry_seg->pagemapsize;
}
datapagemap_add(&pagemap, blknum % ((BlockNumber) RELSEG_SIZE)); datapagemap_add(&pagemap, blknum % ((BlockNumber) RELSEG_SIZE));
pm_entry_seg->pagemap = (char *)pagemap.bitmap;
pm_entry_seg->pagemapsize = pagemap.bitmapsize;
blocknum_str = strtok_r(NULL, ", ", &saved); blocknum_str = strtok_r(NULL, ", ", &saved);
} }
} }
pm_entry->pagemap = (char *)pagemap.bitmap;
pm_entry->pagemapsize = pagemap.bitmapsize;
pagemap.bitmap = NULL;
pagemap.bitmapsize = 0;
if (pagemapset == NULL)
pagemapset = parray_new();
parray_append(pagemapset, pm_entry);
} }
free(segarrary);
PQclear(res); PQclear(res);
return pagemapset; return pagemapset;

View File

@ -113,6 +113,7 @@ bool launch_agent(void)
{ {
char cmd[MAX_CMDLINE_LENGTH]; char cmd[MAX_CMDLINE_LENGTH];
char* ssh_argv[MAX_CMDLINE_OPTIONS]; char* ssh_argv[MAX_CMDLINE_OPTIONS];
char libenv[MAX_CMDLINE_LENGTH] = {0};
int ssh_argc; int ssh_argc;
int outfd[2]; int outfd[2];
int infd[2]; int infd[2];
@ -156,6 +157,19 @@ bool launch_agent(void)
ssh_argv[ssh_argc++] = (char *)cmd; ssh_argv[ssh_argc++] = (char *)cmd;
ssh_argv[ssh_argc] = NULL; ssh_argv[ssh_argc] = NULL;
if (instance_config.remote.libpath)
{
#ifdef WIN32
rc = snprintf_s(libenv, sizeof(libenv), sizeof(libenv) - 1, "set LD_LIBRARY_PATH=%s &&",
instance_config.remote.libpath);
securec_check_ss_c(rc, "\0", "\0");
#else
rc = snprintf_s(libenv, sizeof(libenv), sizeof(libenv) - 1, "export LD_LIBRARY_PATH=%s &&",
instance_config.remote.libpath);
securec_check_ss_c(rc, "\0", "\0");
#endif
}
if (instance_config.remote.path) if (instance_config.remote.path)
{ {
char const* probackup = PROGRAM_NAME_FULL; char const* probackup = PROGRAM_NAME_FULL;
@ -172,27 +186,27 @@ bool launch_agent(void)
} }
if (needs_quotes(instance_config.remote.path) || needs_quotes(PROGRAM_NAME_FULL)) if (needs_quotes(instance_config.remote.path) || needs_quotes(PROGRAM_NAME_FULL))
{ {
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s\\%s\" agent", rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s %s\\%s\" agent",
instance_config.remote.path, probackup); libenv, instance_config.remote.path, probackup);
securec_check_ss_c(rc, "\0", "\0"); securec_check_ss_c(rc, "\0", "\0");
} }
else else
{ {
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s\\%s agent", rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s %s\\%s agent",
instance_config.remote.path, probackup); libenv, instance_config.remote.path, probackup);
securec_check_ss_c(rc, "\0", "\0"); securec_check_ss_c(rc, "\0", "\0");
} }
#else #else
if (needs_quotes(instance_config.remote.path) || needs_quotes(PROGRAM_NAME_FULL)) if (needs_quotes(instance_config.remote.path) || needs_quotes(PROGRAM_NAME_FULL))
{ {
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s/%s\" agent", rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "\"%s %s/%s\" agent",
instance_config.remote.path, probackup); libenv, instance_config.remote.path, probackup);
securec_check_ss_c(rc, "\0", "\0"); securec_check_ss_c(rc, "\0", "\0");
} }
else else
{ {
rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s/%s agent", rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "%s %s/%s agent",
instance_config.remote.path, probackup); libenv, instance_config.remote.path, probackup);
securec_check_ss_c(rc, "\0", "\0"); securec_check_ss_c(rc, "\0", "\0");
} }
#endif #endif

View File

@ -16,6 +16,7 @@ typedef struct RemoteConfig
char* host; char* host;
char* port; char* port;
char* path; char* path;
char* libpath;
char* user; char* user;
char *ssh_config; char *ssh_config;
char *ssh_options; char *ssh_options;

View File

@ -19,6 +19,8 @@
#include "thread.h" #include "thread.h"
#include "common/fe_memutils.h" #include "common/fe_memutils.h"
#define RESTORE_ARRAY_LEN 100
typedef struct typedef struct
{ {
parray *pgdata_files; parray *pgdata_files;
@ -1379,7 +1381,15 @@ create_recovery_conf(time_t backup_id,
/* construct restore_command */ /* construct restore_command */
if (pitr_requested) if (pitr_requested)
{ {
char *timestamp = NULL;
const char *oldtime = NULL;
timestamp = (char *)pg_malloc(RESTORE_ARRAY_LEN);
time2iso(timestamp, RESTORE_ARRAY_LEN, backup->end_time);
oldtime = rt->time_string;
rt->time_string = timestamp;
construct_restore_cmd(fp, rt, restore_command_provided, target_immediate); construct_restore_cmd(fp, rt, restore_command_provided, target_immediate);
rt->time_string = oldtime;
free(timestamp);
} }
if (fio_fflush(fp) != 0 || if (fio_fflush(fp) != 0 ||

View File

@ -36,6 +36,9 @@ static const char *statusName[] =
"CORRUPT" "CORRUPT"
}; };
uint32 NUM_65536 = 65536;
uint32 NUM_10000 = 10000;
const char * const char *
base36enc(long unsigned int value) base36enc(long unsigned int value)
{ {
@ -53,7 +56,7 @@ base36enc(long unsigned int value)
} }
/* /*
* Same as base36enc(), but the result must be released by the user. * Same as base36enc(), but the results must be released by the user.
*/ */
char * char *
base36enc_dup(long unsigned int value) base36enc_dup(long unsigned int value)
@ -77,6 +80,30 @@ base36dec(const char *text)
return strtoul(text, NULL, 36); return strtoul(text, NULL, 36);
} }
static void
checkControlFile(ControlFileData *ControlFile)
{
pg_crc32c crc;
/* Calculate CRC */
INIT_CRC32C(crc);
COMP_CRC32C(crc, (char *) ControlFile, offsetof(ControlFileData, crc));
FIN_CRC32C(crc);
/* Then compare it */
if (!EQ_CRC32C(crc, ControlFile->crc))
elog(ERROR, "Calculated CRC checksum does not match value stored in file.\n"
"Either the file is corrupt, or it has a different layout than this program\n"
"is expecting. The results below are untrustworthy.");
if ((ControlFile->pg_control_version % NUM_65536 == 0 || ControlFile->pg_control_version % NUM_65536 > NUM_10000) &&
ControlFile->pg_control_version / NUM_65536 != 0)
elog(ERROR, "possible byte ordering mismatch\n"
"The byte ordering used to store the pg_control file might not match the one\n"
"used by this program. In that case the results below would be incorrect, and\n"
"the PostgreSQL installation would be incompatible with this data directory.");
}
/* /*
* Verify control file contents in the buffer src, and copy it to *ControlFile. * Verify control file contents in the buffer src, and copy it to *ControlFile.
*/ */
@ -89,6 +116,9 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size)
errno_t rc = memcpy_s(ControlFile, sizeof(ControlFileData), src, sizeof(ControlFileData)); errno_t rc = memcpy_s(ControlFile, sizeof(ControlFileData), src, sizeof(ControlFileData));
securec_check_c(rc, "\0", "\0"); securec_check_c(rc, "\0", "\0");
/* Additional checks on control file */
checkControlFile(ControlFile);
} }
/* /*

View File

@ -25,7 +25,6 @@
#include "common/fe_memutils.h" #include "common/fe_memutils.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "miscadmin.h"
PGconn* conn = NULL; PGconn* conn = NULL;
char source_slot_name[NAMEDATALEN] = {0}; char source_slot_name[NAMEDATALEN] = {0};
@ -315,7 +314,7 @@ BuildErrorCode fetchSourceFileList()
* the received parts. The result set is expected to be of format: * the received parts. The result set is expected to be of format:
* *
* path text -- path in the data directory, e.g "base/1/123" * path text -- path in the data directory, e.g "base/1/123"
* begin int8 -- offset within the file * begin int4 -- offset within the file
* chunk bytea -- file content * chunk bytea -- file content
* ---- * ----
*/ */
@ -339,7 +338,7 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
while ((res = PQgetResult(conn)) != NULL) { while ((res = PQgetResult(conn)) != NULL) {
char* filename = NULL; char* filename = NULL;
int filenamelen; int filenamelen;
int64 chunkoff; int chunkoff;
int chunksize; int chunksize;
int chunkspace; int chunkspace;
char* chunk = NULL; char* chunk = NULL;
@ -363,7 +362,7 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res); PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res);
} }
if (PQftype(res, 0) != TEXTOID && PQftype(res, 1) != INT8OID && PQftype(res, 2) != BYTEAOID && if (PQftype(res, 0) != TEXTOID && PQftype(res, 1) != INT4OID && PQftype(res, 2) != BYTEAOID &&
PQftype(res, 3) != INT4OID) { PQftype(res, 3) != INT4OID) {
pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u %u\n", pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u %u\n",
PQftype(res, 0), PQftype(res, 0),
@ -383,15 +382,15 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res); PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res);
} }
if (PQgetlength(res, 0, 1) != sizeof(int64)) { if (PQgetlength(res, 0, 1) != sizeof(int32)) {
pg_fatal("unexpected result length while fetching remote files\n"); pg_fatal("unexpected result length while fetching remote files\n");
PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res); PG_CHECKBUILD_AND_FREE_PGRESULT_RETURN(res);
} }
/* Read result set to local variables */ /* Read result set to local variables */
errorno = memcpy_s(&chunkoff, sizeof(int64), PQgetvalue(res, 0, 1), sizeof(int64)); errorno = memcpy_s(&chunkoff, sizeof(int32), PQgetvalue(res, 0, 1), sizeof(int32));
securec_check_c(errorno, "\0", "\0"); securec_check_c(errorno, "\0", "\0");
chunkoff = (int64)ntohl64((uint64)chunkoff); chunkoff = ntohl(chunkoff);
chunksize = PQgetlength(res, 0, 2); chunksize = PQgetlength(res, 0, 2);
filenamelen = PQgetlength(res, 0, 0); filenamelen = PQgetlength(res, 0, 0);
@ -422,9 +421,9 @@ static BuildErrorCode receiveFileChunks(const char* sql, FILE* file)
continue; continue;
} }
pg_log(PG_DEBUG, "received chunk for file \"%s\", offset " INT64_FORMAT ", size %d\n", pg_log(PG_DEBUG, "received chunk for file \"%s\", offset %d, size %d\n",
filename, chunkoff, chunksize); filename, chunkoff, chunksize);
fprintf(file, "received chunk for file \"%s\", offset " INT64_FORMAT ", size %d\n", fprintf(file, "received chunk for file \"%s\", offset %d, size %d\n",
filename, chunkoff, chunksize); filename, chunkoff, chunksize);
open_target_file(filename, false); open_target_file(filename, false);
@ -536,7 +535,7 @@ BuildErrorCode executeFileMap(filemap_t* map, FILE* file)
* First create a temporary table, and load it with the blocks that we * First create a temporary table, and load it with the blocks that we
* need to fetch. * need to fetch.
*/ */
sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int8, len int4);"; sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int4, len int4);";
res = PQexec(conn, sql); res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_COMMAND_OK) { if (PQresultStatus(res) != PGRES_COMMAND_OK) {
pg_fatal("could not create temporary table: %s", PQresultErrorMessage(res)); pg_fatal("could not create temporary table: %s", PQresultErrorMessage(res));

View File

@ -63,7 +63,7 @@ const char *excludeFiles[] = {
"postgresql.conf.bak", "postgresql.conf.bak",
"postgresql.conf.old", "postgresql.conf.old",
"pg_ctl.lock", "pg_ctl.lock",
"build_completed.start" "build_completed.start",
"backup_label", "backup_label",
"client.crt", "client.crt",
"client.key", "client.key",

View File

@ -305,14 +305,15 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char*
delete_all_file(bkup_file, true); delete_all_file(bkup_file, true);
PG_CHECKBUILD_AND_RETURN(); PG_CHECKBUILD_AND_RETURN();
} }
if (replication_type == RT_WITH_DUMMY_STANDBY) {
/* Backup local data into pg_rewind_bak dir */
rv = backupFileMap(filemap);
PG_CHECKRETURN_AND_RETURN(rv);
pg_log(PG_PROGRESS, "backup target files success\n");
/* Backup local data into pg_rewind_bak dir */ MoveOldXlogFiles(checkSeg, movedXlogPath);
rv = backupFileMap(filemap); PG_CHECKBUILD_AND_RETURN();
PG_CHECKRETURN_AND_RETURN(rv); }
pg_log(PG_PROGRESS, "backup target files success\n");
MoveOldXlogFiles(checkSeg, movedXlogPath);
PG_CHECKBUILD_AND_RETURN();
pg_log(PG_WARNING, _("starting background WAL receiver\n")); pg_log(PG_WARNING, _("starting background WAL receiver\n"));
nRet = snprintf_s(xlog_start, MAXFNAMELEN, MAXFNAMELEN - 1, "%X/%X", (uint32)(chkptredo >> 32), (uint32)chkptredo); nRet = snprintf_s(xlog_start, MAXFNAMELEN, MAXFNAMELEN - 1, "%X/%X", (uint32)(chkptredo >> 32), (uint32)chkptredo);
securec_check_ss_c(nRet, "", ""); securec_check_ss_c(nRet, "", "");
@ -460,8 +461,10 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char*
} }
/* Remove pg_rewind_bak dir */ /* Remove pg_rewind_bak dir */
delete_all_file(bkup_file, true); if (access(bkup_file, F_OK) == 0) {
PG_CHECKBUILD_AND_RETURN(); delete_all_file(bkup_file, true);
PG_CHECKBUILD_AND_RETURN();
}
if (datadir_target != NULL) { if (datadir_target != NULL) {
free(datadir_target); free(datadir_target);

View File

@ -145,16 +145,12 @@ static void usage(void);
static void showVersion(void); static void showVersion(void);
static PGconn* loginDatabase(char* host, int port, char* user, char* password, char* dbname, const char* progname, static PGconn* loginDatabase(char* host, int port, char* user, char* password, char* dbname, const char* progname,
char* encoding, const char* password_prompt); char* encoding, const char* password_prompt);
#ifdef ENABLE_MULTIPLE_NODES
static void getMyNodename(PGconn* conn); static void getMyNodename(PGconn* conn);
static void getMyGtmMode(PGconn* conn); static void getMyGtmMode(PGconn* conn);
#endif
static void recover2PCForDatabase(database_info* db_info, CleanWorkerInfo* wkinfo); static void recover2PCForDatabase(database_info* db_info, CleanWorkerInfo* wkinfo);
static void recover2PC(PGconn* conn, txn_info* txn, int num); static void recover2PC(PGconn* conn, txn_info* txn, int num);
static void getDatabaseList(PGconn* conn); static void getDatabaseList(PGconn* conn);
#ifdef ENABLE_MULTIPLE_NODES
static void getNodeList(PGconn* conn); static void getNodeList(PGconn* conn);
#endif
static void getPreparedTxnList(PGconn* conn); static void getPreparedTxnList(PGconn* conn);
static void getTxnInfoOnOtherNodesAll(CleanWorkerInfo* wkinfo); static void getTxnInfoOnOtherNodesAll(CleanWorkerInfo* wkinfo);
static void do_commit(PGconn* conn, txn_info* txn, int num); static void do_commit(PGconn* conn, txn_info* txn, int num);
@ -170,10 +166,8 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok);
static void dropTempSchema(PGconn* conn, char* nspname, bool missing_ok); static void dropTempSchema(PGconn* conn, char* nspname, bool missing_ok);
static void getTempSchemaListOnCN(PGconn* conn); static void getTempSchemaListOnCN(PGconn* conn);
#ifdef ENABLE_MULTIPLE_NODES
static void getTempSchemaOnOneDN(PGconn* conn, int no); static void getTempSchemaOnOneDN(PGconn* conn, int no);
static int getTempSchemaListOnDN(PGconn* conn); static int getTempSchemaListOnDN(PGconn* conn);
#endif
static void checkAllocMem(void* p); static void checkAllocMem(void* p);
static void cleanTempSchemaList(); static void cleanTempSchemaList();
static void cleanBackendList(); static void cleanBackendList();
@ -670,7 +664,6 @@ int main(int argc, char* argv[])
exit(1); exit(1);
} }
#ifdef ENABLE_MULTIPLE_NODES
/* /*
* Get my nodename (connected Coordinator) and gtm_mode * Get my nodename (connected Coordinator) and gtm_mode
*/ */
@ -684,7 +677,6 @@ int main(int argc, char* argv[])
transfor_gtm_optoin(gtm_option, gtm_mode), transfor_gtm_optoin(gtm_option, gtm_mode),
gtm_option_num); gtm_option_num);
} }
#endif
/* /*
* Get available databases * Get available databases
@ -712,7 +704,6 @@ int main(int argc, char* argv[])
} }
} }
#ifdef ENABLE_MULTIPLE_NODES
/* /*
* Get list of Nodes * Get list of Nodes
* *
@ -737,7 +728,6 @@ int main(int argc, char* argv[])
pgxc_clean_node_info[ii].type == NODE_TYPE_COORD ? "coordinator" : "datanode"); pgxc_clean_node_info[ii].type == NODE_TYPE_COORD ? "coordinator" : "datanode");
} }
} }
#endif
/* /*
* Only clean temp schema if clean_temp_schema_only == true, * Only clean temp schema if clean_temp_schema_only == true,
@ -751,15 +741,6 @@ int main(int argc, char* argv[])
} }
exit(0); exit(0);
} }
#ifndef ENABLE_MULTIPLE_NODES
else {
PQfinish(coord_conn);
coord_conn = NULL;
write_stderr("%s %s: We only clean temp schema in openGauss, please specify '-e' option.\n",
formatLogTime(), progname);
exit(0);
}
#endif
/* /*
* Only clean plan_table if clean_plan_table_only == true, * Only clean plan_table if clean_plan_table_only == true,
@ -1133,9 +1114,7 @@ static void cleanPlanTableSessidList()
static void dropTempNamespace() static void dropTempNamespace()
{ {
database_info* cur_database = NULL; database_info* cur_database = NULL;
#ifdef ENABLE_MULTIPLE_NODES
int datanode_no = -1; int datanode_no = -1;
#endif
if (head_database_info != NULL) { if (head_database_info != NULL) {
for (cur_database = head_database_info; cur_database != NULL; cur_database = cur_database->next) { for (cur_database = head_database_info; cur_database != NULL; cur_database = cur_database->next) {
@ -1187,12 +1166,11 @@ static void dropTempNamespace()
(void)dropTempSchemas(coord_conn, true); (void)dropTempSchemas(coord_conn, true);
(void)cleanBackendList(); (void)cleanBackendList();
#ifdef ENABLE_MULTIPLE_NODES
datanode_no = getTempSchemaListOnDN(coord_conn); datanode_no = getTempSchemaListOnDN(coord_conn);
(void)getActiveBackendListOnCN(coord_conn, datanode_no); (void)getActiveBackendListOnCN(coord_conn, datanode_no);
(void)dropTempSchemas(coord_conn, true); (void)dropTempSchemas(coord_conn, true);
(void)cleanBackendList(); (void)cleanBackendList();
#endif
if (verbose_opt) if (verbose_opt)
write_stderr("%s %s: drop temp namespace for database \"%s\" finished\n", write_stderr("%s %s: drop temp namespace for database \"%s\" finished\n",
@ -1209,12 +1187,10 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok)
{ {
tempschema_info* cell1 = temp_schema_info; tempschema_info* cell1 = temp_schema_info;
activebackend_info* cell2 = NULL; activebackend_info* cell2 = NULL;
char node_name[NAMEDATALEN];
char temp_buffer[NAMEDATALEN] = {0}; char temp_buffer[NAMEDATALEN] = {0};
char temp_buffer2[NAMEDATALEN] = {0}; char temp_buffer2[NAMEDATALEN] = {0};
#ifdef ENABLE_MULTIPLE_NODES
char node_name[NAMEDATALEN];
bool onOtherCNNode = false; bool onOtherCNNode = false;
#endif
errno_t rc; errno_t rc;
if (temp_schema_info == NULL || active_backend_info == NULL) if (temp_schema_info == NULL || active_backend_info == NULL)
@ -1254,7 +1230,6 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok)
} }
if (cell2 == NULL) { if (cell2 == NULL) {
#ifdef ENABLE_MULTIPLE_NODES
/* /*
* now it is not the active backend, furthermore, we need to * now it is not the active backend, furthermore, we need to
* check whether the schema on the other node: * check whether the schema on the other node:
@ -1329,9 +1304,6 @@ static void dropTempSchemas(PGconn* conn, bool missing_ok)
if (!onOtherCNNode) if (!onOtherCNNode)
dropTempSchema(conn, cell1->tempschema_name, missing_ok); dropTempSchema(conn, cell1->tempschema_name, missing_ok);
} }
#else
dropTempSchema(conn, cell1->tempschema_name, missing_ok);
#endif
} }
cell1 = cell1->next; cell1 = cell1->next;
@ -1443,7 +1415,6 @@ static char* pg_strdup(const char* string)
return tmp; return tmp;
} }
#ifdef ENABLE_MULTIPLE_NODES
static void getMyNodename(PGconn* conn) static void getMyNodename(PGconn* conn)
{ {
static const char* stmt = "SELECT pgxc_node_str()"; static const char* stmt = "SELECT pgxc_node_str()";
@ -1487,7 +1458,6 @@ static void getMyGtmMode(PGconn* conn)
} }
PQclear(res); PQclear(res);
} }
#endif
static void recover2PCForDatabase(database_info* db_info, CleanWorkerInfo* wkinfo) static void recover2PCForDatabase(database_info* db_info, CleanWorkerInfo* wkinfo)
{ {
@ -2352,7 +2322,6 @@ static void add_active_backend_info(int64 sessionID, uint32 tempID, uint32 timeL
} }
} }
#ifdef ENABLE_MULTIPLE_NODES
/* /*
* @Description: get temp schema list of a random DN. * @Description: get temp schema list of a random DN.
* @param[IN] conn: node connection handle * @param[IN] conn: node connection handle
@ -2446,7 +2415,6 @@ static void getTempSchemaOnOneDN(PGconn* conn, int no)
PQclear(res); PQclear(res);
} }
#endif
static void getTempSchemaListOnCN(PGconn* conn) static void getTempSchemaListOnCN(PGconn* conn)
{ {
@ -2458,18 +2426,11 @@ static void getTempSchemaListOnCN(PGconn* conn)
char STMT_GET_TEMP_SCHEMA_LIST[NAMEDATALEN + 128] = {0}; char STMT_GET_TEMP_SCHEMA_LIST[NAMEDATALEN + 128] = {0};
#ifdef ENABLE_MULTIPLE_NODES
rc = snprintf_s(STMT_GET_TEMP_SCHEMA_LIST, rc = snprintf_s(STMT_GET_TEMP_SCHEMA_LIST,
sizeof(STMT_GET_TEMP_SCHEMA_LIST), sizeof(STMT_GET_TEMP_SCHEMA_LIST),
sizeof(STMT_GET_TEMP_SCHEMA_LIST) - 1, sizeof(STMT_GET_TEMP_SCHEMA_LIST) - 1,
"SELECT NSPNAME FROM PG_NAMESPACE WHERE NSPNAME LIKE 'pg_temp_%s_%%'", "SELECT NSPNAME FROM PG_NAMESPACE WHERE NSPNAME LIKE 'pg_temp_%s_%%'",
my_nodename); my_nodename);
#else
rc = snprintf_s(STMT_GET_TEMP_SCHEMA_LIST,
sizeof(STMT_GET_TEMP_SCHEMA_LIST),
sizeof(STMT_GET_TEMP_SCHEMA_LIST) - 1,
"SELECT NSPNAME FROM PG_NAMESPACE WHERE NSPNAME LIKE 'pg_temp_%%'");
#endif
securec_check_ss_c(rc, "\0", "\0"); securec_check_ss_c(rc, "\0", "\0");
if (verbose_opt) if (verbose_opt)
@ -2589,7 +2550,6 @@ static void checkAllocMem(void* p)
} }
} }
#ifdef ENABLE_MULTIPLE_NODES
static void getNodeList(PGconn* conn) static void getNodeList(PGconn* conn)
{ {
int ii; int ii;
@ -2672,7 +2632,6 @@ error_exit:
PQclear(res); PQclear(res);
exit(1); exit(1);
} }
#endif
static char* transfor_gtm_optoin(const char* option, const char* gtm_free_mode) static char* transfor_gtm_optoin(const char* option, const char* gtm_free_mode)
{ {

View File

@ -1526,7 +1526,7 @@ void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid));
scan = systable_beginscan(rel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(rel, DefaultAclOidIndexId, true, NULL, 1, skey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
@ -1623,7 +1623,7 @@ void RemoveDefaultACLById(Oid defaclOid)
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(defaclOid)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(defaclOid));
scan = systable_beginscan(rel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(rel, DefaultAclOidIndexId, true, NULL, 1, skey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
@ -2987,7 +2987,7 @@ static void ExecGrant_Largeobject(InternalGrant* istmt)
/* There's no syscache for pg_largeobject_metadata */ /* There's no syscache for pg_largeobject_metadata */
ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
scan = systable_beginscan(relation, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, entry); scan = systable_beginscan(relation, LargeObjectMetadataOidIndexId, true, NULL, 1, entry);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
@ -6153,7 +6153,7 @@ bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid)); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid));
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, entry); scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, entry);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
@ -6483,7 +6483,7 @@ bool pg_extension_ownercheck(Oid ext_oid, Oid roleid)
ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid)); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid));
scan = systable_beginscan(pg_extension, ExtensionOidIndexId, true, SnapshotNow, 1, entry); scan = systable_beginscan(pg_extension, ExtensionOidIndexId, true, NULL, 1, entry);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))

View File

@ -3191,6 +3191,10 @@
"gs_fault_inject", 1, "gs_fault_inject", 1,
AddBuiltinFunc(_0(4000), _1("gs_fault_inject"), _2(6), _3(true), _4(false), _5(gs_fault_inject), _6(20), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 20, 25, 25, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_fault_inject"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) AddBuiltinFunc(_0(4000), _1("gs_fault_inject"), _2(6), _3(true), _4(false), _5(gs_fault_inject), _6(20), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 20, 25, 25, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_fault_inject"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
), ),
AddFuncGroup(
"gs_get_archive_status", 1,
AddBuiltinFunc(_0(3796), _1("gs_get_archive_status"), _2(0), _3(true), _4(true), _5(gs_get_archive_status), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(4, 25, 25, 1184, 25), _22(4, 'o', 'o', 'o', 'o'), _23(4, "archive_standby", "archive_lsn", "last_arch_time", "archive_path"), _24(NULL), _25("gs_get_archive_status"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
),
AddFuncGroup( AddFuncGroup(
"gs_get_global_barrier_status", 1, "gs_get_global_barrier_status", 1,
AddBuiltinFunc(_0(9032), _1("gs_get_global_barrier_status"), _2(0), _3(true), _4(false), _5(gs_get_global_barrier_status), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(2, 25, 25), _22(2, 'o', 'o'), _23(2, "global_barrier_id", "global_achive_barrier_id"), _24(NULL), _25("gs_get_global_barrier_status"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')) AddBuiltinFunc(_0(9032), _1("gs_get_global_barrier_status"), _2(0), _3(true), _4(false), _5(gs_get_global_barrier_status), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(2, 25, 25), _22(2, 'o', 'o'), _23(2, "global_barrier_id", "global_achive_barrier_id"), _24(NULL), _25("gs_get_global_barrier_status"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))

View File

@ -909,7 +909,7 @@ static void drop_delta_rel(Oid deltataRelId)
Relation depRel = relation_open(DependRelationId, RowExclusiveLock); Relation depRel = relation_open(DependRelationId, RowExclusiveLock);
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId)); ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(deltataRelId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(deltataRelId));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
simple_heap_delete(depRel, &tup->t_self); simple_heap_delete(depRel, &tup->t_self);
} }

View File

@ -569,7 +569,7 @@ static void findDependentObjects(const ObjectAddress* object, int flags, ObjectA
} else } else
nkeys = 2; nkeys = 2;
scan = systable_beginscan(*depRel, DependDependerIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(*depRel, DependDependerIndexId, true, NULL, nkeys, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup);
@ -718,7 +718,7 @@ static void findDependentObjects(const ObjectAddress* object, int flags, ObjectA
} else } else
nkeys = 2; nkeys = 2;
scan = systable_beginscan(*depRel, DependReferenceIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(*depRel, DependReferenceIndexId, true, NULL, nkeys, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup);
@ -1076,7 +1076,7 @@ static void deleteOneObject(const ObjectAddress* object, Relation* depRel, int f
} else } else
nkeys = 2; nkeys = 2;
scan = systable_beginscan(*depRel, DependDependerIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(*depRel, DependDependerIndexId, true, NULL, nkeys, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
simple_heap_delete(*depRel, &tup->t_self); simple_heap_delete(*depRel, &tup->t_self);
@ -1100,7 +1100,7 @@ static void deleteOneObject(const ObjectAddress* object, Relation* depRel, int f
} else } else
nkeys = 2; nkeys = 2;
scan = systable_beginscan(*depRel, DependReferenceIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(*depRel, DependReferenceIndexId, true, NULL, nkeys, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend Pinnedobj = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend Pinnedobj = (Form_pg_depend)GETSTRUCT(tup);
@ -2419,7 +2419,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(castDesc, CastOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(castDesc, CastOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
@ -2503,7 +2503,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId, true, SnapshotNow, 1, skey); adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(adscan); tup = systable_getnext(adscan);
@ -2595,7 +2595,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, SnapshotNow, 1, skey); amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(amscan); tup = systable_getnext(amscan);
@ -2642,7 +2642,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, SnapshotNow, 1, skey); amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(amscan); tup = systable_getnext(amscan);
@ -2687,7 +2687,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
@ -2717,7 +2717,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true, SnapshotNow, 1, skey); tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(tgscan); tup = systable_getnext(tgscan);
@ -2885,7 +2885,7 @@ char* getObjectDescription(const ObjectAddress* object)
ScanKeyInit( ScanKeyInit(
&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); &skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
@ -2984,7 +2984,7 @@ char* getObjectDescription(const ObjectAddress* object)
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(object->objectId)); ObjectIdGetDatum(object->objectId));
SysScanDesc scanDesc = systable_beginscan(pg_rlspolicy, PgRlspolicyOidIndex, true, SnapshotNow, 1, scanKey); SysScanDesc scanDesc = systable_beginscan(pg_rlspolicy, PgRlspolicyOidIndex, true, NULL, 1, scanKey);
HeapTuple tuple = systable_getnext(scanDesc); HeapTuple tuple = systable_getnext(scanDesc);
if (HeapTupleIsValid(tuple) == false) { if (HeapTupleIsValid(tuple) == false) {
@ -3160,7 +3160,7 @@ bool TSConfigurationHasDependentObjects(Oid tsconfoid)
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tsconfoid)); ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tsconfoid));
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_depend pg_depend = (Form_pg_depend)GETSTRUCT(tuple); Form_pg_depend pg_depend = (Form_pg_depend)GETSTRUCT(tuple);
@ -3227,7 +3227,7 @@ static void findTsDependentObjects(ObjectAddresses* targetObjects, Relation depR
ScanKeyInit(&key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cur->classId)); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cur->classId));
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cur->objectId)); ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cur->objectId));
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 2, key);
while(HeapTupleIsValid(tup = systable_getnext(scan))) { while(HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend foundDep = (Form_pg_depend)GETSTRUCT(tup);
otherObj.classId = foundDep->classid; otherObj.classId = foundDep->classid;

View File

@ -2905,7 +2905,7 @@ static void RelationRemoveInheritance(Oid relid)
ScanKeyInit(&key, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&key, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true, SnapshotNow, 1, &key); scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true, NULL, 1, &key);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) while (HeapTupleIsValid(tuple = systable_getnext(scan)))
simple_heap_delete(catalogRelation, &tuple->t_self); simple_heap_delete(catalogRelation, &tuple->t_self);
@ -2963,7 +2963,7 @@ void DeleteAttributeTuples(Oid relid)
/* Use the index to scan only attributes of the target relation */ /* Use the index to scan only attributes of the target relation */
ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, NULL, 1, key);
/* Delete all the matching tuples */ /* Delete all the matching tuples */
while ((atttup = systable_getnext(scan)) != NULL) while ((atttup = systable_getnext(scan)) != NULL)
@ -2996,7 +2996,7 @@ void DeleteSystemAttributeTuples(Oid relid)
ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
ScanKeyInit(&key[1], Anum_pg_attribute_attnum, BTLessEqualStrategyNumber, F_INT2LE, Int16GetDatum(0)); ScanKeyInit(&key[1], Anum_pg_attribute_attnum, BTLessEqualStrategyNumber, F_INT2LE, Int16GetDatum(0));
scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true, NULL, 2, key);
/* Delete all the matching tuples */ /* Delete all the matching tuples */
while ((atttup = systable_getnext(scan)) != NULL) while ((atttup = systable_getnext(scan)) != NULL)
@ -3156,7 +3156,7 @@ void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool
ScanKeyInit(&scankeys[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&scankeys[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
ScanKeyInit(&scankeys[1], Anum_pg_attrdef_adnum, BTEqualStrategyNumber, F_INT2EQ, Int16GetDatum(attnum)); ScanKeyInit(&scankeys[1], Anum_pg_attrdef_adnum, BTEqualStrategyNumber, F_INT2EQ, Int16GetDatum(attnum));
scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true, SnapshotNow, 2, scankeys); scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true, NULL, 2, scankeys);
/* There should be at most one matching tuple, but we loop anyway */ /* There should be at most one matching tuple, but we loop anyway */
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
@ -3204,7 +3204,7 @@ void RemoveAttrDefaultById(Oid attrdefId)
/* Find the pg_attrdef tuple */ /* Find the pg_attrdef tuple */
ScanKeyInit(&scankeys[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(attrdefId)); ScanKeyInit(&scankeys[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(attrdefId));
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true, SnapshotNow, 1, scankeys); scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true, NULL, 1, scankeys);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
@ -3945,7 +3945,7 @@ static bool MergeWithExistingConstraint(
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(RelationGetNamespace(rel))); ObjectIdGetDatum(RelationGetNamespace(rel)));
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey); conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
while (HeapTupleIsValid(tup = systable_getnext(conscan))) { while (HeapTupleIsValid(tup = systable_getnext(conscan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
@ -4060,6 +4060,9 @@ Node* parseParamRef(ParseState* pstate, ParamRef* pref)
pfree_ext(val); pfree_ext(val);
if (pref->number == params_info->numParams && u_sess->parser_cxt.ddl_pbe_context != NULL) { if (pref->number == params_info->numParams && u_sess->parser_cxt.ddl_pbe_context != NULL) {
MemoryContextDelete(u_sess->parser_cxt.ddl_pbe_context); MemoryContextDelete(u_sess->parser_cxt.ddl_pbe_context);
if (((IS_PGXC_COORDINATOR || IS_PGXC_DATANODE) && IsConnFromCoord())) {
u_sess->parser_cxt.param_info = NULL;
}
u_sess->parser_cxt.ddl_pbe_context = NULL; u_sess->parser_cxt.ddl_pbe_context = NULL;
} }
} else { } else {
@ -4251,7 +4254,7 @@ void RemoveStatistics(Oid relid, AttrNumber attnum)
} }
pgstatistic = heap_open(StatisticRelationId, RowExclusiveLock); pgstatistic = heap_open(StatisticRelationId, RowExclusiveLock);
scan = systable_beginscan(pgstatistic, StatisticRelidKindAttnumInhIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(pgstatistic, StatisticRelidKindAttnumInhIndexId, true, NULL, nkeys, key);
/* we must loop even when attnum != 0, in case of inherited stats */ /* we must loop even when attnum != 0, in case of inherited stats */
while (HeapTupleIsValid(tuple = systable_getnext(scan))) while (HeapTupleIsValid(tuple = systable_getnext(scan)))
@ -4266,7 +4269,7 @@ void RemoveStatistics(Oid relid, AttrNumber attnum)
*/ */
nkeys = 2; nkeys = 2;
pgstatistic = heap_open(StatisticExtRelationId, RowExclusiveLock); pgstatistic = heap_open(StatisticExtRelationId, RowExclusiveLock);
scan = systable_beginscan(pgstatistic, StatisticExtRelidKindInhKeyIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(pgstatistic, StatisticExtRelidKindInhKeyIndexId, true, NULL, nkeys, key);
/* we must loop here, in case of inherited stats and extended stats */ /* we must loop here, in case of inherited stats and extended stats */
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
@ -4663,7 +4666,7 @@ List* heap_truncate_find_FKs(List* relationIds)
*/ */
fkeyRel = heap_open(ConstraintRelationId, AccessShareLock); fkeyRel = heap_open(ConstraintRelationId, AccessShareLock);
fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false, SnapshotNow, 0, NULL); fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false, NULL, 0, NULL);
while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan))) { while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -6747,7 +6750,7 @@ bool FindExistingConstraint(const char* ccname, Relation rel)
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(RelationGetNamespace(rel))); ObjectIdGetDatum(RelationGetNamespace(rel)));
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey); conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
while (HeapTupleIsValid(tup = systable_getnext(conscan))) { while (HeapTupleIsValid(tup = systable_getnext(conscan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);

View File

@ -3904,6 +3904,24 @@ static void MotFdwReindex(Relation heapRelation, Relation iRel)
} }
#endif #endif
void PartRelSetHasIndexState(Oid relid)
{
Relation pg_class = heap_open(RelationRelationId, RowExclusiveLock);
HeapTuple tup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(tup)) {
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("cache lookup failed for relation %u", relid)));
}
Form_pg_class pgcform = (Form_pg_class)GETSTRUCT(tup);
/* modify pg_class hasindex is true when reindex and it is false. */
if (!pgcform->relhasindex) {
pgcform->relhasindex = true;
heap_inplace_update(pg_class, tup);
}
heap_freetuple(tup);
heap_close(pg_class, RowExclusiveLock);
}
/* /*
* reindex_index - This routine is used to recreate a single index * reindex_index - This routine is used to recreate a single index
*/ */
@ -4036,6 +4054,7 @@ void reindex_index(Oid indexId, Oid indexPartId, bool skip_constraint_checks,
} }
releasePartitionOidList(&indexPartOidList); releasePartitionOidList(&indexPartOidList);
PartRelSetHasIndexState(heapRelation->rd_id);
// call the internal function, update pg_index system table // call the internal function, update pg_index system table
ATExecSetIndexUsableState(IndexRelationId, iRel->rd_id, true); ATExecSetIndexUsableState(IndexRelationId, iRel->rd_id, true);
CacheInvalidateRelcache(heapRelation); CacheInvalidateRelcache(heapRelation);
@ -4697,7 +4716,7 @@ static void reindexPartIndex(Oid indexId, Oid partOid, bool skip_constraint_chec
ScanKeyInit(&partKey, Anum_pg_partition_indextblid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(partOid)); ScanKeyInit(&partKey, Anum_pg_partition_indextblid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(partOid));
partScan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, SnapshotNow, 1, &partKey); partScan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, NULL, 1, &partKey);
while ((partTuple = systable_getnext(partScan)) != NULL) { while ((partTuple = systable_getnext(partScan)) != NULL) {
partForm = (Form_pg_partition)GETSTRUCT(partTuple); partForm = (Form_pg_partition)GETSTRUCT(partTuple);

View File

@ -4737,7 +4737,7 @@ bool checkGroup(Oid relid, bool missing_ok)
*/ */
pgxc_group = heap_open(PgxcGroupRelationId, AccessShareLock); pgxc_group = heap_open(PgxcGroupRelationId, AccessShareLock);
scan = systable_beginscan(pgxc_group, PgxcGroupGroupNameIndexId, true, SnapshotNow, 0, NULL); scan = systable_beginscan(pgxc_group, PgxcGroupGroupNameIndexId, true, NULL, 0, NULL);
while (HeapTupleIsValid(tuple1 = systable_getnext(scan))) { while (HeapTupleIsValid(tuple1 = systable_getnext(scan))) {
Form_pgxc_group groupForm = (Form_pgxc_group)GETSTRUCT(tuple1); Form_pgxc_group groupForm = (Form_pgxc_group)GETSTRUCT(tuple1);

View File

@ -151,7 +151,7 @@ void RemoveCollationById(Oid collationOid)
ScanKeyInit(&scanKeyData, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(collationOid)); ScanKeyInit(&scanKeyData, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(collationOid));
scandesc = systable_beginscan(rel, CollationOidIndexId, true, SnapshotNow, 1, &scanKeyData); scandesc = systable_beginscan(rel, CollationOidIndexId, true, NULL, 1, &scanKeyData);
tuple = systable_getnext(scandesc); tuple = systable_getnext(scandesc);

View File

@ -382,7 +382,7 @@ bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, Oid objNamespace
ScanKeyInit( ScanKeyInit(
&skey[1], Anum_pg_constraint_connamespace, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objNamespace)); &skey[1], Anum_pg_constraint_connamespace, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objNamespace));
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey); conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
while (HeapTupleIsValid(tup = systable_getnext(conscan))) { while (HeapTupleIsValid(tup = systable_getnext(conscan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
@ -464,7 +464,7 @@ char* ChooseConstraintName(const char* name1, const char* name2, const char* lab
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(namespaceid)); ObjectIdGetDatum(namespaceid));
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, SnapshotNow, 2, skey); conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey);
found = (HeapTupleIsValid(systable_getnext(conscan))); found = (HeapTupleIsValid(systable_getnext(conscan)));
@ -635,11 +635,11 @@ void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, Oid newNspId, bool isT
if (isType) { if (isType) {
ScanKeyInit(&key[0], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ownerId)); ScanKeyInit(&key[0], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ownerId));
scan = systable_beginscan(conRel, ConstraintTypidIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(conRel, ConstraintTypidIndexId, true, NULL, 1, key);
} else { } else {
ScanKeyInit(&key[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ownerId)); ScanKeyInit(&key[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ownerId));
scan = systable_beginscan(conRel, ConstraintRelidIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(conRel, ConstraintRelidIndexId, true, NULL, 1, key);
} }
while (HeapTupleIsValid((tup = systable_getnext(scan)))) { while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
@ -721,7 +721,7 @@ Oid get_relation_constraint_oid(Oid relid, const char* conname, bool missing_ok)
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -770,7 +770,7 @@ Oid get_domain_constraint_oid(Oid typid, const char* conname, bool missing_ok)
ScanKeyInit(&skey[0], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(typid)); ScanKeyInit(&skey[0], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(typid));
scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -824,7 +824,7 @@ bool check_functional_grouping(Oid relid, Index varno, Index varlevelsup, List*
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -914,7 +914,7 @@ List* get_parse_dependency_rel_list(List* conids)
Oid conid = lfirst_oid(lc); Oid conid = lfirst_oid(lc);
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, conid); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, conid);
scan = systable_beginscan(pg_constraint, ConstraintOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintOidIndexId, true, NULL, 1, skey);
/* Only one record should be qualified, and get the relid */ /* Only one record should be qualified, and get the relid */
if (HeapTupleIsValid(tuple = systable_getnext(scan))) { if (HeapTupleIsValid(tuple = systable_getnext(scan))) {

View File

@ -63,7 +63,7 @@ void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt* setstmt)
ScanKeyInit( ScanKeyInit(
&scankey[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseid)); &scankey[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseid));
ScanKeyInit(&scankey[1], Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid)); ScanKeyInit(&scankey[1], Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid));
scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true, SnapshotNow, 2, scankey); scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true, NULL, 2, scankey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
/* /*
@ -238,7 +238,7 @@ void ApplySetting(Oid databaseid, Oid roleid, Relation relsetting, GucSource sou
&keys[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseid)); &keys[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseid));
ScanKeyInit(&keys[1], Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid)); ScanKeyInit(&keys[1], Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(roleid));
scan = systable_beginscan(relsetting, DbRoleSettingDatidRolidIndexId, true, SnapshotNow, 2, keys); scan = systable_beginscan(relsetting, DbRoleSettingDatidRolidIndexId, true, NULL, 2, keys);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
bool isnull = false; bool isnull = false;
Datum datum; Datum datum;

View File

@ -250,7 +250,7 @@ long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDep
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
if (skipExtensionDeps && ((Form_pg_depend)GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION) if (skipExtensionDeps && ((Form_pg_depend)GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
@ -291,7 +291,7 @@ long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId,
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
@ -361,7 +361,7 @@ long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefOb
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
while (HeapTupleIsValid((tup = systable_getnext(scan)))) { while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
@ -420,7 +420,7 @@ static bool isObjectPinned(const ObjectAddress* object, Relation rel)
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
scan = systable_beginscan(rel, DependReferenceIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(rel, DependReferenceIndexId, true, NULL, 2, key);
/* /*
* Since we won't generate additional pg_depend entries for pinned * Since we won't generate additional pg_depend entries for pinned
@ -469,7 +469,7 @@ Oid getExtensionOfObject(Oid classId, Oid objectId)
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
while (HeapTupleIsValid((tup = systable_getnext(scan)))) { while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
@ -511,7 +511,7 @@ bool sequenceIsOwned(Oid seqId, Oid* tableId, int32* colId)
ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId)); ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(seqId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(seqId));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 2, key);
while (HeapTupleIsValid((tup = systable_getnext(scan)))) { while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
@ -559,7 +559,7 @@ List* getOwnedSequences(Oid relid, List* attrList)
&key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId)); &key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
@ -612,7 +612,7 @@ Oid get_constraint_index(Oid constraintId)
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(constraintId)); ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(constraintId));
ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(0)); ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(0));
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 3, key); scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 3, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
@ -657,7 +657,7 @@ Oid get_index_constraint(Oid indexId)
ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(indexId)); ScanKeyInit(&key[1], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(indexId));
ScanKeyInit(&key[2], Anum_pg_depend_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(0)); ScanKeyInit(&key[2], Anum_pg_depend_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(0));
scan = systable_beginscan(depRel, DependDependerIndexId, true, SnapshotNow, 3, key); scan = systable_beginscan(depRel, DependDependerIndexId, true, NULL, 3, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);

View File

@ -145,7 +145,7 @@ void EnumValuesDelete(Oid enumTypeOid)
ScanKeyInit(&key[0], Anum_pg_enum_enumtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(enumTypeOid)); ScanKeyInit(&key[0], Anum_pg_enum_enumtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(enumTypeOid));
scan = systable_beginscan(pg_enum, EnumTypIdLabelIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(pg_enum, EnumTypIdLabelIndexId, true, NULL, 1, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
simple_heap_delete(pg_enum, &tup->t_self); simple_heap_delete(pg_enum, &tup->t_self);

View File

@ -389,7 +389,7 @@ Oid searchHashBucketByBucketid(oidvector *bucketlist, Oid bucketid)
BTEqualStrategyNumber, F_INT4EQ, BTEqualStrategyNumber, F_INT4EQ,
Int32GetDatum(bucketlist->dim1)); Int32GetDatum(bucketlist->dim1));
scan = systable_beginscan(pg_hashbucket, HashBucketBidIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(pg_hashbucket, HashBucketBidIndexId, true, NULL, 3, key);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Datum bucketDatum; Datum bucketDatum;
bool isnull = false; bool isnull = false;
@ -440,7 +440,7 @@ text* searchMergeListByRelid(Oid reloid, bool *find, bool retresult)
BTEqualStrategyNumber, F_OIDEQ, BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(reloid)); ObjectIdGetDatum(reloid));
scan = systable_beginscan(pgxc_class_rel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(pgxc_class_rel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, key);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Datum pgxcDatum; Datum pgxcDatum;
bool isnull = false; bool isnull = false;

View File

@ -73,7 +73,7 @@ List* find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentrelId)); ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentrelId));
scan = systable_beginscan(relation, InheritsParentIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(relation, InheritsParentIndexId, true, NULL, 1, key);
while ((inheritsTuple = systable_getnext(scan)) != NULL) { while ((inheritsTuple = systable_getnext(scan)) != NULL) {
inhrelid = ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhrelid; inhrelid = ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhrelid;
@ -297,7 +297,7 @@ bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(this_relid)); ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(this_relid));
inhscan = systable_beginscan(inhrel, InheritsRelidSeqnoIndexId, true, SnapshotNow, 1, &skey); inhscan = systable_beginscan(inhrel, InheritsRelidSeqnoIndexId, true, NULL, 1, &skey);
while ((inhtup = systable_getnext(inhscan)) != NULL) { while ((inhtup = systable_getnext(inhscan)) != NULL) {
Form_pg_inherits inh = (Form_pg_inherits)GETSTRUCT(inhtup); Form_pg_inherits inh = (Form_pg_inherits)GETSTRUCT(inhtup);

View File

@ -95,7 +95,7 @@ void LargeObjectDrop(Oid loid)
*/ */
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, skey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
@ -110,7 +110,7 @@ void LargeObjectDrop(Oid loid)
*/ */
ScanKeyInit(&skey[0], Anum_pg_largeobject_loid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); ScanKeyInit(&skey[0], Anum_pg_largeobject_loid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
scan = systable_beginscan(pg_largeobject, LargeObjectLOidPNIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_largeobject, LargeObjectLOidPNIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
simple_heap_delete(pg_largeobject, &tuple->t_self); simple_heap_delete(pg_largeobject, &tuple->t_self);
} }
@ -140,7 +140,7 @@ void LargeObjectAlterOwner(Oid loid, Oid newOwnerId)
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid));
scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, skey);
oldtup = systable_getnext(scan); oldtup = systable_getnext(scan);
if (!HeapTupleIsValid(oldtup)) if (!HeapTupleIsValid(oldtup))
@ -232,7 +232,7 @@ bool LargeObjectExists(Oid loid)
pg_lo_meta = heap_open(LargeObjectMetadataRelationId, AccessShareLock); pg_lo_meta = heap_open(LargeObjectMetadataRelationId, AccessShareLock);
sd = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, skey); sd = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, NULL, 1, skey);
tuple = systable_getnext(sd); tuple = systable_getnext(sd);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))

View File

@ -694,7 +694,7 @@ List* getPartitionObjectIdList(Oid relid, char relkind)
ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind)); ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind));
ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
scan = systable_beginscan(relation, PartitionParentOidIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(relation, PartitionParentOidIndexId, true, NULL, 2, key);
while (HeapTupleIsValid((tuple = systable_getnext(scan)))) { while (HeapTupleIsValid((tuple = systable_getnext(scan)))) {
partitionid = HeapTupleGetOid(tuple); partitionid = HeapTupleGetOid(tuple);
@ -728,7 +728,7 @@ List* searchPartitionIndexesByblid(Oid blid)
ScanKeyInit(&key[0], Anum_pg_partition_indextblid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(blid)); ScanKeyInit(&key[0], Anum_pg_partition_indextblid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(blid));
scan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(partRel, PartitionIndexTableIdIndexId, true, NULL, 1, key);
while (HeapTupleIsValid((tup = systable_getnext(scan)))) { while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
dtp = heap_copytuple(tup); dtp = heap_copytuple(tup);
l = lappend(l, dtp); l = lappend(l, dtp);
@ -761,7 +761,7 @@ List* searchPgPartitionByParentId(char parttype, Oid parentId)
ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(parttype)); ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(parttype));
ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentId)); ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentId));
scan = systable_beginscan(pg_partition, PartitionParentOidIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(pg_partition, PartitionParentOidIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
dtuple = heap_copytuple(tuple); dtuple = heap_copytuple(tuple);

View File

@ -116,7 +116,7 @@ void RangeDelete(Oid rangeTypeOid)
ScanKeyInit(&key[0], Anum_pg_range_rngtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(rangeTypeOid)); ScanKeyInit(&key[0], Anum_pg_range_rngtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(rangeTypeOid));
scan = systable_beginscan(pg_range, RangeTypidIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(pg_range, RangeTypidIndexId, true, NULL, 1, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
simple_heap_delete(pg_range, &tup->t_self); simple_heap_delete(pg_range, &tup->t_self);

View File

@ -212,7 +212,7 @@ static void shdepChangeDep(Relation sdepRel, Oid classid, Oid objid, int32 objsu
ScanKeyInit(&key[2], Anum_pg_shdepend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid)); ScanKeyInit(&key[2], Anum_pg_shdepend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid));
ScanKeyInit(&key[3], Anum_pg_shdepend_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(objsubid)); ScanKeyInit(&key[3], Anum_pg_shdepend_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(objsubid));
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, 4, key); scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 4, key);
while ((scantup = systable_getnext(scan)) != NULL) { while ((scantup = systable_getnext(scan)) != NULL) {
/* Ignore if not of the target dependency type */ /* Ignore if not of the target dependency type */
@ -478,7 +478,7 @@ SysScanDesc initAndGetScanByRefId(Relation sdepRel, Oid classId, Oid objectId)
ScanKeyInit(&key[0], Anum_pg_shdepend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); ScanKeyInit(&key[0], Anum_pg_shdepend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId));
ScanKeyInit(&key[1], Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); ScanKeyInit(&key[1], Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId));
return systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, SnapshotNow, NumberOfReferenceKey, key); return systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, NULL, NumberOfReferenceKey, key);
} }
SysScanDesc initAndGetScanByDependerIndexId( SysScanDesc initAndGetScanByDependerIndexId(
@ -511,7 +511,7 @@ SysScanDesc initAndGetScanByDependerIndexId(
} }
} }
return systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, maxAttributeId, key); return systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, maxAttributeId, key);
} }
/* /*
@ -708,7 +708,7 @@ void copyTemplateDependencies(Oid templateDbId, Oid newDbId)
/* Scan all entries with dbid = templateDbId */ /* Scan all entries with dbid = templateDbId */
ScanKeyInit(&key[0], Anum_pg_shdepend_dbid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(templateDbId)); ScanKeyInit(&key[0], Anum_pg_shdepend_dbid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(templateDbId));
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 1, key);
/* Set up to copy the tuples except for inserting newDbId */ /* Set up to copy the tuples except for inserting newDbId */
rc = memset_s(values, sizeof(values), 0, sizeof(values)); rc = memset_s(values, sizeof(values), 0, sizeof(values));
@ -788,7 +788,7 @@ void dropDatabaseDependencies(Oid databaseId)
*/ */
ScanKeyInit(&key[0], Anum_pg_shdepend_dbid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseId)); ScanKeyInit(&key[0], Anum_pg_shdepend_dbid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseId));
/* We leave the other index fields unspecified */ /* We leave the other index fields unspecified */
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 1, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
#ifdef ENABLE_MOT #ifdef ENABLE_MOT
@ -918,7 +918,7 @@ static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int
nkeys = 4; nkeys = 4;
} }
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, SnapshotNow, nkeys, key); scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, nkeys, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_shdepend shdepForm = (Form_pg_shdepend)GETSTRUCT(tup); Form_pg_shdepend shdepForm = (Form_pg_shdepend)GETSTRUCT(tup);
@ -1410,7 +1410,7 @@ bool CheckDependencyOnRespool(Oid classId, Oid refobjectId, List** foundlist, bo
&key[0], Anum_pg_shdepend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ResourcePoolRelationId)); &key[0], Anum_pg_shdepend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ResourcePoolRelationId));
ScanKeyInit(&key[1], Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(refobjectId)); ScanKeyInit(&key[1], Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(refobjectId));
scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_shdepend sdepForm = (Form_pg_shdepend)GETSTRUCT(tup); Form_pg_shdepend sdepForm = (Form_pg_shdepend)GETSTRUCT(tup);

View File

@ -425,7 +425,7 @@ bool RelationRedisCheck(Relation rel)
&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); &skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
pcrel = heap_open(PgxcClassRelationId, AccessShareLock); pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey); pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
htup = systable_getnext(pcscan); htup = systable_getnext(pcscan);
if (!HeapTupleIsValid(htup)) { if (!HeapTupleIsValid(htup)) {
/* Assume local relation only */ /* Assume local relation only */

View File

@ -687,6 +687,7 @@ void RelationTruncate(Relation rel, BlockNumber nblocks)
rel->rd_smgr->smgr_targblock = InvalidBlockNumber; rel->rd_smgr->smgr_targblock = InvalidBlockNumber;
rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber; rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber;
rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber; rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber;
rel->rd_smgr->smgr_cached_nblocks = InvalidBlockNumber;
for (int i = 0; i < rel->rd_smgr->smgr_bcmarry_size; i++) for (int i = 0; i < rel->rd_smgr->smgr_bcmarry_size; i++)
rel->rd_smgr->smgr_bcm_nblocks[i] = InvalidBlockNumber; rel->rd_smgr->smgr_bcm_nblocks[i] = InvalidBlockNumber;

View File

@ -3453,3 +3453,4 @@ CREATE unlogged table statement_history(
); );
REVOKE ALL on table pg_catalog.statement_history FROM public; REVOKE ALL on table pg_catalog.statement_history FROM public;
create index statement_history_time_idx on pg_catalog.statement_history USING btree (start_time, is_slow_sql); create index statement_history_time_idx on pg_catalog.statement_history USING btree (start_time, is_slow_sql);
CREATE OR REPLACE VIEW pg_catalog.gs_archive_status AS SELECT * FROM gs_get_archive_status();

View File

@ -992,7 +992,7 @@ void remove_cmk_args_by_id(Oid id)
HeapTuple tuple; HeapTuple tuple;
ScanKeyInit(&scankey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(id)); ScanKeyInit(&scankey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(id));
scan = systable_beginscan(ce_rel, ClientLogicGlobalSettingsArgsOidIndexId, true, SnapshotNow, 1, &scankey); scan = systable_beginscan(ce_rel, ClientLogicGlobalSettingsArgsOidIndexId, true, NULL, 1, &scankey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
@ -1010,7 +1010,7 @@ void remove_cek_args_by_id(Oid id)
HeapTuple tuple; HeapTuple tuple;
ScanKeyInit(&scankey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(id)); ScanKeyInit(&scankey, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(id));
scan = systable_beginscan(ce_rel, ClientLogicColumnSettingsArgsOidIndexId, true, SnapshotNow, 1, &scankey); scan = systable_beginscan(ce_rel, ClientLogicColumnSettingsArgsOidIndexId, true, NULL, 1, &scankey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
@ -1032,7 +1032,7 @@ void get_global_setting_description(StringInfo buffer, const ObjectAddress *obje
cmKeys = heap_open(ClientLogicGlobalSettingsId, AccessShareLock); cmKeys = heap_open(ClientLogicGlobalSettingsId, AccessShareLock);
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(cmKeys, ClientLogicGlobalSettingsOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(cmKeys, ClientLogicGlobalSettingsOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup)) { if (!HeapTupleIsValid(tup)) {
systable_endscan(rcscan); systable_endscan(rcscan);
@ -1057,7 +1057,7 @@ void get_column_setting_description(StringInfo buffer, const ObjectAddress *obje
column_setting_rel = heap_open(ClientLogicColumnSettingsId, AccessShareLock); column_setting_rel = heap_open(ClientLogicColumnSettingsId, AccessShareLock);
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(column_setting_rel, ClientLogicColumnSettingsOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(column_setting_rel, ClientLogicColumnSettingsOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup)) { if (!HeapTupleIsValid(tup)) {
systable_endscan(rcscan); systable_endscan(rcscan);
@ -1105,7 +1105,7 @@ void get_global_setting_args_description(StringInfo buffer, const ObjectAddress
rel = heap_open(ClientLogicGlobalSettingsArgsId, AccessShareLock); rel = heap_open(ClientLogicGlobalSettingsArgsId, AccessShareLock);
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(rel, ClientLogicGlobalSettingsArgsOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(rel, ClientLogicGlobalSettingsArgsOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup)) { if (!HeapTupleIsValid(tup)) {
systable_endscan(rcscan); systable_endscan(rcscan);
@ -1129,7 +1129,7 @@ void get_column_setting_args_description(StringInfo buffer, const ObjectAddress
rel = heap_open(ClientLogicColumnSettingsArgsId, AccessShareLock); rel = heap_open(ClientLogicColumnSettingsArgsId, AccessShareLock);
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId));
rcscan = systable_beginscan(rel, ClientLogicColumnSettingsArgsOidIndexId, true, SnapshotNow, 1, skey); rcscan = systable_beginscan(rel, ClientLogicColumnSettingsArgsOidIndexId, true, NULL, 1, skey);
tup = systable_getnext(rcscan); tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup)) { if (!HeapTupleIsValid(tup)) {
systable_endscan(rcscan); systable_endscan(rcscan);

View File

@ -288,3 +288,22 @@ bool DllistWithLock::IsEmpty()
END_CRIT_SECTION(); END_CRIT_SECTION();
return ret; return ret;
} }
Dlelem* DllistWithLock::GetHead()
{
Dlelem* head = NULL;
head = m_list.dll_head;
return head;
}
void DllistWithLock::GetLock()
{
START_CRIT_SECTION();
SpinLockAcquire(&(m_lock));
}
void DllistWithLock::ReleaseLock()
{
SpinLockRelease(&(m_lock));
END_CRIT_SECTION();
}

View File

@ -1384,20 +1384,12 @@ DIRECT_TRUST:
*/ */
bool IsLoopBackAddr(Port* port) bool IsLoopBackAddr(Port* port)
{ {
struct sockaddr* remote_addr = (struct sockaddr*)&(port->raddr.addr); const SockAddr remote_addr = port->raddr;
char remote_ip[IP_LEN] = {0}; char remote_ip[IP_LEN] = {0};
char* result = NULL;
/* parse the remote ip address */ (void)pg_getnameinfo_all(&remote_addr.addr, remote_addr.salen, remote_ip, sizeof(remote_ip), NULL, 0,
if (AF_INET6 == remote_addr->sa_family) { NI_NUMERICHOST | NI_NUMERICSERV);
result = inet_net_ntop(AF_INET6, &((struct sockaddr_in*)remote_addr)->sin_addr, IPV6_MAXLEN, remote_ip, IP_LEN);
} else if (AF_INET == remote_addr->sa_family) {
result = inet_net_ntop(AF_INET, &((struct sockaddr_in*)remote_addr)->sin_addr, IPV4_MAXLEN, remote_ip, IP_LEN);
}
if (result == NULL) {
ereport(WARNING, (errmsg("inet_net_ntop remote failed, error: %d", EAFNOSUPPORT)));
}
/* only the remote ip equal to 127.0.0.1 or ::1, return true */ /* only the remote ip equal to 127.0.0.1 or ::1, return true */
if (strlen(remote_ip) != 0 && (strcmp(remote_ip, LOOP_IP_STRING) == 0 || strcmp(remote_ip, LOOP_IPV6_IP) == 0)) { if (strlen(remote_ip) != 0 && (strcmp(remote_ip, LOOP_IP_STRING) == 0 || strcmp(remote_ip, LOOP_IPV6_IP) == 0)) {
return true; return true;

View File

@ -1317,6 +1317,21 @@ static int pq_discardbytes(size_t len)
{ {
size_t amount; size_t amount;
ereport(WARNING,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("incomplete message, client info [Remote IP: %s PORT: %s FD: %d BLOCK: %d], "
"packet info [PqRecvLength: %d PqRecvPointer: %d expectedLen: %d].",
u_sess->proc_cxt.MyProcPort->remote_host,
(u_sess->proc_cxt.MyProcPort->remote_port != NULL &&
u_sess->proc_cxt.MyProcPort->remote_port[0] != '\0')
? u_sess->proc_cxt.MyProcPort->remote_port : "",
u_sess->proc_cxt.MyProcPort->sock,
u_sess->proc_cxt.MyProcPort->noblock,
t_thrd.libpq_cxt.PqRecvLength,
t_thrd.libpq_cxt.PqRecvPointer,
(int)len)));
PrintUnexpectedBufferContent(t_thrd.libpq_cxt.PqRecvBuffer, t_thrd.libpq_cxt.PqRecvLength);
while (len > 0) { while (len > 0) {
while (t_thrd.libpq_cxt.PqRecvPointer >= t_thrd.libpq_cxt.PqRecvLength) { while (t_thrd.libpq_cxt.PqRecvPointer >= t_thrd.libpq_cxt.PqRecvLength) {
if (pq_recvbuf()) { /* If nothing in buffer, then recv some */ if (pq_recvbuf()) { /* If nothing in buffer, then recv some */
@ -2407,3 +2422,55 @@ static size_t pq_disk_read_data_block(
return read_len; return read_len;
} }
/*
* To facilitate fault locating, abnormal packets need to be recorded.
* For security purposes, the maximum print length does not exceed the buffer length.
*/
void PrintUnexpectedBufferContent(const char *buffer, int len)
{
if (buffer == NULL) {
Assert(buffer);
ereport(ERROR,
(errmodule(MOD_COMM_PARAM),
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("PrintUnexpectedPqBufferContent: invalid params[buffer: null len: %d]", len)));
}
if (len <= 0) {
return;
}
/* Line-by-line printing with a width limit of 1024 */
const int nBytePrintLine = 1024;
const int pqBufferSize = PQ_BUFFER_SIZE;
const char defaultNullChar = ' ';
char tmp[nBytePrintLine + 1] = {0};
int i, idx = 0;
len = (len > pqBufferSize) ? pqBufferSize : len;
ereport(WARNING, (errmsg("--------buffer begin--------")));
for (i = 0; i < len; i++) {
idx = i % nBytePrintLine;
if (buffer[i] != '\0') {
tmp[idx] = buffer[i];
} else {
tmp[idx] = defaultNullChar;
}
if ((i + 1) % nBytePrintLine == 0) {
ereport(WARNING, (errmsg("%s", tmp)));
}
}
/* Output buffer with the remaining length. */
if (len % nBytePrintLine != 0) {
/* reset dirty data */
if (idx <= nBytePrintLine) {
errno_t rc = memset_s(tmp + idx + 1, nBytePrintLine - idx, 0, nBytePrintLine - idx);
securec_check(rc, "\0", "\0");
}
ereport(WARNING, (errmsg("%s", tmp)));
}
ereport(WARNING, (errmsg("--------buffer end--------")));
return;
}

View File

@ -4211,6 +4211,9 @@ static Query* _copyQuery(const Query* from)
COPY_SCALAR_FIELD(use_star_targets); COPY_SCALAR_FIELD(use_star_targets);
COPY_SCALAR_FIELD(is_from_full_join_rewrite); COPY_SCALAR_FIELD(is_from_full_join_rewrite);
COPY_SCALAR_FIELD(uniqueSQLId); COPY_SCALAR_FIELD(uniqueSQLId);
#ifndef ENABLE_MULTIPLE_NODES
COPY_STRING_FIELD(unique_sql_text);
#endif
COPY_SCALAR_FIELD(can_push); COPY_SCALAR_FIELD(can_push);
COPY_SCALAR_FIELD(unique_check); COPY_SCALAR_FIELD(unique_check);

View File

@ -3972,7 +3972,7 @@ static bool is_rel_child_of_rel(RangeTblEntry* child_rte, RangeTblEntry* parent_
/* Scan pg_inherits and get all the subclass OIDs one by one. */ /* Scan pg_inherits and get all the subclass OIDs one by one. */
relation = heap_open(InheritsRelationId, AccessShareLock); relation = heap_open(InheritsRelationId, AccessShareLock);
ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentOID)); ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(parentOID));
scan = systable_beginscan(relation, InheritsParentIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(relation, InheritsParentIndexId, true, NULL, 1, key);
while ((inheritsTuple = systable_getnext(scan)) != NULL) { while ((inheritsTuple = systable_getnext(scan)) != NULL) {
inhrelid = ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhrelid; inhrelid = ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhrelid;

View File

@ -219,6 +219,8 @@ static void get_rel_partition_info(Relation partTableRel, List** pos, Const** up
static void get_src_partition_bound(Relation partTableRel, Oid srcPartOid, Const** lowBound, Const** upBound); static void get_src_partition_bound(Relation partTableRel, Oid srcPartOid, Const** lowBound, Const** upBound);
static Oid get_split_partition_oid(Relation partTableRel, SplitPartitionState* splitState); static Oid get_split_partition_oid(Relation partTableRel, SplitPartitionState* splitState);
static List* add_range_partition_def_state(List* xL, List* boundary, const char* partName, const char* tblSpaceName); static List* add_range_partition_def_state(List* xL, List* boundary, const char* partName, const char* tblSpaceName);
static bool CheckStepInRange(ParseState *pstate, Const *startVal, Const *endVal, Const *everyVal,
Form_pg_attribute attr);
static List* divide_start_end_every_internal(ParseState* pstate, char* partName, Form_pg_attribute attr, static List* divide_start_end_every_internal(ParseState* pstate, char* partName, Form_pg_attribute attr,
Const* startVal, Const* endVal, Node* everyExpr, int* numPart, Const* startVal, Const* endVal, Node* everyExpr, int* numPart,
int maxNum, bool isinterval, bool needCheck, bool isPartition); int maxNum, bool isinterval, bool needCheck, bool isPartition);
@ -1406,6 +1408,15 @@ static void transformTableLikeClause(
def->storage = 0; def->storage = 0;
/* copy compression mode from source table */ /* copy compression mode from source table */
def->cmprs_mode = attribute->attcmprmode; def->cmprs_mode = attribute->attcmprmode;
/*
* When analyzing a column-oriented table with default_statistics_target < 0, we will create a row-oriented
* temp table. In this case, ignore the compression flag.
*/
if (u_sess->analyze_cxt.is_under_analyze) {
if (def->cmprs_mode != ATT_CMPR_UNDEFINED) {
def->cmprs_mode = ATT_CMPR_NOCOMPRESS;
}
}
def->raw_default = NULL; def->raw_default = NULL;
def->cooked_default = NULL; def->cooked_default = NULL;
def->collClause = NULL; def->collClause = NULL;
@ -3949,6 +3960,16 @@ List* transformAlterTableStmt(Oid relid, AlterTableStmt* stmt, const char* query
break; break;
case AT_SplitPartition: case AT_SplitPartition:
if (!RELATION_IS_PARTITIONED(rel))
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmodule(MOD_OPT),
errmsg("can not split partition against NON-PARTITIONED table")));
if (rel->partMap->type == PART_TYPE_LIST || rel->partMap->type == PART_TYPE_HASH) {
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("can not split LIST/HASH partition table")));
}
/* transform the boundary of range partition: from A_Const into Const */ /* transform the boundary of range partition: from A_Const into Const */
splitDefState = (SplitPartitionState*)cmd->def; splitDefState = (SplitPartitionState*)cmd->def;
if (!PointerIsValid(splitDefState->split_point)) { if (!PointerIsValid(splitDefState->split_point)) {
@ -3969,12 +3990,6 @@ List* transformAlterTableStmt(Oid relid, AlterTableStmt* stmt, const char* query
Const* upBound = NULL; Const* upBound = NULL;
Oid srcPartOid = InvalidOid; Oid srcPartOid = InvalidOid;
if (!RELATION_IS_PARTITIONED(rel))
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmodule(MOD_OPT),
errmsg("can not split partition against NON-PARTITIONED table")));
/* get partition number */ /* get partition number */
partNum = getNumberOfPartitions(rel); partNum = getNumberOfPartitions(rel);
@ -5408,6 +5423,7 @@ static void get_src_partition_bound(Relation partTableRel, Oid srcPartOid, Const
errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("CAN NOT get detail info from a partitioned relation WITHOUT specified partition."))); errmsg("CAN NOT get detail info from a partitioned relation WITHOUT specified partition.")));
Assert(partTableRel->partMap->type == PART_TYPE_RANGE || partTableRel->partMap->type == PART_TYPE_INTERVAL);
partMap = (RangePartitionMap*)partTableRel->partMap; partMap = (RangePartitionMap*)partTableRel->partMap;
srcPartSeq = partOidGetPartSequence(partTableRel, srcPartOid) - 1; srcPartSeq = partOidGetPartSequence(partTableRel, srcPartOid) - 1;
@ -5727,6 +5743,63 @@ static Oid choose_coerce_type(Oid leftid, Oid rightid)
return InvalidOid; /* let make_op decide */ return InvalidOid; /* let make_op decide */
} }
/* check if everyVal <= endVal - startVal, but think of overflow, we should be careful */
static bool CheckStepInRange(ParseState *pstate, Const *startVal, Const *endVal, Const *everyVal,
Form_pg_attribute attr)
{
List *opr_mi = list_make1(makeString("-"));
List *opr_lt = list_make1(makeString("<"));
List *opr_le = list_make1(makeString("<="));
Datum res;
Oid targetType = attr->atttypid;
Oid targetCollation = attr->attcollation;
int16 targetLen = attr->attlen;
bool targetByval = attr->attbyval;
bool targetIsVarlena = (!targetByval) && (targetLen == -1);
int32 targetTypmod;
if (targetType == DATEOID || targetType == TIMESTAMPOID || targetType == TIMESTAMPTZOID) {
targetTypmod = -1; /* avoid accuracy-problem of date */
} else {
targetTypmod = attr->atttypmod;
}
Const *zeroVal = NULL;
if (targetType == NUMERICOID) {
zeroVal = makeConst(NUMERICOID, targetTypmod, targetCollation, targetLen,
(Datum)DirectFunctionCall3(numeric_in, CStringGetDatum("0.0"), ObjectIdGetDatum(0), Int32GetDatum(-1)),
false, targetByval);
} else if (targetIsVarlena) {
zeroVal = makeConst(UNKNOWNOID, targetTypmod, targetCollation, targetLen,
(Datum)DirectFunctionCall1(byteain, CStringGetDatum("")), false, targetByval);
} else {
zeroVal = makeConst(targetType, targetTypmod, targetCollation, targetLen, (Datum)0, false, targetByval);
}
res = evaluate_opexpr(pstate, opr_lt, (Node *)startVal, (Node *)zeroVal, NULL, -1);
bool flag1 = DatumGetBool(res); /* whether startVal < 0 */
res = evaluate_opexpr(pstate, opr_lt, (Node *)endVal, (Node *)zeroVal, NULL, -1);
bool flag2 = DatumGetBool(res); /* whether endVal < 0 */
/* we've checked startVal < endVal, so if startVal >= 0, make sure endVal >= 0 too,
* (!flag1 && flage) can never happen */
Assert(flag1 || !flag2);
if (flag1 && !flag2) { /* startVal < 0 && endVal >= 0 */
/* check if startVal <= endVal - everyVal */
res = evaluate_opexpr(pstate, opr_mi, (Node *)endVal, (Node *)everyVal, &targetType, -1);
Const *secheck = makeConst(targetType, targetTypmod, targetCollation, targetLen, res, false, targetByval);
res = evaluate_opexpr(pstate, opr_le, (Node *)startVal, (Node *)secheck, NULL, -1);
} else { /* startVal < 0 && endVal < 0, or startVal >= 0 && endVal >= 0 */
/* check if everyVal <= endVal - startVal */
res = evaluate_opexpr(pstate, opr_mi, (Node *)endVal, (Node *)startVal, &everyVal->consttype, -1);
Const *secheck =
makeConst(everyVal->consttype, targetTypmod, targetCollation, targetLen, res, false, targetByval);
res = evaluate_opexpr(pstate, opr_le, (Node *)everyVal, (Node *)secheck, NULL, -1);
}
return DatumGetBool(res);
}
/* /*
* divide_start_end_every_internal * divide_start_end_every_internal
* internal implementaion for dividing an interval indicated by any-datatype * internal implementaion for dividing an interval indicated by any-datatype
@ -5756,6 +5829,7 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
{ {
List* result = NIL; List* result = NIL;
List* opr_pl = NIL; List* opr_pl = NIL;
List* opr_mi = NIL;
List* opr_lt = NIL; List* opr_lt = NIL;
List* opr_le = NIL; List* opr_le = NIL;
List* opr_mul = NIL; List* opr_mul = NIL;
@ -5765,7 +5839,6 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
Oid restypid; Oid restypid;
Const* curpnt = NULL; Const* curpnt = NULL;
int32 nPart; int32 nPart;
bool isEnd = false;
Const* everyVal = NULL; Const* everyVal = NULL;
Oid targetType; Oid targetType;
bool targetByval = false; bool targetByval = false;
@ -5777,11 +5850,23 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
Assert(maxNum > 0 && maxNum <= MAX_PARTITION_NUM); Assert(maxNum > 0 && maxNum <= MAX_PARTITION_NUM);
opr_pl = list_make1(makeString("+")); opr_pl = list_make1(makeString("+"));
opr_mi = list_make1(makeString("-"));
opr_lt = list_make1(makeString("<")); opr_lt = list_make1(makeString("<"));
opr_le = list_make1(makeString("<=")); opr_le = list_make1(makeString("<="));
opr_mul = list_make1(makeString("*")); opr_mul = list_make1(makeString("*"));
opr_eq = list_make1(makeString("=")); opr_eq = list_make1(makeString("="));
/* get target type info */
targetType = attr->atttypid;
targetByval = attr->attbyval;
targetCollation = attr->attcollation;
if (targetType == DATEOID || targetType == TIMESTAMPOID || targetType == TIMESTAMPTZOID) {
targetTypmod = -1; /* avoid accuracy-problem of date */
} else {
targetTypmod = attr->atttypmod;
}
targetLen = attr->attlen;
/* /*
* cast everyExpr to targetType * cast everyExpr to targetType
* Note: everyExpr goes through transformExpr and transformIntoConst already. * Note: everyExpr goes through transformExpr and transformIntoConst already.
@ -5790,31 +5875,43 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
/* first compare start/end value */ /* first compare start/end value */
res = evaluate_opexpr(pstate, opr_le, (Node*)endVal, (Node*)startVal, NULL, -1); res = evaluate_opexpr(pstate, opr_le, (Node*)endVal, (Node*)startVal, NULL, -1);
if (DatumGetBool(res)) if (DatumGetBool(res)) {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("start value must be less than end value for %s \"%s\".", errmsg("start value must be less than end value for %s \"%s\".",
partTypeName, partName))); partTypeName, partName)));
}
/* get target type info */ /* second, we should make sure that everyVal <= endVal - startVal */
targetType = attr->atttypid; if (!CheckStepInRange(pstate, startVal, endVal, everyVal, attr)) {
targetByval = attr->attbyval; ereport(ERROR,
targetCollation = attr->attcollation; (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
if (targetType == DATEOID || targetType == TIMESTAMPOID || targetType == TIMESTAMPTZOID) errmsg("%s step is too big for %s \"%s\".", partTypeName, partTypeName, partName)));
targetTypmod = -1; /* avoid accuracy-problem of date */ }
else
targetTypmod = attr->atttypmod;
targetLen = attr->attlen;
/* build result */ /* build result */
curpnt = startVal; curpnt = startVal;
nPart = 0; nPart = 0;
isEnd = false; while (true) {
while (nPart < maxNum) { /* if too many partitions, report error */
/* compute currentPnt + everyval */ if (nPart >= maxNum) {
res = evaluate_opexpr(pstate, opr_pl, (Node*)curpnt, (Node*)everyVal, &targetType, -1); pfree_ext(pnt);
pnt = makeConst(targetType, targetTypmod, targetCollation, targetLen, res, false, targetByval); ereport(ERROR,
pnt = (Const*)GetTargetValue(attr, (Const*)pnt, false); (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("too many %ss after split %s \"%s\".", partTypeName, partTypeName, partName),
errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not assigned.",
partTypeName, MAX_PARTITION_NUM)));
}
/* compute curpnt + everyval, but if curpnt + everyVal > endVal, we use endVal instead,
* so we can make sure that pnt <= endVal */
if (!CheckStepInRange(pstate, curpnt, endVal, everyVal, attr)) {
pnt = (Const*)copyObject(endVal);
} else {
res = evaluate_opexpr(pstate, opr_pl, (Node*)curpnt, (Node*)everyVal, &targetType, -1);
pnt = makeConst(targetType, targetTypmod, targetCollation, targetLen, res, false, targetByval);
pnt = (Const*)GetTargetValue(attr, (Const*)pnt, false);
}
/* necessary check in first pass */ /* necessary check in first pass */
if (nPart == 0) { if (nPart == 0) {
@ -5865,47 +5962,24 @@ static List* divide_start_end_every_internal(ParseState* pstate, char* partName,
errmsg("%s step is too small for %s \"%s\".", partTypeName, partTypeName, partName))); errmsg("%s step is too small for %s \"%s\".", partTypeName, partTypeName, partName)));
} }
/* pnt must be less than or equal to endVal */
Assert(DatumGetBool(evaluate_opexpr(pstate, opr_le, (Node*)pnt, (Node*)endVal, NULL, -1)));
result = lappend(result, pnt);
nPart++;
/* check to determine if it is the final partition */ /* check to determine if it is the final partition */
res = evaluate_opexpr(pstate, opr_le, (Node*)pnt, (Node*)endVal, NULL, -1); res = evaluate_opexpr(pstate, opr_eq, (Node*)pnt, (Node*)endVal, NULL, -1);
if (DatumGetBool(res)) { if (DatumGetBool(res)) {
result = lappend(result, pnt);
nPart++;
res = evaluate_opexpr(pstate, opr_lt, (Node*)pnt, (Node*)endVal, NULL, -1);
if (!DatumGetBool(res)) {
/* case-1: final partition just matches endVal */
isEnd = true;
break;
}
} else if (nPart == 0) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("%s step is too big for %s \"%s\".", partTypeName, partTypeName, partName)));
} else {
/* case-2: final partition is smaller than others */
pfree_ext(pnt);
pnt = (Const*)copyObject(endVal);
result = lappend(result, pnt);
nPart++;
isEnd = true;
break; break;
} }
curpnt = pnt; curpnt = pnt;
} }
if (!isEnd) {
/* too many partitions, report error */
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("too many %ss after split %s \"%s\".", partTypeName, partTypeName, partName),
errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not assigned.",
partTypeName, MAX_PARTITION_NUM)));
}
/* done */ /* done */
Assert(result && result->length == nPart); Assert(result && result->length == nPart);
if (numPart != NULL) if (numPart != NULL) {
*numPart = nPart; *numPart = nPart;
}
return result; return result;
} }
@ -6607,7 +6681,7 @@ List* transformRangePartStartEndStmt(ParseState* pstate, List* partitionList, Li
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION), (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("too many %ss after split %s \"%s\".", errmsg("too many %ss after split %s \"%s\".",
partTypeName, defState->partitionName, partTypeName), partTypeName, partTypeName, defState->partitionName),
errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not " errhint("number of %ss can not be more than %d, MINVALUE will be auto-included if not "
"assigned.", "assigned.",
partTypeName, MAX_PARTITION_NUM))); partTypeName, MAX_PARTITION_NUM)));

View File

@ -963,7 +963,7 @@ void RelationBuildLocator(Relation rel)
&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); &skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
pcrel = heap_open(PgxcClassRelationId, AccessShareLock); pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey); pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
htup = systable_getnext(pcscan); htup = systable_getnext(pcscan);
if (!HeapTupleIsValid(htup)) { if (!HeapTupleIsValid(htup)) {
/* Assume local relation only */ /* Assume local relation only */

View File

@ -3367,7 +3367,7 @@ char* PgxcGroupGetFirstLogicCluster()
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTGreaterStrategyNumber, F_OIDGT, ObjectIdGetDatum(0)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTGreaterStrategyNumber, F_OIDGT, ObjectIdGetDatum(0));
scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, NULL, 1, skey);
while ((tup = systable_getnext(scan)) != NULL) { while ((tup = systable_getnext(scan)) != NULL) {
group_kind = get_group_kind(tup); group_kind = get_group_kind(tup);
@ -4614,7 +4614,7 @@ List* PgxcGroupGetLogicClusterList(Bitmapset* nodeids)
} }
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTGreaterStrategyNumber, F_OIDGT, ObjectIdGetDatum(0)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTGreaterStrategyNumber, F_OIDGT, ObjectIdGetDatum(0));
scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pgxc_group_rel, PgxcGroupOidIndexId, true, NULL, 1, skey);
while ((tup = systable_getnext(scan)) != NULL) { while ((tup = systable_getnext(scan)) != NULL) {
Oid group_oid = HeapTupleGetOid(tup); Oid group_oid = HeapTupleGetOid(tup);

View File

@ -1174,7 +1174,7 @@ void PgxcNodeAlter(AlterNodeStmt* stmt)
HeapTuple tmptup; HeapTuple tmptup;
TupleDesc pg_node_dsc = RelationGetDescr(rel); TupleDesc pg_node_dsc = RelationGetDescr(rel);
SysScanDesc scan = systable_beginscan(rel, InvalidOid, false, SnapshotNow, 0, NULL); SysScanDesc scan = systable_beginscan(rel, InvalidOid, false, NULL, 0, NULL);
while (HeapTupleIsValid((tmptup = systable_getnext(scan)))) { while (HeapTupleIsValid((tmptup = systable_getnext(scan)))) {
bool isnull = true; bool isnull = true;
Oid scanoid = HeapTupleGetOid(tmptup); Oid scanoid = HeapTupleGetOid(tmptup);

View File

@ -8210,7 +8210,7 @@ bool IsInheritor(Oid relid)
pginherits = heap_open(InheritsRelationId, AccessShareLock); pginherits = heap_open(InheritsRelationId, AccessShareLock);
ScanKeyInit(&key[0], Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, relid); ScanKeyInit(&key[0], Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, relid);
scan = systable_beginscan(pginherits, InheritsRelidSeqnoIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(pginherits, InheritsRelidSeqnoIndexId, true, NULL, 1, key);
if (HeapTupleIsValid(systable_getnext(scan))) { if (HeapTupleIsValid(systable_getnext(scan))) {
ret = true; ret = true;
} }

View File

@ -38,7 +38,7 @@ OBJS = acl.o arrayfuncs.o array_selfuncs.o array_typanalyze.o \
tsquery_op.o tsquery_rewrite.o tsquery_util.o tsrank.o \ tsquery_op.o tsquery_rewrite.o tsquery_util.o tsrank.o \
tsvector.o tsvector_op.o tsvector_parser.o \ tsvector.o tsvector_op.o tsvector_parser.o \
txid.o uuid.o windowfuncs.o xml.o extended_statistics.o clientlogic_bytea.o clientlogicsettings.o \ txid.o uuid.o windowfuncs.o xml.o extended_statistics.o clientlogic_bytea.o clientlogicsettings.o \
median_aggs.o median_aggs.o expr_distinct.o
like.o: like.cpp like_match.cpp like.o: like.cpp like_match.cpp

View File

@ -82,7 +82,7 @@ Datum globalsettingin(PG_FUNCTION_ARGS)
CStringGetDatum(key_name_or_oid)); CStringGetDatum(key_name_or_oid));
hdesc = heap_open(ClientLogicGlobalSettingsId, AccessShareLock); hdesc = heap_open(ClientLogicGlobalSettingsId, AccessShareLock);
sysscan = systable_beginscan(hdesc, ClientLogicGlobalSettingsNameIndexId, true, SnapshotNow, 1, skey); sysscan = systable_beginscan(hdesc, ClientLogicGlobalSettingsNameIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
result = Oid HeapTupleGetOid(tuple); result = Oid HeapTupleGetOid(tuple);
@ -166,7 +166,7 @@ Datum columnsettingin(PG_FUNCTION_ARGS)
CStringGetDatum(key_name_or_oid)); CStringGetDatum(key_name_or_oid));
hdesc = heap_open(ClientLogicColumnSettingsId, AccessShareLock); hdesc = heap_open(ClientLogicColumnSettingsId, AccessShareLock);
sysscan = systable_beginscan(hdesc, ClientLogicColumnSettingsNameIndexId, true, SnapshotNow, 1, skey); sysscan = systable_beginscan(hdesc, ClientLogicColumnSettingsNameIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
result = Oid HeapTupleGetOid(tuple); result = Oid HeapTupleGetOid(tuple);

View File

@ -518,7 +518,7 @@ static double calculate_source_database_size()
/*scan the pg_class to fetch the reltuples of every relation.*/ /*scan the pg_class to fetch the reltuples of every relation.*/
class_rel = heap_open(RelationRelationId, AccessShareLock); class_rel = heap_open(RelationRelationId, AccessShareLock);
pg_class_tuple_desc = class_rel->rd_att; pg_class_tuple_desc = class_rel->rd_att;
scan = systable_beginscan(class_rel, InvalidOid, false, SnapshotNow, 0, NULL); scan = systable_beginscan(class_rel, InvalidOid, false, NULL, 0, NULL);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
tuple_class = (Form_pg_class)GETSTRUCT(tuple); tuple_class = (Form_pg_class)GETSTRUCT(tuple);
Oid relid = HeapTupleHeaderGetOid(tuple->t_data); Oid relid = HeapTupleHeaderGetOid(tuple->t_data);
@ -1931,7 +1931,10 @@ Datum pg_filenode_relation(PG_FUNCTION_ARGS)
Oid relfilenode = PG_GETARG_OID(1); Oid relfilenode = PG_GETARG_OID(1);
Oid heaprel = InvalidOid; Oid heaprel = InvalidOid;
heaprel = RelidByRelfilenode(reltablespace, relfilenode); heaprel = RelidByRelfilenodeCache(reltablespace, relfilenode);
if (!OidIsValid(heaprel)) {
heaprel = RelidByRelfilenode(reltablespace, relfilenode);
}
if (!OidIsValid(heaprel)) if (!OidIsValid(heaprel))
PG_RETURN_NULL(); PG_RETURN_NULL();

View File

@ -0,0 +1,434 @@
/* -------------------------------------------------------------------------
*
* expr_distinct.cpp
* utility functions for get number of distinct of expressions
*
* Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved.
*
* IDENTIFICATION
* src/backend/utils/adt/expr_distinct.cpp
*
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include "access/transam.h"
#include "access/sysattr.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "catalog/pg_proc.h"
#include "nodes/makefuncs.h"
#include "nodes/nodes.h"
#include "optimizer/cost.h"
#include "optimizer/optimizerdebug.h"
#include "optimizer/pathnode.h"
#include "optimizer/planner.h"
#include "optimizer/prep.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/streamplan.h"
#include "optimizer/var.h"
#include "parser/analyze.h"
#include "parser/parse_clause.h"
#include "parser/parse_coerce.h"
#include "parser/parsetree.h"
#include "parser/parse_relation.h"
#include "storage/buf/bufmgr.h"
#include "storage/proc.h"
#include "utils/dynahash.h"
#include "utils/expr_distinct.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/selfuncs.h"
#include "utils/syscache.h"
/*
* Context for estimate number of distinct of function
*/
typedef struct {
double numDistinct[2]; /* numdistinct of the var */
Oid attType; /* attType of current values */
int numMcv; /* original number of MCV values in stats */
int numHisBounds; /* original number of histogram bounds in stats */
/* following data may change during runtime */
int numFMcv; /* length of array mcvValues, may be changed at runtime */
int numFHisBounds; /* length of array hisValues, simliar to mcvValues */
Datum *fMcv; /* "MCV" values or f(..(MCV)), except NULL */
Datum *fHisBounds; /* "histogram bounds" or f(..g(histogram bounds)), except NULL */
bool needAdjust; /* whether var distinct need adjust */
} EstiFuncDistinctContext;
static char *GetFunctionNameWithDefault(Oid fnOid);
static void EstimateExprNumDistinct(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar,
bool *isDefault);
static void GetNumDistinctFuncExpr(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr, bool isJoinVar);
static void GetExprNumDistinctWalker(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar);
static void TransferFunctionNumDistinct(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr,
bool isJoinVar);
static bool CheckFuncArgsForTransferNumDistinct(FuncExpr *funcExpr, Node **varNode);
static bool IsFunctionTransferNumDistinct(FuncExpr *funcExpr);
/*
* The array collects all of the type-cast functions which can transfer number of distinct from any one of
* its arguments, other parameters are viewed as Const.
*/
static Oid g_typeCastFuncOids[] = {
/* type cast from bool */
BOOLTOINT1FUNCOID, BOOLTOINT2FUNCOID, BOOLTOINT4FUNCOID, BOOLTOINT8FUNCOID, BOOLTOTEXTFUNCOID,
/* type cast from int1 */
I1TOI2FUNCOID, I1TOI4FUNCOID, I1TOI8FUNCOID, I1TOF4FUNCOID, I1TOF8FUNCOID, INT1TOBPCHARFUNCOID,
INT1TOVARCHARFUNCOID, INT1TONVARCHAR2FUNCOID, INT1TOTEXTFUNCOID, INT1TONUMERICFUNCOID, INT1TOINTERVALFUNCOID,
/* type cast from int2 */
I2TOI1FUNCOID, INT2TOINT4FUNCOID, INT2TOFLOAT4FUNCOID, INT2TOFLOAT8FUNCOID, INT2TOBPCHAR, INT2TOTEXTFUNCOID,
INT2TOVARCHARFUNCOID, INT2TOINT8FUNCOID, INT2TONUMERICFUNCOID, INT2TOINTERVALFUNCOID,
/* type cast from int4 */
I4TOI1FUNCOID, INT4TOINT2FUNCOID, INT4TOINT8FUNCOID, INT4TOFLOAT8FUNCOID, INTEGER2CASHFUNCOID,
INT4TONUMERICFUNCOID, INT4TOINTERVALFUNCOID, INT4TOHEXFUNCOID, INT4TOBPCHARFUNCOID, INT4TOTEXTFUNCOID,
INT4TOVARCHARFUNCOID, INT4TOCHARFUNCOID, INT4TOCHRFUNCOID,
/* type cast from int8 */
I8TOI1FUNCOID, INT8TOINT2FUNCOID, INT8TOINT4FUNCOID, INT8TOBPCHARFUNCOID, INT8TOTEXTFUNCOID, INT8TOVARCHARFUNCOID,
INT8TONUMERICFUNCOID, INT8TOHEXFUNCOID,
/* type cast from float4/float8 */
FLOAT4TOBPCHARFUNCOID, FLOAT4TOTEXTFUNCOID, FLOAT4TOVARCHARFUNCOID, FLOAT4TOFLOAT8FUNCOID,
FLOAT4TONUMERICFUNCOID, FLOAT8TOBPCHARFUNCOID, FLOAT8TOINTERVALFUNCOID, FLOAT8TOTEXTFUNCOID,
FLOAT8TOVARCHARFUNCOID, FLOAT8TONUMERICFUNCOID, FLOAT8TOTIMESTAMPFUNCOID,
/* type cast from numeric */
NUMERICTOBPCHARFUNCOID, NUMERICTOTEXTFUNCOID, NUMERICTOVARCHARFUNCOID,
/* type cast from timestamp/date/time */
DEFAULTFORMATTIMESTAMP2CHARFUNCOID, DEFAULTFORMATTIMESTAMPTZ2CHARFUNCOID, TIMESATMPTOTEXTFUNCOID,
TIMESTAMPTOVARCHARFUNCOID, TIMESTAMP2TIMESTAMPTZFUNCOID, TIMESTAMPTZ2TIMESTAMPFUNCOID,
DATETIMESTAMPTZFUNCOID, DATETOTIMESTAMPFUNCOID, DATETOBPCHARFUNCOID, DATETOVARCHARFUNCOID, DATETOTEXTFUNCOID,
DATEANDTIMETOTIMESTAMPFUNCOID, DTAETIME2TIMESTAMPTZFUNCOID, TIMETOINTERVALFUNCOID, TIMESTAMPZONETOTEXTFUNCOID,
TIME2TIMETZFUNCOID, RELTIMETOINTERVALFUNCOID,
/* type cast from text */
TODATEDEFAULTFUNCOID, TODATEFUNCOID, TOTIMESTAMPFUNCOID, TOTIMESTAMPDEFAULTFUNCOID,
TEXTTOREGCLASSFUNCOID, TEXTTOINT1FUNCOID, TEXTTOINT2FUNCOID, TEXTTOINT4FUNCOID, TEXTTOINT8FUNCOID,
TEXTTONUMERICFUNCOID, TEXTTOTIMESTAMP, TIMESTAMPTONEWTIMEZONEFUNCOID, TIMESTAMPTZTONEWTIMEZONEFUNCOID,
HEXTORAWFUNCOID,
/* type cast from char/varchar/bpchar */
VARCHARTONUMERICFUNCOID, VARCHARTOINT4FUNCOID, VARCHARTOINT8FUNCOID, VARCHARTOTIMESTAMPFUNCOID,
BPCHARTOINT4FUNCOID, BPCHARTOINT8FUNCOID, BPCHARTONUMERICFUNCOID, BPCHARTOTIMESTAMPFUNCOID,
RTRIM1FUNCOID, BPCHARTEXTFUNCOID, CHARTOBPCHARFUNCOID, CHARTOTEXTFUNCOID
};
static char *GetFunctionNameWithDefault(Oid fnOid)
{
char *funcName = get_func_name(fnOid);
if (funcName == NULL) {
funcName = "unknown-name";
}
return funcName;
}
/*
* Entrance of the distinct estimation for expr whose stats is unavailable
*
* Handle expr-case in get_variable_numdistinct, aim to estimate variable distinct if no stats
* (for the variable) are available. Also, GUC 'cost_model_version' controls the behaviour of
* the router.
*
* Note:
* - function get_variable_numdistinct and get_variable_numdistinct_router should be called
* after examine_variable, otherwise, it may fail to get stats which actually exists.
* - This function may fail to estimate expr distinct, returns 0.0 (means unknown).
* - adjust ratio will be applied to the raw distinct if needAdjust is true, and
* varData->needAdjust is used to transfer the indicators.
*/
double GetExprNumDistinctRouter(VariableStatData *varData, bool needAdjust, STATS_EST_TYPE eType, bool isJoinVar)
{
double distinct = 0.0;
int idx = 0;
bool saveNeedAdjust = varData->needAdjust;
varData->needAdjust = needAdjust;
ereport(DEBUG2, (errmodule(MOD_OPT), errmsg(
"[Get Expr NumDistinct Router]: -------- <START>: adjust: %s --------", needAdjust ? "true" : "false")));
if (IS_PGXC_COORDINATOR && (eType == STATS_TYPE_LOCAL)) {
/* for local distinct */
idx = 0;
} else {
/* for global distinct */
idx = 1;
}
if (varData->numDistinct[idx] > 0.0) {
distinct = clamp_row_est(varData->numDistinct[idx]);
} else if (!varData->isEstimated) {
GetExprNumDistinctWalker(varData->root, varData, varData->var, isJoinVar);
varData->isEstimated = true;
if (varData->numDistinct[idx] > 0.0) {
distinct = clamp_row_est(varData->numDistinct[idx]);
}
}
varData->needAdjust = saveNeedAdjust;
ereport(DEBUG2, (errmodule(MOD_OPT),
errmsg("[Get Expr NumDistinct Router]: -------- <END>: distinct: %.0lf --------", distinct)));
return distinct;
}
/*
* implementation of GetExprNumDistinctRouter with "cost_model_version = 1"
*
* NB: parameters node may be varData->var or other form or sub-node of varData->var
*/
static void GetExprNumDistinctWalker(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar)
{
char *exprName = NULL;
errno_t rc =
memset_s(varData->numDistinct, sizeof(varData->numDistinct[0]) * 2, 0, sizeof(varData->numDistinct[0]) * 2);
securec_check(rc, "\0", "\0");
switch (nodeTag(node)) {
case T_FuncExpr:
exprName = "FuncExpr";
GetNumDistinctFuncExpr(root, varData, (FuncExpr *)node, isJoinVar);
break;
default:
exprName = "Unknown-Expr";
break;
}
ereport(DEBUG2,
(errmodule(MOD_OPT),
(errmsg("[%s Distinct Estimation]: local distinct is %.0lf, global distinct is %.0lf",
exprName, varData->numDistinct[0], varData->numDistinct[1]))));
}
/*
* Estimate the number of distinct of function expression.
*
* Parameters:
* @in funcExpr: the function expression to calculate distinct value
* @in isJoinVar: is the node used for join?
*
* @out: vardata: set the distinct value on numdistinct.
*/
static void GetNumDistinctFuncExpr(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr, bool isJoinVar)
{
if (funcExpr->funcid >= FirstNormalObjectId) {
/* user-defined function, do nothing */
return;
}
/*
* Let p denotes function can transfer distinct, f all other functions, w type-cast functions
* which can also transfer distinct. In general, p contains w. Then all possible cases are:
* 1. p(p(p(..p(var)))): p include w,
* transfer distinct of var to top level
* 2. p(p(p(..p(f(var))))): p include w,
* transfer distinct of f to top level, distinct of f is estimated from var
* 3. f(var):
* estimate distinct of f from var
* 4. f(w(..w(var))
* estimate distinct of f from var
* 5. ..f(..(p(..))): p except w
* can not estimate, return unknown
* 6. ..f(..(f(..))):
* can not estimate, return unknown
*/
/* bool-return function */
if (get_func_rettype(funcExpr->funcid) == BOOLOID) {
varData->numDistinct[0] = 2.0;
varData->numDistinct[1] = 2.0;
return;
}
if (funcExpr->args == NULL) {
ereport(DEBUG2,
(errmodule(MOD_OPT),
errmsg("[Func Distinct Estimation]:can not get number of distinct of function oid %u with no argument",
funcExpr->funcid)));
return;
}
/* if failed to transfer, we can not estimate either */
if (IsFunctionTransferNumDistinct(funcExpr)) {
/* transfer the number of distinct */
TransferFunctionNumDistinct(root, varData, funcExpr, isJoinVar);
} else {
/* estimate the number of distinct */
return;
}
}
/*
* Estimate the number of distinct of the specifed node, work for get_num_distinct_coalesce,
* get_num_distinct_casewhen and so on. The estimated numdistinct are always given, stored in
* vardata->numdistinct[2].
*
* Parameters:
* @in varData: the info we need to calculate distinct value, numdistinct is returned in varData
* @in node: the node to calculate distinct value
* @in isJoinVar: is the node used for join?
* @out isDefault: is the numdistinct is a default value ?
*/
static void EstimateExprNumDistinct(PlannerInfo *root, VariableStatData *varData, Node *node, bool isJoinVar,
bool *isDefault)
{
VariableStatData tmpVarData;
SpecialJoinInfo sjInfo;
errno_t rc = EOK;
varData->numDistinct[0] = 0.0;
varData->numDistinct[1] = 0.0;
/* return after count it if it's Const. */
if (IsA(node, Const)) {
varData->numDistinct[0] = 1.0;
varData->numDistinct[1] = 1.0;
*isDefault = false;
return;
}
/* XXX should min_lefthand ? */
rc = memset_s(&sjInfo, sizeof(sjInfo), 0, sizeof(sjInfo));
securec_check(rc, "\0", "\0");
sjInfo.min_lefthand = root->all_baserels;
sjInfo.min_righthand = NULL;
examine_variable(root, node, 0, &tmpVarData);
tmpVarData.needAdjust = varData->needAdjust;
double joinRatio = get_join_ratio(&tmpVarData, &sjInfo);
varData->numDistinct[0] =
get_variable_numdistinct(&tmpVarData, isDefault, tmpVarData.needAdjust, joinRatio, &sjInfo,
STATS_TYPE_LOCAL, isJoinVar);
varData->numDistinct[1] =
get_variable_numdistinct(&tmpVarData, isDefault, tmpVarData.needAdjust, joinRatio, &sjInfo,
STATS_TYPE_GLOBAL, isJoinVar);
ReleaseVariableStats(tmpVarData);
}
/*
* try to transfer number of distinct of given funcExpr, return unknown if fail
*/
static void TransferFunctionNumDistinct(PlannerInfo *root, VariableStatData *varData, FuncExpr *funcExpr,
bool isJoinVar)
{
bool isDefault = false;
Node *varNode = NULL;
/* check arguments and find the var-argument */
if (!CheckFuncArgsForTransferNumDistinct(funcExpr, &varNode)) {
return;
}
/* recursive to the arg, if there is no distinct for the arg, return unknown */
EstimateExprNumDistinct(root, varData, varNode, isJoinVar, &isDefault);
ereport(DEBUG2,
(errmodule(MOD_OPT),
errmsg("[Func Distinct Estimation]: succeed to transfer number of distinct of function oid: %u",
funcExpr->funcid)));
}
/*
* check arguments of the func, return true and var-node if ok. Assume there is only one var or expr(var,..) in
* its arguments. We allow f(var, const), f(const, var), f(expr(var), const) and f(expr(var1, var2), const)
*
* return true if ok, and varNode indicates the location of the Var
*/
static bool CheckFuncArgsForTransferNumDistinct(FuncExpr *funcExpr, Node **varNode)
{
ListCell *listCell = NULL;
int numVars = 0;
Node *lastNode = NULL;
/* find the first "var" */
foreach (listCell, funcExpr->args) {
Node *node = (Node *)lfirst(listCell);
if (IsA(node, Var)) {
numVars++;
lastNode = node;
} else if (IsA(node, Const)) {
continue;
} else {
List *varList =
pull_var_clause(node, PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS, PVC_RECURSE_SPECIAL_EXPR);
if (varList != NULL) {
numVars++;
lastNode = node;
}
}
}
if (numVars == 0) {
*varNode = (Node *)linitial(funcExpr->args);
return true;
} else if (numVars == 1) {
*varNode = lastNode;
return true;
} else {
*varNode = NULL;
ereport(DEBUG2, (errmodule(MOD_OPT),
errmsg("[Check Args for Transfer]: more than one var-arguments for function oid: %u",
funcExpr->funcid)));
return false;
}
}
/*
* check if the function can transfer number of distinct from one of its parameters
*/
static bool IsFunctionTransferNumDistinct(FuncExpr *funcExpr)
{
/*
* We explicitly allow or disallow functions to transfer number of distinct.
*
* If a function called in form of COERCE_EXPLICIT_CAST/COERCE_IMPLICIT_CAST, we can not
* conclude that this function can transfer number of distinct, e.g.
*
* create table t1(price text);
* values: '20.01',
* '20.02',
* '20.12',
* '20.30',
* '20.99',
* '20.88'
* select price from t1 where int1(price) = 20;
* The filter transformed by Optimizer is:
* (((numeric_in(textout(price), 0::oid, (-1)))::tinyint)::bigint = 20)
*
* numeric::tinyint is the function numeric_int1 which is called as COERCE_EXPLICIT_CAST,
* and it will make rounding to ensure an integer is assigned to int1. Hence a explicitly
* cast function may not transfer number of distinct.
*/
Oid funcId = funcExpr->funcid;
char *funcName = GetFunctionNameWithDefault(funcExpr->funcid);
/* special functions whose oid is not built-in, but we can transfer numdistinct for them */
if (strcmp(funcName, "to_text") == 0 || strcmp(funcName, "to_varchar2") == 0 ||
strcmp(funcName, "to_nvarchar2") == 0 || strcmp(funcName, "to_ts") == 0 ||
(strcmp(funcName, "to_number") == 0 && (funcId != TONUMBERFUNCOID))) {
pfree(funcName);
return true;
}
for (int i = 0; i < (int)lengthof(g_typeCastFuncOids); i++) {
if (g_typeCastFuncOids[i] == funcId) {
pfree(funcName);
return true;
}
}
pfree(funcName);
return false;
}

View File

@ -921,7 +921,7 @@ List* es_explore_declared_stats(Oid relid, VacuumStmt* vacstmt, bool inh)
ScanKeyInit(&key[2], Anum_pg_statistic_ext_stainherit, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(inh)); ScanKeyInit(&key[2], Anum_pg_statistic_ext_stainherit, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(inh));
Relation relation = heap_open(StatisticExtRelationId, AccessShareLock); Relation relation = heap_open(StatisticExtRelationId, AccessShareLock);
SysScanDesc scan = systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, SnapshotNow, 3, key); SysScanDesc scan = systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, NULL, 3, key);
List* es_list = NIL; List* es_list = NIL;
for (HeapTuple tuple = NULL; NULL != (tuple = systable_getnext(scan));) { for (HeapTuple tuple = NULL; NULL != (tuple = systable_getnext(scan));) {
@ -1114,7 +1114,7 @@ static List* es_search_extended_statistics(
Relation relation = heap_open(StatisticExtRelationId, AccessShareLock); Relation relation = heap_open(StatisticExtRelationId, AccessShareLock);
SysScanDesc scan = SysScanDesc scan =
systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, SnapshotNow, num_key, key); systable_beginscan(relation, StatisticExtRelidKindInhKeyIndexId, true, NULL, num_key, key);
int count = 0; int count = 0;
for (HeapTuple tuple = NULL; NULL != (tuple = systable_getnext(scan));) { for (HeapTuple tuple = NULL; NULL != (tuple = systable_getnext(scan));) {

View File

@ -5561,7 +5561,7 @@ static void NUM_numpart_from_char(NUMProc* Np, int id, int plen, int& tmp_len)
* locale sign expected - last read char was NUM_0/9 or NUM_DEC - and * locale sign expected - last read char was NUM_0/9 or NUM_DEC - and
* next char is not digit * next char is not digit
*/ */
if (IS_LSIGN(Np->Num) && isread && (Np->inout_p + 1) <= Np->inout + plen && if (IS_LSIGN(Np->Num) && isread && (Np->inout_p + 1) < Np->inout + plen &&
!isdigit((unsigned char)*(Np->inout_p + 1))) { !isdigit((unsigned char)*(Np->inout_p + 1))) {
int x; int x;
char* tmp = Np->inout_p++; char* tmp = Np->inout_p++;

View File

@ -83,9 +83,14 @@ static Point* lseg_interpt_internal(LSEG* l1, LSEG* l2);
#define LDELIM_C '<' #define LDELIM_C '<'
#define RDELIM_C '>' #define RDELIM_C '>'
/* Maximum number of characters printed by pair_encode() */ /* Maximum number of characters printed by pair_encode().
/* ...+3+7 : 3 accounts for extra_float_digits max value */ * The value range of float8 is -1.79E+308 ~ 1.79E+308.
#define P_MAXLEN (2 * (DBL_DIG + 3 + 7) + 1) * For point(-1.79E+308,-1.79E+308),
* (2 * (DBL_DIG + 3 + 7) + 1 + 1) : 3 accounts for extra_float_digits max value,
* 7 accounts for "-.E+308", first number 1 accounts for comma in the middle of numbers,
* last number 1 accounts for string terminator.
*/
#define P_MAXLEN (2 * (DBL_DIG + 3 + 7) + 1 + 1)
/* /*
* Geometric data types are composed of points. * Geometric data types are composed of points.

View File

@ -94,11 +94,11 @@ Datum current_query(PG_FUNCTION_ARGS)
#define SIGNAL_BACKEND_SUCCESS 0 #define SIGNAL_BACKEND_SUCCESS 0
#define SIGNAL_BACKEND_ERROR 1 #define SIGNAL_BACKEND_ERROR 1
#define SIGNAL_BACKEND_NOPERMISSION 2 #define SIGNAL_BACKEND_NOPERMISSION 2
static int pg_signal_backend(ThreadId pid, int sig) static int pg_signal_backend(ThreadId pid, int sig, bool checkPermission)
{ {
PGPROC* proc = NULL; PGPROC* proc = NULL;
if (!superuser()) { if (checkPermission && !superuser()) {
/* /*
* Since the user is not superuser, check for matching roles. Trust * Since the user is not superuser, check for matching roles. Trust
* that BackendPidGetProc will return NULL if the pid isn't valid, * that BackendPidGetProc will return NULL if the pid isn't valid,
@ -202,7 +202,7 @@ Datum pg_cancel_backend(PG_FUNCTION_ARGS)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("kill backend is prohibited during online expansion.")))); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("kill backend is prohibited during online expansion."))));
r = pg_signal_backend(tid, SIGINT); r = pg_signal_backend(tid, SIGINT, true);
if (r == SIGNAL_BACKEND_NOPERMISSION) if (r == SIGNAL_BACKEND_NOPERMISSION)
ereport(ERROR, ereport(ERROR,
@ -243,7 +243,7 @@ Datum pg_cancel_invalid_query(PG_FUNCTION_ARGS)
#endif #endif
} }
static int kill_backend(ThreadId tid) int kill_backend(ThreadId tid, bool checkPermission)
{ {
/* /*
* It is forbidden to kill backend in the online expansion to protect * It is forbidden to kill backend in the online expansion to protect
@ -253,17 +253,17 @@ static int kill_backend(ThreadId tid)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("kill backend is prohibited during online expansion.")))); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("kill backend is prohibited during online expansion."))));
int r = pg_signal_backend(tid, SIGTERM); int r = pg_signal_backend(tid, SIGTERM, checkPermission);
if (r == SIGNAL_BACKEND_NOPERMISSION) if (r == SIGNAL_BACKEND_NOPERMISSION)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be system admin or have the same role to terminate other backend")))); (errmsg("must be system admin or have the same role to terminate other backend"))));
#ifdef ENABLE_MULTIPLE_NODES
if (t_thrd.proc && t_thrd.proc->workingVersionNum >= 92060) { if (t_thrd.proc && t_thrd.proc->workingVersionNum >= 92060) {
uint64 query_id = get_query_id_beentry(tid); uint64 query_id = get_query_id_beentry(tid);
(void)gs_close_all_stream_by_debug_id(query_id); (void)gs_close_all_stream_by_debug_id(query_id);
} }
#endif
return r; return r;
} }
@ -274,7 +274,7 @@ static int kill_backend(ThreadId tid)
Datum pg_terminate_backend(PG_FUNCTION_ARGS) Datum pg_terminate_backend(PG_FUNCTION_ARGS)
{ {
ThreadId tid = PG_GETARG_INT64(0); ThreadId tid = PG_GETARG_INT64(0);
int r = kill_backend(tid); int r = kill_backend(tid, true);
PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
} }
@ -285,7 +285,7 @@ Datum pg_terminate_session(PG_FUNCTION_ARGS)
int r = -1; int r = -1;
if (tid == sid) { if (tid == sid) {
r = kill_backend(tid); r = kill_backend(tid, true);
} else if (ENABLE_THREAD_POOL) { } else if (ENABLE_THREAD_POOL) {
ThreadPoolSessControl *sess_ctrl = g_threadPoolControler->GetSessionCtrl(); ThreadPoolSessControl *sess_ctrl = g_threadPoolControler->GetSessionCtrl();
int ctrl_idx = sess_ctrl->FindCtrlIdxBySessId(sid); int ctrl_idx = sess_ctrl->FindCtrlIdxBySessId(sid);
@ -952,7 +952,7 @@ void cancel_backend(ThreadId pid)
{ {
int sig_return = 0; int sig_return = 0;
sig_return = pg_signal_backend(pid, SIGINT); sig_return = pg_signal_backend(pid, SIGINT, true);
if (sig_return == SIGNAL_BACKEND_NOPERMISSION) { if (sig_return == SIGNAL_BACKEND_NOPERMISSION) {
ereport(ERROR, ereport(ERROR,
@ -961,3 +961,15 @@ void cancel_backend(ThreadId pid)
errhint("fail to cancel backend process for privilege"))); errhint("fail to cancel backend process for privilege")));
} }
} }
Datum gs_clean_connection_by_memory(PG_FUNCTION_ARGS)
{
int targetMemory = PG_GETARG_INT32(0);
if (targetMemory < 0) {
targetMemory = 0;
}
CleanConnectionByMemory(targetMemory);
PG_RETURN_VOID();
}

View File

@ -7663,8 +7663,8 @@ Datum pg_buffercache_pages(PG_FUNCTION_ARGS)
fctx->tupdesc = BlessTupleDesc(tupledesc); fctx->tupdesc = BlessTupleDesc(tupledesc);
/* Allocate g_instance.attr.attr_storage.NBuffers worth of BufferCachePagesRec records. */ /* Allocate g_instance.attr.attr_storage.NBuffers worth of BufferCachePagesRec records. */
fctx->record = fctx->record = (BufferCachePagesRec *)palloc_huge(CurrentMemoryContext,
(BufferCachePagesRec*)palloc(sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers); sizeof(BufferCachePagesRec) * g_instance.attr.attr_storage.NBuffers);
/* Set max calls and remember the user function context. */ /* Set max calls and remember the user function context. */
funcctx->max_calls = g_instance.attr.attr_storage.NBuffers; funcctx->max_calls = g_instance.attr.attr_storage.NBuffers;
@ -8836,10 +8836,11 @@ Datum gs_total_nodegroup_memory_detail(PG_FUNCTION_ARGS)
SRF_RETURN_DONE(funcctx); SRF_RETURN_DONE(funcctx);
} }
#define MEMORY_TYPES_CNT 24 #define MEMORY_TYPES_CNT 25
const char* MemoryTypeName[] = {"max_process_memory", const char* MemoryTypeName[] = {"max_process_memory",
"process_used_memory", "process_used_memory",
"max_dynamic_memory", "max_dynamic_memory",
"min_dynamic_memory",
"dynamic_used_memory", "dynamic_used_memory",
"dynamic_peak_memory", "dynamic_peak_memory",
"dynamic_used_shrctx", "dynamic_used_shrctx",
@ -8933,63 +8934,67 @@ Datum pv_total_memory_detail(PG_FUNCTION_ARGS)
fclose(f); fclose(f);
} }
mem_size[0] = (int)(g_instance.attr.attr_memory.max_process_memory >> BITS_IN_KB); int index = -1;
mem_size[1] = (int)res; mem_size[++index] = (int)(g_instance.attr.attr_memory.max_process_memory >> BITS_IN_KB);
mem_size[2] = mctx_max_size; mem_size[++index] = (int)res;
mem_size[3] = mctx_used_size; mem_size[++index] = mctx_max_size;
if (MEMPROT_INIT_SIZE > mem_size[3]) mem_size[++index] = (int)(u_sess->attr.attr_memory.min_dynamic_memory >> BITS_IN_KB);
mem_size[3] = MEMPROT_INIT_SIZE; mem_size[++index] = mctx_used_size;
mem_size[4] = (int)(peakChunksPerProcess << (chunkSizeInBits - BITS_IN_MB)); if (MEMPROT_INIT_SIZE > mem_size[index])
mem_size[5] = (int)(shareTrackedMemChunks << (chunkSizeInBits - BITS_IN_MB)); mem_size[index] = MEMPROT_INIT_SIZE;
mem_size[6] = (int)(peakChunksSharedContext << (chunkSizeInBits - BITS_IN_MB)); mem_size[++index] = (int)(peakChunksPerProcess << (chunkSizeInBits - BITS_IN_MB));
mem_size[7] = (int)(backendReservedMemInChunk << (chunkSizeInBits - BITS_IN_MB)); mem_size[++index] = (int)(shareTrackedMemChunks << (chunkSizeInBits - BITS_IN_MB));
mem_size[8] = (int)(backendUsedMemInChunk << (chunkSizeInBits - BITS_IN_MB)); mem_size[++index] = (int)(peakChunksSharedContext << (chunkSizeInBits - BITS_IN_MB));
if (mem_size[8] < 0) { mem_size[++index] = (int)(backendReservedMemInChunk << (chunkSizeInBits - BITS_IN_MB));
mem_size[8] = 0; mem_size[++index] = (int)(backendUsedMemInChunk << (chunkSizeInBits - BITS_IN_MB));
if (mem_size[index] < 0) {
mem_size[index] = 0;
} }
mem_size[9] = maxSharedMemory; mem_size[++index] = maxSharedMemory;
mem_size[10] = shared; mem_size[++index] = shared;
mem_size[11] = (int)(g_instance.attr.attr_storage.cstore_buffers >> BITS_IN_KB); mem_size[++index] = (int)(g_instance.attr.attr_storage.cstore_buffers >> BITS_IN_KB);
mem_size[12] = cu_size; mem_size[++index] = cu_size;
if (comm_size) if (comm_size)
mem_size[13] = comm_original_memory; mem_size[++index] = comm_original_memory;
else else
mem_size[13] = 0; mem_size[++index] = 0;
mem_size[14] = comm_size; mem_size[++index] = comm_size;
mem_size[15] = comm_peak_size; mem_size[++index] = comm_peak_size;
/* other used memory */
mem_size[++index] = (int)(res - shared - text) - mctx_used_size - cu_size;
if (mem_size[index] < 0) // res may be changed
mem_size[index] = 0;
#ifdef ENABLE_MULTIPLE_NODES #ifdef ENABLE_MULTIPLE_NODES
if (is_searchserver_api_load()) { if (is_searchserver_api_load()) {
void* mem_info = get_searchlet_resource_info(&mem_size[18], &mem_size[19]); void* mem_info = get_searchlet_resource_info(&mem_size[index + 2], &mem_size[index + 3]);
if (mem_info != NULL) { if (mem_info != NULL) {
mem_size[17] = g_searchserver_memory; mem_size[index + 1] = g_searchserver_memory;
pfree_ext(mem_info); pfree_ext(mem_info);
} }
} }
#else index += 3;
mem_size[17] = 0;
#endif
mem_size[16] = (int)(res - shared - text) - mctx_used_size - cu_size - mem_size[16];
if (0 > mem_size[16]) // res may be changed
mem_size[16] = 0;
#ifdef ENABLE_MULTIPLE_NODES
PoolConnStat conn_stat; PoolConnStat conn_stat;
pooler_get_connection_statinfo(&conn_stat); pooler_get_connection_statinfo(&conn_stat);
mem_size[20] = (int)(conn_stat.memory_size >> BITS_IN_MB); mem_size[++index] = (int)(conn_stat.memory_size >> BITS_IN_MB);
mem_size[21] = (int)(conn_stat.free_memory_size >> BITS_IN_MB); mem_size[++index] = (int)(conn_stat.free_memory_size >> BITS_IN_MB);
#else #else
mem_size[20] = 0; mem_size[++index] = 0;
mem_size[21] = 0; mem_size[++index] = 0;
mem_size[++index] = 0;
mem_size[++index] = 0;
mem_size[++index] = 0;
#endif #endif
mem_size[22] = (int)(storageTrackedBytes >> BITS_IN_MB);
mem_size[++index] = (int)(storageTrackedBytes >> BITS_IN_MB);
Assert(g_instance.attr.attr_sql.udf_memory_limit >= UDF_DEFAULT_MEMORY); Assert(g_instance.attr.attr_sql.udf_memory_limit >= UDF_DEFAULT_MEMORY);
mem_size[23] = (int)((g_instance.attr.attr_sql.udf_memory_limit - UDF_DEFAULT_MEMORY) >> BITS_IN_KB); mem_size[++index] = (int)((g_instance.attr.attr_sql.udf_memory_limit - UDF_DEFAULT_MEMORY) >> BITS_IN_KB);
ereport(DEBUG2, (errmodule(MOD_LLVM), errmsg("LLVM IR file count is %ld, total memory is %ldKB", ereport(DEBUG2, (errmodule(MOD_LLVM), errmsg("LLVM IR file count is %ld, total memory is %ldKB",
g_instance.codegen_IRload_process_count, g_instance.codegen_IRload_process_count,
g_instance.codegen_IRload_process_count * IR_FILE_SIZE / 1024))); g_instance.codegen_IRload_process_count * IR_FILE_SIZE / 1024)));
Assert(index + 1 == MEMORY_TYPES_CNT);
} }
/* stuff done on every call of the function */ /* stuff done on every call of the function */

View File

@ -56,7 +56,7 @@ static Datum regprocin_booststrap(char* procname)
ScanKeyInit(&skey[0], Anum_pg_proc_proname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(procname)); ScanKeyInit(&skey[0], Anum_pg_proc_proname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(procname));
hdesc = heap_open(ProcedureRelationId, AccessShareLock); hdesc = heap_open(ProcedureRelationId, AccessShareLock);
sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndexId, true, SnapshotNow, 1, skey); sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
result = (RegProcedure)HeapTupleGetOid(tuple); result = (RegProcedure)HeapTupleGetOid(tuple);
@ -416,7 +416,7 @@ Datum regoperin(PG_FUNCTION_ARGS)
&skey[0], Anum_pg_operator_oprname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(opr_name_or_oid)); &skey[0], Anum_pg_operator_oprname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(opr_name_or_oid));
hdesc = heap_open(OperatorRelationId, AccessShareLock); hdesc = heap_open(OperatorRelationId, AccessShareLock);
sysscan = systable_beginscan(hdesc, OperatorNameNspIndexId, true, SnapshotNow, 1, skey); sysscan = systable_beginscan(hdesc, OperatorNameNspIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
result = HeapTupleGetOid(tuple); result = HeapTupleGetOid(tuple);
@ -730,7 +730,7 @@ Datum regclassin(PG_FUNCTION_ARGS)
&skey[0], Anum_pg_class_relname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(class_name_or_oid)); &skey[0], Anum_pg_class_relname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(class_name_or_oid));
hdesc = heap_open(RelationRelationId, AccessShareLock); hdesc = heap_open(RelationRelationId, AccessShareLock);
sysscan = systable_beginscan(hdesc, ClassNameNspIndexId, true, SnapshotNow, 1, skey); sysscan = systable_beginscan(hdesc, ClassNameNspIndexId, true, NULL, 1, skey);
if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
result = HeapTupleGetOid(tuple); result = HeapTupleGetOid(tuple);
@ -877,7 +877,7 @@ Datum regtypein(PG_FUNCTION_ARGS)
ScanKeyInit(&skey[0], Anum_pg_type_typname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(typ_name_or_oid)); ScanKeyInit(&skey[0], Anum_pg_type_typname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(typ_name_or_oid));
hdesc = heap_open(TypeRelationId, AccessShareLock); hdesc = heap_open(TypeRelationId, AccessShareLock);
sysscan = systable_beginscan(hdesc, TypeNameNspIndexId, true, SnapshotNow, 1, skey); sysscan = systable_beginscan(hdesc, TypeNameNspIndexId, true, NULL, 1, skey);
if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
result = HeapTupleGetOid(tuple); result = HeapTupleGetOid(tuple);

View File

@ -940,7 +940,7 @@ static void get_table_partitiondef(StringInfo query, StringInfo buf, Oid tableoi
ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind)); ScanKeyInit(&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind));
ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid)); ScanKeyInit(&key[1], Anum_pg_partition_parentid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
scan = systable_beginscan(relation, PartitionParentOidIndexId, true, SnapshotNow, 2, key); scan = systable_beginscan(relation, PartitionParentOidIndexId, true, NULL, 2, key);
while (HeapTupleIsValid((tuple = systable_getnext(scan)))) { while (HeapTupleIsValid((tuple = systable_getnext(scan)))) {
int2vector* partVec = NULL; int2vector* partVec = NULL;
Datum datum = SysCacheGetAttr(PARTRELID, tuple, Anum_pg_partition_partkey, &isnull); Datum datum = SysCacheGetAttr(PARTRELID, tuple, Anum_pg_partition_partkey, &isnull);
@ -1208,7 +1208,7 @@ static int get_table_attribute(
ScanKeyInit( ScanKeyInit(
&skey[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid)); &skey[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
adscan = systable_beginscan(attrdefDesc, AttrDefaultIndexId, true, SnapshotNow, 1, skey); adscan = systable_beginscan(attrdefDesc, AttrDefaultIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tup = systable_getnext(adscan))) { while (HeapTupleIsValid(tup = systable_getnext(adscan))) {
attrdef = (Form_pg_attrdef)GETSTRUCT(tup); attrdef = (Form_pg_attrdef)GETSTRUCT(tup);
@ -1252,7 +1252,7 @@ char* printDistributeKey(Oid relOid)
ScanKeyInit(&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid)); ScanKeyInit(&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid));
pcrel = heap_open(PgxcClassRelationId, AccessShareLock); pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey); pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
htup = systable_getnext(pcscan); htup = systable_getnext(pcscan);
if (!HeapTupleIsValid(htup)) { if (!HeapTupleIsValid(htup)) {
@ -1551,7 +1551,7 @@ static void get_foreign_constraint_info(StringInfo buf, Oid tableoid, const char
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid)); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -1606,7 +1606,7 @@ static void get_index_list_info(Oid tableoid, StringInfo buf, const char* relnam
ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid)); ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
indrel = heap_open(IndexRelationId, AccessShareLock); indrel = heap_open(IndexRelationId, AccessShareLock);
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey); indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey);
while (HeapTupleIsValid(htup = systable_getnext(indscan))) { while (HeapTupleIsValid(htup = systable_getnext(indscan))) {
Form_pg_index index = (Form_pg_index)GETSTRUCT(htup); Form_pg_index index = (Form_pg_index)GETSTRUCT(htup);
@ -1899,7 +1899,7 @@ static void get_table_alter_info(
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid)); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -2187,7 +2187,7 @@ static char* pg_get_tabledef_worker(Oid tableoid)
ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid)); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableoid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple); Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tuple);
@ -2319,7 +2319,7 @@ static char* pg_get_triggerdef_worker(Oid trigid, bool pretty)
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(trigid)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(trigid));
tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true, SnapshotNow, 1, skey); tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true, NULL, 1, skey);
ht_trig = systable_getnext(tgscan); ht_trig = systable_getnext(tgscan);
@ -3441,7 +3441,7 @@ Datum pg_get_serial_sequence(PG_FUNCTION_ARGS)
ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableOid)); ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableOid));
ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(attnum)); ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(attnum));
scan = systable_beginscan(depRel, DependReferenceIndexId, true, SnapshotNow, 3, key); scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 3, key);
while (HeapTupleIsValid(tup = systable_getnext(scan))) { while (HeapTupleIsValid(tup = systable_getnext(scan))) {
Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup); Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
@ -11136,7 +11136,7 @@ Datum getDistributeKey(PG_FUNCTION_ARGS)
ScanKeyInit(&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid)); ScanKeyInit(&skey, Anum_pgxc_class_pcrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid));
pcrel = heap_open(PgxcClassRelationId, AccessShareLock); pcrel = heap_open(PgxcClassRelationId, AccessShareLock);
pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, SnapshotNow, 1, &skey); pcscan = systable_beginscan(pcrel, PgxcClassPgxcRelIdIndexId, true, NULL, 1, &skey);
htup = systable_getnext(pcscan); htup = systable_getnext(pcscan);
if (!HeapTupleIsValid(htup)) { if (!HeapTupleIsValid(htup)) {

View File

@ -139,6 +139,7 @@
#include "utils/bytea.h" #include "utils/bytea.h"
#include "utils/date.h" #include "utils/date.h"
#include "utils/datum.h" #include "utils/datum.h"
#include "utils/expr_distinct.h"
#include "utils/extended_statistics.h" #include "utils/extended_statistics.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
@ -193,7 +194,7 @@ static Const* string_to_bytea_const(const char* str, size_t str_len);
static List* specialExpr_group_num(PlannerInfo* root, List* nodeList, double* numdistinct, double rows); static List* specialExpr_group_num(PlannerInfo* root, List* nodeList, double* numdistinct, double rows);
static List* add_unique_group_var( static List* add_unique_group_var(
PlannerInfo* root, List* varinfos, Node* var, VariableStatData* vardata, STATS_EST_TYPE eType = STATS_TYPE_LOCAL); PlannerInfo* root, List* varinfos, Node* var, VariableStatData* vardata, STATS_EST_TYPE eType = STATS_TYPE_LOCAL);
static double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo); extern double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo);
bool can_use_possion(VariableStatData* vardata, SpecialJoinInfo* sjinfo, double* ratio); bool can_use_possion(VariableStatData* vardata, SpecialJoinInfo* sjinfo, double* ratio);
extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS); extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS);
extern List* find_skew_join_distribute_keys(Plan* plan); extern List* find_skew_join_distribute_keys(Plan* plan);
@ -2275,9 +2276,9 @@ static double eqjoinsel_inner(
double relfrac1 = 1.0, relfrac2 = 1.0, relfrac; double relfrac1 = 1.0, relfrac2 = 1.0, relfrac;
nd1 = get_variable_numdistinct( nd1 = get_variable_numdistinct(
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL); vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
nd2 = get_variable_numdistinct( nd2 = get_variable_numdistinct(
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL); vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
opfuncoid = get_opcode(opera); opfuncoid = get_opcode(opera);
if (HeapTupleIsValid(vardata1->statsTuple)) { if (HeapTupleIsValid(vardata1->statsTuple)) {
@ -2655,9 +2656,9 @@ static double eqjoinsel_semi(
Oid opfuncoid = OidIsValid(opera) ? get_opcode(opera) : InvalidOid; Oid opfuncoid = OidIsValid(opera) ? get_opcode(opera) : InvalidOid;
nd1 = get_variable_numdistinct( nd1 = get_variable_numdistinct(
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL); vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
nd2 = get_variable_numdistinct( nd2 = get_variable_numdistinct(
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL); vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
/* /*
* We clamp nd2 to be not more than what we estimate the inner relation's * We clamp nd2 to be not more than what we estimate the inner relation's
* size to be. This is intuitively somewhat reasonable since obviously * size to be. This is intuitively somewhat reasonable since obviously
@ -2861,9 +2862,9 @@ static double neqjoinsel_semi(
nullfrac1 = stats1 ? stats1->stanullfrac : 0.0; nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
nd1 = get_variable_numdistinct( nd1 = get_variable_numdistinct(
vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL); vardata1, &isdefault1, true, get_join_ratio(vardata1, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
nd2 = get_variable_numdistinct( nd2 = get_variable_numdistinct(
vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL); vardata2, &isdefault2, true, get_join_ratio(vardata2, sjinfo), sjinfo, STATS_TYPE_GLOBAL, true);
/* /*
* When one of the sides contains zero distinct values, the selectivity is zero; * When one of the sides contains zero distinct values, the selectivity is zero;
@ -4550,6 +4551,8 @@ void examine_variable(PlannerInfo* root, Node* node, int varRelid, VariableStatD
errno_t rc = memset_s(vardata, sizeof(VariableStatData), 0, sizeof(VariableStatData)); errno_t rc = memset_s(vardata, sizeof(VariableStatData), 0, sizeof(VariableStatData));
securec_check(rc, "\0", "\0"); securec_check(rc, "\0", "\0");
vardata->root = root;
/* we enable possion to estimate distinct for default. */ /* we enable possion to estimate distinct for default. */
vardata->enablePossion = true; vardata->enablePossion = true;
/* Save the exposed type of the expression */ /* Save the exposed type of the expression */
@ -4980,7 +4983,7 @@ statistic_proc_security_check(const VariableStatData *vardata, Oid func_oid)
* compare the result to exact integer counts, or might divide by it. * compare the result to exact integer counts, or might divide by it.
*/ */
double get_variable_numdistinct(VariableStatData* vardata, bool* isdefault, bool adjust_rows, double join_ratio, double get_variable_numdistinct(VariableStatData* vardata, bool* isdefault, bool adjust_rows, double join_ratio,
SpecialJoinInfo* sjinfo, STATS_EST_TYPE eType) SpecialJoinInfo* sjinfo, STATS_EST_TYPE eType, bool isJoinVar)
{ {
double stadistinct; double stadistinct;
double stanullfrac = 0.0; double stanullfrac = 0.0;
@ -5067,6 +5070,19 @@ double get_variable_numdistinct(VariableStatData* vardata, bool* isdefault, bool
if (vardata->isunique) if (vardata->isunique)
stadistinct = -1.0 * (1.0 - stanullfrac); stadistinct = -1.0 * (1.0 - stanullfrac);
/*
* If no stats, try to get the estimation
*/
if (ENABLE_SQL_BETA_FEATURE(JOIN_SEL_WITH_CAST_FUNC) && !HeapTupleIsValid(vardata->statsTuple) &&
stadistinct == 0.0) {
stadistinct = GetExprNumDistinctRouter(vardata, adjust_rows, eType, isJoinVar);
if (stadistinct > 0.0) {
ereport(DEBUG2, (errmodule(MOD_OPT),
errmsg("[Get Variable Distinct]: direct distinct is %.0lf by router, early return", stadistinct)));
return clamp_row_est(stadistinct);
}
}
/* /*
* Otherwise we need to get the relation size; punt if not available. * Otherwise we need to get the relation size; punt if not available.
*/ */
@ -6502,7 +6518,8 @@ static void genericcostestimate(PlannerInfo* root, IndexPath* path, double loop_
* enough to not alter index-vs-seqscan decisions, but will prevent * enough to not alter index-vs-seqscan decisions, but will prevent
* indexes of different sizes from looking exactly equally attractive. * indexes of different sizes from looking exactly equally attractive.
*/ */
*indexTotalCost += index->pages * spc_random_page_cost / 100000.0; if (ENABLE_SQL_BETA_FEATURE(INDEX_COST_WITH_LEAF_PAGES_ONLY))
*indexTotalCost += index->pages * spc_random_page_cost / 100000.0;
/* /*
* CPU cost: any complex expressions in the indexquals will need to be * CPU cost: any complex expressions in the indexquals will need to be
@ -8697,7 +8714,7 @@ void set_varratio_after_calc_selectivity(
* Return: * Return:
* minimum join ratio with specific relation * minimum join ratio with specific relation
*/ */
static double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo) double get_join_ratio(VariableStatData* vardata, SpecialJoinInfo* sjinfo)
{ {
double ratio = 1.0; double ratio = 1.0;
ListCell* lc = NULL; ListCell* lc = NULL;

View File

@ -1575,7 +1575,7 @@ static HeapTuple SearchCatCacheMiss(
ereport(DEBUG1, (errmsg("cache->cc_reloid - %d", cache->cc_reloid))); ereport(DEBUG1, (errmsg("cache->cc_reloid - %d", cache->cc_reloid)));
scandesc = systable_beginscan( scandesc = systable_beginscan(
relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), SnapshotNow, nkeys, cur_skey); relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), NULL, nkeys, cur_skey);
while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) { while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) {
ct = CatalogCacheCreateEntry(cache, ntp, arguments, hashValue, hashIndex, false); ct = CatalogCacheCreateEntry(cache, ntp, arguments, hashValue, hashIndex, false);
@ -2452,7 +2452,7 @@ CatCList* SearchCatCacheList(CatCache* cache, int nkeys, Datum v1, Datum v2, Dat
relation = heap_open(cache->cc_reloid, AccessShareLock); relation = heap_open(cache->cc_reloid, AccessShareLock);
scandesc = systable_beginscan( scandesc = systable_beginscan(
relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), SnapshotNow, nkeys, cur_skey); relation, cache->cc_indexoid, IndexScanOK(cache, cur_skey), NULL, nkeys, cur_skey);
/* The list will be ordered iff we are doing an index scan */ /* The list will be ordered iff we are doing an index scan */
ordered = (scandesc->irel != NULL); ordered = (scandesc->irel != NULL);

View File

@ -101,6 +101,7 @@
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "commands/prepare.h" #include "commands/prepare.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "storage/sinval.h" #include "storage/sinval.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/inval.h" #include "utils/inval.h"
@ -561,7 +562,11 @@ void LocalExecuteInvalidationMessage(SharedInvalidationMessage* msg)
if (ENABLE_GPC) { if (ENABLE_GPC) {
bool check = GlobalPlanCache::MsgCheck(msg); bool check = GlobalPlanCache::MsgCheck(msg);
#ifdef ENABLE_MULTIPLE_NODES
if (check == true && u_sess->pcache_cxt.gpc_remote_msg == false) { if (check == true && u_sess->pcache_cxt.gpc_remote_msg == false) {
#else
if (check == true && (u_sess->pcache_cxt.gpc_remote_msg == false || pmState == PM_HOT_STANDBY)) {
#endif
u_sess->pcache_cxt.gpc_in_ddl = true; u_sess->pcache_cxt.gpc_in_ddl = true;
} }
} }

View File

@ -3341,7 +3341,7 @@ static List* GetAllSliceTuples(Relation pgxcSliceRel, Oid tableOid)
F_OIDEQ, ObjectIdGetDatum(tableOid)); F_OIDEQ, ObjectIdGetDatum(tableOid));
ScanKeyInit(&skey[1], Anum_pgxc_slice_type, BTEqualStrategyNumber, ScanKeyInit(&skey[1], Anum_pgxc_slice_type, BTEqualStrategyNumber,
F_CHAREQ, CharGetDatum(PGXC_SLICE_TYPE_SLICE)); F_CHAREQ, CharGetDatum(PGXC_SLICE_TYPE_SLICE));
sliceScan = systable_beginscan(pgxcSliceRel, PgxcSliceOrderIndexId, true, SnapshotNow, 2, skey); sliceScan = systable_beginscan(pgxcSliceRel, PgxcSliceOrderIndexId, true, NULL, 2, skey);
while (HeapTupleIsValid((htup = systable_getnext(sliceScan)))) { while (HeapTupleIsValid((htup = systable_getnext(sliceScan)))) {
dtup = heap_copytuple(htup); dtup = heap_copytuple(htup);
sliceList = lappend(sliceList, dtup); sliceList = lappend(sliceList, dtup);

View File

@ -149,6 +149,10 @@ static HeapTuple ScanPgPartition(Oid targetPartId, bool indexOK, Snapshot snapsh
(errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("cannot read pg_class without having selected a database"))); (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("cannot read pg_class without having selected a database")));
} }
if (snapshot == NULL) {
snapshot = GetCatalogSnapshot();
}
/* /*
* form a scan key * form a scan key
*/ */
@ -237,7 +241,7 @@ static Partition PartitionBuildDesc(Oid targetPartId, bool insertIt, bool isbukc
/* /*
* find the tuple in pg_class corresponding to the given relation id * find the tuple in pg_class corresponding to the given relation id
*/ */
pg_partition_tuple = ScanPgPartition(targetPartId, true, SnapshotNow); pg_partition_tuple = ScanPgPartition(targetPartId, true, NULL);
/* /*
* if no such tuple exists, return NULL * if no such tuple exists, return NULL
*/ */
@ -378,7 +382,7 @@ Partition PartitionIdGetPartition(Oid partitionId, bool isbucket)
char* PartitionOidGetName(Oid partOid) char* PartitionOidGetName(Oid partOid)
{ {
HeapTuple tuple = ScanPgPartition(partOid, true, SnapshotNow); HeapTuple tuple = ScanPgPartition(partOid, true, NULL);
if (!HeapTupleIsValid(tuple)) { if (!HeapTupleIsValid(tuple)) {
return NULL; return NULL;
} }
@ -394,7 +398,7 @@ char* PartitionOidGetName(Oid partOid)
Oid PartitionOidGetTablespace(Oid partOid) Oid PartitionOidGetTablespace(Oid partOid)
{ {
HeapTuple tuple = ScanPgPartition(partOid, true, SnapshotNow); HeapTuple tuple = ScanPgPartition(partOid, true, NULL);
if (!HeapTupleIsValid(tuple)) { if (!HeapTupleIsValid(tuple)) {
return InvalidOid; return InvalidOid;
} }
@ -1333,7 +1337,7 @@ static void PartitionReloadIndexInfo(Partition part)
*/ */
Assert(NULL == part->pd_smgr); Assert(NULL == part->pd_smgr);
pg_partition_tuple = ScanPgPartition(PartitionGetPartid(part), true, SnapshotNow); pg_partition_tuple = ScanPgPartition(PartitionGetPartid(part), true, NULL);
if (!HeapTupleIsValid(pg_partition_tuple)) { if (!HeapTupleIsValid(pg_partition_tuple)) {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_NO_DATA), (errcode(ERRCODE_NO_DATA),
@ -1822,6 +1826,28 @@ bool PartitionInvisibleMetadataKeep(Datum datumRelOptions)
return ret; return ret;
} }
/* Check whether a partition is properly used. */
bool PartitionParentOidIsLive(Datum parentDatum)
{
Oid parentid = InvalidOid;
HeapTuple partTuple = NULL;
if (!PointerIsValid(parentDatum)) {
return false;
}
parentid = DatumGetObjectId(parentDatum);
/* Get table information from syscache */
partTuple = SearchSysCache1WithLogLevel(RELOID, ObjectIdGetDatum(parentid), LOG);
if (HeapTupleIsValid(partTuple)) {
ReleaseSysCache(partTuple);
return true;
}
return false;
}
/* /*
* In pg_partition, search all tuples (visible and invisible) containing wait_clean_gpi=y * In pg_partition, search all tuples (visible and invisible) containing wait_clean_gpi=y
* in reloptios of one partitioed relation and set wait_clean_gpi=n * in reloptios of one partitioed relation and set wait_clean_gpi=n
@ -2008,7 +2034,7 @@ bool PartitionMetadataDisabledClean(Relation pgPartition)
&key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(PART_OBJ_TYPE_PARTED_TABLE)); &key[0], Anum_pg_partition_parttype, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(PART_OBJ_TYPE_PARTED_TABLE));
partTupdesc = RelationGetDescr(pgPartition); partTupdesc = RelationGetDescr(pgPartition);
scan = systable_beginscan(pgPartition, PartitionParentOidIndexId, true, SnapshotNow, 1, key); scan = systable_beginscan(pgPartition, PartitionParentOidIndexId, true, NULL, 1, key);
while (HeapTupleIsValid(tuple = systable_getnext(scan))) { while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
bool isNull = false; bool isNull = false;
Datum partOptions = fastgetattr(tuple, Anum_pg_partition_reloptions, partTupdesc, &isNull); Datum partOptions = fastgetattr(tuple, Anum_pg_partition_reloptions, partTupdesc, &isNull);

View File

@ -103,8 +103,6 @@ static bool ChooseCustomPlan(CachedPlanSource* plansource, ParamListInfo boundPa
static bool IsForceCustomplan(CachedPlanSource *plansource); static bool IsForceCustomplan(CachedPlanSource *plansource);
static bool IsDeleteLimit(CachedPlanSource* plansource, ParamListInfo boundParams); static bool IsDeleteLimit(CachedPlanSource* plansource, ParamListInfo boundParams);
static double cached_plan_cost(CachedPlan* plan); static double cached_plan_cost(CachedPlan* plan);
static void AcquireExecutorLocks(List* stmt_list, bool acquire);
static void AcquirePlannerLocks(List* stmt_list, bool acquire);
static void ScanQueryForLocks(Query* parsetree, bool acquire); static void ScanQueryForLocks(Query* parsetree, bool acquire);
static bool ScanQueryWalker(Node* node, bool* acquire); static bool ScanQueryWalker(Node* node, bool* acquire);
static TupleDesc PlanCacheComputeResultDesc(List* stmt_list); static TupleDesc PlanCacheComputeResultDesc(List* stmt_list);
@ -139,6 +137,25 @@ void InitPlanCache(void)
CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum)0); CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum)0);
} }
/* ddl no need to global it */
static bool IsSupportGPCStmt(const Node* node)
{
bool isSupportGPC = false;
switch (nodeTag(node)) {
case T_InsertStmt:
case T_DeleteStmt:
case T_UpdateStmt:
case T_MergeStmt:
case T_SelectStmt:
isSupportGPC = false;
break;
default:
isSupportGPC = true;
break;
}
return isSupportGPC;
}
/* /*
* CreateCachedPlan: initially create a plan cache entry. * CreateCachedPlan: initially create a plan cache entry.
* *
@ -174,15 +191,8 @@ CachedPlanSource* CreateCachedPlan(Node* raw_parse_tree, const char* query_strin
MemoryContext oldcxt; MemoryContext oldcxt;
Assert(query_string != NULL); /* required as of 8.4 */ Assert(query_string != NULL); /* required as of 8.4 */
bool enable_pbe_gpc = false; bool isSupportGPC = raw_parse_tree && IsSupportGPCStmt(raw_parse_tree);
if (stmt_name != NULL && stmt_name[0] != '\0') { bool enable_pbe_gpc = ENABLE_GPC && stmt_name != NULL && stmt_name[0] != '\0' && !isSupportGPC;
#ifdef ENABLE_MULTIPLE_NODES
/* TransactionStmt do not support shared plan */
enable_pbe_gpc = (ENABLE_CN_GPC && raw_parse_tree && !IsA(raw_parse_tree, TransactionStmt)) || ENABLE_DN_GPC;
#else
enable_pbe_gpc = ENABLE_GPC && raw_parse_tree && !IsA(raw_parse_tree, TransactionStmt);
#endif
}
if(!enable_pbe_gpc && !(ENABLE_CN_GPC && enable_spi_gpc)) { if(!enable_pbe_gpc && !(ENABLE_CN_GPC && enable_spi_gpc)) {
/* /*
@ -710,10 +720,9 @@ List* RevalidateCachedQuery(CachedPlanSource* plansource, bool has_lp)
Assert(plansource->is_valid); Assert(plansource->is_valid);
return NIL; return NIL;
} }
/* if is shared plan, we should acquire plan lock for this transaction */ /* if is shared plan, we should acquire plan lock before check recreate plan */
if (plansource->gpc.status.InShareTable()) { if (plansource->gpc.status.InShareTable()) {
Assert(plansource->is_valid); Assert(plansource->is_valid);
AcquirePlannerLocks(plansource->query_list, true);
return NIL; return NIL;
} }
/* /*
@ -1947,18 +1956,20 @@ CachedPlanSource* CopyCachedPlan(CachedPlanSource* plansource, bool is_share)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot copy a one-shot cached plan"))); ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot copy a one-shot cached plan")));
if (ENABLE_GPC && is_share == true) { if (ENABLE_GPC && is_share == true) {
source_context = AllocSetContextCreate(GLOBAL_PLANCACHE_MEMCONTEXT, source_context = AllocSetContextCreate(GLOBAL_PLANCACHE_MEMCONTEXT,
"GPCCachedPlanSource", "GPCCachedPlanSource",
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_MINSIZE,
ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MAXSIZE,
SHARED_CONTEXT); SHARED_CONTEXT);
ResourceOwnerEnlargeGMemContext(t_thrd.utils_cxt.TopTransactionResourceOwner);
ResourceOwnerRememberGMemContext(t_thrd.utils_cxt.TopTransactionResourceOwner, source_context);
} else { } else {
source_context = AllocSetContextCreate(u_sess->cache_mem_cxt, source_context = AllocSetContextCreate(u_sess->cache_mem_cxt,
"CachedPlanSource", "CachedPlanSource",
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_MINSIZE,
ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE); ALLOCSET_DEFAULT_MAXSIZE);
} }
@ -1992,19 +2003,19 @@ CachedPlanSource* CopyCachedPlan(CachedPlanSource* plansource, bool is_share)
newsource->context = source_context; newsource->context = source_context;
if (ENABLE_GPC && is_share == true) { if (ENABLE_GPC && is_share == true) {
querytree_context = AllocSetContextCreate(source_context, querytree_context = AllocSetContextCreate(source_context,
"GPCCachedPlanQuery", "GPCCachedPlanQuery",
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_MINSIZE,
ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MAXSIZE,
SHARED_CONTEXT); SHARED_CONTEXT);
} }
else { else {
querytree_context = AllocSetContextCreate(source_context, querytree_context = AllocSetContextCreate(source_context,
"CachedPlanQuery", "CachedPlanQuery",
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_MINSIZE,
ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE); ALLOCSET_DEFAULT_MAXSIZE);
} }
MemoryContextSwitchTo(querytree_context); MemoryContextSwitchTo(querytree_context);
newsource->query_list = (List*)copyObject(plansource->query_list); newsource->query_list = (List*)copyObject(plansource->query_list);
@ -2030,6 +2041,7 @@ CachedPlanSource* CopyCachedPlan(CachedPlanSource* plansource, bool is_share)
newsource->opFusionObj = NULL; newsource->opFusionObj = NULL;
newsource->is_checked_opfusion = false; newsource->is_checked_opfusion = false;
newsource->spi_signature = plansource->spi_signature; newsource->spi_signature = plansource->spi_signature;
newsource->gplan_is_fqs = plansource->gplan_is_fqs;
#ifdef ENABLE_MOT #ifdef ENABLE_MOT
newsource->storageEngineType = SE_TYPE_UNSPECIFIED; newsource->storageEngineType = SE_TYPE_UNSPECIFIED;
@ -2101,7 +2113,7 @@ List* CachedPlanGetTargetList(CachedPlanSource* plansource)
* AcquireExecutorLocks: acquire locks needed for execution of a cached plan; * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
* or release them if acquire is false. * or release them if acquire is false.
*/ */
static void AcquireExecutorLocks(List* stmt_list, bool acquire) void AcquireExecutorLocks(List* stmt_list, bool acquire)
{ {
ListCell* lc1 = NULL; ListCell* lc1 = NULL;
@ -2167,7 +2179,7 @@ static void AcquireExecutorLocks(List* stmt_list, bool acquire)
* fail if one has been dropped entirely --- we'll just transiently acquire * fail if one has been dropped entirely --- we'll just transiently acquire
* a non-conflicting lock. * a non-conflicting lock.
*/ */
static void AcquirePlannerLocks(List* stmt_list, bool acquire) void AcquirePlannerLocks(List* stmt_list, bool acquire)
{ {
ListCell* lc = NULL; ListCell* lc = NULL;
@ -2660,12 +2672,13 @@ void DropCachedPlanInternal(CachedPlanSource* plansource)
} }
plansource->lightProxyObj = NULL; plansource->lightProxyObj = NULL;
} else { } else {
if (plansource->opFusionObj != NULL) { if (!plansource->gpc.status.InShareTable() && plansource->opFusionObj != NULL) {
OpFusion *opfusion = (OpFusion *)plansource->opFusionObj; OpFusion *opfusion = (OpFusion *)plansource->opFusionObj;
if (opfusion->m_portalName == NULL || OpFusion::locateFusion(opfusion->m_portalName) == NULL) { if (opfusion->m_local.m_portalName == NULL ||
OpFusion::locateFusion(opfusion->m_local.m_portalName) == NULL) {
OpFusion::tearDown(opfusion); OpFusion::tearDown(opfusion);
} else { } else {
opfusion->m_psrc = NULL; opfusion->m_global->m_psrc = NULL;
} }
plansource->opFusionObj = NULL; plansource->opFusionObj = NULL;
} }

View File

@ -1205,11 +1205,14 @@ HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
pg_class_desc = heap_open(RelationRelationId, AccessShareLock); pg_class_desc = heap_open(RelationRelationId, AccessShareLock);
/* /*
* for logical decoding * The caller might need a tuple that's newer than the one the historic
* snapshot; currently the only case requiring to do so is looking up the
* relfilenode of non mapped system relations during decoding.
*/ */
snapshot = SnapshotNow; snapshot = SnapshotNow;
if (HistoricSnapshotActive()) if (HistoricSnapshotActive() && !force_non_historic) {
snapshot = GetCatalogSnapshot(RelationRelationId); snapshot = GetCatalogSnapshot();
}
/* /*
* The caller might need a tuple that's newer than the one the historic * The caller might need a tuple that's newer than the one the historic
@ -1389,6 +1392,15 @@ static void RelationBuildTupleDesc(Relation relation, bool onlyLoadInitDefVal)
ObjectIdGetDatum(RelationGetRelid(relation))); ObjectIdGetDatum(RelationGetRelid(relation)));
ScanKeyInit(&skey[1], Anum_pg_attribute_attnum, BTGreaterStrategyNumber, F_INT2GT, Int16GetDatum(0)); ScanKeyInit(&skey[1], Anum_pg_attribute_attnum, BTGreaterStrategyNumber, F_INT2GT, Int16GetDatum(0));
/*
* Using historical snapshot in logic decoding.
*/
Snapshot snapshot = NULL;
snapshot = SnapshotNow;
if (HistoricSnapshotActive()) {
snapshot = GetCatalogSnapshot();
}
/* /*
* Open pg_attribute and begin a scan. Force heap scan if we haven't yet * Open pg_attribute and begin a scan. Force heap scan if we haven't yet
* built the critical relcache entries (this includes initdb and startup * built the critical relcache entries (this includes initdb and startup
@ -1396,7 +1408,7 @@ static void RelationBuildTupleDesc(Relation relation, bool onlyLoadInitDefVal)
*/ */
pg_attribute_desc = heap_open(AttributeRelationId, AccessShareLock); pg_attribute_desc = heap_open(AttributeRelationId, AccessShareLock);
pg_attribute_scan = systable_beginscan( pg_attribute_scan = systable_beginscan(
pg_attribute_desc, AttributeRelidNumIndexId, u_sess->relcache_cxt.criticalRelcachesBuilt, SnapshotNow, 2, skey); pg_attribute_desc, AttributeRelidNumIndexId, u_sess->relcache_cxt.criticalRelcachesBuilt, snapshot, 2, skey);
/* /*
* add attribute data to relation->rd_att * add attribute data to relation->rd_att
@ -1651,7 +1663,7 @@ static void RelationBuildRuleLock(Relation relation)
*/ */
rewrite_desc = heap_open(RewriteRelationId, AccessShareLock); rewrite_desc = heap_open(RewriteRelationId, AccessShareLock);
rewrite_tupdesc = RelationGetDescr(rewrite_desc); rewrite_tupdesc = RelationGetDescr(rewrite_desc);
rewrite_scan = systable_beginscan(rewrite_desc, RewriteRelRulenameIndexId, true, SnapshotNow, 1, &key); rewrite_scan = systable_beginscan(rewrite_desc, RewriteRelRulenameIndexId, true, NULL, 1, &key);
while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan))) { while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan))) {
Form_pg_rewrite rewrite_form = (Form_pg_rewrite)GETSTRUCT(rewrite_tuple); Form_pg_rewrite rewrite_form = (Form_pg_rewrite)GETSTRUCT(rewrite_tuple);
@ -2619,7 +2631,7 @@ static OpClassCacheEnt* LookupOpclassInfo(Oid operatorClassOid, StrategyNumber n
*/ */
ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(operatorClassOid)); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(operatorClassOid));
rel = heap_open(OperatorClassRelationId, AccessShareLock); rel = heap_open(OperatorClassRelationId, AccessShareLock);
scan = systable_beginscan(rel, OpclassOidIndexId, indexOK, SnapshotNow, 1, skey); scan = systable_beginscan(rel, OpclassOidIndexId, indexOK, NULL, 1, skey);
if (HeapTupleIsValid(htup = systable_getnext(scan))) { if (HeapTupleIsValid(htup = systable_getnext(scan))) {
Form_pg_opclass opclassform = (Form_pg_opclass)GETSTRUCT(htup); Form_pg_opclass opclassform = (Form_pg_opclass)GETSTRUCT(htup);
@ -2655,7 +2667,7 @@ static OpClassCacheEnt* LookupOpclassInfo(Oid operatorClassOid, StrategyNumber n
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(opcentry->opcintype)); ObjectIdGetDatum(opcentry->opcintype));
rel = heap_open(AccessMethodProcedureRelationId, AccessShareLock); rel = heap_open(AccessMethodProcedureRelationId, AccessShareLock);
scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK, SnapshotNow, 3, skey); scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK, NULL, 3, skey);
while (HeapTupleIsValid(htup = systable_getnext(scan))) { while (HeapTupleIsValid(htup = systable_getnext(scan))) {
Form_pg_amproc amprocform = (Form_pg_amproc)GETSTRUCT(htup); Form_pg_amproc amprocform = (Form_pg_amproc)GETSTRUCT(htup);
@ -5022,7 +5034,7 @@ static void AttrDefaultFetch(Relation relation)
&skey, Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); &skey, Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation)));
adrel = heap_open(AttrDefaultRelationId, AccessShareLock); adrel = heap_open(AttrDefaultRelationId, AccessShareLock);
adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, SnapshotNow, 1, &skey); adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 1, &skey);
found = 0; found = 0;
while (HeapTupleIsValid(htup = systable_getnext(adscan))) { while (HeapTupleIsValid(htup = systable_getnext(adscan))) {
@ -5087,7 +5099,7 @@ static void CheckConstraintFetch(Relation relation)
ObjectIdGetDatum(RelationGetRelid(relation))); ObjectIdGetDatum(RelationGetRelid(relation)));
conrel = heap_open(ConstraintRelationId, AccessShareLock); conrel = heap_open(ConstraintRelationId, AccessShareLock);
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(htup = systable_getnext(conscan))) { while (HeapTupleIsValid(htup = systable_getnext(conscan))) {
Form_pg_constraint conform = (Form_pg_constraint)GETSTRUCT(htup); Form_pg_constraint conform = (Form_pg_constraint)GETSTRUCT(htup);
@ -5251,7 +5263,7 @@ List* RelationGetIndexList(Relation relation)
&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); &skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation)));
indrel = heap_open(IndexRelationId, AccessShareLock); indrel = heap_open(IndexRelationId, AccessShareLock);
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey); indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey);
while (HeapTupleIsValid(htup = systable_getnext(indscan))) { while (HeapTupleIsValid(htup = systable_getnext(indscan))) {
Form_pg_index index = (Form_pg_index)GETSTRUCT(htup); Form_pg_index index = (Form_pg_index)GETSTRUCT(htup);
@ -5413,7 +5425,7 @@ int RelationGetIndexNum(Relation relation)
&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); &skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation)));
indrel = heap_open(IndexRelationId, AccessShareLock); indrel = heap_open(IndexRelationId, AccessShareLock);
indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, SnapshotNow, 1, &skey); indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey);
while (HeapTupleIsValid(htup = systable_getnext(indscan))) { while (HeapTupleIsValid(htup = systable_getnext(indscan))) {
Form_pg_index index = (Form_pg_index)GETSTRUCT(htup); Form_pg_index index = (Form_pg_index)GETSTRUCT(htup);
@ -5776,7 +5788,7 @@ static void ClusterConstraintFetch(__inout Relation relation)
ObjectIdGetDatum(RelationGetRelid(relation))); ObjectIdGetDatum(RelationGetRelid(relation)));
conrel = heap_open(ConstraintRelationId, AccessShareLock); conrel = heap_open(ConstraintRelationId, AccessShareLock);
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, NULL, 1, skey);
while (HeapTupleIsValid(htup = systable_getnext(conscan))) { while (HeapTupleIsValid(htup = systable_getnext(conscan))) {
Form_pg_constraint conform = (Form_pg_constraint)GETSTRUCT(htup); Form_pg_constraint conform = (Form_pg_constraint)GETSTRUCT(htup);
@ -6012,7 +6024,7 @@ void RelationGetExclusionInfo(Relation indexRelation, Oid** operators, Oid** pro
ObjectIdGetDatum(indexRelation->rd_index->indrelid)); ObjectIdGetDatum(indexRelation->rd_index->indrelid));
conrel = heap_open(ConstraintRelationId, AccessShareLock); conrel = heap_open(ConstraintRelationId, AccessShareLock);
conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, SnapshotNow, 1, skey); conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, NULL, 1, skey);
found = false; found = false;
while (HeapTupleIsValid(htup = systable_getnext(conscan))) { while (HeapTupleIsValid(htup = systable_getnext(conscan))) {
@ -6936,7 +6948,7 @@ List* PartitionGetPartIndexList(Partition part)
ObjectIdGetDatum(PartitionGetPartid(part))); ObjectIdGetDatum(PartitionGetPartid(part)));
partrel = heap_open(PartitionRelationId, AccessShareLock); partrel = heap_open(PartitionRelationId, AccessShareLock);
indscan = systable_beginscan(partrel, PartitionIndexTableIdIndexId, true, SnapshotNow, 1, &skey); indscan = systable_beginscan(partrel, PartitionIndexTableIdIndexId, true, NULL, 1, &skey);
while (HeapTupleIsValid(parttup = systable_getnext(indscan))) { while (HeapTupleIsValid(parttup = systable_getnext(indscan))) {
Form_pg_partition partform = (Form_pg_partition)GETSTRUCT(parttup); Form_pg_partition partform = (Form_pg_partition)GETSTRUCT(parttup);

View File

@ -34,8 +34,7 @@
#include "utils/relmapper.h" #include "utils/relmapper.h"
#include "utils/snapmgr.h" #include "utils/snapmgr.h"
/* built first time through in InitializeRelfilenodeMap */ static const int PARTITION_HASH_ELEM_SIZE = 4096;
ScanKeyData relfilenode_skey[2];
typedef struct { typedef struct {
Oid reltablespace; Oid reltablespace;
@ -47,6 +46,17 @@ typedef struct {
Oid relid; /* pg_class.oid */ Oid relid; /* pg_class.oid */
} RelfilenodeMapEntry; } RelfilenodeMapEntry;
typedef struct {
Oid reltablespace;
Oid relfilenode;
} PartfilenodeMapKey;
typedef struct {
PartfilenodeMapKey key; /* lookup key - must be first */
Oid relid; /* pg_partition.oid */
Oid reltoastrelid; /* pg_partition.reltoastrelid */
} PartfilenodeMapEntry;
/* /*
* RelfilenodeMapInvalidateCallback * RelfilenodeMapInvalidateCallback
* Flush mapping entries when pg_class is updated in a relevant fashion. * Flush mapping entries when pg_class is updated in a relevant fashion.
@ -75,30 +85,56 @@ static void RelfilenodeMapInvalidateCallback(Datum arg, Oid relid)
} }
} }
static void PartfilenodeMapInvalidateCallback(Datum arg, Oid relid)
{
HASH_SEQ_STATUS status;
PartfilenodeMapEntry* entry = NULL;
/* callback only gets registered after creating the hash */
Assert(u_sess->relmap_cxt.PartfilenodeMapHash != NULL);
hash_seq_init(&status, u_sess->relmap_cxt.PartfilenodeMapHash);
while ((entry = (PartfilenodeMapEntry*)hash_seq_search(&status)) != NULL) {
/*
* If relid is InvalidOid, signalling a complete reset, we must remove
* all entries, otherwise just remove the specific relation's entry.
* Always remove negative cache entries.
*/
if (relid == InvalidOid || /* complete reset */
entry->relid == InvalidOid || /* negative cache entry */
entry->relid == relid) { /* individual flushed relation */
if (hash_search(u_sess->relmap_cxt.PartfilenodeMapHash,
(void *) &entry->key, HASH_REMOVE, NULL) == NULL) {
ereport(ERROR, (errcode(ERRCODE_RELFILENODEMAP), errmsg("hash table corrupted")));
}
}
}
}
/* /*
* RelfilenodeMapInvalidateCallback * RelfilenodeMapInvalidateCallback
* Initialize cache, either on first use or after a reset. * Initialize cache, either on first use or after a reset.
*/ */
static void InitializeRelfilenodeMap(void) static void InitializeRelfilenodeMap()
{ {
HASHCTL ctl;
int i; int i;
/* build skey */ /* build skey */
errno_t ret = memset_s(&relfilenode_skey, sizeof(relfilenode_skey), 0, sizeof(relfilenode_skey)); errno_t ret = memset_s(&u_sess->relmap_cxt.relfilenodeSkey, sizeof(u_sess->relmap_cxt.relfilenodeSkey), 0,
sizeof(u_sess->relmap_cxt.relfilenodeSkey));
securec_check(ret, "\0", "\0"); securec_check(ret, "\0", "\0");
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
fmgr_info_cxt(F_OIDEQ, &relfilenode_skey[i].sk_func, u_sess->cache_mem_cxt); fmgr_info_cxt(F_OIDEQ, &u_sess->relmap_cxt.relfilenodeSkey[i].sk_func, u_sess->cache_mem_cxt);
relfilenode_skey[i].sk_strategy = BTEqualStrategyNumber; u_sess->relmap_cxt.relfilenodeSkey[i].sk_strategy = BTEqualStrategyNumber;
relfilenode_skey[i].sk_subtype = InvalidOid; u_sess->relmap_cxt.relfilenodeSkey[i].sk_subtype = InvalidOid;
relfilenode_skey[i].sk_collation = InvalidOid; u_sess->relmap_cxt.relfilenodeSkey[i].sk_collation = InvalidOid;
} }
relfilenode_skey[0].sk_attno = Anum_pg_class_reltablespace; u_sess->relmap_cxt.relfilenodeSkey[0].sk_attno = Anum_pg_class_reltablespace;
relfilenode_skey[1].sk_attno = Anum_pg_class_relfilenode; u_sess->relmap_cxt.relfilenodeSkey[1].sk_attno = Anum_pg_class_relfilenode;
/* Initialize the hash table. */ /* Initialize the hash table. */
HASHCTL ctl;
ret = memset_s(&ctl, sizeof(ctl), 0, sizeof(ctl)); ret = memset_s(&ctl, sizeof(ctl), 0, sizeof(ctl));
securec_check(ret, "\0", "\0"); securec_check(ret, "\0", "\0");
ctl.keysize = sizeof(RelfilenodeMapKey); ctl.keysize = sizeof(RelfilenodeMapKey);
@ -118,6 +154,73 @@ static void InitializeRelfilenodeMap(void)
CacheRegisterRelcacheCallback(RelfilenodeMapInvalidateCallback, (Datum)0); CacheRegisterRelcacheCallback(RelfilenodeMapInvalidateCallback, (Datum)0);
} }
static void InitializePartfilenodeMap()
{
HASHCTL ctl;
int i;
/* build skey */
errno_t ret = memset_s(&u_sess->relmap_cxt.partfilenodeSkey,
sizeof(u_sess->relmap_cxt.partfilenodeSkey), 0, sizeof(u_sess->relmap_cxt.partfilenodeSkey));
securec_check(ret, "\0", "\0");
for (i = 0; i < 2; i++) {
fmgr_info_cxt(F_OIDEQ, &u_sess->relmap_cxt.partfilenodeSkey[i].sk_func, u_sess->cache_mem_cxt);
u_sess->relmap_cxt.partfilenodeSkey[i].sk_strategy = BTEqualStrategyNumber;
u_sess->relmap_cxt.partfilenodeSkey[i].sk_subtype = InvalidOid;
u_sess->relmap_cxt.partfilenodeSkey[i].sk_collation = InvalidOid;
}
u_sess->relmap_cxt.partfilenodeSkey[0].sk_attno = Anum_pg_partition_reltablespace;
u_sess->relmap_cxt.partfilenodeSkey[1].sk_attno = Anum_pg_partition_relfilenode;
/* Initialize the hash table. */
ret = memset_s(&ctl, sizeof(ctl), 0, sizeof(ctl));
securec_check(ret, "\0", "\0");
ctl.keysize = sizeof(PartfilenodeMapKey);
ctl.entrysize = sizeof(PartfilenodeMapEntry);
ctl.hash = tag_hash;
ctl.hcxt = u_sess->cache_mem_cxt;
/*
* Only create the relmap_cxt->PartfilenodeMapHash now, so we don't end up partially
* initialized when fmgr_info_cxt() above ERRORs out with an out of memory
* error.
*/
u_sess->relmap_cxt.PartfilenodeMapHash = hash_create("PartfilenodeMap cache",
PARTITION_HASH_ELEM_SIZE, &ctl, HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
/* Watch for invalidation events. */
CacheRegisterRelcacheCallback(PartfilenodeMapInvalidateCallback, (Datum)0);
}
Oid RelidByRelfilenodeCache(Oid reltablespace, Oid relfilenode)
{
RelfilenodeMapKey key;
bool found = true;
if (u_sess->relmap_cxt.RelfilenodeMapHash == NULL) {
InitializeRelfilenodeMap();
}
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace) {
reltablespace = 0;
}
errno_t ret = memset_s(&key, sizeof(key), 0, sizeof(key));
securec_check(ret, "\0", "\0");
key.reltablespace = reltablespace;
key.relfilenode = relfilenode;
RelfilenodeMapEntry* entry =
(RelfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.RelfilenodeMapHash, (void*)&key, HASH_FIND, &found);
if (found) {
return entry->relid;
}
return InvalidOid;
}
/* /*
* Map a relation's (tablespace, filenode) to a relation's oid and cache the * Map a relation's (tablespace, filenode) to a relation's oid and cache the
* result. * result.
@ -135,8 +238,9 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
ScanKeyData skey[2]; ScanKeyData skey[2];
Oid relid; Oid relid;
int rc = 0; int rc = 0;
if (u_sess->relmap_cxt.RelfilenodeMapHash == NULL) if (u_sess->relmap_cxt.RelfilenodeMapHash == NULL) {
InitializeRelfilenodeMap(); InitializeRelfilenodeMap();
}
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */ /* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace) if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace)
@ -148,22 +252,6 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
key.reltablespace = reltablespace; key.reltablespace = reltablespace;
key.relfilenode = relfilenode; key.relfilenode = relfilenode;
/*
* Check cache and enter entry if nothing could be found. Even if no target
* Check cache and return entry if one is found. Even if no target
* relation can be found later on we store the negative match and return a
* InvalidOid from cache. That's not really necessary for performance since
* querying invalid values isn't supposed to be a frequent thing, but the
* implementation is simpler this way.
* InvalidOid from cache. That's not really necessary for performance
* since querying invalid values isn't supposed to be a frequent thing,
* but it's basically free.
*/
entry = (RelfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.RelfilenodeMapHash, (void*)&key, HASH_FIND, &found);
if (found)
return entry->relid;
/* ok, no previous cache entry, do it the hard way */ /* ok, no previous cache entry, do it the hard way */
/* initialize empty/negative cache entry before doing the actual lookups */ /* initialize empty/negative cache entry before doing the actual lookups */
@ -185,14 +273,17 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
relation = heap_open(RelationRelationId, AccessShareLock); relation = heap_open(RelationRelationId, AccessShareLock);
/* copy scankey to local copy, it will be modified during the scan */ /* copy scankey to local copy, it will be modified during the scan */
rc = memcpy_s(skey, sizeof(skey), relfilenode_skey, sizeof(skey)); rc = memcpy_s(skey, sizeof(skey), u_sess->relmap_cxt.relfilenodeSkey, sizeof(skey));
securec_check(rc, "", ""); securec_check(rc, "", "");
/* set scan arguments */ /* set scan arguments */
skey[0].sk_argument = ObjectIdGetDatum(reltablespace); skey[0].sk_argument = ObjectIdGetDatum(reltablespace);
skey[1].sk_argument = ObjectIdGetDatum(relfilenode); skey[1].sk_argument = ObjectIdGetDatum(relfilenode);
scandesc = systable_beginscan(relation, ClassTblspcRelfilenodeIndexId, true, SnapshotNow, 2, skey); /*
* Using historical snapshot in logic decoding.
*/
scandesc = systable_beginscan(relation, ClassTblspcRelfilenodeIndexId, true, NULL, 2, skey);
found = false; found = false;
@ -240,6 +331,39 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
return relid; return relid;
} }
Oid PartitionRelidByRelfilenodeCache(Oid reltablespace, Oid relfilenode, Oid &partationReltoastrelid)
{
PartfilenodeMapKey key;
PartfilenodeMapEntry* entry = NULL;
bool found = false;
if (u_sess->relmap_cxt.PartfilenodeMapHash == NULL) {
InitializePartfilenodeMap();
}
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace) {
reltablespace = 0;
}
key.reltablespace = reltablespace;
key.relfilenode = relfilenode;
/*
* Check cache and return entry if one is found. Even if no target
* relation can be found later on we store the negative match and return a
* InvalidOid from cache. That's not really necessary for performance since
* querying invalid values isn't supposed to be a frequent thing, but the
* implementation is simpler this way.
*/
entry = (PartfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.PartfilenodeMapHash, (void*)&key, HASH_FIND, &found);
if (found) {
partationReltoastrelid = entry->reltoastrelid;
return entry->relid;
}
return InvalidOid;
}
/* /*
* Map a partation-relation's (tablespace, filenode) to it's parent relation's oid and * Map a partation-relation's (tablespace, filenode) to it's parent relation's oid and
* save partation-relation's Reltoastrelid to partationReltoastrelid. * save partation-relation's Reltoastrelid to partationReltoastrelid.
@ -247,38 +371,49 @@ Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
*/ */
Oid PartitionRelidByRelfilenode(Oid reltablespace, Oid relfilenode, Oid& partationReltoastrelid) Oid PartitionRelidByRelfilenode(Oid reltablespace, Oid relfilenode, Oid& partationReltoastrelid)
{ {
bool foundflag = false; PartfilenodeMapKey key;
PartfilenodeMapEntry* entry = NULL;
bool found = false;
SysScanDesc scandesc; SysScanDesc scandesc;
Relation relation; Relation relation;
HeapTuple ntp; HeapTuple ntp;
ScanKeyData skey[2]; ScanKeyData skey[2];
Oid relid = InvalidOid; Oid relid = InvalidOid;
int rc = 0; int rc = 0;
if (u_sess->relmap_cxt.PartfilenodeMapHash == NULL) {
InitializePartfilenodeMap();
}
/* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */ /* pg_class will show 0 when the value is actually u_sess->proc_cxt.MyDatabaseTableSpace */
if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace) if (reltablespace == u_sess->proc_cxt.MyDatabaseTableSpace)
reltablespace = 0; reltablespace = 0;
key.reltablespace = reltablespace;
key.relfilenode = relfilenode;
/* initialize empty/negative cache entry before doing the actual lookups */
relid = InvalidOid;
/* For partition table in MPPDB, the relfilenode is in pg_partition instead of pg_class, /* For partition table in MPPDB, the relfilenode is in pg_partition instead of pg_class,
* so here we scan the pg_partition again to get the parent's oid. */ * so here we scan the pg_partition again to get the parent's oid. */
/* check plain relations by looking in pg_class */ /* check plain relations by looking in pg_class */
relation = heap_open(PartitionRelationId, AccessShareLock); relation = heap_open(PartitionRelationId, AccessShareLock);
rc = memcpy_s(skey, sizeof(skey), relfilenode_skey, sizeof(skey)); rc = memcpy_s(skey, sizeof(skey), u_sess->relmap_cxt.partfilenodeSkey, sizeof(skey));
securec_check(rc, "", ""); securec_check(rc, "", "");
skey[0].sk_attno = Anum_pg_partition_reltablespace; /* set scan arguments */
skey[1].sk_attno = Anum_pg_partition_relfilenode;
skey[0].sk_argument = ObjectIdGetDatum(reltablespace); skey[0].sk_argument = ObjectIdGetDatum(reltablespace);
skey[1].sk_argument = ObjectIdGetDatum(relfilenode); skey[1].sk_argument = ObjectIdGetDatum(relfilenode);
scandesc = systable_beginscan(relation, InvalidOid, false, SnapshotNow, 2, skey); scandesc = systable_beginscan(relation, InvalidOid, false, NULL, 2, skey);
found = false;
while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) { while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) {
if (foundflag) if (found)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_RELFILENODEMAP), (errcode(ERRCODE_RELFILENODEMAP),
errmsg("unexpected duplicate for tablespace %u, relfilenode %u", reltablespace, relfilenode))); errmsg("unexpected duplicate for tablespace %u, relfilenode %u", reltablespace, relfilenode)));
foundflag = true; found = true;
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
if (assert_enabled) { if (assert_enabled) {
@ -299,5 +434,35 @@ Oid PartitionRelidByRelfilenode(Oid reltablespace, Oid relfilenode, Oid& partati
systable_endscan(scandesc); systable_endscan(scandesc);
heap_close(relation, AccessShareLock); heap_close(relation, AccessShareLock);
/*
* Only enter entry into cache now, our opening of pg_partition could have
* caused cache invalidations to be executed which would have deleted a
* new entry if we had entered it above.
*/
if (relid != InvalidOid) {
entry =
(PartfilenodeMapEntry*)hash_search(u_sess->relmap_cxt.PartfilenodeMapHash, (void*)&key, HASH_ENTER, &found);
entry->relid = relid;
entry->reltoastrelid = partationReltoastrelid;
}
return relid; return relid;
} }
Oid HeapGetRelid(Oid reltablespace, Oid relfilenode, Oid &partationReltoastrelid)
{
Oid reloid = InvalidOid;
reloid = RelidByRelfilenodeCache(reltablespace, relfilenode);
if (reloid == InvalidOid) {
reloid = PartitionRelidByRelfilenodeCache(reltablespace, relfilenode, partationReltoastrelid);
}
if (reloid == InvalidOid) {
reloid = RelidByRelfilenode(reltablespace, relfilenode);
}
if (reloid == InvalidOid) {
reloid = PartitionRelidByRelfilenode(reltablespace, relfilenode, partationReltoastrelid);
}
return reloid;
}

Some files were not shown because too many files have changed in this diff Show More