Re: Sending several commands simultaneously to PostgreSQL 8.4

Lists: pgsql-general
From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Sending several commands simultaneously to PostgreSQL 8.4
Date: 2013-01-21 12:57:49
Message-ID: CAADeyWjoM583u8mrtjveURpLY-iimc4Mhr8og63mHUCuXj_uqQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Hello,

I run a card game written in Perl on
a CentOS 6.3 / 64 bit + PostgreSQL 8.4.13
where quite a lot player statistics are written
to the d/b (score, game results, moves, etc.)

Here a player profile: http://preferans.de/DE11198

The machine has a quad intel + 32 GB RAM.

In poostgresql.conf I set:

max_connections = 100
shared_buffers = 4096MB
work_mem = 32MB
log_min_duration_statement = 10000

I also use pgbouncer (for PHP scripts),
but my Perl game daemon talks
directly to /tmp/.s.PGSQL.5432

My game daemon runs in a non-forking loop
and poll()s TCP sockets to the player machines..

Players complain about my server
freezing for few seconds sometimes
and I can see it myself in the game logs -
when data is sometimes written to d/b
(and postmaster processes take 90% CPU).

So my question is:

do I have to program a separate daemon -
which would be polled via a Unix domain
socket by my main game daemon and
which would handle sending SQL commands
(typically insert's and select's)?

Or does such a generic daemon exist already?

Or can multiple commands be sent to
the PostgreSQL simultaneously?

Here is how my Perl daemon talks to to
the d/b usually (this happens inside of the
poll() loop and thus stops everything for ms):

sub logout($) {
my $user = shift;
my $id = $user->{ID};

eval {
my $dbh = DBI->connect_cached(DSN, DBUSER, DBPASS, {
AutoCommit => 1,
PrintWarn => 1,
PrintError => 1,
RaiseError => 1,
FetchHashKeyName => 'NAME_lc',
pg_enable_utf8 => 1
});

if ($user->{SCORE}) {
my $sth_money = $dbh->prepare_cached(
q{select pref_update_money(?, ?)});
$sth_money->execute($id, $user->{SCORE});
$user->{SCORE} = 0;
}

my $sth_logout = $dbh->prepare_cached(
q{update pref_users set logout=now() where id=?});
$sth_logout->execute($id);
};
warn $@ if $@;
}

Thanks for any ideas
Alex


From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Sending several commands simultaneously to PostgreSQL 8.4
Date: 2013-01-21 14:27:07
Message-ID: CAADeyWgLeJZHrR7DLmGJ5k6h6NQJoEgJn-koFrQ_EOhL+W6m-w@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

To make my question more concrete:
if I'd like to round-robin 6 PostgreSQL connections
from my Perl script - how should I change my code:

eval {
my $dbh = DBI->connect_cached(DSN, DBUSER, DBPASS, {
AutoCommit => 1,
PrintWarn => 1,
PrintError => 1,
RaiseError => 1,
FetchHashKeyName => 'NAME_lc',
pg_enable_utf8 => 1
});
..........SQL commands.......
};
warn $@ if $@;
}

I.e. I don't understand how to combine
this with the DBI connect_cached() call?

How to make it return different connections?

Thanks
Alex


From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Sending several commands simultaneously to PostgreSQL 8.4
Date: 2013-01-21 14:45:27
Message-ID: CAADeyWjMUG6wHqXox4pMyXMbBx672RfG=ydNA3AZbhpq6p0U_A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I would like to add a private "key" to make
my dbh's different throughout my script:

eval {
my $dbh = DBI->connect_cached(DSN, DBUSER, DBPASS, {
AutoCommit => 1,
MY_PRIVATE_KEY => __FILE__.__LINE__, ### <-- HERE
PrintWarn => 1,
PrintError => 1,
RaiseError => 1,
FetchHashKeyName => 'NAME_lc',
pg_enable_utf8 => 1
});
..........SQL commands.......
};
warn $@ if $@;
}

As sugested by
http://search.cpan.org/~timb/DBI-1.616/DBI.pm#connect_cached

But how could I check - if this has worked
at my server and spawned more connections
through the /tmp/.s.PGSQL.5432
(versus the pg_bouncer connections
for PHP-scripts through /tmp/.s.PGSQL.6432) ?

I've tried:

# select * from pg_stat_activity where usename='XXXXX';

but the client_port is null there
(because I use Unix sockets?)

Thanks
Alex


From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Sending several commands simultaneously to PostgreSQL 8.4
Date: 2013-01-23 12:13:46
Message-ID: CAADeyWj4BCtmoQVz1o0VD2JSG-BEdzFZrMFp1qmnY-btOz0UfA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I've ended up calling this procedure
in the loop before poll() - to run queued
commands from an array of hashes:

sub execSql {
eval {
my $dbh = DBI->connect_cached(DSN, DBUSER, DBPASS, {
private_key => __FILE__,
AutoCommit => 1,
PrintWarn => 1,
PrintError => 1,
RaiseError => 1,
FetchHashKeyName => 'NAME_lc',
pg_enable_utf8 => 1
});

if ($WaitSql && $dbh->pg_ready) {
$WaitSql = 0;
$dbh->pg_result();
}

if (!$WaitSql && @Sqls) {
$WaitSql = 1;
my $sql = shift @Sqls;
my $cmd = $sql->{CMD};
my $args = $sql->{ARGS};
my $sth = $dbh->prepare_cached($cmd,
{ pg_async => PG_ASYNC + PG_OLDQUERY_WAIT });
$sth->execute(@$args);
}
};
warn $@ if $@;
}


From: Jeff Janes <jeff(dot)janes(at)gmail(dot)com>
To: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
Cc: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Sending several commands simultaneously to PostgreSQL 8.4
Date: 2013-01-24 02:26:16
Message-ID: CAMkU=1zUhLXHvizPp-N_O8ctkj7ebxfnieW=bGquuchWksrPyw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Monday, January 21, 2013, Alexander Farber wrote:

> To make my question more concrete:
> if I'd like to round-robin 6 PostgreSQL connections
> from my Perl script - how should I change my code:
>

But what would that accomplish? If your server is constipated on the IO
channel, all 6 connections will suffer the same.

Cheers,

Jeff


From: Jeff Janes <jeff(dot)janes(at)gmail(dot)com>
To: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
Cc: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Sending several commands simultaneously to PostgreSQL 8.4
Date: 2013-01-24 02:26:16
Message-ID: CAMkU=1zE=id9EUmwZkHwkSxevRgxD7VPAow5OWv5+tJ3xB4fqg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Monday, January 21, 2013, Alexander Farber wrote:

> Hello,
>
> I run a card game written in Perl on
> a CentOS 6.3 / 64 bit + PostgreSQL 8.4.13
> where quite a lot player statistics are written
> to the d/b (score, game results, moves, etc.)
>
> Here a player profile: http://preferans.de/DE11198
>
> The machine has a quad intel + 32 GB RAM.
>
> In poostgresql.conf I set:
>
> max_connections = 100
> shared_buffers = 4096MB
> work_mem = 32MB
> log_min_duration_statement = 10000
>
> I also use pgbouncer (for PHP scripts),
> but my Perl game daemon talks
> directly to /tmp/.s.PGSQL.5432
>

Why not have Perl go through pgbouncer as well?

>
> My game daemon runs in a non-forking loop
> and poll()s TCP sockets to the player machines..
>
> Players complain about my server
> freezing for few seconds sometimes
> and I can see it myself in the game logs -
> when data is sometimes written to d/b
> (and postmaster processes take 90% CPU).
>

Any idea what causes that? Your code only seems to do anything with the
database at the time that someone logs out. Does everyone log out at the
same time?

>
> So my question is:
>
> do I have to program a separate daemon -
> which would be polled via a Unix domain
> socket by my main game daemon and
> which would handle sending SQL commands
> (typically insert's and select's)?
>

One alternative possibility would be to use synchronous_commit=off. This
opens up the possibility that transactions would be lost in the case of a
crash. But you change your code to send off updates and not wait for a
response, as you seem to be proposing, then you are also introducing that
possibility, just implicitly.

Cheers,

Jeff