首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >postgres中的Solr导入锁定表

问postgres中的Solr导入锁定表
EN

Stack Overflow用户
提问于 2013-02-26 03:03:46
回答 2查看 644关注 0票数 0

我正忙着为一个关于度假屋的网站实现Solr。该网站使用Postgres作为主数据库。对于搜索结果,我们希望使用Solr作为后端来获取可用的度假屋。

导入数据库的各个部分是通过使用带有JdbcDataSource的DataImportHandler完成的。

DataImportHandler的缩写版本:

代码语言:javascript
复制
<?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>

导入大约运行一个小时,将1300万条记录导入Solr。问题是在导入期间无法更新表fewo_property_availability_details,因为存在一个锁定表的AccessShareLock。这将防止更新/插入表中的数据,并使这些查询排队。过了一段时间,它们堆积得太多,数据库就会失败。

我的问题是:有没有一种好的方法来导入数据,而不会对常规查询造成太多的阻碍?例如,在x个导入记录之后启动一个新事务,让其他查询有时间运行吗?

我使用的是在Ubuntu 12.04上运行的Solr 4.0和Postgres 9.1。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2013-02-26 12:57:30

根据the documentation,AccessShareLock仅与AccessExclusiveLock冲突

ACCESS EXCLUSIVE只能通过ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL和非限定LOCK TABLE语句获得。

查看一下pg_catalog.pg_locks,看看是否可以获得有关锁关系的更多信息。您还可以在PostgreSQL维基上找到一些有用的锁查询:http://wiki.postgresql.org/wiki/Lock_Monitoring

完全有可能的是,你的数据库不是锁住了,而是无法处理繁重的并发读/写负载。如果您的高速缓存很小,在没有BBU控制器的普通(非固态硬盘)磁盘上运行,并且/或者您还没有针对您的环境调优PostgreSQL配置,这种情况尤其可能发生。

票数 2
EN

Stack Overflow用户

发布于 2013-02-26 19:29:36

或者,您可以根据从DIH中选择的内容创建物化视图(在oracle和MySQL中是可能的),然后可以将refresh选项设置为FAST (这意味着视图将始终包含最新数据)。您将实现的目标:-更快的导入-在此之后,您可以进行部分导入(而不是完全导入),以仅获取新的或更改的数据。看看这个link希望将会有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15074444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档