Regarding Postgres Dynamic Shared Memory (DSA)
Hello everyone,
I'm building In-Memory index extension for Postgres, for which i'm trying
to use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.
Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}
Because of this code, Postgres is not starting. Not even giving any error
messages in pg logs. Hence, i'm totally clue less :(
Please let me know how to proceed. Your help is highly appreciated.
PS: Applied all the DSM related patches over Postgres 9.6.1 as per below
thread and confirmed the same by running some test programs.
/messages/by-id/CAEepm=1z5WLuNoJ80PaCvz6EtG9dN0j-KuHcHtU6QEfcPP5-qA@mail.gmail.com
Thanks & Best Regards,
- Mahi
On Tue, May 23, 2017 at 6:42 AM, Mahi Gurram <teckymahi@gmail.com> wrote:
I'm building In-Memory index extension for Postgres, for which i'm trying to
use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}Because of this code, Postgres is not starting. Not even giving any error
messages in pg logs. Hence, i'm totally clue less :(
It seems to me that you are creating those too early. For example, for
a background worker process, DSA segments would likely be created in
the main process routine. Without understanding what you are trying to
achieve, it is hard to make a good answer. You could always use a
ramdisk, but that would be likely be a waste of memory as Postgres has
its own buffer pool, killing the performance gains of OS caching.
--
Michael
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi Michael,
Thanks for your response.
All i'm building is In-Memory Index as an extension over Postgres.
Postgres Indexes will get Insert calls and Read calls from various
processes(typically client/connection process - forked processes to
postmaster process). Hence i have to maintain my In-Memory index in shared
memory.
If i create DynamicSharedArea (DSA) in postmaster/main process, all these
Client/Connection processes(In-Memory Index Processes) need not attach to
that DSA using area handle. Because these are forked processes to
postmaster/Main process and hence they automatically gets attached.
Hence i'm trying to create DSA in _PG_init function as it is called by
postmaster/main process.
Hope this is clear.
Thanks & Best Regards,
- Mahi
On Tue, May 23, 2017 at 5:30 PM, Michael Paquier <michael.paquier@gmail.com>
wrote:
Show quoted text
On Tue, May 23, 2017 at 6:42 AM, Mahi Gurram <teckymahi@gmail.com> wrote:
I'm building In-Memory index extension for Postgres, for which i'm
trying to
use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}Because of this code, Postgres is not starting. Not even giving any error
messages in pg logs. Hence, i'm totally clue less :(It seems to me that you are creating those too early. For example, for
a background worker process, DSA segments would likely be created in
the main process routine. Without understanding what you are trying to
achieve, it is hard to make a good answer. You could always use a
ramdisk, but that would be likely be a waste of memory as Postgres has
its own buffer pool, killing the performance gains of OS caching.
--
Michael
Hi,
As Michael said, i'm creating DSA too early. Shared_Preload libraries are
loading prior to memory related stuff.
But i'm totally clueless how to solve my use case.
Please help me with any work around.
Thanks & Best Regards,
- Mahi
On Tue, May 23, 2017 at 5:52 PM, Mahi Gurram <teckymahi@gmail.com> wrote:
Show quoted text
Hi Michael,
Thanks for your response.
All i'm building is In-Memory Index as an extension over Postgres.
Postgres Indexes will get Insert calls and Read calls from various
processes(typically client/connection process - forked processes to
postmaster process). Hence i have to maintain my In-Memory index in shared
memory.If i create DynamicSharedArea (DSA) in postmaster/main process, all these
Client/Connection processes(In-Memory Index Processes) need not attach to
that DSA using area handle. Because these are forked processes to
postmaster/Main process and hence they automatically gets attached.Hence i'm trying to create DSA in _PG_init function as it is called by
postmaster/main process.Hope this is clear.
Thanks & Best Regards,
- MahiOn Tue, May 23, 2017 at 5:30 PM, Michael Paquier <
michael.paquier@gmail.com> wrote:On Tue, May 23, 2017 at 6:42 AM, Mahi Gurram <teckymahi@gmail.com> wrote:
I'm building In-Memory index extension for Postgres, for which i'm
trying to
use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}Because of this code, Postgres is not starting. Not even giving any
error
messages in pg logs. Hence, i'm totally clue less :(
It seems to me that you are creating those too early. For example, for
a background worker process, DSA segments would likely be created in
the main process routine. Without understanding what you are trying to
achieve, it is hard to make a good answer. You could always use a
ramdisk, but that would be likely be a waste of memory as Postgres has
its own buffer pool, killing the performance gains of OS caching.
--
Michael
One solution that is striking me is....
1. I'll create one background worker and will initialise DSA in it.
2. If there are any callbacks available for client open/close connections,
i'll attach/detach to the DSA in those callbacks.
But i'm not sure there are such callbacks available. If such callbacks
exists in postgres and you guys know please help me out with that.
Thanks & Best Regards,
- Mahi
On Wed, May 24, 2017 at 11:32 AM, Mahi Gurram <teckymahi@gmail.com> wrote:
Show quoted text
Hi,
As Michael said, i'm creating DSA too early. Shared_Preload libraries are
loading prior to memory related stuff.But i'm totally clueless how to solve my use case.
Please help me with any work around.
Thanks & Best Regards,
- MahiOn Tue, May 23, 2017 at 5:52 PM, Mahi Gurram <teckymahi@gmail.com> wrote:
Hi Michael,
Thanks for your response.
All i'm building is In-Memory Index as an extension over Postgres.
Postgres Indexes will get Insert calls and Read calls from various
processes(typically client/connection process - forked processes to
postmaster process). Hence i have to maintain my In-Memory index in shared
memory.If i create DynamicSharedArea (DSA) in postmaster/main process, all these
Client/Connection processes(In-Memory Index Processes) need not attach to
that DSA using area handle. Because these are forked processes to
postmaster/Main process and hence they automatically gets attached.Hence i'm trying to create DSA in _PG_init function as it is called by
postmaster/main process.Hope this is clear.
Thanks & Best Regards,
- MahiOn Tue, May 23, 2017 at 5:30 PM, Michael Paquier <
michael.paquier@gmail.com> wrote:On Tue, May 23, 2017 at 6:42 AM, Mahi Gurram <teckymahi@gmail.com>
wrote:I'm building In-Memory index extension for Postgres, for which i'm
trying to
use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}Because of this code, Postgres is not starting. Not even giving any
error
messages in pg logs. Hence, i'm totally clue less :(
It seems to me that you are creating those too early. For example, for
a background worker process, DSA segments would likely be created in
the main process routine. Without understanding what you are trying to
achieve, it is hard to make a good answer. You could always use a
ramdisk, but that would be likely be a waste of memory as Postgres has
its own buffer pool, killing the performance gains of OS caching.
--
Michael
On Wed, May 24, 2017 at 11:39 AM, Mahi Gurram <teckymahi@gmail.com> wrote:
One solution that is striking me is....
1. I'll create one background worker and will initialise DSA in it.
2. If there are any callbacks available for client open/close connections,
i'll attach/detach to the DSA in those callbacks.But i'm not sure there are such callbacks available. If such callbacks
exists in postgres and you guys know please help me out with that.
We do share DSA handle, planned statement, params etc from master
backend with workers. See ExecInitParallelPlan that might help you in
your work.
--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, May 23, 2017 at 10:42 PM, Mahi Gurram <teckymahi@gmail.com> wrote:
Hello everyone,
I'm building In-Memory index extension for Postgres, for which i'm trying to
use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}Because of this code, Postgres is not starting. Not even giving any error
messages in pg logs. Hence, i'm totally clue less :(Please let me know how to proceed. Your help is highly appreciated.
Hi Mahi
If your plan is to write a preloaded library, then I think your
_PG_init() function needs to register a callback with
shmem_startup_hook. See pgss_shmem_startup for an example. You may
need to set up a piece of traditional named shared memory that
backends can use to find either (1) the handle for your DSA area or
(2) your DSA area itself (if you use the 'in place' constructor), and
also allocate and share a lock tranche number.
Another approach would be to create the DSA area on demand (ie the
first time you need it for your new index feature), if you don't want
to have to preload the library, but there is a small problem with
that, at least in theory. You probably still need to use a small bit
of named traditional shmem for discovery purposes, and it's slightly
against the rules to do that when you haven't called
RequestAddinShmemSpace, and it's too late to do that.
--
Thomas Munro
http://www.enterprisedb.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi Thomas,
If your plan is to write a preloaded library, then I think your
_PG_init() function needs to register a callback with
shmem_startup_hook. See pgss_shmem_startup for an example. You may
need to set up a piece of traditional named shared memory that
backends can use to find either (1) the handle for your DSA area or
(2) your DSA area itself (if you use the 'in place' constructor), and
also allocate and share a lock tranche number.
Followed the same as per your suggestion. Refer the code snippet below:
void
_PG_init(void){
RequestAddinShmemSpace(100000000);
PreviousShmemHook = shmem_startup_hook;
shmem_startup_hook = BufferShmemHook;
}
void BufferShmemHook(){
dsa_area *area;
dsa_pointer data_ptr;
char *mem;
area = dsa_create(my_tranche_id());
data_ptr = dsa_allocate(area, 42);
mem = (char *) dsa_get_address(area, data_ptr);
if (mem != NULL){
snprintf(mem, 42, "Hello world");
}
bool found;
shmemData = ShmemInitStruct("Mahi_Shared_Data",
sizeof(shared_data),
&found);
shmemData->shared_area = area;
shmemData->shared_area_handle = dsa_get_handle(area);
shmemData->shared_data_ptr = data_ptr;
shmemData->head=NULL;
}
Wrote one UDF function, which is called by one of the client connection and
that tries to use the same dsa. *But unfortunately it is behaving strange*.
First call to my UDF function is throwing segmentation fault and postgres
is quitting and auto restarting. If i try calling the same UDF function
again in new connection(after postgres restart) it is working fine.
Put some prints in postgres source code and found that dsa_allocate() is
trying to use area->control(dsa_area_control object) which is pointing to
wrong address but after restarting it is pointing to right address and
hence it is working fine after restart.
I'm totally confused and stuck at this point. Please help me in solving
this.
*PS: It is working fine in Mac.. in only linux systems i'm facing this
behaviour*.
I have attached the zip of my extension code along with screenshot of the
pgclient and log file with debug prints for better understanding.
**logfile is edited for providing some comments for better understanding*.
Please help me in solving this.
Awaiting your response.
Thanks & Best Regards,
- Mahi
On Sat, May 27, 2017 at 7:53 PM, Thomas Munro <thomas.munro@enterprisedb.com
Show quoted text
wrote:
On Tue, May 23, 2017 at 10:42 PM, Mahi Gurram <teckymahi@gmail.com> wrote:
Hello everyone,
I'm building In-Memory index extension for Postgres, for which i'm
trying to
use DSA. But ended with some issues, as it is not allowing me to create
DSA(Dynamic Shared Area) in _PG_init function.Please refer my_PG_init code below:
void
_PG_init(void)
{
area = dsa_create(LWLockNewTrancheId(), "CustomIndex_DSA");
area_handle = dsa_get_handle(area);
}Because of this code, Postgres is not starting. Not even giving any error
messages in pg logs. Hence, i'm totally clue less :(Please let me know how to proceed. Your help is highly appreciated.
Hi Mahi
If your plan is to write a preloaded library, then I think your
_PG_init() function needs to register a callback with
shmem_startup_hook. See pgss_shmem_startup for an example. You may
need to set up a piece of traditional named shared memory that
backends can use to find either (1) the handle for your DSA area or
(2) your DSA area itself (if you use the 'in place' constructor), and
also allocate and share a lock tranche number.Another approach would be to create the DSA area on demand (ie the
first time you need it for your new index feature), if you don't want
to have to preload the library, but there is a small problem with
that, at least in theory. You probably still need to use a small bit
of named traditional shmem for discovery purposes, and it's slightly
against the rules to do that when you haven't called
RequestAddinShmemSpace, and it's too late to do that.--
Thomas Munro
http://www.enterprisedb.com