Improving mod_perl Driven Site's Performance -- Part V: Sharing Memory Page 3

By Stas Bekman (Send Email)
Posted Jan 24, 2001


Here is the Apache::Registry test script that I have used:

  preload_dbi.pl
  --------------
  use strict;
  use GTop ();
  use DBI ();

  my  = DBI->connect("DBI:mysql:test::localhost",
                         "",
                         "",
                         {
                          PrintError => 1, # warn() on errors

                          RaiseError => 0, # don't die on error
                          AutoCommit => 1, # commit executes
                                           # immediately
                         }
                        )
    or die "Cannot connect to database: ::errstr";

  my  = shift;
  ->send_http_header('text/plain');

  my  = "show tables";
  my  = ->prepare();
  ->execute();
  my @data = ();
  while (my @row = ->fetchrow_array){
    push @data, @row;
  }
  print "Data: @data\n";
  ->disconnect(); # NOP under Apache::DBI

  my  = GTop->new->proc_mem(25883);
  my   = ->size;
  my  = ->share;
  my   =  - ;
  printf "%8s %8s %8s\n", qw(Size Shared Diff);
  printf "%8d %8d %8d (bytes)\n",,,;

The script opens a connection to the database 'test' and issues a query to learn what tables the databases has. When the data is collected and printed the connection would be closed in the regular case, but Apache::DBI overrides it with empty method. When the data is processed a familiar to you already code to print the memory usage follows.

The server was restarted before each new test.

So here are the results of the five tests that were conducted, sorted by the Diff column:

  1. After the first request:
      Version     Size   Shared     Diff        Test type
      --------------------------------------------------------------------
            1  3465216  2621440   843776  install_driver
            2  3461120  2609152   851968  install_driver & connect_on_init
            3  3465216  2605056   860160  preload driver
            4  3461120  2494464   966656  nothing added
            5  3461120  2482176   978944  connect_on_init

  2. After the second request (all the subsequent request showed the same results):
      Version     Size   Shared    Diff         Test type

      --------------------------------------------------------------------
            1  3469312  2609152   860160  install_driver
            2  3481600  2605056   876544  install_driver & connect_on_init
            3  3469312  2588672   880640  preload driver
            4  3477504  2482176   995328  nothing added
            5  3481600  2469888  1011712  connect_on_init

Now what do we conclude from looking at these numbers. First we see that only after a second reload we get the final memory footprint for a specific request in question (if you pass different arguments the memory usage might and will be different).

But both tables show the same pattern of memory usage. We can clearly see that the real winner is the startup.pl file's version where the MySQL driver was installed (1). Since we want to have a connection ready for the first request made to the freshly spawned child process, we generally use the second version (2) which uses somewhat more memory, but has almost the same number of shared memory pages. The third version only preloads the driver which results in smaller shared memory. The last two versions having nothing initialized (4) and having only the connect_on_init() method used (5). The former is a little bit better than the latter, but both significantly worse than the first two versions.



Comment and Contribute

Your name/nickname

Your email

(Maximum characters: 1200). You have characters left.