web-dev-qa-db-fra.com

Importation d'un grand vidage SQL avec des millions d'instructions INSERT

Je dois importer un gros .sql fichier (8,1 Go décompressé) dans PostgreSQL. J'ai essayé d'utiliser \i /path/to/file.sql mais c'est beaucoup trop lent.

Comment accélérer l'importation? Je dois importer ces données chaque semaine.

les 2000 premières lignes peuvent être trouvées ici , tandis que le vidage compressé de 1 Go peut être trouvé ici

--
-- PostgreSQL database dump
--

-- Dumped from database version 9.5.3
-- Dumped by pg_dump version 9.5.2

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: rpo; Type: SCHEMA; Schema: -; Owner: -
--

C'est la seule façon dont je peux obtenir les données. Le fichier complet a env. 38 000 000 lignes. Comment puis-je accélérer l'importation?

6
Ondrej Vrabel

Cette sauvegarde a été sauvegardée sous forme d'instructions individuelles (avec pg_dump --inserts)

INSERT INTO esa2010_codes VALUES (11002, 'Národn
INSERT INTO esa2010_codes VALUES (11003, 'Nefina
INSERT INTO esa2010_codes VALUES (12502, 'Národn
INSERT INTO esa2010_codes VALUES (11001, 'Verejn
INSERT INTO esa2010_codes VALUES (12602, 'Národn
INSERT INTO esa2010_codes VALUES (12603, 'Finanč
INSERT INTO esa2010_codes VALUES (12503, 'Ostatn

Ceci est documenté comme étant lent (de man pg_dump)

--inserts Vider les données sous forme de commandes INSERT (plutôt que COPY). Cela rendra la restauration très lente ; il est principalement utile pour créer des vidages qui peuvent être chargés dans des bases de données non PostgreSQL. Cependant, puisque cette option génère une commande distincte pour chaque ligne, une erreur lors du rechargement d'une ligne entraîne uniquement la perte de cette ligne plutôt que le contenu de la table entière. Notez que la restauration peut échouer complètement si vous avez réorganisé l'ordre des colonnes. L'option --column-inserts Est sûre contre les changements d'ordre des colonnes, bien qu'elle soit encore plus lente.

Voilà pourquoi c'est si lent. Ce que vous allez vouloir faire est de désactiver certains des paramètres de durabilité , en particulier synchronous_commit, Bien que fsync vous aidera aussi

Vous pouvez le faire très simplement en exécutant la commande suivante avant d'exécuter votre \i file.sql.

SET synchronous_commit TO off;

Cela fera beaucoup pour l'accélérer. N'oubliez pas de réactiver les options de durabilité après avoir terminé. Je parie que cela se terminera dans quelques heures, une fois que vous aurez réglé cela. Si vous avez besoin de plus de vitesse, n'hésitez pas à désactiver fsync et full_page_writes Sur le cluster jusqu'à ce que vous obteniez les données - bien que je ne le ferai pas si la base de données avait des données que vous nécessaire en elle, ou si c'était la production. Enfin, si vous avez besoin de la vitesse et qu'il s'agit d'une base de données de production, vous pouvez tout mettre en œuvre sur votre propre copie et la vider avec les options par défaut de pg_dump, Que vous pourrez charger beaucoup plus rapidement .

14
Evan Carroll

Une autre option consiste à exécuter l'importation en une seule transaction (si cela est possible):

BEGIN;
\i dump.sql
COMMIT;

PostgreSQL s'exécute en mode de validation automatique par défaut - cela signifie que chaque commande est terminée par commit - et la validation est terminée par fsync (et fsync est assez lent). Il peut être réduit par un commit asunchronnous (réponse d'Evan Carroll) ou réduit à un par transaction explicite.

Une autre possibilité consiste à désactiver la vérification de l'intégrité référentielle (si elle est utilisée). Cette variante est possible, car nous pouvons nous attendre à ce que le vidage soit cohérent et correct. Vous pouvez voir les détails de la commande ALTER TABLE xx DISABLE TRIGGER ALL.

La source de votre fichier est pg_dump. L'accélération la plus simple peut être effectuée en utilisant une option lors de la création du vidage.

  1. N'utilisez pas l'option --inserts. Le format de copie est beaucoup plus rapide pour la restauration

  2. Utilisez l'option --disable-triggers pour désactiver la vérification RI (attendez-vous à des données correctes)

  3. Vous pouvez utiliser un format personnalisé -F option. Ensuite, vous pouvez utiliser pg_restore pour restaurer et construire des index (opération la plus lente) en parallèle.

2
Pavel Stehule