0

別荘に関する Web サイトに Solr を実装するのに忙しくしています。この Web サイトでは、Postgres をメイン データベースとして使用しています。検索結果については、利用可能な別荘を取得するためのバックエンドとして Solr を使用したいと考えています。

データベースの一部をインポートするには、JdbcDataSource で DataImportHandler を使用します。

DataImportHandler の短縮バージョン:

<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
     <dataSource type="JdbcDataSource" driver="org.postgresql.Driver" name="Solr"
                    url="jdbc:postgresql://host:port/database" user="*" password="*" readOnly="true"/>
    <document>
<entity name="availabilities" transformer="RegexTransformer" pk="id"
        query="
            SELECT concat('A',pa.availability_id,'-',pad.start_date,'-',pad.period_type_id) as unique_availability_id,
            pa.property_id,
            NULLIF(CONCAT(ST_X(pl.position),',',ST_Y(pl.position)),',') as locationhash,
            pl.position_accurate,
            true as is_availability,
            region.child_id as city_id,
            region.ancestor_id as province_id,
            (
                SELECT array_to_string(array(SELECT binnen.ancestor_id
                FROM fewo_Location_Ancestry binnen
                WHERE binnen.child_id = region.child_id
                AND   binnen.ancestor_type_id = 12), ',')
            ) AS region_id,
            pl.country_id,
            pl.min_persons,
            pl.max_persons,
            fap.bedrooms,
            pl.specifications,
            pl.property_state_id,
            pa.availability_id,
            pad.period_type_id,
            pad.start_date,
            pad.end_date,
            (
                SELECT COUNT(*) &gt; 0 FROM fewo_last_minute_details flmd
                WHERE flmd.property_id = pa.property_id
                AND flmd.details_id = pad.details_id
                LIMIT 1
            ) AS last_minute,
            CASE (
                SELECT COUNT(*) &gt; 0 FROM fewo_last_minute_details flmd
                WHERE flmd.property_id = pa.property_id
                AND flmd.details_id = pad.details_id
                LIMIT 1
            ) WHEN true THEN pad.discount_price
                    ELSE pad.price
            END as price,
            pl.positioning_fee,
            pl.sort_order   
            FROM fewo_property_availability_details pad
                INNER JOIN fewo_property_availability pa USING (availability_id)
                INNER JOIN fewo_Property_Location pl ON pa.property_id=pl.property_id
                INNER JOIN fewo_all_properties fap ON pl.property_id=fap.property_id
                INNER JOIN fewo_Location_Ancestry region ON (region.child_id =pl.location_id  AND region.ancestor_type_id = 7)
            WHERE pad.start_date &gt; current_date
        ">
    <field name="id" column="unique_availability_id"/>
        <field name="property_id" column="property_id"/>
        <field name="parent_id" column="property_id"/>
        <field name="is_availability" column="is_availability"/>
        <field name="positionCoord" column="locationhash"/>
        <field name="position_accurate" column="position_accurate"/>
        <field name="city_id" column="city_id"/>
        <field name="province_id" column="province_id"/>
        <field name="region_id" column="region_id" splitBy="," sourceColName="region_id"/>
        <field name="country_id" column="country_id"/>
        <field name="min_persons" column="min_persons"/>
        <field name="max_persons" column="max_persons"/>
        <field name="bedrooms" column="bedrooms"/>
        <entity name="fewo_all_property_specifications" transformer="foo.SpecTransformer" pk="property_id"
            cacheKey="property_id"
            cacheLookup="availabilities.property_id"
            query="SELECT property_id, specification_id, COALESCE(value,'true') as val FROM fewo_all_property_specifications"
            processor="CachedSqlEntityProcessor">
        </entity>
        <field name="property_state_id" column="property_state_id"/>
        <field name="availability_id" column="availability_id"/>
        <field name="period_type_id" column="period_type_id"/>
        <field name="start_date" column="start_date"/>
        <field name="end_date" column="end_date"/>
        <field name="last_minute" column="last_minute" />
        <field name="price" column="price"/>
        <field name="positioning_fee" column="positioning_fee"/>
        <field name="sort_order" column="sort_order"/>
    </entity>   
    </document>
</dataConfig>

インポートは約 1 時間実行され、1,300 万件のレコードが Solr にインポートされます。問題は、テーブルをロックしている AccessShareLock があるため、インポート中にテーブル fewo_property_availability_details を更新できないことです。これにより、テーブルへのデータの更新/挿入が防止され、これらのクエリがキューに入れられます。しばらくすると、それらが積み重なりすぎて、データベースに障害が発生します。

私の質問は次のとおりです。通常のクエリをあまり妨げずにデータをインポートする良い方法はありますか? x 個のレコードをインポートした後に新しいトランザクションを開始すると、他のクエリを実行する時間ができますか?

Ubuntu 12.04 で実行されている Solr 4.0 と Postgres 9.1 を使用しています。

ありがとう

4

2 に答える 2

2

AccessShareLockドキュメントAccessExclusiveLockによると、 とのみ競合します

ACCESS EXCLUSIVEALTER TABLEDROP TABLETRUNCATEREINDEXCLUSTERVACUUM FULLおよび非修飾LOCK TABLEステートメントによってのみ取得されます。

pg_catalog.pg_locksロック関係とは何かについての詳細情報を取得できるかどうかを確認するには、 を参照してください。また、PostgreSQL wiki で役立つロック クエリをいくつか見つけることができます: http://wiki.postgresql.org/wiki/Lock_Monitoring

物事を保持するためにロックするのではなく、DB が重い同時読み取り/書き込み負荷に対処できない可能性は十分にあります。これは特に、キャッシュが小さい場合、BBU RAID コントローラーを使用せずに通常の (SSD 以外の) ディスクで実行している場合、および/または環境に合わせて PostgreSQL 構成を調整していない場合に発生する可能性があります。

于 2013-02-26T04:57:30.310 に答える
0

または、DIH からの選択に基づいてマテリアライズド ビューを作成し (Oracle および MySQL で可能)、更新オプションを FAST に設定することもできます (つまり、ビューには常に新しいデータが含まれます)。達成されること: - インポートの高速化 - テーブルのロックなし その後、部分インポート (完全インポートではない) を実行して、新しいデータまたは変更されたデータのみを取得できます。このリンクを参照してください 。

于 2013-02-26T11:29:35.713 に答える