it-swarm.com.de

Überwintern Sie langsam, um Postgres-Verbindung zu erwerben

Es fällt mir sehr schwer, dieses Problem zu beheben. Immer wenn ich versuche, eine Verbindung zu Postgres herzustellen, dauert es eine ganze Minute. Nachdem die Verbindung hergestellt ist, ist alles in Ordnung. Ich habe versucht, alle Zuordnungen zu deaktivieren und keine zu laden. Trotzdem dauert es lange, bis die Verbindung hergestellt ist. Ich habe auch versucht, die Validierung zu deaktivieren, kein Unterschied. Wenn ich eine einfache, einfache JDBC-Verbindung verwende, erfolgt dies sofort. Hibernate macht etwas, das viel Zeit in Anspruch nimmt, und ich scheine es nicht einzugrenzen. Jede Eingabe wird sehr geschätzt!

Postgres-Fahrer:

postgresql-9.1-901.jdbc4.jar

Konfigurationseinstellungen:

<hibernate-configuration>
    <session-factory>
    <!-- properties -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="connection.driver_class">org.postgresql.Driver</property>

        <property name="connection.url">jdbc:postgresql://xxxx.com:5432/xxxxx</property>
        <property name="connection.username">xxxxxxx</property>
        <property name="connection.password">xxxxxxx</property>

    </session-factory>
</hibernate-configuration>

Zusätzliche Einstellungen im Code:

    config.setProperty("hibernate.hbm2ddl.auto", hbm2ddlMode);
    //config.setProperty("hibernate.cache.use_query_cache", "true");
    config.setProperty("hibernate.cache.use_second_level_cache", "true");
    //config.setProperty("hibernate.cache.region.factory_class", "net.sf.ehcache.hibernate.EhCacheRegionFactory");
    config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");
    //config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
    config.setProperty("hibernate.jdbc.fetch_size", "100");
    config.setProperty("hibernate.jdbc.batch_size", "30");
    config.setProperty("hibernate.jdbc.use_scrollable_resultset", "true");
    config.setProperty("hibernate.connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");

    config.setProperty("hibernate.c3p0.acquire_increment", "1");
    config.setProperty("hibernate.c3p0.idle_test_period", "0");
    config.setProperty("hibernate.c3p0.min_size", "1");
    config.setProperty("hibernate.c3p0.max_size", "2");
    config.setProperty("hibernate.c3p0.timeout", "0");
    config.setProperty("javax.persistence.validation.mode", "none");

Hier ist das Codesegment, in dem die Verzögerung auftritt:

private SessionFactory buildSessionFactory() throws Exception {
        ServiceRegistry serviceRegistry  = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();

            //Building session takes a whole minute without mappings!!!
        sessionFactory = config.buildSessionFactory(serviceRegistry);

        validateConnection();

        return sessionFactory;
    }

Hier sind die Log-Ergebnisse:

[main] 2012-04-09 10:40:32,823 110391 INFO  C3P0ConnectionProvider - HHH000046: 
Connection properties: {user=hgaidb_test, password=****}
[main] 2012-04-09 10:40:32,823 110391 INFO  C3P0ConnectionProvider - HHH000006: 
Autocommit mode: false
[main] 2012-04-09 10:40:34,100 111668 DEBUG JdbcServicesImpl - Database ->
       name : PostgreSQL
    version : 8.3.3
      major : 8
      minor : 3
[main] 2012-04-09 10:40:34,101 111669 DEBUG JdbcServicesImpl - Driver ->
       name : PostgreSQL Native Driver
    version : PostgreSQL 9.1 JDBC4 (build 901)
      major : 9
      minor : 1
*******************************************************************************
// 1 MINUTE DELAY
*******************************************************************************
[main] 2012-04-09 10:40:34,102 111670 DEBUG JdbcServicesImpl - JDBC version : 4.
0
[main] 2012-04-09 10:41:21,632 159200 INFO  Dialect - HHH000400: Using dialect: 
org.hibernate.dialect.PostgreSQLDialect
*******************************************************************************
[main] 2012-04-09 10:41:21,669 159237 INFO  LobCreatorBuilder - HHH000424: Disab
ling contextual LOB creation as createClob() method threw error : Java.lang.refl
ect.InvocationTargetException
[main] 2012-04-09 10:41:21,814 159382 DEBUG SettingsFactory - Automatic flush du
ring beforeCompletion(): disabled
[main] 2012-04-09 10:41:21,814 159382 DEBUG SettingsFactory - Automatic session 
close at end of transaction: disabled
[main] 2012-04-09 10:41:21,815 159383 DEBUG SettingsFactory - JDBC batch size: 3
0
[main] 2012-04-09 10:41:21,816 159384 DEBUG SettingsFactory - JDBC batch updates
 for versioned data: disabled
[main] 2012-04-09 10:41:21,816 159384 DEBUG SettingsFactory - Scrollable result 
sets: enabled
[main] 2012-04-09 10:41:21,817 159385 DEBUG SettingsFactory - Wrap result sets: 
disabled
[main] 2012-04-09 10:41:21,818 159386 DEBUG SettingsFactory - JDBC3 getGenerated
Keys(): enabled
[main] 2012-04-09 10:41:21,818 159386 DEBUG SettingsFactory - JDBC result set fe
tch size: 100
[main] 2012-04-09 10:41:21,819 159387 DEBUG SettingsFactory - Connection release
 mode: auto
[main] 2012-04-09 10:41:21,819 159387 INFO  TransactionFactoryInitiator - HHH000
399: Using default transaction strategy (direct JDBC transactions)
[main] 2012-04-09 10:41:21,844 159412 DEBUG SettingsFactory - Default batch fetc
h size: 1
[main] 2012-04-09 10:41:21,844 159412 DEBUG SettingsFactory - Generate SQL with 
comments: disabled
[main] 2012-04-09 10:41:21,845 159413 DEBUG SettingsFactory - Order SQL updates 
by primary key: disabled
[main] 2012-04-09 10:41:21,846 159414 DEBUG SettingsFactory - Order SQL inserts 
for batching: disabled
[main] 2012-04-09 10:41:21,846 159414 DEBUG SettingsFactory - Query translator: 
org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory
[main] 2012-04-09 10:41:21,867 159435 INFO  ASTQueryTranslatorFactory - HHH00039
7: Using ASTQueryTranslatorFactory
[main] 2012-04-09 10:41:21,867 159435 DEBUG SettingsFactory - Query language sub
stitutions: {}
[main] 2012-04-09 10:41:21,867 159435 DEBUG SettingsFactory - JPA-QL strict comp
liance: disabled
[main] 2012-04-09 10:41:21,868 159436 DEBUG SettingsFactory - Second-level cache
: enabled
[main] 2012-04-09 10:41:21,868 159436 DEBUG SettingsFactory - Query cache: disab
led
[main] 2012-04-09 10:41:21,869 159437 DEBUG SettingsFactory - Cache region facto
ry : org.hibernate.cache.internal.NoCachingRegionFactory
[main] 2012-04-09 10:41:21,872 159440 DEBUG SettingsFactory - org.hibernate.cach
e.internal.NoCachingRegionFactory did not provide constructor accepting Java.uti
l.Properties; attempting no-arg constructor.
[main] 2012-04-09 10:41:21,873 159441 DEBUG SettingsFactory - Optimize cache for
 minimal puts: disabled
[main] 2012-04-09 10:41:21,873 159441 DEBUG SettingsFactory - Structured second-
level cache entries: disabled
[main] 2012-04-09 10:41:21,873 159441 DEBUG SettingsFactory - Statistics: disabl
ed
[main] 2012-04-09 10:41:21,874 159442 DEBUG SettingsFactory - Deleted entity syn
thetic identifier rollback: disabled
[main] 2012-04-09 10:41:21,874 159442 DEBUG SettingsFactory - Default entity-mod
e: pojo
[main] 2012-04-09 10:41:21,875 159443 DEBUG SettingsFactory - Named query checki
ng : enabled
[main] 2012-04-09 10:41:21,875 159443 DEBUG SettingsFactory - Check Nullability 
in Core (should be disabled when Bean Validation is on): enabled
[main] 2012-04-09 10:41:21,876 159444 DEBUG SettingsFactory - multi-tenancy stra
tegy : NONE

Ich habe etwas mehr darüber nachgedacht und den Debugger durchlaufen. Ich habe nicht alle Quellen in meinem Klassenpfad, aber ich kann immer noch die Variablen sehen. Während dieser einen Minute Wartezeit fragt Hibernate die Tabelle pg_catalog.pg_type ab:

[SELECT typname FROM pg_catalog.pg_type WHERE oid = , ]

Hier ist ein Screenshot:

DebugWindow

53
Jason Huntley

Ich habe es korrigiert =) Ich musste mich wirklich umsehen, um die Antwort auf diese Frage zu finden. Im Grunde geht es darum, Metadaten und den JDBC-Treiber zu laden. Es lädt ALL META DATA, einschließlich der Kommentare neben SQL-Spalten und anderen verschiedenen Konstrukten, die für den Betrieb nicht benötigt werden. Ich weiß nicht, warum dies standardmäßig aktiviert ist. Sie sollten diese Funktion jedoch unbedingt deaktivieren, wenn Sie sie nicht explizit benötigen:

config.setProperty("hibernate.temp.use_jdbc_metadata_defaults","false");

Sofortige Verbindung jetzt!

Die einzige Information, die ich dazu finden konnte, ist im Code:

107     // 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
108     // The need for it is intended to be alleviated with future development, thus it is
109     // not defined as an Environment constant...
110     //
111     // it is used to control whether we should consult the JDBC metadata to determine
112     // certain Settings default values; it is useful to *not* do this when the database
113     // may not be available (mainly in tools usage).
114     boolean useJdbcMetadata = ConfigurationHelper.getBoolean( "hibernate.temp.use_jdbc_metadata_defaults", configValues, true );

http://grepcode.com/file/repo1.maven.org/maven2/org.hibernate/hibernate-core/4.1.1.Final/org/hibernate/engine/jdbc/internal/JdbcServicesImpl.Java#JdbcServicesImpl

112
Jason Huntley

Ich musste auch hibernate.jdbc.use_get_generated_keys aktivieren, ansonsten wurde bei der Identitätserzeugungsstrategie eine Ausnahme ausgelöst. Bevor es automatisch aktiviert wurde, basierend auf Metadaten, die von DB empfangen wurden. Meine ganze Lösung bestand also darin, die folgenden zwei Zeilen zu persistence.xml hinzuzufügen:

<property name="hibernate.jdbc.use_get_generated_keys" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
7
mmm

Ich hatte Probleme mit der scrollbaren Ergebnismenge, daher musste ich den dritten Parameter hinzufügen, siehe unten:

<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<property name="hibernate.jdbc.use_get_generated_keys">true</property>
<property name="hibernate.jdbc.use_scrollable_resultset">true</property>
1

Fast 7 Jahre später und das ist immer noch ein Problem ...

Das Deaktivieren der "Temp" -Taste hilft zwar, Eigenschaften einzeln zu aktivieren, die automatisch konfiguriert werden (siehe andere Antworten).

Bei Oracle und Teradata habe ich keine solche Verlangsamung bemerkt, also habe ich tief gegraben und herausgefunden, wo der langsamste Teil ist: https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src /main/Java/org/postgresql/jdbc/PgDatabaseMetaData.Java#L2237

Dieses resultSet hat in meinem Fall 372 Zeilen (Typen). Für jeden Fahrer werden dann mehrere Anrufe von https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/Java/org/postgresql/jdbc/TypeInfoCache.Java#L204 abgesetzt was zu Tonnen von SQL-Anweisungen gegen die DB führt.

Keine Ahnung, wie man das jetzt beschleunigen kann, zum Glück wird es einmal benötigt und dann zwischengespeichert.

1
zeratul021

Ein Postgresql-Server kann mehrere Datenbanken enthalten. Leider können Sie nicht Metadaten anderer Datenbanken zu einer Verbindung ausblenden , deshalb dauert das Lesen der Metadaten durch den jdbc-Treiber lange Zeit!

Trennen Sie diese Datenbanken auf verschiedene Postgres-Server, und die Performance beim Lesen von Metadaten wird gesteigert!

Lesen Sie wie man sich auf Centos trennt .

1
Peter Rader

Das klingt vage nach einem Problem, das wir in Ruby on Rails gesehen haben. Sie könnten nach einer ähnlichen Ursache suchen, die ich hier beschrieben habe:

http://archives.postgresql.org/pgsql-performance/2009-11/msg00128.php

Kurz gesagt, dieses Problem wurde durch die explizite Registrierung des JDBC-Treibers aus mehreren ClassLoader-Kontexten verursacht.

0
kgrittn