public inbox for [email protected]
help / color / mirror / Atom feedRe: shared-memory based stats collector - v70
39+ messages / 7 participants
[nested] [flat]
* Re: shared-memory based stats collector - v70
@ 2022-04-14 01:20 ` Michael Paquier <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Michael Paquier @ 2022-04-14 01:20 UTC (permalink / raw)
To: David G. Johnston <[email protected]>; +Cc: Andres Freund <[email protected]>; Kyotaro Horiguchi <[email protected]>; Melanie Plageman <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, Apr 13, 2022 at 04:56:45PM -0700, David G. Johnston wrote:
> Sorry, apparently this "2000-01-01" behavior only manifests after crash
> recovery on v15 (didn't check v14); after a clean initdb on v15 I got the
> same initdb timestamp.
>
> Feels like we should still report the "end of crash recovery timestamp" for
> these instead of 2000-01-01 (which I guess is derived from 0) if we are not
> willing to produce null (and it seems other parts of the system using these
> stats assumes non-null).
I can see this timestamp as well after crash recovery. This seems
rather misleading to me. I have added an open item.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
@ 2022-07-20 15:35 ` Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:05 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
1 sibling, 2 replies; 39+ messages in thread
From: Greg Stark @ 2022-07-20 15:35 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Kyotaro Horiguchi <[email protected]>; Melanie Plageman <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
So I'm finally wrapping my head around this new code. There is
something I'm surprised by that perhaps I'm misreading or perhaps I
shouldn't be surprised by, not sure.
Is it true that the shared memory allocation contains the hash table
entry and body of every object in every database? I guess I was
assuming I would find some kind of LRU cache which loaded data from
disk on demand. But afaict it loads everything on startup and then
never loads from disk later. The disk is purely for recovering state
after a restart.
On the one hand the rest of Postgres seems to be designed on the
assumption that the number of tables and database objects is limited
only by disk space. The catalogs are stored in relational storage
which is read through the buffer cache. On the other hand it's true
that syscaches don't do expire entries (though I think the assumption
is that no one backend touches very much).
It seems like if we really think the total number of database objects
is reasonably limited to scales that fit in RAM there would be a much
simpler database design that would just store the catalog tables in
simple in-memory data structures and map them all on startup without
doing all the work Postgres does to make relational storage scale.
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-07-20 15:55 ` Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Melanie Plageman @ 2022-07-20 15:55 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Andres Freund <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, Jul 20, 2022 at 11:35 AM Greg Stark <[email protected]> wrote:
> On the one hand the rest of Postgres seems to be designed on the
> assumption that the number of tables and database objects is limited
> only by disk space. The catalogs are stored in relational storage
> which is read through the buffer cache. On the other hand it's true
> that syscaches don't do expire entries (though I think the assumption
> is that no one backend touches very much).
>
> It seems like if we really think the total number of database objects
> is reasonably limited to scales that fit in RAM there would be a much
> simpler database design that would just store the catalog tables in
> simple in-memory data structures and map them all on startup without
> doing all the work Postgres does to make relational storage scale.
>
I think efforts to do such a thing have gotten caught up in solving
issues around visibility and managing the relationship between local and
global caches [1]. It doesn't seem like the primary technical concern
was memory usage.
[1]
https://www.postgresql.org/message-id/flat/4E72940DA2BF16479384A86D54D0988A567B9245%40G01JPEXMBKW04
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
@ 2022-07-20 16:08 ` Tom Lane <[email protected]>
2022-07-20 16:34 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
0 siblings, 2 replies; 39+ messages in thread
From: Tom Lane @ 2022-07-20 16:08 UTC (permalink / raw)
To: Melanie Plageman <[email protected]>; +Cc: Greg Stark <[email protected]>; Andres Freund <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Melanie Plageman <[email protected]> writes:
> On Wed, Jul 20, 2022 at 11:35 AM Greg Stark <[email protected]> wrote:
>> It seems like if we really think the total number of database objects
>> is reasonably limited to scales that fit in RAM there would be a much
>> simpler database design that would just store the catalog tables in
>> simple in-memory data structures and map them all on startup without
>> doing all the work Postgres does to make relational storage scale.
> I think efforts to do such a thing have gotten caught up in solving
> issues around visibility and managing the relationship between local and
> global caches [1]. It doesn't seem like the primary technical concern
> was memory usage.
AFAIR, the previous stats collector implementation had no such provision
either: it'd just keep adding hashtable entries as it received info about
new objects. The only thing that's changed is that now those entries are
in shared memory instead of process-local memory. We'd be well advised to
be sure that memory can be swapped out under pressure, but otherwise I'm
not seeing that things have gotten worse.
regards, tom lane
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
@ 2022-07-20 16:34 ` Andres Freund <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Andres Freund @ 2022-07-20 16:34 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Melanie Plageman <[email protected]>; Greg Stark <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-07-20 12:08:35 -0400, Tom Lane wrote:
> AFAIR, the previous stats collector implementation had no such provision
> either: it'd just keep adding hashtable entries as it received info about
> new objects.
Yep.
> The only thing that's changed is that now those entries are in shared
> memory instead of process-local memory. We'd be well advised to be
> sure that memory can be swapped out under pressure, but otherwise I'm
> not seeing that things have gotten worse.
FWIW, I ran a few memory usage benchmarks. Without stats accesses the
memory usage with shared memory stats was sometimes below, sometimes
above the "old" memory usage, depending on the number of objects. As
soon as there's stats access, it's well below (that includes things like
autovac workers).
I think there's quite a bit of memory usage reduction potential around
dsa.c - we occasionally end up with [nearly] unused dsm segments.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
@ 2022-07-20 18:41 ` Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-07-20 18:41 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Melanie Plageman <[email protected]>; Andres Freund <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, 20 Jul 2022 at 12:08, Tom Lane <[email protected]> wrote:
>
> AFAIR, the previous stats collector implementation had no such provision
> either: it'd just keep adding hashtable entries as it received info about
> new objects. The only thing that's changed is that now those entries are
> in shared memory instead of process-local memory. We'd be well advised to
> be sure that memory can be swapped out under pressure, but otherwise I'm
> not seeing that things have gotten worse.
Just to be clear I'm not looking for ways things have gotten worse.
Just trying to understand what I'm reading and I guess I came in with
assumptions that led me astray.
But... adding entries as it received info about new objects isn't the
same as having info on everything. I didn't really understand how the
old system worked but if you had a very large schema but each session
only worked with a small subset did the local stats data ever absorb
info on the objects it never touched?
All that said -- having all objects loaded in shared memory makes my
work way easier. It actually seems feasible to dump out all the
objects from shared memory and including objects from other databases
and if I don't need a consistent snapshot it even seems like it would
be possible to do that without having a copy of more than one stats
entry at a time in local memory. I hope that doesn't cause huge
contention on the shared hash table to be doing that regularly.
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-07-20 19:08 ` Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Andres Freund @ 2022-07-20 19:08 UTC (permalink / raw)
To: Greg Stark <[email protected]>; Tom Lane <[email protected]>; +Cc: Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On July 20, 2022 8:41:53 PM GMT+02:00, Greg Stark <[email protected]> wrote:
>On Wed, 20 Jul 2022 at 12:08, Tom Lane <[email protected]> wrote:
>>
>> AFAIR, the previous stats collector implementation had no such provision
>> either: it'd just keep adding hashtable entries as it received info about
>> new objects. The only thing that's changed is that now those entries are
>> in shared memory instead of process-local memory. We'd be well advised to
>> be sure that memory can be swapped out under pressure, but otherwise I'm
>> not seeing that things have gotten worse.
>
>Just to be clear I'm not looking for ways things have gotten worse.
>Just trying to understand what I'm reading and I guess I came in with
>assumptions that led me astray.
>
>But... adding entries as it received info about new objects isn't the
>same as having info on everything. I didn't really understand how the
>old system worked but if you had a very large schema but each session
>only worked with a small subset did the local stats data ever absorb
>info on the objects it never touched?
Each backend only had stats for things it touched. But the stats collector read all files at startup into hash tables and absorbed all generated stats into those as well.
>All that said -- having all objects loaded in shared memory makes my
>work way easier.
What are your trying to do?
>It actually seems feasible to dump out all the
>objects from shared memory and including objects from other databases
>and if I don't need a consistent snapshot it even seems like it would
>be possible to do that without having a copy of more than one stats
>entry at a time in local memory. I hope that doesn't cause huge
>contention on the shared hash table to be doing that regularly.
The stats accessors now default to not creating a full snapshot of stats data at first access (but that's configurable). So yes, that behavior is possible. E.g. autovac now uses a single object access like you describe.
Andres
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-07-21 15:07 ` Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-07-21 15:07 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, 20 Jul 2022 at 15:09, Andres Freund <[email protected]> wrote:
>
> Each backend only had stats for things it touched. But the stats collector read all files at startup into hash tables and absorbed all generated stats into those as well.
Fascinating. I'm surprised this didn't raise issues previously for
people with millions of tables. I wonder if it wasn't causing issues
and we just didn't hear about them because there were other bigger
issues :)
> >All that said -- having all objects loaded in shared memory makes my
> >work way easier.
>
> What are your trying to do?
I'm trying to implement an exporter for prometheus/openmetrics/etc
that dumps directly from shared memory without going through the SQL
backend layer. I believe this will be much more reliable, lower
overhead, safer, and consistent than writing SQL queries.
Ideally I would want to dump out the stats without connecting to each
database. I suspect that would run into problems where the schema
really adds a lot of information (such as which table each index is on
or which table a toast relation is for. There are also some things
people think of as stats that are maintained in the catalog such as
reltuples and relpages. So I'm imagining this won't strictly stay true
in the end.
It seems like just having an interface to iterate over the shared hash
table and return entries one by one without filtering by database
would be fairly straightforward and I would be able to do most of what
I want just with that. There's actually enough meta information in the
stats entries to be able to handle them as they come instead of trying
to process look up specific stats one by one.
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-09 10:18 ` Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 16:40 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
0 siblings, 2 replies; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-09 10:18 UTC (permalink / raw)
To: Greg Stark <[email protected]>; Andres Freund <[email protected]>; +Cc: Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 7/21/22 5:07 PM, Greg Stark wrote:
> On Wed, 20 Jul 2022 at 15:09, Andres Freund <[email protected]> wrote:
>> What are your trying to do?
> Ideally I would want to dump out the stats without connecting to each
> database.
I can see the use case too (specially for monitoring tools) of being
able to collect the stats without connecting to each database.
> It seems like just having an interface to iterate over the shared hash
> table and return entries one by one without filtering by database
> would be fairly straightforward and I would be able to do most of what
> I want just with that.
What do you think about adding a function in core PG to provide such
functionality? (means being able to retrieve all the stats (+ eventually
add some filtering) without the need to connect to each database).
If there is some interest, I'd be happy to work on it and propose a patch.
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-09 16:00 ` Greg Stark <[email protected]>
2022-08-09 16:47 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
1 sibling, 2 replies; 39+ messages in thread
From: Greg Stark @ 2022-08-09 16:00 UTC (permalink / raw)
To: Drouvot, Bertrand <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Tue, 9 Aug 2022 at 06:19, Drouvot, Bertrand <[email protected]> wrote:
>
>
> What do you think about adding a function in core PG to provide such
> functionality? (means being able to retrieve all the stats (+ eventually
> add some filtering) without the need to connect to each database).
I'm working on it myself too. I'll post a patch for discussion in a bit.
I was more aiming at a C function that extensions could use directly
rather than an SQL function -- though I suppose having the former it
would be simple enough to implement the latter using it. (though it
would have to be one for each stat type I guess)
The reason I want a C function is I'm trying to get as far as I can
without a connection to a database, without a transaction, without
accessing the catalog, and as much as possible without taking locks. I
think this is important for making monitoring highly reliable and low
impact on production. It's also kind of fundamental to accessing stats
for objects from other databases since we won't have easy access to
the catalogs for the other databases.
The main problem with my current code is that I'm accessing the shared
memory hash table directly. This means the I'm possibly introducing
locking contention on the shared memory hash table. I'm thinking of
separating the shared memory hash scan from the metric scan so the
list can be quickly built minimizing the time the lock is held. We
could possibly also only rebuild that list at a lower frequency than
the metrics gathering so new objects might not show up instantly.
I have a few things I would like to suggest for future improvements to
this infrastructure. I haven't polished the details of it yet but the
main thing I think I'm missing is the catalog name for the object. I
don't want to have to fetch it from the catalog and in any case I
think it would generally be useful and might regularize the
replication slot handling too.
I also think it would be nice to have a change counter for every stat
object, or perhaps a change time. Prometheus wouldn't be able to make
use of it but other monitoring software might be able to receive only
metrics that have changed since the last update which would really
help on databases with large numbers of mostly static objects. Even on
typical databases there are tons of builtin objects (especially
functions) that are probably never getting updates.
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-09 16:47 ` Andres Freund <[email protected]>
2022-08-10 08:13 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 18:18 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
1 sibling, 2 replies; 39+ messages in thread
From: Andres Freund @ 2022-08-09 16:47 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-08-09 12:00:46 -0400, Greg Stark wrote:
> I was more aiming at a C function that extensions could use directly
> rather than an SQL function -- though I suppose having the former it
> would be simple enough to implement the latter using it. (though it
> would have to be one for each stat type I guess)
I think such a C extension could exist today, without patching core code? It'd
be a bit ugly to include pgstat_internal.h, I guess, but other than that...
> The reason I want a C function is I'm trying to get as far as I can
> without a connection to a database, without a transaction, without
> accessing the catalog, and as much as possible without taking locks.
I assume you don't include lwlocks under locks?
> I think this is important for making monitoring highly reliable and low
> impact on production.
I'm doubtful about that, but whatever.
> The main problem with my current code is that I'm accessing the shared
> memory hash table directly. This means the I'm possibly introducing
> locking contention on the shared memory hash table.
I don't think that's a large enough issue to worry about unless you're
polling at a very high rate, which'd be a bad idea in itself. If a backend
can't get the lock for some stats change it'll defer flushing the stats a bit,
so it'll not cause a lot of other problems.
> I'm thinking of separating the shared memory hash scan from the metric scan
> so the list can be quickly built minimizing the time the lock is held.
I'd really really want to see some evidence that any sort of complexity here
is worth it.
> I have a few things I would like to suggest for future improvements to
> this infrastructure. I haven't polished the details of it yet but the
> main thing I think I'm missing is the catalog name for the object. I
> don't want to have to fetch it from the catalog and in any case I
> think it would generally be useful and might regularize the
> replication slot handling too.
I'm *dead* set against including catalog names in shared memory stats. That'll
add a good amount of memory usage and complexity, without any sort of
comensurate gain.
> I also think it would be nice to have a change counter for every stat
> object, or perhaps a change time. Prometheus wouldn't be able to make
> use of it but other monitoring software might be able to receive only
> metrics that have changed since the last update which would really
> help on databases with large numbers of mostly static objects.
I think you're proposing adding overhead that doesn't even have a real user.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 16:47 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-08-10 08:13 ` Drouvot, Bertrand <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-10 08:13 UTC (permalink / raw)
To: Andres Freund <[email protected]>; Greg Stark <[email protected]>; +Cc: Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/9/22 6:47 PM, Andres Freund wrote:
> Hi,
>
> On 2022-08-09 12:00:46 -0400, Greg Stark wrote:
>> I was more aiming at a C function that extensions could use directly
>> rather than an SQL function -- though I suppose having the former it
>> would be simple enough to implement the latter using it. (though it
>> would have to be one for each stat type I guess)
> I think such a C extension could exist today, without patching core code? It'd
> be a bit ugly to include pgstat_internal.h, I guess, but other than that...
Yeah, agree that writing such an extension is doable today.
>> The main problem with my current code is that I'm accessing the shared
>> memory hash table directly. This means the I'm possibly introducing
>> locking contention on the shared memory hash table.
> I don't think that's a large enough issue to worry about unless you're
> polling at a very high rate, which'd be a bad idea in itself. If a backend
> can't get the lock for some stats change it'll defer flushing the stats a bit,
> so it'll not cause a lot of other problems.
+1
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 16:47 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-08-10 18:18 ` Greg Stark <[email protected]>
2022-08-10 19:48 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 22:23 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
1 sibling, 2 replies; 39+ messages in thread
From: Greg Stark @ 2022-08-10 18:18 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Tue, 9 Aug 2022 at 12:48, Andres Freund <[email protected]> wrote:
> > The reason I want a C function is I'm trying to get as far as I can
> > without a connection to a database, without a transaction, without
> > accessing the catalog, and as much as possible without taking locks.
>
> I assume you don't include lwlocks under locks?
I guess it depends on which lwlock :) I would be leery of a monitoring
system taking an lwlock that could interfere with regular transactions
doing work. Or taking a lock that is itself the cause of the problem
elsewhere that you really need stats to debug would be a deal breaker.
> I don't think that's a large enough issue to worry about unless you're
> polling at a very high rate, which'd be a bad idea in itself. If a backend
> can't get the lock for some stats change it'll defer flushing the stats a bit,
> so it'll not cause a lot of other problems.
Hm. I wonder if we're on the same page about what constitutes a "high rate".
I've seen people try push prometheus or other similar systems to 5s
poll intervals. That would be challenging for Postgres due to the
volume of statistics. The default is 30s and people often struggle to
even have that function for large fleets. But if you had a small
fleet, perhaps an iot style system with a "one large table" type of
schema you might well want stats every 5s or even every 1s.
> I'm *dead* set against including catalog names in shared memory stats. That'll
> add a good amount of memory usage and complexity, without any sort of
> comensurate gain.
Well it's pushing the complexity there from elsewhere. If the labels
aren't in the stats structures then the exporter needs to connect to
each database, gather all the names into some local cache and then it
needs to worry about keeping it up to date. And if there are any
database problems such as disk errors or catalog objects being locked
then your monitoring breaks though perhaps it can be limited to just
missing some object names or having out of date names.
> > I also think it would be nice to have a change counter for every stat
> > object, or perhaps a change time. Prometheus wouldn't be able to make
> > use of it but other monitoring software might be able to receive only
> > metrics that have changed since the last update which would really
> > help on databases with large numbers of mostly static objects.
>
> I think you're proposing adding overhead that doesn't even have a real user.
I guess I'm just brainstorming here. I don't need to currently no. It
doesn't seem like significant overhead though compared to the locking
and copying though?
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 16:47 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 18:18 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-10 19:48 ` Greg Stark <[email protected]>
2022-08-10 22:26 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-08-10 19:48 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
One thing that's bugging me is that the names we use for these stats
are *all* over the place.
The names go through three different stages
pgstat structs -> pgstatfunc tupledescs -> pg_stat_* views
(Followed by a fourth stage where pg_exporter or whatever names for
the monitoring software)
And for some reason both transitions (plus the exporter) felt the need
to fiddle with the names or values. And not in any sort of even
vaguely consistent way. So there are three (or four) different sets of
names for the same metrics :(
e.g.
* Some of the struct elements have abbreviated words which are
expanded in the tupledesc names or the view columns -- some have long
names which get abbreviated.
* Some struct members have n_ prefixes (presumably to avoid C keywords
or other namespace issues?) and then lose them at one of the other
stages. But then the relation stats do not have n_ prefixes and then
the pg_stat view *adds* n_ prefixes in the SQL view!
* Some columns are added together in the SQL view which seems like
gratuitously hiding information from the user. The pg_stat_*_tables
view actually looks up information from the indexes stats and combines
them to get idx_scan and idx_tup_fetch.
* The pg_stat_bgwriter view returns data from two different fixed
entries, the checkpointer and the bgwriter, is there a reason those
are kept separately but then reported as if they're one thing?
Some of the simpler renaming could be transparently fixed by making
the internal stats match the public facing names. But for many of them
I think the internal names are better. And the cases where the views
aggregate data in a way that loses information are not something I
want to reproduce.
I had intended to use the internal names directly, reasoning that
transparency and consistency are the direction to be headed. But in
some cases I think the current public names are the better choice -- I
certainly don't want to remove n_* prefixes from some names but then
add them to different names! And some of the cases where the data is
combined or modified do seem like they would be missed.
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 16:47 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 18:18 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 19:48 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-10 22:26 ` Andres Freund <[email protected]>
0 siblings, 0 replies; 39+ messages in thread
From: Andres Freund @ 2022-08-10 22:26 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-08-10 15:48:15 -0400, Greg Stark wrote:
> One thing that's bugging me is that the names we use for these stats
> are *all* over the place.
Yes. I had a huge issue with this when polishing the patch. And Horiguchi-san
did as well. I had to limit the amount of cleanup done to make it feasible to
get anything committed. I think it's a bit less bad than before, but by no
means good.
> * The pg_stat_bgwriter view returns data from two different fixed
> entries, the checkpointer and the bgwriter, is there a reason those
> are kept separately but then reported as if they're one thing?
Historical raisins. Checkpointer and bgwriter used to be one thing, but isn't
anymore.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 16:47 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 18:18 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-10 22:23 ` Andres Freund <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Andres Freund @ 2022-08-10 22:23 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-08-10 14:18:25 -0400, Greg Stark wrote:
> > I don't think that's a large enough issue to worry about unless you're
> > polling at a very high rate, which'd be a bad idea in itself. If a backend
> > can't get the lock for some stats change it'll defer flushing the stats a bit,
> > so it'll not cause a lot of other problems.
>
> Hm. I wonder if we're on the same page about what constitutes a "high rate".
>
> I've seen people try push prometheus or other similar systems to 5s
> poll intervals. That would be challenging for Postgres due to the
> volume of statistics. The default is 30s and people often struggle to
> even have that function for large fleets. But if you had a small
> fleet, perhaps an iot style system with a "one large table" type of
> schema you might well want stats every 5s or even every 1s.
That's probably fine. Although I think you might run into trouble not from the
stats subystem side, but from the "amount of data" side. On a system with a
lot of objects that can be a fair amount. If you really want to do very low
latency stats reporting, I suspect you'd have to build an incremental system.
> > I'm *dead* set against including catalog names in shared memory stats. That'll
> > add a good amount of memory usage and complexity, without any sort of
> > comensurate gain.
>
> Well it's pushing the complexity there from elsewhere. If the labels
> aren't in the stats structures then the exporter needs to connect to
> each database, gather all the names into some local cache and then it
> needs to worry about keeping it up to date. And if there are any
> database problems such as disk errors or catalog objects being locked
> then your monitoring breaks though perhaps it can be limited to just
> missing some object names or having out of date names.
Shrug. If the stats system state desynchronizes from an alter table rename
you'll also have a problem in monitoring.
And even if you can benefit from having all that information, it'd still be an
overhead born by everybody for a very small share of users.
> > > I also think it would be nice to have a change counter for every stat
> > > object, or perhaps a change time. Prometheus wouldn't be able to make
> > > use of it but other monitoring software might be able to receive only
> > > metrics that have changed since the last update which would really
> > > help on databases with large numbers of mostly static objects.
> >
> > I think you're proposing adding overhead that doesn't even have a real user.
>
> I guess I'm just brainstorming here. I don't need to currently no. It
> doesn't seem like significant overhead though compared to the locking
> and copying though?
Yes, timestamps aren't cheap to determine (nor free too store, but that's a
lesser issue).
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-10 08:04 ` Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-10 08:04 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/9/22 6:00 PM, Greg Stark wrote:
> On Tue, 9 Aug 2022 at 06:19, Drouvot, Bertrand <[email protected]> wrote:
>>
>> What do you think about adding a function in core PG to provide such
>> functionality? (means being able to retrieve all the stats (+ eventually
>> add some filtering) without the need to connect to each database).
> I'm working on it myself too. I'll post a patch for discussion in a bit.
Great! Thank you!
Out of curiosity, would you be also interested by such a feature for
previous versions (that will not get the patch in) ?
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-10 21:25 ` Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-08-10 21:25 UTC (permalink / raw)
To: Drouvot, Bertrand <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, 10 Aug 2022 at 04:05, Drouvot, Bertrand <[email protected]> wrote:
>
> Hi,
>
> On 8/9/22 6:00 PM, Greg Stark wrote:
> > On Tue, 9 Aug 2022 at 06:19, Drouvot, Bertrand <[email protected]> wrote:
> >>
> >> What do you think about adding a function in core PG to provide such
> >> functionality? (means being able to retrieve all the stats (+ eventually
> >> add some filtering) without the need to connect to each database).
> > I'm working on it myself too. I'll post a patch for discussion in a bit.
>
> Great! Thank you!
So I was adding the code to pgstat.c because I had thought there were
some data types I needed and/or static functions I needed. However you
and Andres encouraged me to check again now. And indeed I was able,
after fixing a couple things, to make the code work entirely
externally.
This is definitely not polished and there's a couple obvious things
missing. But at the risk of embarrassment I've attached my WIP. Please
be gentle :) I'll post the github link in a bit when I've fixed up
some meta info.
I'm definitely not wedded to the idea of using callbacks, it was just
the most convenient way to get started, especially when I was putting
the main loop in pgstat.c. Ideally I do want to keep open the
possibility of streaming the results out without buffering the whole
set in memory.
> Out of curiosity, would you be also interested by such a feature for
> previous versions (that will not get the patch in) ?
I always had trouble understanding the existing stats code so I was
hoping the new code would make it easier. It seems to have worked but
it's possible I'm wrong and it was always possible and the problem was
always just me :)
--
greg
Attachments:
[text/x-csrc] telemetry.c (9.1K, ../../CAM-w4HP_YL8uPrNiv2DPKmq1KD3QLEX7CBLc5DCJ9j7mf7eerw@mail.gmail.com/2-telemetry.c)
download | inline:
/*-------------------------------------------------------------------------
*
* telemetry.c
*
* Most of this code was copied from pg_prewarm.c as a template.
*
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#include "access/relation.h"
#include "access/xact.h"
#include "catalog/pg_class.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgworker.h"
#include "postmaster/interrupt.h"
#include "storage/buf_internals.h"
#include "storage/dsm.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/lwlock.h"
#include "storage/proc.h"
#include "storage/procsignal.h"
#include "storage/shmem.h"
#include "storage/smgr.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
#include "utils/datetime.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/resowner.h"
#include "telemetry.h"
#include "telemetry_pgstat.h"
PG_MODULE_MAGIC;
/* We should already have included what we need to get uint64_t size_t
fd_set socklen_t and struct sockaddr so don't let microhttpd
include extra stuff for them */
#define MHD_PLATFORM_H
#include <microhttpd.h>
/* MHD_USE_EPOLL */
/* MHD_USE_AUTO */
/* MHD_OPTION_CONNECTION_LIMIT */
/* MHD_OPTION_CONNECTION_TIMEOUT */
/* MHD_OPTION_EXTERNAL_LOGGER */
/* Background worker harness */
void _PG_init(void);
/* Actual internal background worker main entry point */
static void telemetry_start_worker(unsigned short port);
/* GUC variables. */
static int telemetry_port = 9187; /* TCP port to listen on for metrics */
static char *telemetry_listen_addresses; /* TCP listen addresses */
static bool telemetry = true; /* start worker automatically on default port */
static enum MHD_Result
telemetry_handler(void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
size_t *upload_data_size,
void **con_cls);
/*
* Module load callback.
*/
void
_PG_init(void)
{
DefineCustomIntVariable("telemetry.port",
"TCP Port to serve metrics on by default",
NULL,
&telemetry_port,
9187, 1, 65535,
PGC_SIGHUP,
0, /* flags */
NULL, NULL, NULL /* hooks */
);
DefineCustomStringVariable("telemetry.listen_addresses",
"TCP Listen Addresses to serve metrics on by default",
NULL,
&telemetry_listen_addresses,
"*",
PGC_SIGHUP,
GUC_LIST_INPUT, /* flags */
NULL, NULL, NULL /* hooks */
);
if (!process_shared_preload_libraries_in_progress)
return;
/* can't define PGC_POSTMASTER variable after startup */
DefineCustomBoolVariable("telemetry.start_server",
"Starts the telemetry worker on startup.",
NULL,
&telemetry,
true,
PGC_POSTMASTER,
0,
NULL,
NULL,
NULL);
EmitWarningsOnPlaceholders("telemetry");
/* Register telemetry worker, if enabled. */
if (telemetry)
telemetry_start_worker(telemetry_port);
}
static void telemetry_logger(void *arg, const char *fmt, va_list ap);
struct MHD_OptionItem mhd_ops[] = {
{ MHD_OPTION_EXTERNAL_LOGGER, (intptr_t)telemetry_logger, NULL },
{ MHD_OPTION_CONNECTION_LIMIT, 10, NULL },
{ MHD_OPTION_CONNECTION_TIMEOUT, 30, NULL },
{ MHD_OPTION_END, 0, NULL }
};
/*
* Main entry point for the leader telemetry process. This is invoked
* *in* the background worker process.
*/
void
telemetry_main(Datum main_arg)
{
/* Handle -1 or out of range values? */
unsigned short port = DatumGetInt32(main_arg);
WaitEventSet *waitset;
WaitEvent event;
struct MHD_Daemon *daemon;
enum MHD_Result mhd_retval;
const union MHD_DaemonInfo *mhd_info;
/*fd_set r_fdset, w_fdset, e_fdset;*/
/*int max_fd, i;*/
unsigned long long mhd_timeout;
long timeout;
/* Establish signal handlers; once that's done, unblock signals. */
pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
BackgroundWorkerUnblockSignals();
daemon = MHD_start_daemon(MHD_USE_ERROR_LOG | MHD_USE_EPOLL /* flags */,
port,
NULL /* accept callback */, NULL /* closure */,
telemetry_handler /* default handler */, NULL /* closure */,
MHD_OPTION_ARRAY, mhd_ops,
MHD_OPTION_END);
waitset = CreateWaitEventSet(TopMemoryContext, 3);
mhd_info = MHD_get_daemon_info(daemon, MHD_DAEMON_INFO_EPOLL_FD);
if (mhd_info != NULL && mhd_info->epoll_fd > 0)
{
elog(LOG, "telemetry got %d as epoll file descriptor", mhd_info->epoll_fd);
AddWaitEventToSet(waitset, WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE, mhd_info->epoll_fd, NULL, NULL);
} else {
elog(LOG, "telemetry couldn't get mhd epoll fd");
return;
/*
max_fd = 0;
mhd_retval = MHD_get_fdset(daemon, r_fdset, w_fdset, e_fdset, &max_fd);
for(i=0;i++;i<=max_fd) {
if (FD_ISSET(i, r_fdset)) AddWaitEventToSet(waitset, WL_SOCKET_READABLE, i, NULL, NULL);
if (FD_ISSET(i, w_fdset)) AddWaitEventToSet(waitset, WL_SOCKET_WRITEABLE, i, NULL, NULL);
}
*/
}
AddWaitEventToSet(waitset, WL_LATCH_SET, PGINVALID_SOCKET, MyLatch, NULL);
AddWaitEventToSet(waitset, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET, NULL, NULL);
/* wait for requests */
while (!ShutdownRequestPending)
{
/* In case of a SIGHUP, just reload the configuration. */
if (ConfigReloadPending)
{
int old_port = telemetry_port;
ConfigReloadPending = false;
ProcessConfigFile(PGC_SIGHUP);
if (old_port != telemetry_port) {
;/* restart web server on new port */
}
}
mhd_retval = MHD_run(daemon);
if (mhd_retval != MHD_YES) {
elog(LOG, "mhd_no from MHD_run()");
}
mhd_retval = MHD_get_timeout (daemon, &mhd_timeout);
if (mhd_retval == MHD_YES && mhd_timeout > 0 && mhd_timeout < 10000) {
timeout = (long)timeout;
} else {
timeout = 10000;
}
elog(LOG, "telemetry worker waiting %0.3fs for requests", (double)timeout/1000);
WaitEventSetWait(waitset, (timeout<10000 ? (long)timeout : 10000), &event, 1, PG_WAIT_EXTENSION);
/* Reset the latch, loop. */
ResetLatch(MyLatch);
}
MHD_stop_daemon(daemon);
}
/*
* SQL-callable function to launch telemetry.
*/
PG_FUNCTION_INFO_V1(telemetry_server_start);
Datum
telemetry_server_start(PG_FUNCTION_ARGS)
{
unsigned short port = PG_GETARG_INT32(0);
telemetry_start_worker(port);
PG_RETURN_VOID();
}
/*
* Start telemetry worker process.
*/
static void
telemetry_start_worker(unsigned short port)
{
BackgroundWorker worker;
BackgroundWorkerHandle *handle;
BgwHandleStatus status;
pid_t pid;
MemSet(&worker, 0, sizeof(BackgroundWorker));
worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
worker.bgw_start_time = BgWorkerStart_ConsistentState;
worker.bgw_main_arg = Int32GetDatum(port);
strcpy(worker.bgw_library_name, "telemetry");
strcpy(worker.bgw_function_name, "telemetry_main");
strcpy(worker.bgw_name, "telemetry server");
strcpy(worker.bgw_type, "telemetry server");
if (process_shared_preload_libraries_in_progress)
{
RegisterBackgroundWorker(&worker);
return;
}
/* must set notify PID to wait for startup */
worker.bgw_notify_pid = MyProcPid;
if (!RegisterDynamicBackgroundWorker(&worker, &handle))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("could not register background process"),
errhint("You may need to increase max_worker_processes.")));
status = WaitForBackgroundWorkerStartup(handle, &pid);
if (status != BGWH_STARTED)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("could not start background process"),
errhint("More details may be available in the server log.")));
}
struct activity_stats stats;
static enum MHD_Result
telemetry_handler(void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
size_t *upload_data_size,
void **con_cls)
{
struct MHD_Response *mhd_response;
enum MHD_Result mhd_retval;
char *buf;
elog(LOG, "telemetry %s request: %s", method, url);
buf = pg_stat_dump_stats_string();
mhd_response = MHD_create_response_from_buffer(strlen(buf), (void*)buf, MHD_RESPMEM_PERSISTENT);
if (!mhd_response) {
elog(LOG, "NULL response!");
return MHD_NO;
}
mhd_retval = MHD_queue_response(connection, 200, mhd_response);
MHD_destroy_response(mhd_response);
if (mhd_retval != MHD_YES) {
elog(LOG, "mhd_no from queue_response");
return MHD_NO;
}
return MHD_YES;
}
static void telemetry_logger(void *arg, const char *fmt, va_list ap)
{
char buf[256];
int retval;
retval = vsnprintf(buf, sizeof(buf), fmt, ap);
if (retval >= sizeof(buf)) {
elog(LOG, "message buffer overflow need %d bytes", retval);
} else {
elog(LOG, "telemetry mhd log: %s", buf);
}
}
[text/x-csrc] telemetry_pgstat.c (15.6K, ../../CAM-w4HP_YL8uPrNiv2DPKmq1KD3QLEX7CBLc5DCJ9j7mf7eerw@mail.gmail.com/3-telemetry_pgstat.c)
download | inline:
#include "postgres.h"
#include <unistd.h>
#include "access/transam.h"
#include "access/xact.h"
#include "lib/dshash.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lwlock.h"
#include "storage/pg_shmem.h"
#include "storage/shmem.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/pgstat_internal.h"
#include "utils/timestamp.h"
#include <math.h>
#include <float.h>
/* SQL callable interface to return metrics */
Datum
pg_stat_dump_stats(PG_FUNCTION_ARGS);
/* C-level call for telemetry monitoring agent to call */
char *
pg_stat_dump_stats_string(void);
/* XXX */
typedef void (*dump_stats_cb)(PgStat_Kind kind, const char *kind_name, Oid dboid, Oid objoid, const char *name, void *body, void *closure);
static void
pgstat_dump_stats(dump_stats_cb callback, void *closure)
{
PgStat_Kind kind;
dshash_seq_status hstat;
PgStatShared_HashEntry *ps;
struct timespec tstart={0,0}, tend={0,0};
clock_gettime(CLOCK_MONOTONIC, &tstart);
pgstat_assert_is_up();
pgstat_fetch_consistency = PGSTAT_FETCH_CONSISTENCY_NONE;
elog(NOTICE, "dumping stats contents");
/*
* XXX: The following could now be generalized to just iterate over
* pgstat_kind_infos instead of knowing about the different kinds of
* stats.
*/
for (kind=PGSTAT_KIND_FIRST_VALID; kind <= PGSTAT_KIND_LAST; kind++)
{
if (pgstat_get_kind_info(kind)->fixed_amount)
pgstat_snapshot_fixed(kind);
}
callback(PGSTAT_KIND_ARCHIVER, pgstat_get_kind_info(PGSTAT_KIND_ARCHIVER)->name, InvalidOid, InvalidOid, NULL, &pgStatLocal.snapshot.archiver, closure);
callback(PGSTAT_KIND_BGWRITER, pgstat_get_kind_info(PGSTAT_KIND_BGWRITER)->name, InvalidOid, InvalidOid, NULL, &pgStatLocal.snapshot.bgwriter, closure);
callback(PGSTAT_KIND_CHECKPOINTER, pgstat_get_kind_info(PGSTAT_KIND_CHECKPOINTER)->name, InvalidOid, InvalidOid, NULL, &pgStatLocal.snapshot.checkpointer, closure);
for (int i = 0 ; i < SLRU_NUM_ELEMENTS; i++ ) {
callback(PGSTAT_KIND_SLRU, pgstat_get_kind_info(PGSTAT_KIND_SLRU)->name, InvalidOid, InvalidOid, slru_names[i], &pgStatLocal.snapshot.slru[i], closure);
}
callback(PGSTAT_KIND_WAL, pgstat_get_kind_info(PGSTAT_KIND_WAL)->name, InvalidOid, InvalidOid, NULL, &pgStatLocal.snapshot.wal, closure);
/*
* Walk through the stats entries
*/
dshash_seq_init(&hstat, pgStatLocal.shared_hash, false);
while ((ps = dshash_seq_next(&hstat)) != NULL)
{
PgStatShared_Common *shstats;
void *body;
const PgStat_KindInfo *kind_info = NULL;
CHECK_FOR_INTERRUPTS();
/* we may have some "dropped" entries not yet removed, skip them */
Assert(!ps->dropped);
if (ps->dropped)
continue;
shstats = (PgStatShared_Common *) dsa_get_address(pgStatLocal.dsa, ps->body);
body = pgstat_get_entry_data(ps->key.kind, shstats);
kind_info = pgstat_get_kind_info(ps->key.kind);
/* if not dropped the valid-entry refcount should exist */
Assert(pg_atomic_read_u32(&ps->refcount) > 0);
if (!kind_info->to_serialized_name)
{
callback(ps->key.kind, kind_info->name, ps->key.dboid, ps->key.objoid, NULL, body, closure);
}
else
{
/* stats entry identified by name on disk (e.g. replication slots) */
NameData name;
kind_info->to_serialized_name(shstats, &name);
callback(ps->key.kind, kind_info->name, InvalidOid, InvalidOid, NameStr(name), body, closure);
}
}
dshash_seq_term(&hstat);
clock_gettime(CLOCK_MONOTONIC, &tend);
elog(NOTICE,
"pgstat_dump_stats took about %0.3f ms\n",
1000 * (((double)tend.tv_sec + 1.0e-9*tend.tv_nsec) -
((double)tstart.tv_sec + 1.0e-9*tstart.tv_nsec))
);
}
/*
* Lots of work left to do here
*
* Prometheus expects double precision floats and all our counters are
* integers so the best strategy is just to have them wrap at 2^53 to avoid
* losing precision. Prometheus treats that as a reset so we trade absolute
* value for precision but since they're counters that's fine.
*
* Our timestamps are 64-bit microseconds and Prometheus standard is to use
* double precision in units of seconds. That loses precision for dates far in
* the future and past but these stats just have things like the time of the
* last failure.
*
*/
#define COUNTER_MASK ((1LL<<DBL_MANT_DIG)-1)
static void emit_counter(const char *name, char *labels, PgStat_Counter counter, void *closure)
{
StringInfo response = closure;
int64 val = counter & COUNTER_MASK;
/* Assert check that we are printed values that don't lose precision in
* doubles */
double valf = (double)val;
Assert((int64)valf == val);
if (labels)
appendStringInfo(response, "%s{%s}=%lu\n", name, labels, val);
else
appendStringInfo(response, "%s=%lu\n", name, val);
}
static void emit_timestamptz(const char *name, char *labels, TimestampTz timestamp, void *closure)
{
StringInfo response = closure;
double val = timestamp== 0 ? NAN : (double)timestamp / 1000000 + SECS_PER_DAY*(POSTGRES_EPOCH_JDATE-UNIX_EPOCH_JDATE);
if (labels)
appendStringInfo(response, "%s{%s}=%lf\n", name, labels, val);
else
appendStringInfo(response, "%s=%lf\n", name, val);
}
static void
dump_stats_callback(PgStat_Kind kind, const char *kind_name, Oid dboid, Oid objoid, const char *name, void *body, void *closure) {
if (dboid == InvalidOid && objoid == InvalidOid && name == NULL) {
elog(WARNING, "stats for \"%s\" with no key?!", kind_name);
}
switch(kind) {
/* stats for variable-numbered objects */
case PGSTAT_KIND_DATABASE:
{
PgStat_StatDBEntry *stats = body;
/* db=0 represents the background workers apparently? */
char *labels = dboid==0 ? NULL : psprintf("db=\"%d\"", dboid);
emit_counter("xact_commit", labels, stats->n_xact_commit, closure);
emit_counter("xact_rollback", labels, stats->n_xact_rollback, closure);
emit_counter("blks_fetched", labels, stats->n_blocks_fetched, closure);
emit_counter("blks_hit", labels, stats->n_blocks_hit, closure);
emit_counter("tup_returned", labels, stats->n_tuples_returned, closure);
emit_counter("tup_fetched", labels, stats->n_tuples_fetched, closure);
emit_counter("tup_inserted", labels, stats->n_tuples_inserted, closure);
emit_counter("tup_updated", labels, stats->n_tuples_updated, closure);
emit_counter("tup_deleted", labels, stats->n_tuples_deleted, closure);
emit_timestamptz("last_autovac_time", labels, stats->last_autovac_time, closure);
/* Why do we do this?? */
emit_counter("conflicts",
labels,
(stats->n_conflict_tablespace +
stats->n_conflict_lock +
stats->n_conflict_snapshot +
stats->n_conflict_bufferpin +
stats->n_conflict_startup_deadlock),
closure);
/*
emit_counter("conflicts_tablespace", labels, stats->n_conflict_tablespace, closure);
emit_counter("conflicts_lock", labels, stats->n_conflict_lock, closure);
emit_counter("conflicts_snapshot", labels, stats->n_conflict_snapshot, closure);
emit_counter("conflicts_bufferpin", labels, stats->n_conflict_bufferpin, closure);
emit_counter("conflicts_startup_deadlock", labels, stats->n_conflict_startup_deadlock, closure);
*/
emit_counter("temp_files", labels, stats->n_temp_files, closure);
emit_counter("temp_bytes", labels, stats->n_temp_bytes, closure);
emit_counter("deadlocks", labels, stats->n_deadlocks, closure);
emit_counter("checksum_failures", labels, stats->n_checksum_failures, closure);
emit_timestamptz("last_checksum_failure", labels, stats->last_checksum_failure, closure);
emit_counter("blk_read_time", labels, stats->n_block_read_time, closure);
emit_counter("blk_write_time", labels, stats->n_block_write_time, closure);
emit_counter("numbackends", labels, stats->n_sessions, closure);
emit_counter("session_time", labels, stats->total_session_time, closure);
emit_counter("active_time", labels, stats->total_active_time, closure);
emit_counter("idle_in_transaction_time", labels, stats->total_idle_in_xact_time, closure);
emit_counter("sessions_abandoned", labels, stats->n_sessions_abandoned, closure);
emit_counter("sessions_fatal", labels, stats->n_sessions_fatal, closure);
emit_counter("sessions_killed", labels, stats->n_sessions_killed, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
case PGSTAT_KIND_RELATION:
{
PgStat_StatTabEntry *stats = body;
/* db=0 represents the shared tables apparently? */
char *labels = dboid==0
? psprintf("oid=\"%d\"", objoid)
: psprintf("db=\"%d\",oid=\"%d\"", dboid,objoid);
emit_counter("numscans", labels, stats->numscans, closure);
emit_counter("tuples_returned", labels, stats->tuples_returned, closure);
emit_counter("tuples_fetched", labels, stats->tuples_fetched, closure);
emit_counter("tuples_inserted", labels, stats->tuples_inserted, closure);
emit_counter("tuples_updated", labels, stats->tuples_updated, closure);
emit_counter("tuples_deleted", labels, stats->tuples_deleted, closure);
emit_counter("tuples_hot_updated", labels, stats->tuples_hot_updated, closure);
emit_counter("n_live_tuples", labels, stats->n_live_tuples, closure);
emit_counter("n_dead_tuples", labels, stats->n_dead_tuples, closure);
emit_counter("changes_since_analyze", labels, stats->changes_since_analyze, closure);
emit_counter("inserts_since_vacuum", labels, stats->inserts_since_vacuum, closure);
emit_counter("blocks_fetched", labels, stats->blocks_fetched, closure);
emit_counter("blocks_hit", labels, stats->blocks_hit, closure);
emit_timestamptz("vacuum_timestamp", labels, stats->vacuum_timestamp, closure);
emit_counter("vacuum_count", labels, stats->vacuum_count, closure);
emit_timestamptz("autovac_vacuum_timestamp", labels, stats->autovac_vacuum_timestamp, closure);
emit_counter("autovac_vacuum_count", labels, stats->autovac_vacuum_count, closure);
emit_timestamptz("analyze_timestamp", labels, stats->analyze_timestamp, closure);
emit_counter("analyze_count", labels, stats->analyze_count, closure);
emit_timestamptz("autovac_analyze_timestamp", labels, stats->autovac_analyze_timestamp, closure);
emit_counter("autovac_analyze_count", labels, stats->autovac_analyze_count, closure);
break;
}
case PGSTAT_KIND_FUNCTION:
{
PgStat_StatFuncEntry *stats = body;
char *labels = psprintf("db=\"%d\",oid=\"%d\"", dboid,objoid);
emit_counter("calls", labels, stats->f_numcalls, closure);
emit_counter("total_time", labels, stats->f_total_time, closure);
emit_counter("self_time", labels, stats->f_self_time, closure);
break;
}
case PGSTAT_KIND_REPLSLOT:
{
PgStat_StatReplSlotEntry *stats = body;
char *labels = psprintf("slot_name=\"%s\"", name);
emit_counter("spill_txns", labels, stats->spill_txns, closure);
emit_counter("spill_count", labels, stats->spill_count, closure);
emit_counter("spill_bytes", labels, stats->spill_bytes, closure);
emit_counter("stream_txns", labels, stats->stream_txns, closure);
emit_counter("stream_count", labels, stats->stream_count, closure);
emit_counter("stream_bytes", labels, stats->stream_bytes, closure);
emit_counter("total_txns", labels, stats->total_txns, closure);
emit_counter("total_bytes", labels, stats->total_bytes, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
case PGSTAT_KIND_SUBSCRIPTION:
{
PgStat_StatSubEntry *stats = body;
char *labels = psprintf("db=\"%d\",oid=\"%d\"", dboid,objoid);
emit_counter("apply_error_count", labels, stats->apply_error_count, closure);
emit_counter("sync_error_count", labels, stats->sync_error_count, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
/* stats for fixed-numbered objects -- these are actually invoked
* explicitly from dump_stats on the snapshot objects rather than through
* the dshash iteration */
case PGSTAT_KIND_ARCHIVER:
{
PgStat_ArchiverStats *stats = body;
char *labels = NULL;
emit_counter("archived_count", labels, stats->archived_count, closure);
/* last_archived_wal*/
emit_timestamptz("last_archived_timestamp", labels, stats->last_archived_timestamp, closure);
emit_counter("failed_count", labels, stats->failed_count, closure);
/* last_failed_wal */
emit_timestamptz("last_failed_timestamp", labels, stats->last_failed_timestamp, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
case PGSTAT_KIND_BGWRITER:
{
PgStat_BgWriterStats *stats = body;
char *labels = NULL;
emit_counter("buffers_clean", labels, stats->buf_written_clean, closure);
emit_counter("maxwritten_clean", labels, stats->maxwritten_clean, closure);
emit_counter("buffers_alloc", labels, stats->buf_alloc, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
case PGSTAT_KIND_CHECKPOINTER:
{
PgStat_CheckpointerStats *stats = body;
char *labels = NULL;
emit_counter("checkpoints_timed", labels, stats->timed_checkpoints, closure);
emit_counter("checkpoints_req", labels, stats->requested_checkpoints, closure);
emit_counter("checkpoint_write_time", labels, stats->checkpoint_write_time, closure);
emit_counter("checkpoint_sync_time", labels, stats->checkpoint_sync_time, closure);
emit_counter("buffers_checkpoint", labels, stats->buf_written_checkpoints, closure);
emit_counter("buffers_backend", labels, stats->buf_written_backend, closure);
emit_counter("buffers_backend_fsync", labels, stats->buf_fsync_backend, closure);
break;
}
case PGSTAT_KIND_SLRU:
{
PgStat_SLRUStats *stats = body;
char *labels = psprintf("slru=\"%s\"", name);
emit_counter("blks_zeroed", labels, stats->blocks_zeroed, closure);
emit_counter("blks_hit", labels, stats->blocks_hit, closure);
emit_counter("blks_read", labels, stats->blocks_read, closure);
emit_counter("blks_written", labels, stats->blocks_written, closure);
emit_counter("blks_exists", labels, stats->blocks_exists, closure);
emit_counter("flushes", labels, stats->flush, closure);
emit_counter("truncates", labels, stats->truncate, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
case PGSTAT_KIND_WAL:
{
PgStat_WalStats *stats = body;
char *labels=NULL;
emit_counter("wal_records", labels, stats->wal_records, closure);
emit_counter("wal_fpi", labels, stats->wal_fpi, closure);
emit_counter("wal_bytes", labels, stats->wal_bytes, closure);
emit_counter("wal_buffers_full", labels, stats->wal_buffers_full, closure);
emit_counter("wal_write", labels, stats->wal_write, closure);
emit_counter("wal_sync", labels, stats->wal_sync, closure);
emit_counter("wal_write_time", labels, stats->wal_write_time, closure);
emit_counter("wal_sync_time", labels, stats->wal_sync_time, closure);
/*emit_timestamptz("stat_reset_timestamp", labels, stats->stat_reset_timestamp, closure);*/
break;
}
case PGSTAT_KIND_INVALID:
elog(WARNING, "Invalid stats object type found");
break;
}
}
PG_FUNCTION_INFO_V1(pg_stat_dump_stats);
Datum
pg_stat_dump_stats(PG_FUNCTION_ARGS)
{
StringInfo response = makeStringInfo();
pgstat_dump_stats(&dump_stats_callback, response);
/* Test overflow behaviour, the emitted values should be distinct and wrap around to 0 */
emit_counter("test_value", "value=0", 0, response);
emit_counter("test_value", "value=1<<53-2", (1LL<<53)-2, response);
emit_counter("test_value", "value=1<<53-1", (1LL<<53)-1, response);
emit_counter("test_value", "value=1<<53", 1LL<<53, response);
elog(WARNING, "stats:\n%s", response->data);
elog(WARNING, "DBL_MANT_DIG=%d COUNTER_MASK=%llx", DBL_MANT_DIG, COUNTER_MASK);
PG_RETURN_INT32(response->len);
}
char *
pg_stat_dump_stats_string(void)
{
StringInfo response = makeStringInfo();
pgstat_dump_stats(&dump_stats_callback, response);
return response->data;
}
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-11 06:11 ` Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-11 06:11 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/10/22 11:25 PM, Greg Stark wrote:
> On Wed, 10 Aug 2022 at 04:05, Drouvot, Bertrand <[email protected]> wrote:
>> Hi,
>>
>> On 8/9/22 6:00 PM, Greg Stark wrote:
>>> On Tue, 9 Aug 2022 at 06:19, Drouvot, Bertrand <[email protected]> wrote:
>>>> What do you think about adding a function in core PG to provide such
>>>> functionality? (means being able to retrieve all the stats (+ eventually
>>>> add some filtering) without the need to connect to each database).
>>> I'm working on it myself too. I'll post a patch for discussion in a bit.
>> Great! Thank you!
> So I was adding the code to pgstat.c because I had thought there were
> some data types I needed and/or static functions I needed. However you
> and Andres encouraged me to check again now. And indeed I was able,
> after fixing a couple things, to make the code work entirely
> externally.
Nice!
Though I still think to have an SQL API in core could be useful to.
As Andres was not -1 about that idea (as it should be low cost to add
and maintain) as long as somebody cares enough to write something: then
I'll give it a try and submit a patch for it.
>
> This is definitely not polished and there's a couple obvious things
> missing. But at the risk of embarrassment I've attached my WIP. Please
> be gentle :) I'll post the github link in a bit when I've fixed up
> some meta info.
Thanks! I will have a look at it on github (once you share the link).
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-15 14:46 ` Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-08-15 14:46 UTC (permalink / raw)
To: Drouvot, Bertrand <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, 11 Aug 2022 at 02:11, Drouvot, Bertrand <[email protected]> wrote:
>
> As Andres was not -1 about that idea (as it should be low cost to add
> and maintain) as long as somebody cares enough to write something: then
> I'll give it a try and submit a patch for it.
I agree it would be a useful feature. I think there may be things to
talk about here though.
1) Are you planning to go through the local hash table and
LocalSnapshot and obey the consistency mode? I was thinking a flag
passed to build_snapshot to request global mode might be sufficient
instead of a completely separate function.
2) When I did the function attached above I tried to avoid returning
the whole set and make it possible to process them as they arrive. I
actually was hoping to get to the point where I could start shipping
out network data as they arrive and not even buffer up the response,
but I think I need to be careful about hash table locking then.
3) They key difference here is that we're returning whatever stats are
in the hash table rather than using the catalog to drive a list of id
numbers to look up. I guess the API should make it clear this is what
is being returned -- on that note I wonder if I've done something
wrong because I noted a few records with InvalidOid where I didn't
expect it.
4) I'm currently looping over the hash table returning the records all
intermixed. Some users will probably want to do things like "return
all Relation records for all databases" or "return all Index records
for database id xxx". So some form of filtering may be best or perhaps
a way to retrieve just the keys so they can then be looked up one by
one (through the local cache?).
5) On that note I'm not clear how the local cache will interact with
these cross-database lookups. That should probably be documented...
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-16 12:49 ` Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-16 12:49 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/15/22 4:46 PM, Greg Stark wrote:
> On Thu, 11 Aug 2022 at 02:11, Drouvot, Bertrand <[email protected]> wrote:
>> As Andres was not -1 about that idea (as it should be low cost to add
>> and maintain) as long as somebody cares enough to write something: then
>> I'll give it a try and submit a patch for it.
> I agree it would be a useful feature. I think there may be things to
> talk about here though.
>
> 1) Are you planning to go through the local hash table and
> LocalSnapshot and obey the consistency mode? I was thinking a flag
> passed to build_snapshot to request global mode might be sufficient
> instead of a completely separate function.
I think the new API should behave as PGSTAT_FETCH_CONSISTENCY_NONE (as
querying from all the databases increases the risk of having to deal
with "large" number of objects).
I've in mind to do something along those lines (still need to add some
filtering, extra check on the permission,...):
+ dshash_seq_init(&hstat, pgStatLocal.shared_hash, false);
+ while ((p = dshash_seq_next(&hstat)) != NULL)
+ {
+ Datum values[PG_STAT_GET_ALL_TABLES_STATS_COLS];
+ bool nulls[PG_STAT_GET_ALL_TABLES_STATS_COLS];
+ PgStat_StatTabEntry * tabentry = NULL;
+ MemSet(values, 0, sizeof(values));
+ MemSet(nulls, false, sizeof(nulls));
+
+ if (p->key.kind != PGSTAT_KIND_RELATION)
+ continue;
+ if (p->dropped)
+ continue;
+
+ stats_data = dsa_get_address(pgStatLocal.dsa, p->body);
+ LWLockAcquire(&stats_data->lock, LW_SHARED);
+ tabentry = pgstat_get_entry_data(PGSTAT_KIND_RELATION,
stats_data);
+
+
+ values[0] = ObjectIdGetDatum(p->key.dboid);
+ values[1] = ObjectIdGetDatum(p->key.objoid);
+ values[2]= DatumGetInt64(tabentry->tuples_inserted);
.
.
+ tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
values, nulls);
+ LWLockRelease(&stats_data->lock);
+ }
+ dshash_seq_term(&hstat);
What do you think?
> 2) When I did the function attached above I tried to avoid returning
> the whole set and make it possible to process them as they arrive.
Is it the way it has been done? (did not look at your function yet)
> I
> actually was hoping to get to the point where I could start shipping
> out network data as they arrive and not even buffer up the response,
> but I think I need to be careful about hash table locking then.
If using dshash_seq_next() the already returned elements are locked.
But I guess you would like to unlock them (if you are able to process
them as they arrive)?
> 3) They key difference here is that we're returning whatever stats are
> in the hash table rather than using the catalog to drive a list of id
> numbers to look up.
Right.
> I guess the API should make it clear this is what
> is being returned
Right. I think we'll end up with a set of relations id (not their names)
and their associated stats.
> -- on that note I wonder if I've done something
> wrong because I noted a few records with InvalidOid where I didn't
> expect it.
It looks like that InvalidOid for the dbid means that the entry is for a
shared relation.
Where did you see them (while not expecting them)?
> 4) I'm currently looping over the hash table returning the records all
> intermixed. Some users will probably want to do things like "return
> all Relation records for all databases" or "return all Index records
> for database id xxx". So some form of filtering may be best or perhaps
> a way to retrieve just the keys so they can then be looked up one by
> one (through the local cache?).
I've in mind to add some filtering on the dbid (I think it could be
useful for monitoring tool with a persistent connection to one database
but that wants to pull the stats database per database).
I don't think a look up through the local cache will work if the
entry/key is related to another database the API is launched from.
> 5) On that note I'm not clear how the local cache will interact with
> these cross-database lookups. That should probably be documented...
yeah I don't think that would work (if by local cache you mean what is
in the relcache).
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-17 19:46 ` Greg Stark <[email protected]>
2022-08-17 23:30 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-18 06:27 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
0 siblings, 2 replies; 39+ messages in thread
From: Greg Stark @ 2022-08-17 19:46 UTC (permalink / raw)
To: Drouvot, Bertrand <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Tue, 16 Aug 2022 at 08:49, Drouvot, Bertrand <[email protected]> wrote:
>
>
> + if (p->key.kind != PGSTAT_KIND_RELATION)
> + continue;
Hm. So presumably this needs to be extended. Either to let the caller
decide which types of stats to return or to somehow return all the
stats intermixed. In my monitoring code I did the latter because I
didn't think going through the hash table repeatedly would be very
efficient. But it's definitely a pretty awkward API since I need a
switch statement that explicitly lists each case and casts the result.
> > 2) When I did the function attached above I tried to avoid returning
> > the whole set and make it possible to process them as they arrive.
>
> Is it the way it has been done? (did not look at your function yet)
I did it with callbacks. It was quick and easy and convenient for my
use case. But in general I don't really like callbacks and would think
some kind of iterator style api would be nicer.
I am handling the stats entries as they turn up. I'm constructing the
text output for each in a callback and buffering up the whole http
response in a string buffer.
I think that's ok but if I wanted to avoid buffering it up and do
network i/o then I would think the thing to do would be to build the
list of entry keys and then loop over that list doing a hash lookup
for each one and generating the response for each out and writing it
to the network. That way there wouldn't be anything locked, not even
the hash table, while doing network i/o. It would mean a lot of
traffic on the hash table though.
> > -- on that note I wonder if I've done something
> > wrong because I noted a few records with InvalidOid where I didn't
> > expect it.
>
> It looks like that InvalidOid for the dbid means that the entry is for a
> shared relation.
Ah yes. I had actually found that but forgotten it.
There's also a database entry with dboid=InvalidOid which is
apparently where background workers with no database attached report
stats.
> I've in mind to add some filtering on the dbid (I think it could be
> useful for monitoring tool with a persistent connection to one database
> but that wants to pull the stats database per database).
>
> I don't think a look up through the local cache will work if the
> entry/key is related to another database the API is launched from.
Isn't there also a local hash table used to find the entries to reduce
traffic on the shared hash table? Even if you don't take a snapshot
does it get entered there? There are definitely still parts of this
I'm working on a pretty vague understanding of :/
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-17 23:30 ` Andres Freund <[email protected]>
2022-08-18 06:39 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Andres Freund @ 2022-08-17 23:30 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-08-17 15:46:42 -0400, Greg Stark wrote:
> Isn't there also a local hash table used to find the entries to reduce
> traffic on the shared hash table? Even if you don't take a snapshot
> does it get entered there? There are definitely still parts of this
> I'm working on a pretty vague understanding of :/
Yes, there is. But it's more about code that generates stats, rather than
reporting functions. While there's backend local pending stats we need to have
a refcount on the shared stats item so that the stats item can't be dropped
and then revived when those local stats are flushed.
Relevant comments from pgstat.c:
* To avoid contention on the shared hashtable, each backend has a
* backend-local hashtable (pgStatEntryRefHash) in front of the shared
* hashtable, containing references (PgStat_EntryRef) to shared hashtable
* entries. The shared hashtable only needs to be accessed when no prior
* reference is found in the local hashtable. Besides pointing to the
* shared hashtable entry (PgStatShared_HashEntry) PgStat_EntryRef also
* contains a pointer to the shared statistics data, as a process-local
* address, to reduce access costs.
*
* The names for structs stored in shared memory are prefixed with
* PgStatShared instead of PgStat. Each stats entry in shared memory is
* protected by a dedicated lwlock.
*
* Most stats updates are first accumulated locally in each process as pending
* entries, then later flushed to shared memory (just after commit, or by
* idle-timeout). This practically eliminates contention on individual stats
* entries. For most kinds of variable-numbered pending stats data is stored
* in PgStat_EntryRef->pending. All entries with pending data are in the
* pgStatPending list. Pending statistics updates are flushed out by
* pgstat_report_stat().
*
pgstat_internal.h has more details about the refcount aspect:
* Per-object statistics are stored in the "shared stats" hashtable. That
* table's entries (PgStatShared_HashEntry) contain a pointer to the actual stats
* data for the object (the size of the stats data varies depending on the
* kind of stats). The table is keyed by PgStat_HashKey.
*
* Once a backend has a reference to a shared stats entry, it increments the
* entry's refcount. Even after stats data is dropped (e.g., due to a DROP
* TABLE), the entry itself can only be deleted once all references have been
* released.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-17 23:30 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-08-18 06:39 ` Drouvot, Bertrand <[email protected]>
0 siblings, 0 replies; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-18 06:39 UTC (permalink / raw)
To: Andres Freund <[email protected]>; Greg Stark <[email protected]>; +Cc: Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/18/22 1:30 AM, Andres Freund wrote:
> Hi,
>
> On 2022-08-17 15:46:42 -0400, Greg Stark wrote:
>> Isn't there also a local hash table used to find the entries to reduce
>> traffic on the shared hash table? Even if you don't take a snapshot
>> does it get entered there? There are definitely still parts of this
>> I'm working on a pretty vague understanding of :/
> Yes, there is. But it's more about code that generates stats, rather than
> reporting functions. While there's backend local pending stats we need to have
> a refcount on the shared stats item so that the stats item can't be dropped
> and then revived when those local stats are flushed.
What do you think about something along those lines for the reporting
part only?
Datum
pgstat_fetch_all_tables_stats(PG_FUNCTION_ARGS)
{
int dbid = PG_ARGISNULL(0) ? -1 : (int) PG_GETARG_OID(0);
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
dshash_seq_status hstat;
PgStatShared_HashEntry *p;
PgStatShared_Common *stats_data;
/* Only members of pg_read_all_stats can use this function */
if (!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
{
aclcheck_error(ACLCHECK_NO_PRIV, OBJECT_FUNCTION,
"pgstat_fetch_all_tables_stats");
}
pgstat_assert_is_up();
SetSingleFuncCall(fcinfo, 0);
dshash_seq_init(&hstat, pgStatLocal.shared_hash, false);
while ((p = dshash_seq_next(&hstat)) != NULL)
{
Datum values[PG_STAT_GET_ALL_TABLES_STATS_COLS];
bool nulls[PG_STAT_GET_ALL_TABLES_STATS_COLS];
PgStat_StatTabEntry * tabentry = NULL;
MemSet(values, 0, sizeof(values));
MemSet(nulls, false, sizeof(nulls));
/* If looking for specific dbid, ignore all the others */
if (dbid != -1 && p->key.dboid != (Oid) dbid)
continue;
/* If the entry is not of kind relation then ignore it */
if (p->key.kind != PGSTAT_KIND_RELATION)
continue;
/* If the entry has been dropped then ignore it */
if (p->dropped)
continue;
stats_data = dsa_get_address(pgStatLocal.dsa, p->body);
LWLockAcquire(&stats_data->lock, LW_SHARED);
tabentry = pgstat_get_entry_data(p->key.kind, stats_data);
values[0] = ObjectIdGetDatum(p->key.dboid);
values[1] = ObjectIdGetDatum(p->key.objoid);
values[2]= DatumGetInt64(tabentry->tuples_inserted);
values[3]= DatumGetInt64(tabentry->tuples_updated);
values[4]= DatumGetInt64(tabentry->tuples_deleted);
.
.
.
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
values, nulls);
LWLockRelease(&stats_data->lock);
}
dshash_seq_term(&hstat);
return (Datum) 0;
}
I also tried to make use of pgstat_get_entry_ref() but went into a
failed assertion: pgstat_get_entry_ref -> dshash_find ->
ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(hash_table) due to lock acquired by
dshash_seq_next().
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-18 06:27 ` Drouvot, Bertrand <[email protected]>
2022-08-18 19:26 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-18 06:27 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/17/22 9:46 PM, Greg Stark wrote:
> On Tue, 16 Aug 2022 at 08:49, Drouvot, Bertrand <[email protected]> wrote:
>>
>> + if (p->key.kind != PGSTAT_KIND_RELATION)
>> + continue;
> Hm. So presumably this needs to be extended. Either to let the caller
> decide which types of stats to return or to somehow return all the
> stats intermixed. In my monitoring code I did the latter because I
> didn't think going through the hash table repeatedly would be very
> efficient. But it's definitely a pretty awkward API since I need a
> switch statement that explicitly lists each case and casts the result.
What I had in mind is to provide an API to retrieve stats for those that
would need to connect to each database individually otherwise.
That's why I focused on PGSTAT_KIND_RELATION that has
PgStat_KindInfo.accessed_across_databases set to false.
I think that another candidate could also be PGSTAT_KIND_FUNCTION.
I think that's the 2 cases where a monitoring tool connected to a single
database is currently missing stats related to databases it is not
connected to.
So what about 2 functions? one to get the stats for the relations and
one to get the stats for the functions? (And maybe a view on top of each
of them?)
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-18 06:27 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-18 19:26 ` Greg Stark <[email protected]>
2022-08-18 19:51 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-08-18 19:26 UTC (permalink / raw)
To: Drouvot, Bertrand <[email protected]>; +Cc: Andres Freund <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, 18 Aug 2022 at 02:27, Drouvot, Bertrand <[email protected]> wrote:
>
> What I had in mind is to provide an API to retrieve stats for those that
> would need to connect to each database individually otherwise.
>
> That's why I focused on PGSTAT_KIND_RELATION that has
> PgStat_KindInfo.accessed_across_databases set to false.
>
> I think that another candidate could also be PGSTAT_KIND_FUNCTION.
And indexes of course. It's a bit frustrating since without the
catalog you won't know what table the index actually is for... But
they're pretty important stats.
On that note though... What do you think about having the capability
to add other stats kinds to the stats infrastructure? It would make a
lot of sense for pg_stat_statements to add its entries here instead of
having to reimplement a lot of the same magic. And I have in mind an
extension that allows adding other stats and it would be nice to avoid
having to reimplement any of this.
To do that I guess more of the code needs to be moved to be table
driven from the kind structs either with callbacks or with other meta
data. So the kind record could contain tupledesc and the code to
construct the returned tuple so that these functions could return any
custom entry as well as the standard entries.
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-18 06:27 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-18 19:26 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-18 19:51 ` Andres Freund <[email protected]>
2022-08-19 06:12 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Andres Freund @ 2022-08-18 19:51 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Drouvot, Bertrand <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-08-18 15:26:31 -0400, Greg Stark wrote:
> And indexes of course. It's a bit frustrating since without the
> catalog you won't know what table the index actually is for... But
> they're pretty important stats.
FWIW, I think we should split relation stats into table and index
stats. Historically it'd have added a lot of complexity to separate the two,
but I don't think that's the case anymore. And we waste space for index stats
by having lots of table specific fields.
> On that note though... What do you think about having the capability
> to add other stats kinds to the stats infrastructure?
Getting closer to that was one of my goals working on the shared memory stats
stuff.
> It would make a lot of sense for pg_stat_statements to add its entries here
> instead of having to reimplement a lot of the same magic.
Yes, we should move pg_stat_statements over.
It's pretty easy to get massive contention on stats entries with
pg_stat_statements, because it doesn't have support for "batching" updates to
shared stats. And reimplementing the same logic in pg_stat_statements.c
doesn't make sense.
And the set of normalized queries could probably stored in DSA as well - the
file based thing we have right now is problematic.
> To do that I guess more of the code needs to be moved to be table
> driven from the kind structs either with callbacks or with other meta
> data.
Pretty much all of it already is. The only substantial missing bit is
reading/writing of stats files, but that should be pretty easy. And of course
making the callback array extensible.
> So the kind record could contain tupledesc and the code to construct the
> returned tuple so that these functions could return any custom entry as well
> as the standard entries.
I don't see how this would work well - we don't have functions returning
variable kinds of tuples. And what would convert a struct to a tuple?
Nor do I think it's needed - if you have an extension providing a new stats
kind it can also provide accessors.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-10 08:04 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-11 06:11 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-16 12:49 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-18 06:27 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-18 19:26 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-18 19:51 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-08-19 06:12 ` Drouvot, Bertrand <[email protected]>
0 siblings, 0 replies; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-19 06:12 UTC (permalink / raw)
To: Andres Freund <[email protected]>; Greg Stark <[email protected]>; +Cc: Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/18/22 9:51 PM, Andres Freund wrote:
> Hi,
>
> On 2022-08-18 15:26:31 -0400, Greg Stark wrote:
>> And indexes of course. It's a bit frustrating since without the
>> catalog you won't know what table the index actually is for... But
>> they're pretty important stats.
> FWIW, I think we should split relation stats into table and index
> stats. Historically it'd have added a lot of complexity to separate the two,
> but I don't think that's the case anymore. And we waste space for index stats
> by having lots of table specific fields.
It seems to me that we should work on that first then, what do you
think? (If so I can try to have a look at it).
And once done then resume the work to provide the APIs to get all
tables/indexes from all the databases.
That way we'll be able to provide one API for the tables and one for the
indexes (instead of one API for both like my current POC is doing).
>> On that note though... What do you think about having the capability
>> to add other stats kinds to the stats infrastructure?
I think that's a good idea and that would be great to have.
> Getting closer to that was one of my goals working on the shared memory stats
> stuff.
>
>
>> It would make a lot of sense for pg_stat_statements to add its entries here
>> instead of having to reimplement a lot of the same magic.
> Yes, we should move pg_stat_statements over.
>
> It's pretty easy to get massive contention on stats entries with
> pg_stat_statements, because it doesn't have support for "batching" updates to
> shared stats. And reimplementing the same logic in pg_stat_statements.c
> doesn't make sense.
>
> And the set of normalized queries could probably stored in DSA as well - the
> file based thing we have right now is problematic.
>
>
>> To do that I guess more of the code needs to be moved to be table
>> driven from the kind structs either with callbacks or with other meta
>> data.
> Pretty much all of it already is. The only substantial missing bit is
> reading/writing of stats files, but that should be pretty easy. And of course
> making the callback array extensible.
>
>
>> So the kind record could contain tupledesc and the code to construct the
>> returned tuple so that these functions could return any custom entry as well
>> as the standard entries.
> I don't see how this would work well - we don't have functions returning
> variable kinds of tuples. And what would convert a struct to a tuple?
>
> Nor do I think it's needed - if you have an extension providing a new stats
> kind it can also provide accessors.
I think the same (the extension should be able to do that).
I really like the idea of being able to provide new stats kind.
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-09 16:40 ` Andres Freund <[email protected]>
2022-08-10 07:37 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
1 sibling, 1 reply; 39+ messages in thread
From: Andres Freund @ 2022-08-09 16:40 UTC (permalink / raw)
To: Drouvot, Bertrand <[email protected]>; +Cc: Greg Stark <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-08-09 12:18:47 +0200, Drouvot, Bertrand wrote:
> What do you think about adding a function in core PG to provide such
> functionality? (means being able to retrieve all the stats (+ eventually add
> some filtering) without the need to connect to each database).
I'm not that convinced by the use case, but I think it's also low cost to add
and maintain, so if somebody cares enough to write something...
The only thing I would "request" is that such a function requires more
permissions than the default accessors do. I think it's a minor problem that
we allow so much access within a database right now, regardless of object
permissions, but it'd not be a great idea to expand that to other databases,
in bulk?
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 15:55 ` Re: shared-memory based stats collector - v70 Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Re: shared-memory based stats collector - v70 Tom Lane <[email protected]>
2022-07-20 18:41 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-07-20 19:08 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-07-21 15:07 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 10:18 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-09 16:40 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-08-10 07:37 ` Drouvot, Bertrand <[email protected]>
0 siblings, 0 replies; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-10 07:37 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Greg Stark <[email protected]>; Tom Lane <[email protected]>; Melanie Plageman <[email protected]>; Kyotaro Horiguchi <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 8/9/22 6:40 PM, Andres Freund wrote:
> Hi,
>
> On 2022-08-09 12:18:47 +0200, Drouvot, Bertrand wrote:
>> What do you think about adding a function in core PG to provide such
>> functionality? (means being able to retrieve all the stats (+ eventually add
>> some filtering) without the need to connect to each database).
> I'm not that convinced by the use case, but I think it's also low cost to add
> and maintain, so if somebody cares enough to write something...
Ack.
>
> The only thing I would "request" is that such a function requires more
> permissions than the default accessors do. I think it's a minor problem that
> we allow so much access within a database right now, regardless of object
> permissions, but it'd not be a great idea to expand that to other databases,
> in bulk?
Agree that special attention would need to be pay around permissions.
Something like allow its usage if member of pg_read_all_stats?
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-07-20 15:35 ` Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-07-20 16:05 ` Andres Freund <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Andres Freund @ 2022-07-20 16:05 UTC (permalink / raw)
To: Greg Stark <[email protected]>; +Cc: Kyotaro Horiguchi <[email protected]>; Melanie Plageman <[email protected]>; Justin Pryzby <[email protected]>; Thomas Munro <[email protected]>; David G. Johnston <[email protected]>; PostgreSQL Hackers <[email protected]>
Hi,
On 2022-07-20 11:35:13 -0400, Greg Stark wrote:
> Is it true that the shared memory allocation contains the hash table
> entry and body of every object in every database?
Yes. However, note that that was already the case with the old stats
collector - it also kept everything in memory. In addition every read
access to stats loaded a copy of the stats (well of the global stats and
the relevant per-database stats).
It might be worth doing something fancier at some point - the shared
memory stats was already a huge effort, cramming yet another change in
there would pretty much have guaranteed that it'd fail.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
@ 2022-08-08 15:53 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Greg Stark @ 2022-08-08 15:53 UTC (permalink / raw)
To: PostgreSQL Hackers <[email protected]>; Andres Freund <[email protected]>
I'm trying to wrap my head around the shared memory stats collector
infrastructure from
<[email protected]> committed in
5891c7a8ed8f2d3d577e7eea34dacff12d7b6bbd.
I have one question about locking -- afaics there's nothing protecting
reading the shared memory stats. There is an lwlock protecting
concurrent updates of the shared memory stats, but that lock isn't
taken when we read the stats. Are we ok relying on atomic 64-bit reads
or is there something else going on that I'm missing?
In particular I'm looking at pgstat.c:847 in pgstat_fetch_entry()
which does this:
memcpy(stats_data,
pgstat_get_entry_data(kind, entry_ref->shared_stats),
kind_info->shared_data_len);
stats_data is the returned copy of the stats entry with all the
statistics in it. But it's copied from the shared memory location
directly using memcpy and there's no locking or change counter or
anything protecting this memcpy that I can see.
--
greg
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
@ 2022-08-09 08:24 ` Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Kyotaro Horiguchi @ 2022-08-09 08:24 UTC (permalink / raw)
To: [email protected]; +Cc: [email protected]; [email protected]
At Mon, 8 Aug 2022 11:53:19 -0400, Greg Stark <[email protected]> wrote in
> I'm trying to wrap my head around the shared memory stats collector
> infrastructure from
> <[email protected]> committed in
> 5891c7a8ed8f2d3d577e7eea34dacff12d7b6bbd.
>
> I have one question about locking -- afaics there's nothing protecting
> reading the shared memory stats. There is an lwlock protecting
> concurrent updates of the shared memory stats, but that lock isn't
> taken when we read the stats. Are we ok relying on atomic 64-bit reads
> or is there something else going on that I'm missing?
>
> In particular I'm looking at pgstat.c:847 in pgstat_fetch_entry()
> which does this:
>
> memcpy(stats_data,
> pgstat_get_entry_data(kind, entry_ref->shared_stats),
> kind_info->shared_data_len);
>
> stats_data is the returned copy of the stats entry with all the
> statistics in it. But it's copied from the shared memory location
> directly using memcpy and there's no locking or change counter or
> anything protecting this memcpy that I can see.
We take LW_SHARED while creating a snapshot of fixed-numbered
stats. On the other hand we don't for variable-numbered stats. I
agree to you, that we need that also for variable-numbered stats.
If I'm not missing something, it's strange that pgstat_lock_entry()
only takes LW_EXCLUSIVE. The atached changes the interface of
pgstat_lock_entry() but there's only one user since another read of
shared stats entry is not using reference. Thus the interface change
might be too much. If I just add bare LWLockAcquire/Release() to
pgstat_fetch_entry,the amount of the patch will be reduced.
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
Attachments:
[text/x-patch] pg_stat_snapshot_takes_read_lock_1.patch (5.5K, ../../[email protected]/2-pg_stat_snapshot_takes_read_lock_1.patch)
download | inline diff:
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 88e5dd1b2b..7c4e5f0238 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -844,9 +844,11 @@ pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
else
stats_data = MemoryContextAlloc(pgStatLocal.snapshot.context,
kind_info->shared_data_len);
+ pgstat_lock_entry(entry_ref, LW_SHARED, false);
memcpy(stats_data,
pgstat_get_entry_data(kind, entry_ref->shared_stats),
kind_info->shared_data_len);
+ pgstat_unlock_entry(entry_ref);
if (pgstat_fetch_consistency > PGSTAT_FETCH_CONSISTENCY_NONE)
{
@@ -983,9 +985,15 @@ pgstat_build_snapshot(void)
entry->data = MemoryContextAlloc(pgStatLocal.snapshot.context,
kind_info->shared_size);
+ /*
+ * We're directly accesing the shared stats entry not using
+ * reference. pg_stat_lock_entry() cannot be used here.
+ */
+ LWLockAcquire(&stats_data->lock, LW_SHARED);
memcpy(entry->data,
pgstat_get_entry_data(kind, stats_data),
kind_info->shared_size);
+ LWLockRelease(&stats_data->lock);
}
dshash_seq_term(&hstat);
diff --git a/src/backend/utils/activity/pgstat_database.c b/src/backend/utils/activity/pgstat_database.c
index d9275611f0..fdf4d022c1 100644
--- a/src/backend/utils/activity/pgstat_database.c
+++ b/src/backend/utils/activity/pgstat_database.c
@@ -364,7 +364,7 @@ pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
pendingent = (PgStat_StatDBEntry *) entry_ref->pending;
sharedent = (PgStatShared_Database *) entry_ref->shared_stats;
- if (!pgstat_lock_entry(entry_ref, nowait))
+ if (!pgstat_lock_entry(entry_ref, LW_EXCLUSIVE, nowait))
return false;
#define PGSTAT_ACCUM_DBCOUNT(item) \
diff --git a/src/backend/utils/activity/pgstat_function.c b/src/backend/utils/activity/pgstat_function.c
index 427d8c47fc..318db0b3c8 100644
--- a/src/backend/utils/activity/pgstat_function.c
+++ b/src/backend/utils/activity/pgstat_function.c
@@ -200,7 +200,7 @@ pgstat_function_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
/* localent always has non-zero content */
- if (!pgstat_lock_entry(entry_ref, nowait))
+ if (!pgstat_lock_entry(entry_ref, LW_EXCLUSIVE, nowait))
return false;
shfuncent->stats.f_numcalls += localent->f_counts.f_numcalls;
diff --git a/src/backend/utils/activity/pgstat_relation.c b/src/backend/utils/activity/pgstat_relation.c
index a846d9ffb6..98dda726db 100644
--- a/src/backend/utils/activity/pgstat_relation.c
+++ b/src/backend/utils/activity/pgstat_relation.c
@@ -782,7 +782,7 @@ pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
return true;
}
- if (!pgstat_lock_entry(entry_ref, nowait))
+ if (!pgstat_lock_entry(entry_ref, LW_EXCLUSIVE, nowait))
return false;
/* add the values to the shared entry. */
diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c
index 89060ef29a..fdd20d80a1 100644
--- a/src/backend/utils/activity/pgstat_shmem.c
+++ b/src/backend/utils/activity/pgstat_shmem.c
@@ -568,14 +568,14 @@ pgstat_release_entry_ref(PgStat_HashKey key, PgStat_EntryRef *entry_ref,
}
bool
-pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait)
+pgstat_lock_entry(PgStat_EntryRef *entry_ref, LWLockMode mode, bool nowait)
{
LWLock *lock = &entry_ref->shared_stats->lock;
if (nowait)
- return LWLockConditionalAcquire(lock, LW_EXCLUSIVE);
+ return LWLockConditionalAcquire(lock, mode);
- LWLockAcquire(lock, LW_EXCLUSIVE);
+ LWLockAcquire(lock, mode);
return true;
}
@@ -598,7 +598,7 @@ pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, Oid objoid,
entry_ref = pgstat_get_entry_ref(kind, dboid, objoid, true, NULL);
/* lock the shared entry to protect the content, skip if failed */
- if (!pgstat_lock_entry(entry_ref, nowait))
+ if (!pgstat_lock_entry(entry_ref, LW_EXCLUSIVE, nowait))
return NULL;
return entry_ref;
@@ -920,7 +920,7 @@ pgstat_reset_entry(PgStat_Kind kind, Oid dboid, Oid objoid, TimestampTz ts)
if (!entry_ref || entry_ref->shared_entry->dropped)
return;
- (void) pgstat_lock_entry(entry_ref, false);
+ (void) pgstat_lock_entry(entry_ref, LW_EXCLUSIVE, false);
shared_stat_reset_contents(kind, entry_ref->shared_stats, ts);
pgstat_unlock_entry(entry_ref);
}
diff --git a/src/backend/utils/activity/pgstat_subscription.c b/src/backend/utils/activity/pgstat_subscription.c
index e1072bd5ba..eeb2e3370f 100644
--- a/src/backend/utils/activity/pgstat_subscription.c
+++ b/src/backend/utils/activity/pgstat_subscription.c
@@ -91,7 +91,7 @@ pgstat_subscription_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
/* localent always has non-zero content */
- if (!pgstat_lock_entry(entry_ref, nowait))
+ if (!pgstat_lock_entry(entry_ref, LW_EXCLUSIVE, nowait))
return false;
#define SUB_ACC(fld) shsubent->stats.fld += localent->fld
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 9303d05427..fe1ac0f274 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -580,7 +580,7 @@ extern void pgstat_detach_shmem(void);
extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, Oid objoid,
bool create, bool *found);
-extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait);
+extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, LWLockMode mode, bool nowait);
extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref);
extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
extern void pgstat_drop_all_entries(void);
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
@ 2022-08-09 16:53 ` Andres Freund <[email protected]>
2022-08-10 02:39 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Andres Freund @ 2022-08-09 16:53 UTC (permalink / raw)
To: Kyotaro Horiguchi <[email protected]>; +Cc: [email protected]; [email protected]
Hi,
On 2022-08-09 17:24:35 +0900, Kyotaro Horiguchi wrote:
> At Mon, 8 Aug 2022 11:53:19 -0400, Greg Stark <[email protected]> wrote in
> > I'm trying to wrap my head around the shared memory stats collector
> > infrastructure from
> > <[email protected]> committed in
> > 5891c7a8ed8f2d3d577e7eea34dacff12d7b6bbd.
> >
> > I have one question about locking -- afaics there's nothing protecting
> > reading the shared memory stats. There is an lwlock protecting
> > concurrent updates of the shared memory stats, but that lock isn't
> > taken when we read the stats. Are we ok relying on atomic 64-bit reads
> > or is there something else going on that I'm missing?
Yes, that's not right. Not sure how it ended up that way. There was a lot of
refactoring and pushing down the locking into different places, I guess it got
lost somewhere on the way :(. It's unlikely to be a large problem, but we
should fix it.
> If I'm not missing something, it's strange that pgstat_lock_entry()
> only takes LW_EXCLUSIVE.
I think it makes some sense, given that there's a larger number of callers for
that in various stats-emitting code. Perhaps we could just add a separate
function with a _shared() suffix?
> The atached changes the interface of
> pgstat_lock_entry() but there's only one user since another read of
> shared stats entry is not using reference. Thus the interface change
> might be too much. If I just add bare LWLockAcquire/Release() to
> pgstat_fetch_entry,the amount of the patch will be reduced.
Could you try the pgstat_lock_entry_shared() approach?
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
@ 2022-08-10 02:39 ` Kyotaro Horiguchi <[email protected]>
2022-08-10 12:02 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Kyotaro Horiguchi @ 2022-08-10 02:39 UTC (permalink / raw)
To: [email protected]; +Cc: [email protected]; [email protected]
At Tue, 9 Aug 2022 09:53:19 -0700, Andres Freund <[email protected]> wrote in
> Hi,
>
> On 2022-08-09 17:24:35 +0900, Kyotaro Horiguchi wrote:
> > If I'm not missing something, it's strange that pgstat_lock_entry()
> > only takes LW_EXCLUSIVE.
>
> I think it makes some sense, given that there's a larger number of callers for
> that in various stats-emitting code. Perhaps we could just add a separate
> function with a _shared() suffix?
Sure. That was an alternative I had in my mind.
> > The atached changes the interface of
> > pgstat_lock_entry() but there's only one user since another read of
> > shared stats entry is not using reference. Thus the interface change
> > might be too much. If I just add bare LWLockAcquire/Release() to
> > pgstat_fetch_entry,the amount of the patch will be reduced.
>
> Could you try the pgstat_lock_entry_shared() approach?
Of course. Please find the attached.
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 02:39 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
@ 2022-08-10 12:02 ` Drouvot, Bertrand <[email protected]>
2022-08-22 02:32 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
0 siblings, 1 reply; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-10 12:02 UTC (permalink / raw)
To: Kyotaro Horiguchi <[email protected]>; [email protected]; +Cc: [email protected]; [email protected]
Hi,
On 8/10/22 4:39 AM, Kyotaro Horiguchi wrote:
> At Tue, 9 Aug 2022 09:53:19 -0700, Andres Freund <[email protected]> wrote in
>> Could you try the pgstat_lock_entry_shared() approach?
> Of course. Please find the attached.
Thanks for the patch!
It looks good to me.
One nit comment though, instead of:
+ /*
+ * Take lwlock directly instead of using
pg_stat_lock_entry_shared()
+ * which requires a reference.
+ */
what about?
+ /*
+ * Acquire the LWLock directly instead of using
pg_stat_lock_entry_shared()
+ * which requires a reference.
+ */
I think that's more consistent with other comments mentioning LWLock
acquisition.
Regards,
--
Bertrand Drouvot
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 02:39 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-10 12:02 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
@ 2022-08-22 02:32 ` Kyotaro Horiguchi <[email protected]>
2022-08-22 05:51 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-23 03:20 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
0 siblings, 2 replies; 39+ messages in thread
From: Kyotaro Horiguchi @ 2022-08-22 02:32 UTC (permalink / raw)
To: [email protected]; +Cc: [email protected]; [email protected]; [email protected]
At Wed, 10 Aug 2022 14:02:34 +0200, "Drouvot, Bertrand" <[email protected]> wrote in
> what about?
>
> + /*
> + * Acquire the LWLock directly instead of using
> pg_stat_lock_entry_shared()
> + * which requires a reference.
> + */
>
>
> I think that's more consistent with other comments mentioning LWLock
> acquisition.
Sure. Thaks!. I did that in the attached.
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 02:39 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-10 12:02 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-22 02:32 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
@ 2022-08-22 05:51 ` Drouvot, Bertrand <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Drouvot, Bertrand @ 2022-08-22 05:51 UTC (permalink / raw)
To: Kyotaro Horiguchi <[email protected]>; +Cc: [email protected]; [email protected]; [email protected]
Hi,
On 8/22/22 4:32 AM, Kyotaro Horiguchi wrote:
> At Wed, 10 Aug 2022 14:02:34 +0200, "Drouvot, Bertrand" <[email protected]> wrote in
>> what about?
>>
>> + /*
>> + * Acquire the LWLock directly instead of using
>> pg_stat_lock_entry_shared()
>> + * which requires a reference.
>> + */
>>
>>
>> I think that's more consistent with other comments mentioning LWLock
>> acquisition.
> Sure. Thaks!. I did that in the attached.
Thank you!
The patch looks good to me.
Regards,
Bertrand
^ permalink raw reply [nested|flat] 39+ messages in thread
* Re: shared-memory based stats collector - v70
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Re: shared-memory based stats collector - v70 Andres Freund <[email protected]>
2022-08-10 02:39 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
2022-08-10 12:02 ` Re: shared-memory based stats collector - v70 Drouvot, Bertrand <[email protected]>
2022-08-22 02:32 ` Re: shared-memory based stats collector - v70 Kyotaro Horiguchi <[email protected]>
@ 2022-08-23 03:20 ` Andres Freund <[email protected]>
1 sibling, 0 replies; 39+ messages in thread
From: Andres Freund @ 2022-08-23 03:20 UTC (permalink / raw)
To: Kyotaro Horiguchi <[email protected]>; +Cc: [email protected]; [email protected]; [email protected]
Hi,
On 2022-08-22 11:32:14 +0900, Kyotaro Horiguchi wrote:
> At Wed, 10 Aug 2022 14:02:34 +0200, "Drouvot, Bertrand" <[email protected]> wrote in
> > what about?
> >
> > + /*
> > + * Acquire the LWLock directly instead of using
> > pg_stat_lock_entry_shared()
> > + * which requires a reference.
> > + */
> >
> >
> > I think that's more consistent with other comments mentioning LWLock
> > acquisition.
>
> Sure. Thaks!. I did that in the attached.
Pushed, thanks!
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 39+ messages in thread
end of thread, other threads:[~2022-08-23 03:20 UTC | newest]
Thread overview: 39+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2022-04-14 01:20 ` Michael Paquier <[email protected]>
2022-07-20 15:35 ` Greg Stark <[email protected]>
2022-07-20 15:55 ` Melanie Plageman <[email protected]>
2022-07-20 16:08 ` Tom Lane <[email protected]>
2022-07-20 16:34 ` Andres Freund <[email protected]>
2022-07-20 18:41 ` Greg Stark <[email protected]>
2022-07-20 19:08 ` Andres Freund <[email protected]>
2022-07-21 15:07 ` Greg Stark <[email protected]>
2022-08-09 10:18 ` Drouvot, Bertrand <[email protected]>
2022-08-09 16:00 ` Greg Stark <[email protected]>
2022-08-09 16:47 ` Andres Freund <[email protected]>
2022-08-10 08:13 ` Drouvot, Bertrand <[email protected]>
2022-08-10 18:18 ` Greg Stark <[email protected]>
2022-08-10 19:48 ` Greg Stark <[email protected]>
2022-08-10 22:26 ` Andres Freund <[email protected]>
2022-08-10 22:23 ` Andres Freund <[email protected]>
2022-08-10 08:04 ` Drouvot, Bertrand <[email protected]>
2022-08-10 21:25 ` Greg Stark <[email protected]>
2022-08-11 06:11 ` Drouvot, Bertrand <[email protected]>
2022-08-15 14:46 ` Greg Stark <[email protected]>
2022-08-16 12:49 ` Drouvot, Bertrand <[email protected]>
2022-08-17 19:46 ` Greg Stark <[email protected]>
2022-08-17 23:30 ` Andres Freund <[email protected]>
2022-08-18 06:39 ` Drouvot, Bertrand <[email protected]>
2022-08-18 06:27 ` Drouvot, Bertrand <[email protected]>
2022-08-18 19:26 ` Greg Stark <[email protected]>
2022-08-18 19:51 ` Andres Freund <[email protected]>
2022-08-19 06:12 ` Drouvot, Bertrand <[email protected]>
2022-08-09 16:40 ` Andres Freund <[email protected]>
2022-08-10 07:37 ` Drouvot, Bertrand <[email protected]>
2022-07-20 16:05 ` Andres Freund <[email protected]>
2022-08-08 15:53 Re: shared-memory based stats collector - v70 Greg Stark <[email protected]>
2022-08-09 08:24 ` Kyotaro Horiguchi <[email protected]>
2022-08-09 16:53 ` Andres Freund <[email protected]>
2022-08-10 02:39 ` Kyotaro Horiguchi <[email protected]>
2022-08-10 12:02 ` Drouvot, Bertrand <[email protected]>
2022-08-22 02:32 ` Kyotaro Horiguchi <[email protected]>
2022-08-22 05:51 ` Drouvot, Bertrand <[email protected]>
2022-08-23 03:20 ` Andres Freund <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox