Thread: Big insert/delete memory problems

Big insert/delete memory problems

From
Kurt Overberg
Date:
Hi all,  I have a kinda weird postgres sql question for everyone.  When
running the following SQL commands:


delete from xrefmembergroup where membergroupid = 2 ; select 1 as true;

insert into xrefmembergroup (membergroupid, memberid) select 2 as
membergroupid, member.id as memberid from member where  ((extract(year
from age(birthdate))) >= '17' ); select 1 as true;

...my memory usage goes nuts- allocates 20-30 Mb per time I run this.
After it finishes these commands, the memory usage does not go back
down, so after awhile, memory usage becomes a problem.   I would
estimate that the xrefmembergroup table has about 20,000-30,000 rows in
it, and I'm deleting/inserting about 5000 rows at a time with these
commands, which run VERY fast.

Here's the table definition:

     Column     |           Type           |
Modifiers
---------------+--------------------------+------------------------------------------------------------
  id            | integer                  | not null default
nextval('"xrefmembergroup_id_seq"'::text)
  membergroupid | integer                  | not null default 0
  memberid      | integer                  | not null default 0
  timestamp     | timestamp with time zone | default
"timestamp"('now'::text)
Indexes: xrefmembergroup_pkey primary key btree (id),
          membergroupid_xrefmembergroup_key btree (membergroupid),
          memberid_xrefmembergroup_key btree (memberid)


Is this an excessive delete/insert?  Am I breaking 'good form' here?
Thanks for any help!

/kurt




Re: Big insert/delete memory problems

From
Tom Lane
Date:
Kurt Overberg <kurt@hotdogrecords.com> writes:
> delete from xrefmembergroup where membergroupid = 2 ; select 1 as true;

> insert into xrefmembergroup (membergroupid, memberid) select 2 as
> membergroupid, member.id as memberid from member where  ((extract(year
> from age(birthdate))) >= '17' ); select 1 as true;

> ...my memory usage goes nuts- allocates 20-30 Mb per time I run this.

Postgres version?

Sounds like a memory leak, but there's not enough info here to debug it.
Which of these queries exactly is leaking memory?  If it's the
INSERT/SELECT (as I suspect), what's the schema of the 'member' table?

            regards, tom lane

Re: Big insert/delete memory problems

From
Kurt Overberg
Date:
Darn it, I knew I forgot something.  I'm running on redhat 7.3, with
postgresql version 7.3.2, accessing it through tomcat 4.1.18.  It
APPEARS that its the insert that bumps the memory.  Here's the schema
for the member table:


          Column         |           Type           |
   Modifiers
------------------------+--------------------------+---------------------------------------------------
  id                     | integer                  | not null default
nextval('"member_id_seq"'::text)
  username               | character varying(16)    | not null
  password               | character varying(16)    | not null
  email                  | character varying(255)   | not null
  firstname              | character varying(32)    | not null
  lastname               | character varying(32)    | not null
  address1               | character varying(100)   | default ''
  address2               | character varying(100)   | default ''
  address3               | character varying(100)   | default ''
  city                   | character varying(50)    | default ''
  state                  | character varying(10)    | default ''
  zipcode                | character varying(10)    | default ''
  telephone              | character varying(20)    | default ''
  fax                    | character varying(20)    | default ''
  imname                 | character varying(50)    | default ''
  implatform             | character varying(20)    | default ''
  gender                 | character(1)             |
  birthdate              | date                     |
  notifycampaigns        | boolean                  | default false
  notifytasks            | boolean                  | default false
  notifypoints           | boolean                  | default false
  notifyrewards          | boolean                  | default false
  contactemail           | boolean                  | default false
  contactim              | boolean                  | default false
  contactmail            | boolean                  | default false
  contacttelephone       | boolean                  | default false
  contactmembers         | boolean                  | default false
  receivecampaignresults | boolean                  | default false
  receivenewsletter      | boolean                  | default false
  educationlevel         | character varying(30)    | default ''
  studentorworking       | character varying(10)    | default ''
  companyname            | character varying(50)    | default ''
  title                  | character varying(50)    | default ''
  studentlevel           | character varying(30)    |
  implatformother        | character varying(20)    | default ''
  signedup               | timestamp with time zone | default
"timestamp"('now'::text)
  flags                  | character(20)            | default
'00000000000000000000'
  last_login             | timestamp with time zone | default
"timestamp"('now'::text)
  rating                 | double precision         | default 0.5


Thanks Tom.  I at my wit's end here.

/kurt


Tom Lane wrote:
> Kurt Overberg <kurt@hotdogrecords.com> writes:
>
>>delete from xrefmembergroup where membergroupid = 2 ; select 1 as true;
>
>
>>insert into xrefmembergroup (membergroupid, memberid) select 2 as
>>membergroupid, member.id as memberid from member where  ((extract(year
>>from age(birthdate))) >= '17' ); select 1 as true;
>
>
>>...my memory usage goes nuts- allocates 20-30 Mb per time I run this.
>
>
> Postgres version?
>
> Sounds like a memory leak, but there's not enough info here to debug it.
> Which of these queries exactly is leaking memory?  If it's the
> INSERT/SELECT (as I suspect), what's the schema of the 'member' table?
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
>
>



Re: Big insert/delete memory problems

From
Tom Lane
Date:
Kurt Overberg <kurt@hotdogrecords.com> writes:
> Darn it, I knew I forgot something.  I'm running on redhat 7.3, with
> postgresql version 7.3.2, accessing it through tomcat 4.1.18.  It
> APPEARS that its the insert that bumps the memory.  Here's the schema
> for the member table:

I created the two tables, loaded some dummy data into member, and
inserted/selected like mad ... no sign of memory bloat.  So there's
something else involved here.  Any plpgsql functions being used?
Triggers or foreign keys?

            regards, tom lane

Re: Big insert/delete memory problems

From
Kurt Overberg
Date:
Hmmmm....are you running on RedHat 7.3?  I'm not using any plpgsql,
triggers or foreignkeys.  Very simple DB.  I'm using the pre-compiled
RPM version of 7.3.2 on the production machine.  I have a similar
environment setup  running under Debian (woody), but that's a version
that I compiled from the source, and I can't really seem to duplicate
this behavior.  Things are kinda moving around a bit, because I'm
switching from Struts DB pooling to the Postgresql driver JDBC2 pooling
mechanism as well (this is a live production server, and I gotta get
this thing fixed so I can get some sleep and stop having to babysit the
site), so I'm throwing everything I can think of at this.  So here's the
main question:

During a large select/insert like this, the memory use of the pgsql
backend goes up, right?  Is it supposed to go down afterwards?  I just
need one fact to hang on to here to help me work this out.  I think my
plan at this point is to compile 7.3.2 on redhat with a fresh install
and see how that behaves.

Thanks again, Tom.  I appreciate your help.

/kurt


Tom Lane wrote:
> Kurt Overberg <kurt@hotdogrecords.com> writes:
>
>>Darn it, I knew I forgot something.  I'm running on redhat 7.3, with
>>postgresql version 7.3.2, accessing it through tomcat 4.1.18.  It
>>APPEARS that its the insert that bumps the memory.  Here's the schema
>>for the member table:
>
>
> I created the two tables, loaded some dummy data into member, and
> inserted/selected like mad ... no sign of memory bloat.  So there's
> something else involved here.  Any plpgsql functions being used?
> Triggers or foreign keys?
>
>             regards, tom lane
>
>



Re: Big insert/delete memory problems

From
Tom Lane
Date:
Kurt Overberg <kurt@hotdogrecords.com> writes:
> main question:

> During a large select/insert like this, the memory use of the pgsql
> backend goes up, right?

No, it's not supposed to go up in the first place.  When I run what
I think is the same case, I don't see the backend's resident-set-size
going above a couple meg.  You seem to be suffering an internal memory
leak, which is not a very surprising kind of bug --- but I don't
understand why I can't duplicate it.

Let's see ... what locale and encoding are you using?  Maybe it depends
on that.

            regards, tom lane

Re: Big insert/delete memory problems

From
Kurt Overberg
Date:
Okay- here's exactly what I'm seeing: I'm getting these figures from
top.  I see the query come in, and it goes to a postgres that's running
at 19Mb.  After the request, that postgres process (backend?) is at
39252 (37658 of that is shared).  My Locale is set to 'C', and my
client_encoding is the default (database encoding?).  Hope this helps.
Let me know if you want me to try anything else.  I'm currently
installing the compiled version, I'll let you know how it goes.

/kurt


(here's my postgresql.conf file, in case you'd want it)

#
#       Connection Parameters
#
tcpip_socket = true
#ssl = false

max_connections = 64
#superuser_reserved_connections = 2

#port = 5432
#hostname_lookup = false
#show_source_port = false

#unix_socket_directory = ''
#unix_socket_group = ''
#unix_socket_permissions = 0777 # octal

#virtual_host = ''

#krb_server_keyfile = ''


#
#       Shared Memory Size
#
shared_buffers = 30400          # min max_connections*2 or 16, 8KB each
#max_fsm_relations = 1000       # min 10, fsm is free space map, ~40 bytes
#max_fsm_pages = 10000          # min 1000, fsm is free space map, ~6 bytes
#max_locks_per_transaction = 64 # min 10
#wal_buffers = 8                # min 4, typically 8KB each

#
#       Non-shared Memory Sizes
#
sort_mem = 16384 # 32168                # min 64, size in KB
vacuum_mem = 16384 # 32168              # min 1024, size in KB


#
#       Write-ahead log (WAL)
#
#checkpoint_segments = 3        # in logfile segments, min 1, 16MB each
#checkpoint_timeout = 300       # range 30-3600, in seconds
#
#commit_delay = 0               # range 0-100000, in microseconds
#commit_siblings = 5            # range 1-1000
#
#fsync = true
#wal_sync_method = fsync        # the default varies across platforms:
#                               # fsync, fdatasync, open_sync, or
open_datasync
#wal_debug = 0                  # range 0-16


#
#       Optimizer Parameters
#
#enable_seqscan = true
#enable_indexscan = true
#enable_tidscan = true
#enable_sort = true
#enable_nestloop = true
#enable_mergejoin = true
#enable_hashjoin = true

#effective_cache_size = 1000    # typically 8KB each
#random_page_cost = 4           # units are one sequential page fetch cost
#cpu_tuple_cost = 0.01          # (same)
#cpu_index_tuple_cost = 0.001   # (same)
#cpu_operator_cost = 0.0025     # (same)

#default_statistics_target = 10 # range 1-1000

#
#       GEQO Optimizer Parameters
#
#geqo = true
#geqo_selection_bias = 2.0      # range 1.5-2.0
#geqo_threshold = 11
#geqo_pool_size = 0             # default based on tables in statement,
                                 # range 128-1024
#geqo_effort = 1
#geqo_generations = 0
#geqo_random_seed = -1          # auto-compute seed


#
#       Message display
#
server_min_messages = notice    # Values, in order of decreasing detail:
                                 #   debug5, debug4, debug3, debug2, debug1,
                                 #   info, notice, warning, error, log,
fatal,
                                 #   panic
client_min_messages = notice    # Values, in order of decreasing detail:
                                 #   debug5, debug4, debug3, debug2, debug1,
                                 #   log, info, notice, warning, error
#silent_mode = false

log_connections = true
#log_pid = false
#log_statement = false
#log_duration = false
log_timestamp = true

#log_min_error_statement = error # Values in order of increasing severity:
                                  #   debug5, debug4, debug3, debug2,
debug1,
                                  #   info, notice, warning, error,
panic(off)

#debug_print_parse = false
#debug_print_rewritten = false
#debug_print_plan = false
#debug_pretty_print = false

#explain_pretty_print = true

# requires USE_ASSERT_CHECKING
#debug_assertions = true


#
#       Syslog
#
syslog = 0                      # range 0-2
syslog_facility = 'LOCAL0'
syslog_ident = 'postgres'


#
#       Statistics
#
#show_parser_stats = false
#show_planner_stats = false
#show_executor_stats = false
#show_statement_stats = false

# requires BTREE_BUILD_STATS
#show_btree_build_stats = false


#
#       Access statistics collection
#
#stats_start_collector = true
#stats_reset_on_server_start = true
#stats_command_string = false
#stats_row_level = false
#stats_block_level = false


#
#       Lock Tracing
#
#trace_notify = false

# requires LOCK_DEBUG
#trace_locks = false
#trace_userlocks = false
#trace_lwlocks = false
#debug_deadlocks = false
#trace_lock_oidmin = 16384
#trace_lock_table = 0


#
#       Misc
#
#autocommit = true
#dynamic_library_path = '$libdir'
#search_path = '$user,public'
#datestyle = 'iso, us'
#timezone = unknown             # actually, defaults to TZ environment
setting
#australian_timezones = false
#client_encoding = sql_ascii    # actually, defaults to database encoding
#authentication_timeout = 60    # 1-600, in seconds
#deadlock_timeout = 1000        # in milliseconds
#default_transaction_isolation = 'read committed'
#max_expr_depth = 10000         # min 10
#max_files_per_process = 1000   # min 25
#password_encryption = true
#sql_inheritance = true
#transform_null_equals = false
#statement_timeout = 0          # 0 is disabled, in milliseconds
#db_user_namespace = false



#
#       Locale settings
#
# (initialized by initdb -- may be changed)
LC_MESSAGES = 'C'
LC_MONETARY = 'C'
LC_NUMERIC = 'C'
LC_TIME = 'C'

Tom Lane wrote:
> Kurt Overberg <kurt@hotdogrecords.com> writes:
>
>>main question:
>
>
>>During a large select/insert like this, the memory use of the pgsql
>>backend goes up, right?
>
>
> No, it's not supposed to go up in the first place.  When I run what
> I think is the same case, I don't see the backend's resident-set-size
> going above a couple meg.  You seem to be suffering an internal memory
> leak, which is not a very surprising kind of bug --- but I don't
> understand why I can't duplicate it.
>
> Let's see ... what locale and encoding are you using?  Maybe it depends
> on that.
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org
>
>



Re: Big insert/delete memory problems

From
Kurt Overberg
Date:
Tom,

After installing the compiled version, things are looking better.  The
processes are still growing, but not nearly as fast as before

I think this problem may have something to do with my connection from
Tomcat.  I'm using the JDBC2 drivers from postgresql.org, and when I
reset my tomcat, memory usage on those backends goes way down (back to
normal).  So it seems like something in the JDBC driver is keeping those
backends large.  I'm using the PooledDataSource object for accessing
this database.  Don't know if that helps or not.  I'll try to post to
the JDBC list and see what I can find.  Thanks again!

/kurt





Tom Lane wrote:
> Kurt Overberg <kurt@hotdogrecords.com> writes:
>
>>main question:
>
>
>>During a large select/insert like this, the memory use of the pgsql
>>backend goes up, right?
>
>
> No, it's not supposed to go up in the first place.  When I run what
> I think is the same case, I don't see the backend's resident-set-size
> going above a couple meg.  You seem to be suffering an internal memory
> leak, which is not a very surprising kind of bug --- but I don't
> understand why I can't duplicate it.
>
> Let's see ... what locale and encoding are you using?  Maybe it depends
> on that.
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org
>
>



Re: Big insert/delete memory problems

From
Kurt Overberg
Date:
Just to follow up on this thread, I found the problem(s).  JDBC2
connection pooling AND that pre-compiled version on RedHat.  After
switching to my compiled version, I was still seeing memory leaking from
the postgresql processes.  BUT- it wasn't as bad as it was with the
precompiled version.  It was still leaking too much for me to be
comfortable with though, so I stopped doing connection pooling.  Its a
bit slower, especially with DB connection intensive operations, but now
postgresql takes up less memory than my apache processes!  WOOOO HOOOOO!
   So the problem appears to be that Jdbc2 connection pooling makes
postgresql leak, at least on RedHat 7.3.   Thanks Tom!


/kurt


Kurt Overberg wrote:
> Hi all,  I have a kinda weird postgres sql question for everyone.  When
> running the following SQL commands:
>
>
> delete from xrefmembergroup where membergroupid = 2 ; select 1 as true;
>
> insert into xrefmembergroup (membergroupid, memberid) select 2 as
> membergroupid, member.id as memberid from member where  ((extract(year
> from age(birthdate))) >= '17' ); select 1 as true;
>
> ...my memory usage goes nuts- allocates 20-30 Mb per time I run this.
> After it finishes these commands, the memory usage does not go back
> down, so after awhile, memory usage becomes a problem.   I would
> estimate that the xrefmembergroup table has about 20,000-30,000 rows in
> it, and I'm deleting/inserting about 5000 rows at a time with these
> commands, which run VERY fast.
>
> Here's the table definition:
>
>     Column     |           Type           | Modifiers
> ---------------+--------------------------+------------------------------------------------------------
>
>  id            | integer                  | not null default
> nextval('"xrefmembergroup_id_seq"'::text)
>  membergroupid | integer                  | not null default 0
>  memberid      | integer                  | not null default 0
>  timestamp     | timestamp with time zone | default
> "timestamp"('now'::text)
> Indexes: xrefmembergroup_pkey primary key btree (id),
>          membergroupid_xrefmembergroup_key btree (membergroupid),
>          memberid_xrefmembergroup_key btree (memberid)
>
>
> Is this an excessive delete/insert?  Am I breaking 'good form' here?
> Thanks for any help!
>
> /kurt
>
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
>
>



Re: Big insert/delete memory problems

From
Tom Lane
Date:
Kurt Overberg <kurt@hotdogrecords.com> writes:
>    So the problem appears to be that Jdbc2 connection pooling makes
> postgresql leak, at least on RedHat 7.3.

There's something fishy about that conclusion.  How could the JDBC code
cause a server-side memory leak?

            regards, tom lane