From 47769e12ceb614ec73342f1a7c5fcbed66ec538d Mon Sep 17 00:00:00 2001 From: April01xxx Date: Tue, 31 Dec 2024 12:05:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BA=BF=E7=A8=8B=E6=B1=A0?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B=E5=BC=80=E5=90=AF=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=BC=93=E5=AD=98=E5=90=8E=E8=B7=A8=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=E8=AE=BF=E9=97=AE=E4=B8=B4=E6=97=B6=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=AE=95=E6=9C=BA=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/threadpool/knl_session.cpp | 1 + src/gausskernel/storage/access/transam/xact.cpp | 12 ++++++++++++ src/gausskernel/storage/file/fd.cpp | 8 ++++++++ src/include/knl/knl_session.h | 2 ++ src/include/threadpool/threadpool_worker.h | 3 ++- src/test/regress/wastebin/expected/hw_cursor.out | 15 +++++++++++++++ src/test/regress/wastebin/sql/hw_cursor.sql | 11 +++++++++++ 7 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/gausskernel/process/threadpool/knl_session.cpp b/src/gausskernel/process/threadpool/knl_session.cpp index 9ba7af3a3e..35d0bf885e 100755 --- a/src/gausskernel/process/threadpool/knl_session.cpp +++ b/src/gausskernel/process/threadpool/knl_session.cpp @@ -963,6 +963,7 @@ static void knl_u_storage_init(knl_u_storage_context* storage_cxt) /* var in fd.cpp */ storage_cxt->nfile = 0; storage_cxt->have_xact_temporary_files = false; + storage_cxt->num_interxact_temporary_files = 0; storage_cxt->temporary_files_size = 0; storage_cxt->numAllocatedDescs = 0; storage_cxt->maxAllocatedDescs = 0; diff --git a/src/gausskernel/storage/access/transam/xact.cpp b/src/gausskernel/storage/access/transam/xact.cpp index da25add9b2..c606082495 100755 --- a/src/gausskernel/storage/access/transam/xact.cpp +++ b/src/gausskernel/storage/access/transam/xact.cpp @@ -506,6 +506,18 @@ bool WorkerThreadCanSeekAnotherMission(ThreadStayReason* reason) *reason = TWORKER_GETNEXTXID; return false; } + + /* + * When global syscache is enabled, PathNameOpenFile_internal() allocates + * VFDs in thread's memory rather then session's memory. If we access VFDs + * across transactions in thread pool mode, for example, WITH HOLD cursor, + * it may cause us to access memory that does not belong to this thread. + */ + if (EnableGlobalSysCache() && u_sess->storage_cxt.num_interxact_temporary_files > 0) { + *reason = TWORKER_HOLDPORTAL; + return false; + } + /* can not release worker if session is inside a transaction */ if (s->blockState != TBLOCK_DEFAULT) { *reason = TWORKER_STILLINTRANS; diff --git a/src/gausskernel/storage/file/fd.cpp b/src/gausskernel/storage/file/fd.cpp index bd20c41718..d55c1dda3c 100755 --- a/src/gausskernel/storage/file/fd.cpp +++ b/src/gausskernel/storage/file/fd.cpp @@ -1538,6 +1538,9 @@ File OpenTemporaryFile(bool interXact) /* Register it with the current resource owner */ if (!interXact) { RegisterTemporaryFile(file); + } else { + Assert(!(vfdcache[file].fdstate & FD_CLOSE_AT_EOXACT)); + u_sess->storage_cxt.num_interxact_temporary_files++; } return file; @@ -1937,6 +1940,11 @@ void FileClose(File file) errno = stat_errno; ereport(LOG, (errmsg("could not stat file \"%s\": %m", vfdP->fileName))); } + + if (!(vfdP->fdstate & FD_CLOSE_AT_EOXACT)) { + Assert(u_sess->storage_cxt.num_interxact_temporary_files > 0); + u_sess->storage_cxt.num_interxact_temporary_files--; + } } /* Unregister it from the resource owner */ diff --git a/src/include/knl/knl_session.h b/src/include/knl/knl_session.h index 32f4964de7..0629e98189 100644 --- a/src/include/knl/knl_session.h +++ b/src/include/knl/knl_session.h @@ -1892,6 +1892,8 @@ typedef struct knl_u_storage_context { * to close */ bool have_xact_temporary_files; + /* Number of temporary file descriptors across transaction. */ + int num_interxact_temporary_files; /* * Tracks the total size of all temporary files. Note: when temp_file_limit * is being enforced, this cannot overflow since the limit cannot be more diff --git a/src/include/threadpool/threadpool_worker.h b/src/include/threadpool/threadpool_worker.h index a34006fb08..f81e62c8ef 100644 --- a/src/include/threadpool/threadpool_worker.h +++ b/src/include/threadpool/threadpool_worker.h @@ -73,7 +73,8 @@ typedef enum { TWORKER_STILLINTRANS, TWORKER_UNCONSUMEMESSAGE, TWORKER_CANSEEKNEXTSESSION, - TWORKER_PREDEADSESSION + TWORKER_PREDEADSESSION, + TWORKER_HOLDPORTAL } ThreadStayReason; class ThreadPoolGroup; diff --git a/src/test/regress/wastebin/expected/hw_cursor.out b/src/test/regress/wastebin/expected/hw_cursor.out index 8624da5cd9..7397945023 100644 --- a/src/test/regress/wastebin/expected/hw_cursor.out +++ b/src/test/regress/wastebin/expected/hw_cursor.out @@ -2690,3 +2690,18 @@ select * from pro_cursor_c0019(); ERROR: cannot open FETCH query as cursor CONTEXT: PL/pgSQL function pro_cursor_c0019() line 5 at OPEN drop table t1; +create table t1(c1 int, c2 text, c3 text); +insert into t1 values (generate_series(1,10000), 'hello world', 'foobar'); +set work_mem = '64kB'; +declare cur_with_hold_t1 no scroll binary cursor with hold for select * from t1; +fetch forward 2 from cur_with_hold_t1; + c1 | c2 | c3 +----+-------------+-------- + | hello world | foobar + | hello world | foobar +(2 rows) + +move forward 1 in cur_with_hold_t1; +close cur_with_hold_t1; +drop table t1; +reset work_mem; diff --git a/src/test/regress/wastebin/sql/hw_cursor.sql b/src/test/regress/wastebin/sql/hw_cursor.sql index b32ae85bf9..7d8f1d8a89 100644 --- a/src/test/regress/wastebin/sql/hw_cursor.sql +++ b/src/test/regress/wastebin/sql/hw_cursor.sql @@ -2147,3 +2147,14 @@ select * from pro_cursor_c0019(); close pro_cursor_c0019_1; select * from pro_cursor_c0019(); drop table t1; + +create table t1(c1 int, c2 text, c3 text); +insert into t1 values (generate_series(1,10000), 'hello world', 'foobar'); +set work_mem = '64kB'; +declare cur_with_hold_t1 no scroll binary cursor with hold for select * from t1; +fetch forward 2 from cur_with_hold_t1; +move forward 1 in cur_with_hold_t1; + +close cur_with_hold_t1; +drop table t1; +reset work_mem; -- Gitee