powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обслуживание секций
18 сообщений из 18, страница 1 из 1
Обслуживание секций
    #39878310
Фотография DSKalugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть секционированная таблица ru.propose_sod и её секция private.propose_sod_ru_2019 с данными за 2019г размером 1,8ТБ
Планирую заменить период секционирования с "годового" на "помесячный" (слишком медленно выполняются запросы + сложности в обслуживании секций)
Можно ли в наполненной секции заменить верхнюю границу диапазона с '2020-01-01' на '2019-11-01'?
Не повлечет ли это действие риск потери данных или выделение дополнительного пространства на диске (который и так переполнен) или блокировку таблицы на длительное время... ?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
-- секционированная таблица
CREATE TABLE ru.propose_sod (
  id BIGSERIAL,
  receive_id INTEGER DEFAULT 0 NOT NULL,
  date_begin DATE NOT NULL,
  balance_begin REAL DEFAULT 0 NOT NULL,
  quantity_credit REAL DEFAULT 0 NOT NULL,
  price_credit REAL DEFAULT 0 NOT NULL,
  quantity_debit REAL DEFAULT 0 NOT NULL,
  price_debit REAL DEFAULT 0 NOT NULL,
  drugs_sha1 VARCHAR(40),
  flag_set SMALLINT DEFAULT 0 NOT NULL
) 
PARTITION BY RANGE (date_begin)
WITH (oids = false);
-- секция
CREATE TABLE private.propose_sod_ru_2019 PARTITION OF ru.propose_sod(
  CONSTRAINT pk_propose_sod_ru_2019 PRIMARY KEY(id),
  CONSTRAINT fk_propose_sod_ru_2019_r FOREIGN KEY (receive_id)
    REFERENCES ru.receive_day(id)
    ON DELETE CASCADE
    ON UPDATE NO ACTION
    NOT DEFERRABLE
) 
FOR VALUES FROM ('2019-01-01') TO ('2020-01-01')
WITH (oids = false)
TABLESPACE arch_global;

CREATE INDEX propose_sod_ru_2019_date_begin_idx ON private.propose_sod_ru_2019
  USING btree (date_begin)
  TABLESPACE arch_global;

CREATE INDEX propose_sod_ru_2019_drugs_sha1 ON private.propose_sod_ru_2019
  USING btree (drugs_sha1 COLLATE pg_catalog."default")
  TABLESPACE arch_global;

CREATE INDEX propose_sod_ru_2019_rcv_id ON private.propose_sod_ru_2019
  USING btree (receive_id)
  TABLESPACE arch_global;
-- мастер
CREATE TABLE ru.receive_day (
  id SERIAL,
  organization_id INTEGER DEFAULT 0 NOT NULL,
  date_receive TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
  date_begin DATE,
  date_end DATE,
  price_sum DOUBLE PRECISION DEFAULT 0 NOT NULL,
  total_positions INTEGER DEFAULT 0 NOT NULL,
  unknown_positions INTEGER DEFAULT 0 NOT NULL,
  hash_data VARCHAR(40) DEFAULT ''::character varying NOT NULL,
  flag_set INTEGER DEFAULT 0 NOT NULL,
  meta JSONB,
  CONSTRAINT pk_ps_receive_so_ru PRIMARY KEY(id)
) 
WITH (oids = false);
CREATE INDEX ps_receive_so_ru_idx_db ON ru.receive_day
  USING btree (date_begin);

CREATE INDEX ps_receive_so_ru_idx_o ON ru.receive_day
  USING btree (organization_id);



PostgreSQL 11 / Ubuntu / Размер БД 7,2ТБ / Заполненность диска 96%(!)
...
Рейтинг: 0 / 0
Обслуживание секций
    #39878316
lr2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
lr2
Гость
SET friday_mode = ON;


Сначала хорошо бы сделать VACUUM FULL.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39878323
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
alter table private.propose_sod_ru_2019 add constraint tmp_attach check (date_begin >= '2019-01-01' and date_begin < '2019-11-01') not valid;
alter table private.propose_sod_ru_2019 validate constraint tmp_attach;
alter table ru.propose_sod DETACH PARTITION  private.propose_sod_ru_2019;
alter table ru.propose_sod ATTACH PARTITION private.propose_sod_ru_2019 FOR VALUES FROM ('2019-01-01') TO ('2019-11-01');
alter table private.propose_sod_ru_2019 drop constraint tmp_attach;



без check attach partition будет проверять данные на соответствие ограничению. (seqscan в один поток без индексов)
...
Рейтинг: 0 / 0
Обслуживание секций
    #39878343
Фотография DSKalugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lr2Сначала хорошо бы сделать VACUUM FULL.
Это повлечет за собой блокировку и выделение места ~ 1,8ТБ для пересоздания таблицы. А места уже нет :-(
...
Рейтинг: 0 / 0
Обслуживание секций
    #39878364
Фотография DSKalugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkij, спасибо!
...
Рейтинг: 0 / 0
Обслуживание секций
    #39957042
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый вечер!

Подскажите пожалуйста, а можно где-нибудь в Postgres посмотреть границы уже созданной секции RANGE?
...
Рейтинг: 0 / 0
Обслуживание секций
    #39960802
Фотография DSKalugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MacArrow,

в DDL секции
...
Рейтинг: 0 / 0
Обслуживание секций
    #39969383
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DSKalugin,

Спасибо! Это понятно, особенно теоретически...

А есть какие-то таблицы, представления, "хранимки", из которых по запросу можно получить необходимые данные о секции, в том числе и границы диапазона?
...
Рейтинг: 0 / 0
Обслуживание секций
    #39969435
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MacArrow
А есть какие-то таблицы, представления, "хранимки", из которых по запросу можно получить необходимые данные о секции, в том числе и границы диапазона?

Технически это pg_class.relpartbound. Но это pg_node_tree. pg_dump и psql с ним работают просто как с данностью (psql вызывает именно так):
SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relkind FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhrelid AND i.inhparent = '159622' ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
В результате получается всё выражение текстом, например "FOR VALUES FROM ('2020-04-01 00:00:00') TO ('2020-05-01 00:00:00')"
...
Рейтинг: 0 / 0
Обслуживание секций
    #39970667
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij,

Большое спасибо!

А вот ещё вопрос: можно ли по значению ключа секции определить саму секцию (имя)?
...
Рейтинг: 0 / 0
Обслуживание секций
    #39970868
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MacArrow,

емнип tuple routing из backend'а не экспортирован никак.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39973938
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij,

Понятно! Спасибо!
...
Рейтинг: 0 / 0
Обслуживание секций
    #39988768
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Написано: "Создайте в секционируемой таблице индекс, будет автоматически создан отдельный индекс в каждой секции, и все секции, которые вы будете создавать или присоединять позднее, тоже будут содержать такой индекс".
Вопрос:
Если индекс создан в "голову" уже после создания секций (очень многих секций, причём в разных таблицах разными методами), есть ли "штатная" возможность создать индексы по всем секциям?
Или же поможет только самописная процедура, которая всё это сделает?
Буду весьма благодарен за конструктивный ответ.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39988982
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MacArrow
Если индекс создан в "голову" уже после создания секций (очень многих секций, причём в разных таблицах разными методами), есть ли "штатная" возможность создать индексы по всем секциям?

create index на головной раздел по всем секциям индексы сам и создаст.

А вот если нужен create index concurrently - то только ручками. Оживление сейчас по этому вопросу есть, может в pg14 и войдёт даже.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39989272
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij,

И снова огромнейшее спасибо!

Я имел в виду, что при создании секции, в этой же секции создаются индексы по "головному". Если это concurrently, то да, он.
Просто столкнулись с такой проблемой: потребовался новый индекс на секционированную таблицу, создали в "голову", но на быстродействие запроса это никак не повлияло... Ради эксперимента отдетачили и приаттачили секции по одной из таблиц, индексы в секциях создались и запрос выполнился много быстрее.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39989325
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MacArrow,

уточните как именно индекс создавался. Конкретный запрос.
create index on table_name - создаст индексы по всему дереву
create index concurrently on table_name - откажется работать, т.к. поддержка пока не реализована
create index on only table_name - создаст invalid индекс только на головном разделе и так и задумано.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39991233
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij,

Я извиняюсь за нубство в этом вопросе, т.к. не вникал особо, как Постгрес сам делает индексы на секции...
Но если конкретно, то алгоритм такой:
- при создании таблицы, скриптом же создавался индекс по ключевому столбцу, например:
скриптикиCREATE TABLE balance (id serial, acc_id bigint, in_amt numeric, dt_amt numeric, ct_amt numeric, out_amt numeric, op_dt date) PARTITION BY RANGE (op_dt);
CREATE INDEX balance_op_dt_idx ON balance (op_dt);

- дальше, перед загрузкой вызывается АПИ, где создаётся секция (примерно как тут ) и автоматом ПГ создаёт индекс на секцию.
Поискав по DDL, нашёл для этих секций связанные скрипты создания индексов, например, вот один из них (получается, что никакого concurrently):
скриптикиCREATE INDEX balance_20200701_op_dt_idx ON balance_20200701 USING btree (op_dt);

- уже после загрузки данных потребовалось ввести новый индекс на acc_id, который создали в "голову":
скриптикиCREATE INDEX balance_acc_id_idx ON balance (acc_id);

Но он не возымел никакого действия на быстродействие
Как я понял опытным путём, это из-за того, что не были созданы индексы на секциях (выявлено отсутствием DDL-скриптов для индексов, привязанных к этим самым секциям).
Дальше Вы мне подсказали, что индексы на секции "штатными" средствами ПГ никак быстро не создать, а только ручками... Как выяснилось теперь, Вы имели в виду что-то другое
Тем не менее, самописной процедурой, где отдетачили и снова приаттачили все секции, были всё-таки (полу-)автоматически созданы так необходимые индексы на каждую секцию.
В результате получили необходимое быстродействие выполнения запросов.
...
Рейтинг: 0 / 0
Обслуживание секций
    #39991237
MacArrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, забыл...
Соответственно, в результате выполнения этой "самописной процедуры detach&attach", появились DDL-скрипты для индексов, привязанных к этим самым секциям, например такой:
скриптикиCREATE INDEX balance_20200701_acc_id_idx ON balance_20200701 USING btree (acc_id);


P.S. Если что, то эти самые скрипты (да и сами индексы и другие объекты БД) я вижу при помощи DBeaver.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обслуживание секций
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]