Giter VIP home page Giter VIP logo

Comments (22)

RekGRpth avatar RekGRpth commented on August 10, 2024 1

in your use case, it is the deleted_table_expr

yes

from diskquota.

xuebinsu avatar xuebinsu commented on August 10, 2024

To avoid building large string, maybe we should use COPY to flush to diskquota.table_size when the change set is large.

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

maybe we should use COPY

how can we use copy for deleting?

from diskquota.

xuebinsu avatar xuebinsu commented on August 10, 2024

maybe we should use COPY

how can we use copy for deleting?

Sorry, I might make a false assumption. Just to confirm, in your use case, it is the deleted_table_expr rather than the insert_statement that caused this ERROR, correct?

from diskquota.

xuebinsu avatar xuebinsu commented on August 10, 2024

OK. Could you please elaborate on why using views can mitigate this issue?

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

why using views can mitigate this issue?

because with view one may execute something like

delete from diskquota.table_size where (tableid, segid) in ( SELECT * FROM deleted_table_view );

where deleted_table_view is view, realized via c-function like pg_stat_activity and pg_stat_get_activity

from diskquota.

xuebinsu avatar xuebinsu commented on August 10, 2024

why using views can mitigate this issue?

because with view one may execute something like

delete from diskquota.table_size where (tableid, segid) in ( SELECT * FROM deleted_table_view );

where deleted_table_view is view, realized via c-function like pg_stat_activity and pg_stat_get_activity

Thanks! I think that's a good idea!

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

I discovered that leads to this problem. Bug is more deep!

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

at start diskquota tries to load all table into hash map in ram

ret = SPI_execute("select tableid, size, segid from diskquota.table_size", true, 0);

but in our case it fails with error

"ERROR","XX000","invalid memory alloc request size 1073741824 (context 'SPI TupTable') (mcxt.c:1357)",,,,,"SQL statement ""select tableid, size, segid from diskquota.table_size""",,0,,"mcxt.c",571,

but this error is catched by

diskquota/src/quotamodel.c

Lines 796 to 845 in a939bc0

PG_TRY();
{
if (SPI_OK_CONNECT != SPI_connect())
{
ereport(ERROR,
(errcode(ERRCODE_INTERNAL_ERROR), errmsg("[diskquota] unable to connect to execute SPI query")));
}
connected = true;
PushActiveSnapshot(GetTransactionSnapshot());
pushed_active_snap = true;
/*
* initialization stage all the tables are active. later loop, only the
* tables whose disk size changed will be treated as active
*
* local_active_table_stat_map only contains the active tables which belong
* to the current database.
*/
local_active_table_stat_map = gp_fetch_active_tables(is_init);
bool hasActiveTable = (hash_get_num_entries(local_active_table_stat_map) != 0);
/* TODO: if we can skip the following steps when there is no active table */
/* recalculate the disk usage of table, schema and role */
calculate_table_disk_usage(is_init, local_active_table_stat_map);
for (QuotaType type = 0; type < NUM_QUOTA_TYPES; ++type)
{
check_quota_map(type);
}
/* flush local table_size_map to user table table_size */
flush_to_table_size();
/* copy local reject map back to shared reject map */
bool reject_map_changed = flush_local_reject_map();
/*
* Dispatch rejectmap entries to segments to perform hard-limit.
* If the bgworker is in init mode, the rejectmap should be refreshed anyway.
* Otherwise, only when the rejectmap is changed or the active_table_list is
* not empty the rejectmap should be dispatched to segments.
*/
if (is_init || (diskquota_hardlimit && (reject_map_changed || hasActiveTable)))
dispatch_rejectmap(local_active_table_stat_map);
hash_destroy(local_active_table_stat_map);
}
PG_CATCH();
{
/* Prevents interrupts while cleaning up */
HOLD_INTERRUPTS();
EmitErrorReport();
FlushErrorState();
ret = false;
/* Now we can allow interrupts again */
RESUME_INTERRUPTS();
}
thus diskquota simply ignores ignores unsuccessful loading and filling hash map and thinks that it contains nothing and forms sql to remove all ids from table, but again exceeds max alloc size

Cannot enlarge string buffer containing 1073741807 bytes by 20 more bytes.

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

instead load all table to ram at once I suggest doing something like in pg_prewarm extension or simply fetch by portions via SPI_cursor_fetch

from diskquota.

xuebinsu avatar xuebinsu commented on August 10, 2024

Thanks! Great analysis!

from diskquota.

zhrt123 avatar zhrt123 commented on August 10, 2024
"ERROR","XX000","invalid memory alloc request size 1073741824 (context 'SPI TupTable') (mcxt.c:1357)",,,,,"SQL statement ""select tableid, size, segid from diskquota.table_size""",,0,,"mcxt.c",571,

Can you please tell me the scene of this error? This error will not be raised unless the number of entries exceeds 10^8, and we have not encountered that situation currently.

diskquota.table_size is used to avoid scanning all tables during cluster startup. And we're considering just scanning all tables and removing diskquota.table_size in diskquota-3.0, so that we do not need to fetch or store table size. To avoid occupying too many resources, we will scan tables in portions. I hope to get your opinion.

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

Can you please tell me the scene of this error? This error will not be raised unless the number of entries exceeds 10^8, and we have not encountered that situation currently.

this error occures on diskquota 2.0 when

select count(*) from diskquota.table_size;
118458142

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

I hope to get your opinion.

My opinion: segments should manage quotas instead coordinator

from diskquota.

zhrt123 avatar zhrt123 commented on August 10, 2024

Can you please tell me the scene of this error? This error will not be raised unless the number of entries exceeds 10^8, and we have not encountered that situation currently.

this error occures on diskquota 2.0 when

select count(*) from diskquota.table_size;
118458142

How do you insert these entries, by creating 10^8 tables?

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

How do you insert these entries, by creating 10^8 tables?

it became so big after updating from 1.0 to 2.0

from diskquota.

zhrt123 avatar zhrt123 commented on August 10, 2024

I hope to get your opinion.

My opinion: segments should manage quotas instead coordinator

The segment just has its own table-size information and does not know the entire table's size and whether the quota limit is exceeded. So we manage the quota config on the coordinator.

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

The segment just has its own table-size information and does not know the entire table's size and whether the quota limit is exceeded. So we manage the quota config on the coordinator.

I suggest distribute whole quota limit between all segments equally or by some GUC or even setup limit per segmen

from diskquota.

zhrt123 avatar zhrt123 commented on August 10, 2024

I suggest distribute whole quota limit between all segments equally or by some GUC or even setup limit per segment

Thanks for your advice. We've added a per-segment quota limit in diskquota-2.0, which indicates each segment can not exceed quota_size * ratio and the whole size can not exceed quota_size. If we just dispatch quota_size * ratio to each segment and quota_size * ratio * segment_number exceeded quota_size, the whole quota limit will be invalid.

from diskquota.

zhrt123 avatar zhrt123 commented on August 10, 2024

it became so big after updating from 1.0 to 2.0

we added a per-segment quota in diskquota-2.0. It splits each table's size with segid, so the number of entries is multiplied by segment_number.

from diskquota.

RekGRpth avatar RekGRpth commented on August 10, 2024

It splits each table's size with segid, so the number of entries is multiplied by segment_number.

we have over 500 segments

from diskquota.

zhrt123 avatar zhrt123 commented on August 10, 2024

we have over 500 segments

Too many TableSizeEntrys is the problem of diskquota-2.x and we plan to solve this problem in diskquota-3.0.

from diskquota.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.