Oplossing (Samenvatting)
Details zijn hieronder uitgewerkt.
-
Verwijder onnodige bestanden:
- Verwijder logbestanden en andere bestanden die niet meer nodig zijn.
-
Optimaliseer de database:
REINDEX TABLE job_jobarchive;
Als alternatief kun je de index verwijderen:
DROP INDEX [index_name] ON job_jobarchive;
-
Opschonen en analyseren:
VACUUM ANALYZE job_jobarchive;
-
Gebruik
pg_repack
:In de shell, als gebruiker
postgres
, voer het volgende uit om de tabel te herstructureren:pg_repack -d dbname -t job_jobarchive
Terwijl
VACUUM FULL job_jobarchive;
Werkt niet omdat er een foutmelding optreedt.
user_de=# VACUUM FULL job_jobarchive;
ERROR: could not extend file "base/98628770/1388599947.114": wrote only 4096 of 8192 bytes at block 14990040
HINT: Check free disk space.
Dus we waren een aantal dagen aan het experimenteren en zijn gegaan van
Filesystem Size Used Avail Use% Mounted on
tmpfs 13G 892K 13G 1% /run
/dev/md2 934G 886G 381M 100% /
tmpfs 63G 0 63G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/nvme1n1 938G 733G 158G 83% /media/backup
/dev/md1 487M 82M 381M 18% /boot
naar
Filesystem Size Used Avail Use% Mounted on
tmpfs 13G 1.1M 13G 1% /run
/dev/md2 934G 231G 656G 27% /
tmpfs 63G 6.2M 63G 1% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/nvme1n1 938G 733G 158G 83% /media/backup
/dev/md1 487M 82M 381M 18% /boot
tmpfs 13G 0 13G 0% /run/user/0
Dat ging erg goed.
Maar wat heb ik precies gedaan, en wat moet ik nog automatiseren om dit in de toekomst te voorkomen?
service pgpool2 status
Inloggen
psql -h localhost -U username -d dbname
Verwijder alle records die zijn gesloten, offline zijn gezet en geen contactgegevens van bedrijven bevatten. Deze worden via XML door een derde partij gepubliceerd en vervolgens gearchiveerd.
DELETE
FROM job_jobarchive
WHERE (email IS NULL OR email = '') AND for_index = FALSE;
SELECT COUNT(*)
FROM job_jobarchive
WHERE (email IS NULL OR email = '') AND for_index = FALSE;
SELECT COUNT(*)
FROM job_jobarchive
WHERE for_index = FALSE;
SELECT COUNT(id)
FROM job_jobarchive
WHERE payed = FALSE;
De logica is dat we een query uitvoeren waarbij alle clicks en views worden geüpdatet voor gearchiveerde jobs op basis van hun jobID, zodat...
SELECT COUNT(*)
FROM job_jobarchive
WHERE payed = TRUE;
Toon alle jobs in het archief die ooit direct of indirect betaald zijn aangeklikt en in het verleden verkeer genereerden toen ze nog open waren.
user_de=> SELECT COUNT(*)
user-> FROM job_jobarchive
user-> WHERE payed = TRUE;
count
---------
7410945
(1 row)
Met deze query kan ik alle jobs in het archief identificeren die ooit verkeer hebben gegenereerd. Alleen de aangeduide jobs blijven behouden voor beveiligings- en statistische doeleinden, terwijl de rest wordt verwijderd."
UPDATE job_jobarchive
SET payed = TRUE
WHERE job_id IN (SELECT id FROM viewjob_viewjob);
Ja, inderdaad, een kleine verwijdering was niet voldoende. Ik moest niet alleen logs en dergelijke verwijderen, maar ook meer grondig te werk gaan.
ERROR: could not extend file "base/98628770/143848844.118": wrote only 4096 of 8192 bytes at block 15532936
HINT: Check free disk space.
Filesystem Size Used Avail Use% Mounted on
tmpfs 13G 892K 13G 1% /run
/dev/md2 934G 886G 381M 100% /
tmpfs 63G 0 63G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/nvme1n1 938G 733G 158G 83% /media/backup
/dev/md1 487M 82M 381M 18% /boot
Verwijderen laste 7 dagen.
DELETE FROM job_jobarchive
WHERE added >= date_trunc('week', current_date)
AND added < date_trunc('week', current_date) + interval '7 days';
pg_repack -d dbname -t job_jobarchive
Het probleem is dat de database in een staat verkeert waarin VACUUM niet meer kan worden uitgevoerd. Daardoor levert het verwijderen van data geen vrijgekomen ruimte op in de database.
Ik moet dus op de een of andere manier alsnog VACUUM uitvoeren.
Mijn plan is om eerst Elastic te stoppen en de archive-index te verwijderen, aangezien deze 87 GB in beslag neemt. In deze configuratie draaien naast de databaseservers ook Elastic-instanties voor betere prestaties en horizontale schaalbaarheid.
curl -X GET "http://138.201.8.xxx:9200/_cat/indices?v"
root@Ubuntu-2010-groovy-64-minimal /var # curl -X DELETE "http://138.201.8.xxx:9200/archive"
{"acknowledged":true}root@Ubuntu-2010-groovy-64-minimal /var # curl -X GET "http://138.201.8.xxx:9200/_cat/indices?v"
dan verwijderen wat er over blijft.
Filesystem Size Used Avail Use% Mounted on
tmpfs 13G 900K 13G 1% /run
/dev/md2 934G 799G 88G 91% /
tmpfs 63G 0 63G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/nvme1n1 938G 733G 158G 83% /media/backup
/dev/md1 487M 82M 381M 18% /boot
tmpfs 13G 0 13G 0% /run/user/0
Er is nog steeds niet genoeg ruimte beschikbaar om VACUUM FULL of pg_repack uit te voeren.
postgres@Ubuntu-2010-groovy-64-minimal:~$ pg_repack -d dbname -t job_jobarchive
INFO: repacking table "public.job_jobarchive"
ERROR: query failed: ERROR: could not extend file "base/98628770/1333137786.97": wrote only 4096 of 8192 bytes at block 12748168
HINT: Check free disk space.
DETAIL: query was:
postgres@Ubuntu-2010-groovy-64-minimal:~$
postgres@Ubuntu-2010-groovy-64-minimal:~$ psql -U postgres -d dbname
df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 13G 1.1M 13G 1% /run
/dev/md2 934G 760G 127G 86% /
tmpfs 63G 256K 63G 1% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/nvme1n1 938G 733G 158G 83% /media/backup
/dev/md1 487M 82M 381M 18% /boot
tmpfs 13G 0 13G 0% /run/user/0
schemaname | tablename | table_size | bloat_size | total_size
------------+----------------+------------+------------+------------
public | job_jobarchive | 646 GB | 6045 MB | 651 GB
Er is momenteel slechts 6 GB vrije ruimte beschikbaar. Ik moet een mechanisme ontwikkelen om alles grondig op te schonen en ongeveer 90% van de data te verwijderen. Alleen gegevens met e-mails en gegevens die aangeklikt zijn, moeten behouden blijven.
We kunnen dit doen zodra we zien dat het verwijderen van data daadwerkelijk resulteert in een afname van de databasegrootte. Op dit moment verwijder ik data, maar de grootte blijft hetzelfde. Wel heb ik een index verwijderd, wat direct 10 GB aan ruimte opleverde.
Vervolgens moet ik al mijn tabellen met statistieken één voor één nalopen en aanduiden welke records payed = True
moeten worden in het archief. Dit maakt duidelijk dat deze records in het archief mogen blijven.
Jobs met een e-mailadres worden automatisch gemarkeerd als payed = True
, omdat ze contactgegevens bevatten en betalende klanten vertegenwoordigen.
Payed = True
in het archief betekent in dit geval dat het record belangrijk is en behouden moet blijven.
For_index = False hoeveel?
De oplossing om dergelijke problemen in de toekomst te voorkomen is door records die essentieel zijn te markeren met payed = true
. Dit zorgt ervoor dat alleen belangrijke gegevens behouden blijven, terwijl overige data efficiënt verwijderd kan worden. Zo blijft de database beheersbaar en geoptimaliseerd.
+ Alle posts die momenteel een e-mailadres bevatten, zijn er 10 miljoen.
- Tabellen die hierbij betrokken zijn:
viewjob_viewjob
applicationclickscount
spontaneousapplication
SELECT COUNT(*) FROM job_jobarchive WHERE payed = TRUE;
count
----------
18809826
SELECT
column_name,
data_type,
is_nullable,
character_maximum_length
FROM
information_schema.columns
WHERE
table_name = 'spontaneous_spontaneousapplication';
UPDATE job_jobarchive
SET payed = TRUE
WHERE job_id IN (
SELECT job_id
FROM viewjob_viewjob
);
UPDATE job_jobarchive
SET payed = TRUE
WHERE job_id IN (
SELECT job_id
FROM job_applicationclickscount
);
UPDATE job_jobarchive
SET payed = TRUE
WHERE job_id IN (
SELECT job_id
FROM spontaneous_spontaneousapplication
);
UPDATE job_jobarchive
SET payed = TRUE
WHERE email IS NOT NULL AND email != '';
DELETE FROM job_jobarchive
WHERE payed = FALSE
bloat_info
WITH bloat_info AS (
SELECT
nspname AS schemaname,
relname AS tablename,
pg_size_pretty(pg_table_size(C.oid)) AS table_size,
pg_size_pretty(pg_total_relation_size(C.oid) - pg_table_size(C.oid)) AS bloat_size,
pg_size_pretty(pg_total_relation_size(C.oid)) AS total_size
FROM
pg_class C
JOIN
pg_namespace N ON (C.relnamespace = N.oid)
WHERE
C.relkind = 'r' AND N.nspname NOT IN ('pg_catalog', 'information_schema')
)
SELECT * FROM bloat_info WHERE tablename = 'your_table_name';
Server met informatie Archive leeg maken omdat Postgresql heeft volledige disk heeft ingenomen. Zo los je het op.
Comments
Post a Comment