首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在更新过程中最小化数据库争用的可能性

如何在更新过程中最小化数据库争用的可能性
EN

Stack Overflow用户
提问于 2013-12-30 20:03:18
回答 1查看 410关注 0票数 3

我编写了一些PostgreSQL数据库客户端代码,以便使用来自多个客户端的IP地址和主机名表更新中央数据库。有两个表:一个保存IP地址和主机名之间的映射,另一个保存尚未解析为主机名的IP地址队列。

以下是IP地址到主机名映射表:

代码语言:javascript
复制
CREATE TABLE g_hostmap(
    appliance_id     INTEGER,
    ip               INET,
    fqdn             TEXT,
    resolve_time     TIMESTAMP, 
    expire_time      TIMESTAMP,
    UNIQUE(appliance_id, ip))

以下是工作队列表:

代码语言:javascript
复制
CREATE TABLE g_hostmap_work(
    ip               INET,
    input_table      TEXT)

数据库客户端每次从单个工作队列表中提取请求。每个请求都包含请求主机名的私有IPv4地址。

工作流程如下:每个客户端定期向中央数据库工作队列查询需要主机名的IP地址列表,对地址执行反向DNS查找,然后使用(IP地址,主机名)对更新主机名表,每次一个。我希望通过尝试同时解析相同的IP地址,尽量减少多个客户端重复工作的可能性。

我将每一批更新限制在更大的10行或10%的工作队列中。客户的时间安排有点独立。如何在更新过程中进一步最小化DNS名称服务器和主机名表的争用?我的客户担心会有很多重复的工作。

下面是对工作队列中的项计数的初始查询:

代码语言:javascript
复制
SELECT COUNT(*)
       FROM g_hostmap_work queued
       LEFT JOIN g_hostmap cached
            ON queued.ip = cached.ip
            AND now() < cached.expire_time

下面是返回工作队列中项子集的查询:

代码语言:javascript
复制
SELECT queued.ip, queued.input_table, cached.expire_time
       FROM g_hostmap_work queued
       LEFT JOIN g_hostmap cached
            ON queued.ip = cached.ip
            AND now() < cached.expire_time
       LIMIT 10

下面是使用新的IP地址/主机名映射更新数据库的单个INSERT语句的示例:

代码语言:javascript
复制
INSERT INTO g_hostmap_20131230 VALUES
(NULL, '192.168.54.133', 'powwow.site', now(), now() + 900 * INTERVAL '1 SECOND')
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-31 01:28:46

我要提出一个奇怪的建议。向源表中添加一个auto大int,并使用模块化划分创建一组10个索引。下面是一个简单的测试用例:

代码语言:javascript
复制
create table queue (id bigserial, input text);
create index q0 on queue (id) where id%10=0;
create index q1 on queue (id) where id%10=1;
create index q2 on queue (id) where id%10=2;
create index q3 on queue (id) where id%10=3;
create index q4 on queue (id) where id%10=4;
create index q5 on queue (id) where id%10=5;
create index q6 on queue (id) where id%10=6;
create index q7 on queue (id) where id%10=7;
create index q8 on queue (id) where id%10=8;
create index q9 on queue (id) where id%10=9;
insert into queue select generate_series(1,50000),'this';

我们在这里所做的是创建一组索引,索引表的1/10。接下来,我们将选择其中一个区域中的一个块来处理:

代码语言:javascript
复制
begin;
select * from queue where id%10=0 limit 100 for update;
id  | input 
------+-------
10 | this
20 | this
30 | this
-- do work here --
commit;

有趣的部分。如果使用此设置的工作人员超过10个,则只需循环使用这些数字,超过10的工作人员将在上面的select update运行时等待。但是任何其他数字(1到9)仍然有效。

代码语言:javascript
复制
begin;
select * from queue where id%10=1 limit 100 for update;
 id  | input 
-----+-------
   1 | this
  11 | this
  21 | this
  31 | this
-- do work here
commit;

这样,所有的工作都被分成10个桶。还要更多的桶吗?在%之后更改数字,并增加要匹配的索引数。

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

https://stackoverflow.com/questions/20846631

复制
相关文章

相似问题

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