Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit090010f

Browse files
committed
Improve performance of find_tabstat_entry()/get_tabstat_entry()
Patch introduces a hash map reloid -> PgStat_TableStatus which improvesperformance in case of large number of tables/partitions.Author: Aleksander AlekseevReviewed-by: Andres Freund, Anastasia Lubennikova, Tels, mehttps://commitfest.postgresql.org/13/1058/
1 parentd655614 commit090010f

File tree

1 file changed

+93
-46
lines changed

1 file changed

+93
-46
lines changed

‎src/backend/postmaster/pgstat.c

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,20 @@ typedef struct TabStatusArray
173173

174174
staticTabStatusArray*pgStatTabList=NULL;
175175

176+
/*
177+
* pgStatTabHash entry
178+
*/
179+
typedefstructTabStatHashEntry
180+
{
181+
Oidt_id;
182+
PgStat_TableStatus*tsa_entry;
183+
}TabStatHashEntry;
184+
185+
/*
186+
* Hash table for O(1) t_id -> tsa_entry lookup
187+
*/
188+
staticHTAB*pgStatTabHash=NULL;
189+
176190
/*
177191
* Backends store per-function info that's waiting to be sent to the collector
178192
* in this hash table (indexed by function OID).
@@ -840,6 +854,14 @@ pgstat_report_stat(bool force)
840854
tsa->tsa_used=0;
841855
}
842856

857+
/*
858+
* pgStatTabHash is outdated on this point so we have to clean it,
859+
* hash_destroy() will remove hash memory context, allocated in
860+
* make_sure_stat_tab_initialized()
861+
*/
862+
hash_destroy(pgStatTabHash);
863+
pgStatTabHash=NULL;
864+
843865
/*
844866
* Send partial messages. Make sure that any pending xact commit/abort
845867
* gets counted, even if there are no table stats to send.
@@ -1684,60 +1706,88 @@ pgstat_initstats(Relation rel)
16841706
rel->pgstat_info=get_tabstat_entry(rel_id,rel->rd_rel->relisshared);
16851707
}
16861708

1709+
/*
1710+
* Make sure pgStatTabList and pgStatTabHash are initialized.
1711+
*/
1712+
staticvoid
1713+
make_sure_stat_tab_initialized()
1714+
{
1715+
HASHCTLctl;
1716+
MemoryContextnew_ctx;
1717+
1718+
if(!pgStatTabList)
1719+
{
1720+
/* This is first time procedure is called */
1721+
pgStatTabList= (TabStatusArray*)MemoryContextAllocZero(TopMemoryContext,
1722+
sizeof(TabStatusArray));
1723+
}
1724+
1725+
if(pgStatTabHash)
1726+
return;
1727+
1728+
/* Hash table was freed or never existed. */
1729+
1730+
new_ctx=AllocSetContextCreate(
1731+
TopMemoryContext,
1732+
"PGStatLookupHashTableContext",
1733+
ALLOCSET_DEFAULT_SIZES);
1734+
1735+
memset(&ctl,0,sizeof(ctl));
1736+
ctl.keysize=sizeof(Oid);
1737+
ctl.entrysize=sizeof(TabStatHashEntry);
1738+
ctl.hcxt=new_ctx;
1739+
1740+
pgStatTabHash=hash_create("pgstat t_id to tsa_entry lookup hash table",
1741+
TABSTAT_QUANTUM,&ctl,HASH_ELEM |HASH_BLOBS |HASH_CONTEXT);
1742+
}
1743+
16871744
/*
16881745
* get_tabstat_entry - find or create a PgStat_TableStatus entry for rel
16891746
*/
16901747
staticPgStat_TableStatus*
16911748
get_tabstat_entry(Oidrel_id,boolisshared)
16921749
{
1750+
TabStatHashEntry*hash_entry;
16931751
PgStat_TableStatus*entry;
16941752
TabStatusArray*tsa;
1695-
TabStatusArray*prev_tsa;
1696-
inti;
1753+
boolfound;
1754+
1755+
make_sure_stat_tab_initialized();
16971756

16981757
/*
1699-
*Search the already-used tabstat slots for this relation.
1758+
*Find an entry or create a new one.
17001759
*/
1701-
prev_tsa=NULL;
1702-
for (tsa=pgStatTabList;tsa!=NULL;prev_tsa=tsa,tsa=tsa->tsa_next)
1760+
hash_entry=hash_search(pgStatTabHash,&rel_id,HASH_ENTER,&found);
1761+
if(found)
1762+
returnhash_entry->tsa_entry;
1763+
1764+
/*
1765+
* `hash_entry` was just created and now we have to fill it.
1766+
* First make sure there is a free space in a last element of pgStatTabList.
1767+
*/
1768+
tsa=pgStatTabList;
1769+
while(tsa->tsa_used==TABSTAT_QUANTUM)
17031770
{
1704-
for (i=0;i<tsa->tsa_used;i++)
1771+
if(tsa->tsa_next==NULL)
17051772
{
1706-
entry=&tsa->tsa_entries[i];
1707-
if (entry->t_id==rel_id)
1708-
returnentry;
1773+
tsa->tsa_next= (TabStatusArray*)MemoryContextAllocZero(TopMemoryContext,
1774+
sizeof(TabStatusArray));
17091775
}
17101776

1711-
if (tsa->tsa_used<TABSTAT_QUANTUM)
1712-
{
1713-
/*
1714-
* It must not be present, but we found a free slot instead. Fine,
1715-
* let's use this one. We assume the entry was already zeroed,
1716-
* either at creation or after last use.
1717-
*/
1718-
entry=&tsa->tsa_entries[tsa->tsa_used++];
1719-
entry->t_id=rel_id;
1720-
entry->t_shared=isshared;
1721-
returnentry;
1722-
}
1777+
tsa=tsa->tsa_next;
17231778
}
17241779

17251780
/*
1726-
* We ran out of tabstat slots, so allocate more. Be sure they're zeroed.
1727-
*/
1728-
tsa= (TabStatusArray*)MemoryContextAllocZero(TopMemoryContext,
1729-
sizeof(TabStatusArray));
1730-
if (prev_tsa)
1731-
prev_tsa->tsa_next=tsa;
1732-
else
1733-
pgStatTabList=tsa;
1734-
1735-
/*
1736-
* Use the first entry of the new TabStatusArray.
1781+
* Add an entry.
17371782
*/
17381783
entry=&tsa->tsa_entries[tsa->tsa_used++];
17391784
entry->t_id=rel_id;
17401785
entry->t_shared=isshared;
1786+
1787+
/*
1788+
* Add a corresponding entry to pgStatTabHash.
1789+
*/
1790+
hash_entry->tsa_entry=entry;
17411791
returnentry;
17421792
}
17431793

@@ -1749,22 +1799,19 @@ get_tabstat_entry(Oid rel_id, bool isshared)
17491799
PgStat_TableStatus*
17501800
find_tabstat_entry(Oidrel_id)
17511801
{
1752-
PgStat_TableStatus*entry;
1753-
TabStatusArray*tsa;
1754-
inti;
1802+
TabStatHashEntry*hash_entry;
17551803

1756-
for (tsa=pgStatTabList;tsa!=NULL;tsa=tsa->tsa_next)
1757-
{
1758-
for (i=0;i<tsa->tsa_used;i++)
1759-
{
1760-
entry=&tsa->tsa_entries[i];
1761-
if (entry->t_id==rel_id)
1762-
returnentry;
1763-
}
1764-
}
1804+
/*
1805+
* There are no entries at all.
1806+
*/
1807+
if(!pgStatTabHash)
1808+
returnNULL;
17651809

1766-
/* Not present */
1767-
returnNULL;
1810+
hash_entry=hash_search(pgStatTabHash,&rel_id,HASH_FIND,NULL);
1811+
if(!hash_entry)
1812+
returnNULL;
1813+
1814+
returnhash_entry->tsa_entry;
17681815
}
17691816

17701817
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp