I have written some PostgreSQL database client code to update a central database with a table of IP addresses and host names from multiple clients. There are two tables: one to hold mappings between IP addresses and host names, and one to hold a queue of IP addresses that have not yet been resolved to host names.
Here is the IP-address-to-host-name mapping table:
CREATE TABLE g_hostmap(
appliance_id INTEGER,
ip INET,
fqdn TEXT,
resolve_time TIMESTAMP,
expire_time TIMESTAMP,
UNIQUE(appliance_id, ip))
Here is the work queue table:
CREATE TABLE g_hostmap_work(
ip INET,
input_table TEXT)
The database clients each pull requests from a single work queue table. Each request contains a private IPv4 address for which a host name is requested.
The work flow is as follows: each client periodically queries the central database work queue for a list of IP addresses for which host names are needed, performs a reverse DNS look-up on the addresses, and then updates the host name table with the (IP address, host name) pairs, one at a time. I wish to minimize the likelihood that multiple clients will duplicate effort by attempting to resolve the same IP addresses simultaneously.
I limit each batch of updates to the larger of 10 rows or 10% of the size of the work queue in rows. The timing of the clients is somewhat independent. How can I further minimize contention for the DNS name server and host name table during the update process? My customer is concerned that there will be much duplication of effort.
Here is the initial query for a count of items in the work queue:
SELECT COUNT(*)
FROM g_hostmap_work queued
LEFT JOIN g_hostmap cached
ON queued.ip = cached.ip
AND now() < cached.expire_time
Here is the query to return a subset of items in the work queue:
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
Here is an example of a single INSERT statement to update the database with a new IP address/host name mapping:
INSERT INTO g_hostmap_20131230 VALUES
(NULL, '192.168.54.133', 'powwow.site', now(), now() + 900 * INTERVAL '1 SECOND')