]> granicus.if.org Git - pgbadger/commitdiff
Update tools/pgbadger_tools script to be compatible with new binary file format in...
authorGilles Darold <gilles@darold.net>
Mon, 17 Jun 2019 14:42:29 +0000 (16:42 +0200)
committerGilles Darold <gilles@darold.net>
Mon, 17 Jun 2019 14:42:29 +0000 (16:42 +0200)
tools/pgbadger_tools

index 6bc69aa30949028db2a15d2050107b7dc7e56c43..f2039b805dfe7cb26fd8239473eb9da091a91057 100755 (executable)
@@ -35,7 +35,7 @@ my @SQL_ACTION   = ('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'COPY FROM', 'COPY T
 my %overall_stat        = ();
 my %pgb_overall_stat    = ();
 my %overall_checkpoint  = ();
-my @top_slowest         = ();
+my %top_slowest         = ();
 my %normalyzed_info     = ();
 my %error_info          = ();
 my %pgb_error_info      = ();
@@ -61,12 +61,18 @@ my %cur_info            = ();
 my %cur_temp_info       = ();
 my %cur_lock_info       = ();
 my %tsung_session       = ();
+my %errors_code          = ();
 my @top_locked_info     = ();
 my @top_tempfile_info   = ();
 my @log_files           = ();
 my $nlines              = 0;
 my $sample              = 3;
 my $top                 = 20;
+my $anonymize           = 0;
+
+# Let's say --explode was not used to generate the binary files
+# in this case all data are stored under the postgres database.
+my $def_db = 'postgres';
 
 ##################################################################
 # Get the command line parameters
@@ -158,17 +164,17 @@ if ($psql_cmd) {
 ##################################################################
 if ($explain_slowest) {
     &logmsg('LOG', "Output each slowest queries within explain statement.");
-    &dump_slowest_queries();
+    &dump_slowest_queries($def_db);
 }
 # when option --explain-time-consuming is set at command line
 if ($explain_time_consuming) {
     &logmsg('LOG', "Output each most times consuming queries within explain statement.");
-    &dump_times_consuming_queries();
+    &dump_times_consuming_queries($def_db);
 }
 # when option --explain-normalized is set at command line
 if ($explain_normalized) {
     &logmsg('LOG', "Output each slowest normalized queries within explain statement.");
-    &dump_normalized_slowest_queries();
+    &dump_normalized_slowest_queries($def_db);
 }
 
 ####################################################################
@@ -184,11 +190,11 @@ if ($csv_time_consuming || $csv_slowest || $csv_normalized) {
                Text::CSV->import();
        }
        if ($csv_time_consuming) {
-               &csv_times_consuming_queries();
+               &csv_times_consuming_queries($def_db);
        } elsif ($csv_slowest) {
-               &csv_slowest_queries();
+               &csv_slowest_queries($def_db);
        } elsif ($csv_normalized) {
-               &csv_normalized_queries();
+               &csv_normalized_queries($def_db);
        }
 }
 
@@ -320,31 +326,40 @@ sub logmsg
 }
 
 ####
-# Stores top N error sample queries
+# Stores top N error sample queries, taken from pgbadger script
 ####
 sub set_top_error_sample
 {
-       my ($q, $date, $real_error, $detail, $context, $statement, $hint, $db, $user, $app, $remote) = @_;
+       my ($curdb, $q, $date, $real_error, $detail, $context, $statement, $hint, $db, $user, $app, $remote, $sqlstate) = @_;
+
+       $errors_code{$curdb}{$sqlstate}++ if ($sqlstate);
 
        # Stop when we have our number of samples
-       if (!exists $error_info{$q}{date} || ($#{$error_info{$q}{date}} < $sample)) {
-               if ( ($q =~ /deadlock detected/) || ($real_error && !grep(/^\Q$real_error\E$/, @{$error_info{$q}{error}})) ) {
-                       push(@{$error_info{$q}{date}},      $date);
-                       push(@{$error_info{$q}{detail}},    $detail);
-                       push(@{$error_info{$q}{context}},   $context);
-                       push(@{$error_info{$q}{statement}}, $statement);
-                       push(@{$error_info{$q}{hint}},      $hint);
-                       push(@{$error_info{$q}{error}},     $real_error);
-                       push(@{$error_info{$q}{db}},        $db);
-                       push(@{$error_info{$q}{user}},      $user);
-                       push(@{$error_info{$q}{app}},       $app);
-                       push(@{$error_info{$q}{remote}},    $remote);
+       if (!exists $error_info{$curdb}{$q}{date} || ($#{$error_info{$curdb}{$q}{date}}+1 < $sample)) {
+               if ( ($q =~ /deadlock detected/) || ($real_error && !grep(/^\Q$real_error\E$/, @{$error_info{$curdb}{$q}{error}})) ) {
+                       if ($anonymize) {
+                               $context = &anonymize_query($context);
+                               $statement = &anonymize_query($statement);
+                               $detail = &anonymize_query($detail);
+                       }
+
+                       push(@{$error_info{$curdb}{$q}{date}},      $date);
+                       push(@{$error_info{$curdb}{$q}{detail}},    $detail);
+                       push(@{$error_info{$curdb}{$q}{context}},   $context);
+                       push(@{$error_info{$curdb}{$q}{statement}}, $statement);
+                       push(@{$error_info{$curdb}{$q}{hint}},      $hint);
+                       push(@{$error_info{$curdb}{$q}{error}},     $real_error);
+                       push(@{$error_info{$curdb}{$q}{db}},    $db);
+                       push(@{$error_info{$curdb}{$q}{user}},      $user);
+                       push(@{$error_info{$curdb}{$q}{app}},       $app);
+                       push(@{$error_info{$curdb}{$q}{remote}},    $remote);
+                       push(@{$error_info{$curdb}{$q}{sqlstate}},  $sqlstate);
                }
        }
 }
 
 ####
-# Load statistics from binary file into memory
+# Load statistics from binary file into memory, the function is copied from pgbadger script
 ####
 sub load_stats
 {
@@ -373,50 +388,93 @@ sub load_stats
        my %_tempfile_info = %{$stats{tempfile_info}};
        my %_cancelled_info = %{$stats{cancelled_info}};
        my %_logs_type = %{$stats{logs_type}};
+       my %_errors_code = %{$stats{errors_code}};
        my %_lock_info = %{$stats{lock_info}};
        my %_per_minute_info = %{$stats{per_minute_info}};
        my %_pgb_per_minute_info = %{$stats{pgb_per_minute_info}};
-       my @_top_slowest = @{$stats{top_slowest}};
+       my %_top_slowest = %{$stats{top_slowest}};
        my $_nlines = $stats{nlines};
        my $_first_log_timestamp = $stats{first_log_timestamp};
        my $_last_log_timestamp = $stats{last_log_timestamp};
        my @_log_files = @{$stats{log_files}};
        my %_autovacuum_info = %{$stats{autovacuum_info}};
        my %_autoanalyze_info = %{$stats{autoanalyze_info}};
-       my @_top_locked_info = @{$stats{top_locked_info}};
-       my @_top_tempfile_info = @{$stats{top_tempfile_info}};
-       my @_top_cancelled_info = @{$stats{top_cancelled_info}};
+       my %_top_locked_info = %{$stats{top_locked_info}};
+       my %_top_tempfile_info = %{$stats{top_tempfile_info}};
+       my %_top_cancelled_info = %{$stats{top_cancelled_info}};
 
        ### overall_stat ###
 
-       $overall_stat{queries_number} += $_overall_stat{queries_number};
-
-       if ($_overall_stat{'first_log_ts'}) {
-               $overall_stat{'first_log_ts'} = $_overall_stat{'first_log_ts'}
-                       if (!$overall_stat{'first_log_ts'} || 
-                               ($overall_stat{'first_log_ts'} gt $_overall_stat{'first_log_ts'}));
+       # Those a used to update the progress bar and are not related to any database
+       $overall_stat{'queries_number'} += $_overall_stat{'queries_number'};
+       $overall_stat{'errors_number'} += $_overall_stat{'errors_number'};
+       $pgb_overall_stat{'queries_number'} += $_pgb_overall_stat{'queries_number'};
+       $pgb_overall_stat{'errors_number'} += $_pgb_overall_stat{'errors_number'};
+       foreach my $d (keys %{ $_overall_stat{nlines} })
+       {
+               $overall_stat{'nlines'}{$d} += $_overall_stat{'nlines'}{$d};
        }
 
-       $overall_stat{'last_log_ts'} = $_overall_stat{'last_log_ts'}
-               if not $overall_stat{'last_log_ts'}
-                       or $overall_stat{'last_log_ts'} lt $_overall_stat{'last_log_ts'};
+       foreach my $curdb (keys %_overall_stat)
+       {
+               next if (grep(/^$curdb$/, 'queries_number', 'errors_number', 'queries_number', 'errors_number', 'nlines'));
+               if ($_overall_stat{$curdb}{'first_log_ts'}) {
+                       $overall_stat{$curdb}{'first_log_ts'} = $_overall_stat{$curdb}{'first_log_ts'}
+                               if (!$overall_stat{$curdb}{'first_log_ts'} ||
+                                       ($overall_stat{$curdb}{'first_log_ts'} gt $_overall_stat{$curdb}{'first_log_ts'}));
+               }
 
-       if ($_overall_stat{'first_query_ts'}) {
-               $overall_stat{'first_query_ts'} = $_overall_stat{'first_query_ts'}
-                       if (!$overall_stat{'first_query_ts'} ||
-                               ($overall_stat{'first_query_ts'} gt $_overall_stat{'first_query_ts'}));
-       }
+               $overall_stat{$curdb}{'last_log_ts'} = $_overall_stat{$curdb}{'last_log_ts'}
+                       if not $overall_stat{$curdb}{'last_log_ts'}
+                               or $overall_stat{$curdb}{'last_log_ts'} lt $_overall_stat{$curdb}{'last_log_ts'};
 
-       $overall_stat{'last_query_ts'} = $_overall_stat{'last_query_ts'}
-               if not $overall_stat{'last_query_ts'} 
-                       or $overall_stat{'last_query_ts'} lt $_overall_stat{'last_query_ts'};
+               $overall_stat{$curdb}{'queries_number'} += $_overall_stat{$curdb}{'queries_number'};
+               $overall_stat{$curdb}{'errors_number'} += $_overall_stat{$curdb}{'errors_number'};
+               $pgb_overall_stat{$curdb}{'queries_number'} += $_pgb_overall_stat{$curdb}{'queries_number'};
+               $pgb_overall_stat{$curdb}{'errors_number'} += $_pgb_overall_stat{$curdb}{'errors_number'};
+
+               if ($_overall_stat{$curdb}{'first_query_ts'}) {
+                       $overall_stat{$curdb}{'first_query_ts'} = $_overall_stat{$curdb}{'first_query_ts'}
+                               if (!$overall_stat{$curdb}{'first_query_ts'} ||
+                                       ($overall_stat{$curdb}{'first_query_ts'} gt $_overall_stat{$curdb}{'first_query_ts'}));
+               }
 
-       $overall_stat{errors_number} += $_overall_stat{errors_number};
-       $overall_stat{queries_duration} += $_overall_stat{queries_duration};
+               $overall_stat{$curdb}{'last_query_ts'} = $_overall_stat{$curdb}{'last_query_ts'}
+                       if not $overall_stat{$curdb}{'last_query_ts'}
+                               or $overall_stat{$curdb}{'last_query_ts'} lt $_overall_stat{$curdb}{'last_query_ts'};
+
+               $overall_stat{$curdb}{queries_duration} += $_overall_stat{$curdb}{queries_duration};
+
+               foreach my $a (@SQL_ACTION) {
+                       $overall_stat{$curdb}{$a} += $_overall_stat{$curdb}{$a}
+                       if exists $_overall_stat{$curdb}{$a};
+               }
+
+               foreach my $k (keys %{$_overall_stat{$curdb}{peak}}) {
+                       $overall_stat{$curdb}{peak}{$k}{query} += $_overall_stat{$curdb}{peak}{$k}{query};
+                       $overall_stat{$curdb}{peak}{$k}{select} += $_overall_stat{$curdb}{peak}{$k}{select};
+                       $overall_stat{$curdb}{peak}{$k}{write} += $_overall_stat{$curdb}{peak}{$k}{write};
+                       $overall_stat{$curdb}{peak}{$k}{connection} += $_overall_stat{$curdb}{peak}{$k}{connection};
+                       $overall_stat{$curdb}{peak}{$k}{session} += $_overall_stat{$curdb}{peak}{$k}{session};
+                       $overall_stat{$curdb}{peak}{$k}{tempfile_size} += $_overall_stat{$curdb}{peak}{$k}{tempfile_size};
+                       $overall_stat{$curdb}{peak}{$k}{tempfile_count} += $_overall_stat{$curdb}{peak}{$k}{tempfile_count};
+                       $overall_stat{$curdb}{peak}{$k}{cancelled_size} += $_overall_stat{$curdb}{peak}{$k}{cancelled_size};
+                       $overall_stat{$curdb}{peak}{$k}{cancelled_count} += $_overall_stat{$curdb}{peak}{$k}{cancelled_count};
+               }
+
+               foreach my $k (keys %{$_overall_stat{$curdb}{histogram}{query_time}}) {
+                       $overall_stat{$curdb}{histogram}{query_time}{$k} += $_overall_stat{$curdb}{histogram}{query_time}{$k};
+               }
+               $overall_stat{$curdb}{histogram}{query_total} += $_overall_stat{$curdb}{histogram}{total};
+               $overall_stat{$curdb}{histogram}{query_total} += $_overall_stat{$curdb}{histogram}{query_total};
+               foreach my $k (keys %{$_overall_stat{$curdb}{histogram}{session_time}}) {
+                       $overall_stat{$curdb}{histogram}{session_time}{$k} += $_overall_stat{$curdb}{histogram}{session_time}{$k};
+               }
+               $overall_stat{$curdb}{histogram}{session_total} += $_overall_stat{$curdb}{histogram}{session_total};
 
-       foreach my $a (@SQL_ACTION) {
-               $overall_stat{$a} += $_overall_stat{$a}
-               if exists $_overall_stat{$a};
+               foreach my $k ('prepare', 'bind','execute') {
+                       $overall_stat{$curdb}{$k} += $_overall_stat{$curdb}{$k};
+               }
        }
 
        $overall_checkpoint{checkpoint_warning} += $_overall_checkpoint{checkpoint_warning};
@@ -424,35 +482,11 @@ sub load_stats
                if ($_overall_checkpoint{checkpoint_write} > $overall_checkpoint{checkpoint_write});
        $overall_checkpoint{checkpoint_sync} = $_overall_checkpoint{checkpoint_sync}
                if ($_overall_checkpoint{checkpoint_sync} > $overall_checkpoint{checkpoint_sync});
-       foreach my $k (keys %{$_overall_stat{peak}}) {
-               $overall_stat{peak}{$k}{query} += $_overall_stat{peak}{$k}{query};
-               $overall_stat{peak}{$k}{select} += $_overall_stat{peak}{$k}{select};
-               $overall_stat{peak}{$k}{write} += $_overall_stat{peak}{$k}{write};
-               $overall_stat{peak}{$k}{connection} += $_overall_stat{peak}{$k}{connection};
-               $overall_stat{peak}{$k}{session} += $_overall_stat{peak}{$k}{session};
-               $overall_stat{peak}{$k}{tempfile_size} += $_overall_stat{peak}{$k}{tempfile_size};
-               $overall_stat{peak}{$k}{tempfile_count} += $_overall_stat{peak}{$k}{tempfile_count};
-               $overall_stat{peak}{$k}{cancelled_size} += $_overall_stat{peak}{$k}{cancelled_size};
-               $overall_stat{peak}{$k}{cancelled_count} += $_overall_stat{peak}{$k}{cancelled_count};
-       }
-
-       foreach my $k (keys %{$_overall_stat{histogram}{query_time}}) {
-               $overall_stat{histogram}{query_time}{$k} += $_overall_stat{histogram}{query_time}{$k};
-       }
-       $overall_stat{histogram}{query_total} += $_overall_stat{histogram}{total};
-       $overall_stat{histogram}{query_total} += $_overall_stat{histogram}{query_total};
-       foreach my $k (keys %{$_overall_stat{histogram}{session_time}}) {
-               $overall_stat{histogram}{session_time}{$k} += $_overall_stat{histogram}{session_time}{$k};
-       }
-       $overall_stat{histogram}{session_total} += $_overall_stat{histogram}{session_total};
-
-       foreach my $k ('prepare', 'bind','execute') {
-               $overall_stat{$k} += $_overall_stat{$k};
-       }
-
        foreach my $k (keys %{$_overall_checkpoint{peak}}) {
                $overall_checkpoint{peak}{$k}{checkpoint_wbuffer} += $_overall_checkpoint{peak}{$k}{checkpoint_wbuffer};
                $overall_checkpoint{peak}{$k}{walfile_usage} += $_overall_checkpoint{peak}{$k}{walfile_usage};
+               $overall_checkpoint{peak}{$k}{distance} += $_overall_checkpoint{peak}{$k}{distance};
+               $overall_checkpoint{peak}{$k}{estimate} += $_overall_checkpoint{peak}{$k}{estimate};
        }
 
        ### pgbouncer related overall stats ###
@@ -470,98 +504,106 @@ sub load_stats
        }
        $pgb_overall_stat{histogram}{session_total} += $_pgb_overall_stat{histogram}{session_total};
 
-       $pgb_overall_stat{errors_number} += $_pgb_overall_stat{errors_number};
-
        ### Logs level ###
 
-       foreach my $l (qw(LOG WARNING ERROR FATAL PANIC DETAIL HINT STATEMENT CONTEXT)) {
-               $logs_type{$l} += $_logs_type{$l} if exists $_logs_type{$l};
+       foreach my $l (qw(LOG WARNING ERROR FATAL PANIC DETAIL HINT STATEMENT CONTEXT))
+       {
+               foreach my $curdb (keys %_logs_type)
+               {
+                       $logs_type{$curdb}{$l} += $_logs_type{$curdb}{$l} if exists $_logs_type{$curdb}{$l};
+               }
+       }
+
+       ### Errors code ###
+
+       foreach my $curdb (keys %_errors_code)
+       {
+               foreach my $c (keys %{$_errors_code{$curdb}}) {
+                       $errors_code{$curdb}{$c} += $_errors_code{$curdb}{$c};
+               }
        }
 
        ### database_info ###
 
-       foreach my $db (keys %_database_info) {
-               foreach my $k (keys %{ $_database_info{$db} }) {
-                       $database_info{$db}{$k} += $_database_info{$db}{$k};
+       foreach my $curdb (keys %_database_info)
+       {
+               foreach my $db (keys %{$_database_info{$curdb}}) {
+                       foreach my $k (keys %{ $_database_info{$curdb}{$db} }) {
+                               $database_info{$curdb}{$db}{$k} += $_database_info{$curdb}{$db}{$k};
+                       }
                }
        }
 
        ### application_info ###
 
-       foreach my $app (keys %_application_info) {
-               foreach my $k (keys %{ $_application_info{$app} }) {
-                       $application_info{$app}{$k} += $_application_info{$app}{$k};
+       foreach my $curdb (keys %_application_info)
+       {
+               foreach my $app (keys %{$_application_info{$curdb}}) {
+                       foreach my $k (keys %{ $_application_info{$curdb}{$app} }) {
+                               $application_info{$curdb}{$app}{$k} += $_application_info{$curdb}{$app}{$k};
+                       }
                }
        }
 
        ### user_info ###
 
-       foreach my $u (keys %_user_info) {
-               foreach my $k (keys %{ $_user_info{$u} }) {
-                       $user_info{$u}{$k} += $_user_info{$u}{$k};
+       foreach my $curdb (keys %_user_info)
+       {
+               foreach my $u (keys %{$_user_info{$curdb}}) {
+                       foreach my $k (keys %{ $_user_info{$curdb}{$u} }) {
+                               $user_info{$curdb}{$u}{$k} += $_user_info{$curdb}{$u}{$k};
+                       }
                }
        }
 
        ### host_info ###
 
-       foreach my $h (keys %_host_info) {
-               foreach my $k (keys %{ $_host_info{$h} }) {
-                       $host_info{$h}{$k} += $_host_info{$h}{$k};
+       foreach my $curdb (keys %_host_info)
+       {
+               foreach my $h (keys %{$_host_info{$curdb}}) {
+                       foreach my $k (keys %{ $_host_info{$curdb}{$h} }) {
+                               $host_info{$curdb}{$h}{$k} += $_host_info{$curdb}{$h}{$k};
+                       }
                }
        }
 
 
        ### connection_info ###
 
-       foreach my $db (keys %{ $_connection_info{database} }) {
-               $connection_info{database}{$db} += $_connection_info{database}{$db};
-       }
+       foreach my $curdb (keys %_connection_info)
+       {
+               foreach my $db (keys %{ $_connection_info{$curdb}{database} }) {
+                       $connection_info{$curdb}{database}{$db} += $_connection_info{$curdb}{database}{$db};
+               }
 
-       foreach my $db (keys %{ $_connection_info{database_user} }) {
-               foreach my $user (keys %{ $_connection_info{database_user}{$db} }) {
-                       $connection_info{database_user}{$db}{$user} += $_connection_info{database_user}{$db}{$user};
+               foreach my $db (keys %{ $_connection_info{$curdb}{database_user} }) {
+                       foreach my $user (keys %{ $_connection_info{$curdb}{database_user}{$db} }) {
+                               $connection_info{$curdb}{database_user}{$db}{$user} += $_connection_info{$curdb}{database_user}{$db}{$user};
+                       }
                }
-       }
 
-       foreach my $user (keys %{ $_connection_info{user} }) {
-               $connection_info{user}{$user} += $_connection_info{user}{$user};
-       }
+               foreach my $db (keys %{ $_connection_info{$curdb}{database_host} }) {
+                       foreach my $user (keys %{ $_connection_info{$curdb}{database_host}{$db} }) {
+                               $connection_info{$curdb}{database_host}{$db}{$user} += $_connection_info{$curdb}{database_host}{$db}{$user};
+                       }
+               }
 
-       foreach my $host (keys %{ $_connection_info{host} }) {
-               $connection_info{host}{$host} += $_connection_info{host}{$host};
-       }
+               foreach my $user (keys %{ $_connection_info{$curdb}{user} }) {
+                       $connection_info{$curdb}{user}{$user} += $_connection_info{$curdb}{user}{$user};
+               }
 
-       $connection_info{count} += $_connection_info{count};
+               foreach my $host (keys %{ $_connection_info{$curdb}{host} }) {
+                       $connection_info{$curdb}{host}{$host} += $_connection_info{$curdb}{host}{$host};
+               }
 
-       foreach my $day (keys %{ $_connection_info{chronos} }) {
-               foreach my $hour (keys %{ $_connection_info{chronos}{$day} }) {
+               $connection_info{$curdb}{count} += $_connection_info{$curdb}{count};
 
-                       $connection_info{chronos}{$day}{$hour}{count} += $_connection_info{chronos}{$day}{$hour}{count}
+               foreach my $day (keys %{ $_connection_info{$curdb}{chronos} })
+               {
+                       foreach my $hour (keys %{ $_connection_info{$curdb}{chronos}{$day} }) {
 
-###############################################################################
-# May be used in the future to display more detailed information on connection
-#
-#                      foreach my $db (keys %{ $_connection_info{chronos}{$day}{$hour}{database} }) {
-#                              $connection_info{chronos}{$day}{$hour}{database}{$db} += $_connection_info{chronos}{$day}{$hour}{database}{$db};
-#                      }
-#
-#                      foreach my $db (keys %{ $_connection_info{chronos}{$day}{$hour}{database_user} }) {
-#                              foreach my $user (keys %{ $_connection_info{chronos}{$day}{$hour}{database_user}{$db} }) {
-#                                      $connection_info{chronos}{$day}{$hour}{database_user}{$db}{$user} +=
-#                                              $_connection_info{chronos}{$day}{$hour}{database_user}{$db}{$user};
-#                              }
-#                      }
-#
-#                      foreach my $user (keys %{ $_connection_info{chronos}{$day}{$hour}{user} }) {
-#                              $connection_info{chronos}{$day}{$hour}{user}{$user} +=
-#                                      $_connection_info{chronos}{$day}{$hour}{user}{$user};
-#                      }
-#
-#                      foreach my $host (keys %{ $_connection_info{chronos}{$day}{$hour}{host} }) {
-#                              $connection_info{chronos}{$day}{$hour}{host}{$host} +=
-#                                      $_connection_info{chronos}{$day}{$hour}{host}{$host};
-#                      }
-###############################################################################
+                               $connection_info{$curdb}{chronos}{$day}{$hour}{count} += $_connection_info{$curdb}{chronos}{$day}{$hour}{count};
+                       }
                }
        }
 
@@ -577,6 +619,12 @@ sub load_stats
                }
        }
 
+       foreach my $db (keys %{ $_pgb_connection_info{database_host} }) {
+               foreach my $user (keys %{ $_pgb_connection_info{database_host}{$db} }) {
+                       $pgb_connection_info{database_host}{$db}{$user} += $_pgb_connection_info{database_host}{$db}{$user};
+               }
+       }
+
        foreach my $user (keys %{ $_pgb_connection_info{user} }) {
                $pgb_connection_info{user}{$user} += $_pgb_connection_info{user}{$user};
        }
@@ -601,35 +649,40 @@ sub load_stats
 
        ### error_info ###
 
-       foreach my $q (keys %_error_info) {
-               $error_info{$q}{count} += $_error_info{$q}{count};
-               foreach my $day (keys %{ $_error_info{$q}{chronos} }) {
-                       foreach my $hour (keys %{$_error_info{$q}{chronos}{$day}}) {
-                               $error_info{$q}{chronos}{$day}{$hour}{count} += $_error_info{$q}{chronos}{$day}{$hour}{count};
-                               foreach my $min (keys %{$_error_info{$q}{chronos}{$day}{$hour}{min}}) {
-                                       $error_info{$q}{chronos}{$day}{$hour}{min}{$min} += $_error_info{$q}{chronos}{$day}{$hour}{min}{$min};
+       foreach my $curdb (keys %_error_info)
+       {
+               foreach my $q (keys %{$_error_info{$curdb}}) {
+                       $error_info{$curdb}{$q}{count} += $_error_info{$curdb}{$q}{count};
+                       foreach my $day (keys %{ $_error_info{$curdb}{$q}{chronos} }) {
+                               foreach my $hour (keys %{$_error_info{$curdb}{$q}{chronos}{$day}}) {
+                                       $error_info{$curdb}{$q}{chronos}{$day}{$hour}{count} += $_error_info{$curdb}{$q}{chronos}{$day}{$hour}{count};
+                                       foreach my $min (keys %{$_error_info{$curdb}{$q}{chronos}{$day}{$hour}{min}}) {
+                                               $error_info{$curdb}{$q}{chronos}{$day}{$hour}{min}{$min} += $_error_info{$curdb}{$q}{chronos}{$day}{$hour}{min}{$min};
+                                       }
                                }
                        }
-               }
-               for (my $i = 0; $i <= $#{$_error_info{$q}{date}}; $i++) {
-                       &set_top_error_sample(  $q, 
-                                                                       $_error_info{$q}{date}[$i], 
-                                                                       $_error_info{$q}{error}[$i],
-                                                                       $_error_info{$q}{detail}[$i], 
-                                                                       $_error_info{$q}{context}[$i], 
-                                                                       $_error_info{$q}{statement}[$i],
-                                                                       $_error_info{$q}{hint}[$i], 
-                                                                       $_error_info{$q}{db}[$i],
-                                                                       $_error_info{$q}{user}[$i],
-                                                                       $_error_info{$q}{app}[$i],
-                                                                       $_error_info{$q}{remote}[$i]
-                                                                       );
+                       for (my $i = 0; $i <= $#{$_error_info{$curdb}{$q}{date}}; $i++) {
+                               &set_top_error_sample( $curdb, $q,
+                                                                               $_error_info{$curdb}{$q}{date}[$i],
+                                                                               $_error_info{$curdb}{$q}{error}[$i],
+                                                                               $_error_info{$curdb}{$q}{detail}[$i],
+                                                                               $_error_info{$curdb}{$q}{context}[$i],
+                                                                               $_error_info{$curdb}{$q}{statement}[$i],
+                                                                               $_error_info{$curdb}{$q}{hint}[$i],
+                                                                               $_error_info{$curdb}{$q}{db}[$i],
+                                                                               $_error_info{$curdb}{$q}{user}[$i],
+                                                                               $_error_info{$curdb}{$q}{app}[$i],
+                                                                               $_error_info{$curdb}{$q}{remote}[$i],
+                                                                               $_error_info{$curdb}{$q}{sqlstate}[$i]
+                                                                               );
+                       }
                }
        }
 
        ### pgbouncer error_info ###
 
-       foreach my $q (keys %_pgb_error_info) {
+       foreach my $q (keys %_pgb_error_info)
+       {
                $pgb_error_info{$q}{count} += $_pgb_error_info{$q}{count};
                foreach my $day (keys %{ $_pgb_error_info{$q}{chronos} }) {
                        foreach my $hour (keys %{$_pgb_error_info{$q}{chronos}{$day}}) {
@@ -640,8 +693,8 @@ sub load_stats
                        }
                }
                for (my $i = 0; $i <= $#{$_pgb_error_info{$q}{date}}; $i++) {
-                       &pgb_set_top_error_sample(      $q, 
-                                                                       $_pgb_error_info{$q}{date}[$i], 
+                       &pgb_set_top_error_sample($q,
+                                                                       $_pgb_error_info{$q}{date}[$i],
                                                                        $_pgb_error_info{$q}{error}[$i],
                                                                        $_pgb_error_info{$q}{db}[$i],
                                                                        $_pgb_error_info{$q}{user}[$i],
@@ -666,71 +719,78 @@ sub load_stats
 
        ### per_minute_info ###
 
-       foreach my $day (keys %_per_minute_info) {
-               foreach my $hour (keys %{ $_per_minute_info{$day} }) {
-                       foreach my $min (keys %{ $_per_minute_info{$day}{$hour} }) {
-                               $per_minute_info{$day}{$hour}{$min}{connection}{count} +=
-                                       ($_per_minute_info{$day}{$hour}{$min}{connection}{count} || 0);
-                               $per_minute_info{$day}{$hour}{$min}{session}{count} +=
-                                       ($_per_minute_info{$day}{$hour}{$min}{session}{count} || 0);
-                               $per_minute_info{$day}{$hour}{$min}{query}{count} +=
-                                       ($_per_minute_info{$day}{$hour}{$min}{query}{count} || 0);
-                               $per_minute_info{$day}{$hour}{$min}{query}{duration} += $_per_minute_info{$day}{$hour}{$min}{query}{duration};
-                               $per_minute_info{$day}{$hour}{$min}{query}{min} = $_per_minute_info{$day}{$hour}{$min}{query}{min} if (!exists $per_minute_info{$day}{$hour}{$min}{query}{min} || ($per_minute_info{$day}{$hour}{$min}{query}{min} > $_per_minute_info{$day}{$hour}{$min}{query}{min}));
-                               $per_minute_info{$day}{$hour}{$min}{query}{max} = $_per_minute_info{$day}{$hour}{$min}{query}{max} if (!exists $per_minute_info{$day}{$hour}{$min}{query}{max} || ($per_minute_info{$day}{$hour}{$min}{query}{max} < $_per_minute_info{$day}{$hour}{$min}{query}{max}));
-
-                               foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{connection}{second} }) {
-                                       $per_minute_info{$day}{$hour}{$min}{connection}{second}{$sec} +=
-                                               ($_per_minute_info{$day}{$hour}{$min}{connection}{second}{$sec} || 0);
-                               }
-                               foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{session}{second} }) {
-                                       $per_minute_info{$day}{$hour}{$min}{session}{second}{$sec} +=
-                                               ($_per_minute_info{$day}{$hour}{$min}{session}{second}{$sec} || 0);
-                               }
-                               foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{query}{second} }) {
-                                       $per_minute_info{$day}{$hour}{$min}{query}{second}{$sec} +=
-                                               ($_per_minute_info{$day}{$hour}{$min}{query}{second}{$sec} || 0);
-                               }
-                               foreach my $action (@SQL_ACTION) {
-                                       next if (!exists $_per_minute_info{$day}{$hour}{$min}{$action});
-                                       $per_minute_info{$day}{$hour}{$min}{$action}{count} += ($_per_minute_info{$day}{$hour}{$min}{$action}{count} || 0);
-                                       $per_minute_info{$day}{$hour}{$min}{$action}{duration} += ($_per_minute_info{$day}{$hour}{$min}{$action}{duration} || 0);
-                                       foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{$action}{second} }) {
-                                               $per_minute_info{$day}{$hour}{$min}{$action}{second}{$sec} +=
-                                                       ($_per_minute_info{$day}{$hour}{$min}{$action}{second}{$sec} || 0);
+       foreach my $curdb (keys %_per_minute_info) {
+               foreach my $day (keys %{$_per_minute_info{$curdb}}) {
+                       foreach my $hour (keys %{ $_per_minute_info{$curdb}{$day} }) {
+                               foreach my $min (keys %{ $_per_minute_info{$curdb}{$day}{$hour} }) {
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{connection}{count} +=
+                                               ($_per_minute_info{$curdb}{$day}{$hour}{$min}{connection}{count} || 0);
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{session}{count} +=
+                                               ($_per_minute_info{$curdb}{$day}{$hour}{$min}{session}{count} || 0);
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{count} +=
+                                               ($_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{count} || 0);
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{duration} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{duration};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{min} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{min} if (!exists $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{min} || ($per_minute_info{$curdb}{$day}{$hour}{$min}{query}{min} > $_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{min}));
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{max} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{max} if (!exists $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{max} || ($per_minute_info{$curdb}{$day}{$hour}{$min}{query}{max} < $_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{max}));
+
+                                       foreach my $sec (keys %{ $_per_minute_info{$curdb}{$day}{$hour}{$min}{connection}{second} }) {
+                                               $per_minute_info{$curdb}{$day}{$hour}{$min}{connection}{second}{$sec} +=
+                                                       ($_per_minute_info{$curdb}{$day}{$hour}{$min}{connection}{second}{$sec} || 0);
                                        }
-                               }
-                               foreach my $k ('prepare', 'bind','execute') {
-                                       if (exists $_per_minute_info{$day}{$hour}{$min}{$k}) {
-                                               $per_minute_info{$day}{$hour}{$min}{$k} += $_per_minute_info{$day}{$hour}{$min}{$k};
+                                       foreach my $sec (keys %{ $_per_minute_info{$curdb}{$day}{$hour}{$min}{session}{second} }) {
+                                               $per_minute_info{$curdb}{$day}{$hour}{$min}{session}{second}{$sec} +=
+                                                       ($_per_minute_info{$curdb}{$day}{$hour}{$min}{session}{second}{$sec} || 0);
+                                       }
+                                       foreach my $sec (keys %{ $_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{second} }) {
+                                               $per_minute_info{$curdb}{$day}{$hour}{$min}{query}{second}{$sec} +=
+                                                       ($_per_minute_info{$curdb}{$day}{$hour}{$min}{query}{second}{$sec} || 0);
+                                       }
+                                       foreach my $action (@SQL_ACTION) {
+                                               next if (!exists $_per_minute_info{$curdb}{$day}{$hour}{$min}{$action});
+                                               $per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{count} += ($_per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{count} || 0);
+                                               $per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{duration} += ($_per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{duration} || 0);
+                                               foreach my $sec (keys %{ $_per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{second} }) {
+                                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{second}{$sec} +=
+                                                               ($_per_minute_info{$curdb}{$day}{$hour}{$min}{$action}{second}{$sec} || 0);
+                                               }
+                                       }
+                                       foreach my $k ('prepare', 'bind','execute') {
+                                               if (exists $_per_minute_info{$curdb}{$day}{$hour}{$min}{$k}) {
+                                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{$k} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{$k};
+                                               }
+                                       }
+                                       foreach my $log (keys %{ $_per_minute_info{$curdb}{$day}{$hour}{$min}{log_level} }) {
+                                               $per_minute_info{$curdb}{$day}{$hour}{$min}{log_level}{$log} +=
+                                                       ($_per_minute_info{$curdb}{$day}{$hour}{$min}{log_level}{$log} || 0);
                                        }
-                               }
-                               foreach my $log (keys %{ $_per_minute_info{$day}{$hour}{$min}{log_level} }) {
-                                       $per_minute_info{$day}{$hour}{$min}{log_level}{$log} +=
-                                               ($_per_minute_info{$day}{$hour}{$min}{log_level}{$log} || 0);
-                               }
 
-                               $per_minute_info{$day}{$hour}{$min}{cancelled}{count} += $_per_minute_info{$day}{$hour}{$min}{cancelled}{count}
-                                               if defined $_per_minute_info{$day}{$hour}{$min}{cancelled}{count};
-                               $per_minute_info{$day}{$hour}{$min}{tempfile}{count} += $_per_minute_info{$day}{$hour}{$min}{tempfile}{count}
-                                               if defined $_per_minute_info{$day}{$hour}{$min}{tempfile}{count};
-                               $per_minute_info{$day}{$hour}{$min}{tempfile}{size} += $_per_minute_info{$day}{$hour}{$min}{tempfile}{size}
-                                               if defined $_per_minute_info{$day}{$hour}{$min}{tempfile}{size};
-
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{file_removed} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{file_removed};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{sync} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{wbuffer} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{wbuffer};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{file_recycled} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{file_recycled};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{total} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{total};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{file_added} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{file_added};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{write} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{write};
-                               $per_minute_info{$day}{$hour}{$min}{autovacuum}{count} += $_per_minute_info{$day}{$hour}{$min}{autovacuum}{count};
-                               $per_minute_info{$day}{$hour}{$min}{autoanalyze}{count} += $_per_minute_info{$day}{$hour}{$min}{autoanalyze}{count};
-
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_files} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_files};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_avg} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_avg};
-                               $per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest} = $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest}
-                                       if ($_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest} > $per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest});
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{cancelled}{count} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{cancelled}{count}
+                                                       if defined $_per_minute_info{$curdb}{$day}{$hour}{$min}{cancelled}{count};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{'tempfile'}{count} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{'tempfile'}{count}
+                                                       if defined $_per_minute_info{$curdb}{$day}{$hour}{$min}{'tempfile'}{count};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{'tempfile'}{size} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{'tempfile'}{size}
+                                                       if defined $_per_minute_info{$curdb}{$day}{$hour}{$min}{'tempfile'}{size};
+
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{file_removed} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{file_removed};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{wbuffer} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{wbuffer};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{file_recycled} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{file_recycled};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{total} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{total};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{file_added} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{file_added};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{write} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{write};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{autovacuum}{count} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{autovacuum}{count};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{autoanalyze}{count} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{autoanalyze}{count};
+
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_files} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_files};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_avg} += $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_avg};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_longest} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_longest}
+                                               if ($_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_longest} > $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{sync_longest});
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{distance} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{distance};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{distance_count} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{distance_count};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{estimate} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{estimate};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{warnning} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{warning};
+                                       $per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{warning_seconds} = $_per_minute_info{$curdb}{$day}{$hour}{$min}{checkpoint}{warning_seconds};
+                               }
                        }
                }
        }
@@ -744,13 +804,13 @@ sub load_stats
                                        ($_pgb_per_minute_info{$day}{$hour}{$min}{connection}{count} || 0);
                                $pgb_per_minute_info{$day}{$hour}{$min}{session}{count} +=
                                        ($_pgb_per_minute_info{$day}{$hour}{$min}{session}{count} || 0);
-                               $pgb_per_minute_info{$day}{$hour}{$min}{t_req} += 
+                               $pgb_per_minute_info{$day}{$hour}{$min}{t_req} +=
                                        ($_pgb_per_minute_info{$day}{$hour}{$min}{t_req} || 0);
-                               $pgb_per_minute_info{$day}{$hour}{$min}{t_inbytes} += 
+                               $pgb_per_minute_info{$day}{$hour}{$min}{t_inbytes} +=
                                        ($_pgb_per_minute_info{$day}{$hour}{$min}{t_inbytes} || 0);
-                               $pgb_per_minute_info{$day}{$hour}{$min}{t_outbytes} += 
+                               $pgb_per_minute_info{$day}{$hour}{$min}{t_outbytes} +=
                                        ($_pgb_per_minute_info{$day}{$hour}{$min}{t_outbytes} || 0);
-                               $pgb_per_minute_info{$day}{$hour}{$min}{t_avgduration} += 
+                               $pgb_per_minute_info{$day}{$hour}{$min}{t_avgduration} +=
                                        ($_pgb_per_minute_info{$day}{$hour}{$min}{t_avgduration} || 0);
                        }
                }
@@ -758,23 +818,26 @@ sub load_stats
 
        ### lock_info ###
 
-       foreach my $lock (keys %_lock_info) {
-               $lock_info{$lock}{count} += $_lock_info{$lock}{count};
+       foreach my $curdb (keys %_lock_info)
+       {
+               foreach my $lock (keys %{$_lock_info{$curdb}}) {
+                       $lock_info{$curdb}{$lock}{count} += $_lock_info{$curdb}{$lock}{count};
 
-               foreach my $day (keys %{ $_lock_info{chronos} }) {
-                       foreach my $hour (keys %{ $_lock_info{chronos}{$day} }) {
-                               $lock_info{chronos}{$day}{$hour}{count} += $_lock_info{chronos}{$day}{$hour}{count};
-                               $lock_info{chronos}{$day}{$hour}{duration} += $_lock_info{chronos}{$day}{$hour}{duration};
+                       foreach my $day (keys %{ $_lock_info{$curdb}{chronos} }) {
+                               foreach my $hour (keys %{ $_lock_info{$curdb}{chronos}{$day} }) {
+                                       $lock_info{$curdb}{chronos}{$day}{$hour}{count} += $_lock_info{$curdb}{chronos}{$day}{$hour}{count};
+                                       $lock_info{$curdb}{chronos}{$day}{$hour}{duration} += $_lock_info{$curdb}{chronos}{$day}{$hour}{duration};
+                               }
                        }
-               }
 
-               $lock_info{$lock}{duration} += $_lock_info{$lock}{duration};
+                       $lock_info{$curdb}{$lock}{duration} += $_lock_info{$curdb}{$lock}{duration};
 
-               foreach my $type (keys %{$_lock_info{$lock}}) {
-                       next if $type =~ /^(count|chronos|duration)$/;
+                       foreach my $type (keys %{$_lock_info{$curdb}{$lock}}) {
+                               next if $type =~ /^(count|chronos|duration)$/;
 
-                       $lock_info{$lock}{$type}{count} += $_lock_info{$lock}{$type}{count};
-                       $lock_info{$lock}{$type}{duration} += $_lock_info{$lock}{$type}{duration};
+                               $lock_info{$curdb}{$lock}{$type}{count} += $_lock_info{$curdb}{$lock}{$type}{count};
+                               $lock_info{$curdb}{$lock}{$type}{duration} += $_lock_info{$curdb}{$lock}{$type}{duration};
+                       }
                }
        }
 
@@ -784,128 +847,125 @@ sub load_stats
 
        ### normalyzed_info ###
 
-       foreach my $stmt (keys %_normalyzed_info) {
-
-               if (!$_normalyzed_info{$stmt}{count}) {
-                       $normalyzed_info{$stmt}{average} = 0;
-               } else {
-                       $normalyzed_info{$stmt}{average} = $_normalyzed_info{$stmt}{duration} / $_normalyzed_info{$stmt}{count};
-                       $normalyzed_info{$stmt}{average} =~ s/(\.\d{3}).*/$1/;
-               }
+       foreach my $curdb (keys %_normalyzed_info) {
+               foreach my $stmt (keys %{$_normalyzed_info{$curdb}}) {
 
-               foreach my $dt (keys %{$_normalyzed_info{$stmt}{samples}} ) {
-                       foreach my $k (keys %{$_normalyzed_info{$stmt}{samples}{$dt}} ) {
-                               $normalyzed_info{$stmt}{samples}{$dt}{$k} = $_normalyzed_info{$stmt}{samples}{$dt}{$k};
+                       foreach my $dt (keys %{$_normalyzed_info{$curdb}{$stmt}{samples}} ) {
+                               foreach my $k (keys %{$_normalyzed_info{$curdb}{$stmt}{samples}{$dt}} ) {
+                                       $normalyzed_info{$curdb}{$stmt}{samples}{$dt}{$k} = $_normalyzed_info{$curdb}{$stmt}{samples}{$dt}{$k};
+                               }
                        }
-               }
 
-               # Keep only the top N samples
-               my $i = 1;
-               foreach my $k (sort {$b <=> $a} keys %{$normalyzed_info{$stmt}{samples}}) {
-                       if ($i > $sample) {
-                               delete $normalyzed_info{$stmt}{samples}{$k};
+                       # Keep only the top N samples
+                       my $i = 1;
+                       foreach my $k (sort {$b <=> $a} keys %{$normalyzed_info{$curdb}{$stmt}{samples}}) {
+                               if ($i > $sample) {
+                                       delete $normalyzed_info{$curdb}{$stmt}{samples}{$k};
+                               }
+                               $i++;
                        }
-                       $i++;
-               }
 
-               $normalyzed_info{$stmt}{count} += $_normalyzed_info{$stmt}{count};
+                       $normalyzed_info{$curdb}{$stmt}{count} += $_normalyzed_info{$curdb}{$stmt}{count};
 
-               # Set min / max duration for this query
-               if (!exists $normalyzed_info{$stmt}{min} || ($normalyzed_info{$stmt}{min} > $_normalyzed_info{$stmt}{min})) { 
-                       $normalyzed_info{$stmt}{min} = $_normalyzed_info{$stmt}{min};
-               }
-               if (!exists $normalyzed_info{$stmt}{max} || ($normalyzed_info{$stmt}{max} < $_normalyzed_info{$stmt}{max})) { 
-                       $normalyzed_info{$stmt}{max} = $_normalyzed_info{$stmt}{max};
-               }
+                       # Set min / max duration for this query
+                       if (!exists $normalyzed_info{$curdb}{$stmt}{min} || ($normalyzed_info{$curdb}{$stmt}{min} > $_normalyzed_info{$curdb}{$stmt}{min})) {
+                               $normalyzed_info{$curdb}{$stmt}{min} = $_normalyzed_info{$curdb}{$stmt}{min};
+                       }
+                       if (!exists $normalyzed_info{$curdb}{$stmt}{max} || ($normalyzed_info{$curdb}{$stmt}{max} < $_normalyzed_info{$curdb}{$stmt}{max})) {
+                               $normalyzed_info{$curdb}{$stmt}{max} = $_normalyzed_info{$curdb}{$stmt}{max};
+                       }
 
-               foreach my $day (keys %{$_normalyzed_info{$stmt}{chronos}} ) {
-                       foreach my $hour (keys %{$_normalyzed_info{$stmt}{chronos}{$day}} ) {
-                               $normalyzed_info{$stmt}{chronos}{$day}{$hour}{count} +=
-                                       $_normalyzed_info{$stmt}{chronos}{$day}{$hour}{count};
-                               $normalyzed_info{$stmt}{chronos}{$day}{$hour}{duration} +=
-                                       $_normalyzed_info{$stmt}{chronos}{$day}{$hour}{duration};
-                               foreach my $min (keys %{$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min}} ) {
-                                       $normalyzed_info{$stmt}{chronos}{$day}{$hour}{min}{$min} +=
-                                               $_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min}{$min};
-                               }
-                               foreach my $min (keys %{$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min_duration}} ) {
-                                       $normalyzed_info{$stmt}{chronos}{$day}{$hour}{min_duration}{$min} +=
-                                               $_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min_duration}{$min};
+                       foreach my $day (keys %{$_normalyzed_info{$curdb}{$stmt}{chronos}} ) {
+                               foreach my $hour (keys %{$_normalyzed_info{$curdb}{$stmt}{chronos}{$day}} ) {
+                                       $normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{count} +=
+                                               $_normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{count};
+                                       $normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{duration} +=
+                                               $_normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{duration};
+                                       foreach my $min (keys %{$_normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{min}} ) {
+                                               $normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{min}{$min} +=
+                                                       $_normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{min}{$min};
+                                       }
+                                       foreach my $min (keys %{$_normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{min_duration}} ) {
+                                               $normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{min_duration}{$min} +=
+                                                       $_normalyzed_info{$curdb}{$stmt}{chronos}{$day}{$hour}{min_duration}{$min};
+                                       }
                                }
                        }
-               }
 
-               $normalyzed_info{$stmt}{duration} += $_normalyzed_info{$stmt}{duration};
+                       $normalyzed_info{$curdb}{$stmt}{duration} += $_normalyzed_info{$curdb}{$stmt}{duration};
 
-               if (exists $_normalyzed_info{$stmt}{locks}) {
-                       $normalyzed_info{$stmt}{locks}{count} += $_normalyzed_info{$stmt}{locks}{count};
-                       $normalyzed_info{$stmt}{locks}{wait} += $_normalyzed_info{$stmt}{locks}{wait};
-                       if (!exists $normalyzed_info{$stmt}{locks}{minwait} || ($normalyzed_info{$stmt}{locks}{minwait} > $_normalyzed_info{$stmt}{locks}{minwait})) { 
-                               $normalyzed_info{$stmt}{locks}{minwait} = $_normalyzed_info{$stmt}{locks}{minwait};
-                       }
-                       if (!exists $normalyzed_info{$stmt}{locks}{maxwait} || ($normalyzed_info{$stmt}{locks}{maxwait} < $_normalyzed_info{$stmt}{locks}{maxwait})) { 
-                               $normalyzed_info{$stmt}{locks}{maxwait} = $_normalyzed_info{$stmt}{locks}{maxwait};
+                       if (exists $_normalyzed_info{$curdb}{$stmt}{locks}) {
+                               $normalyzed_info{$curdb}{$stmt}{locks}{count} += $_normalyzed_info{$curdb}{$stmt}{locks}{count};
+                               $normalyzed_info{$curdb}{$stmt}{locks}{wait} += $_normalyzed_info{$curdb}{$stmt}{locks}{wait};
+                               if (!exists $normalyzed_info{$curdb}{$stmt}{locks}{minwait} || ($normalyzed_info{$curdb}{$stmt}{locks}{minwait} > $_normalyzed_info{$stmt}{locks}{minwait})) {
+                                       $normalyzed_info{$curdb}{$stmt}{locks}{minwait} = $_normalyzed_info{$curdb}{$stmt}{locks}{minwait};
+                               }
+                               if (!exists $normalyzed_info{$curdb}{$stmt}{locks}{maxwait} || ($normalyzed_info{$curdb}{$stmt}{locks}{maxwait} < $_normalyzed_info{$curdb}{$stmt}{locks}{maxwait})) {
+                                       $normalyzed_info{$curdb}{$stmt}{locks}{maxwait} = $_normalyzed_info{$curdb}{$stmt}{locks}{maxwait};
+                               }
                        }
-               }
 
-               if (exists $_normalyzed_info{$stmt}{tempfiles}) {
-                       $normalyzed_info{$stmt}{tempfiles}{count} += $_normalyzed_info{$stmt}{tempfiles}{count};
-                       $normalyzed_info{$stmt}{tempfiles}{size} += $_normalyzed_info{$stmt}{tempfiles}{size};
-                       if (!exists $normalyzed_info{$stmt}{tempfiles}{minsize} || ($normalyzed_info{$stmt}{tempfiles}{minsize} > $_normalyzed_info{$stmt}{tempfiles}{minsize})) { 
-                               $normalyzed_info{$stmt}{tempfiles}{minsize} = $_normalyzed_info{$stmt}{tempfiles}{minsize};
-                       }
-                       if (!exists $normalyzed_info{$stmt}{tempfiles}{maxsize} || ($normalyzed_info{$stmt}{tempfiles}{maxsize} < $_normalyzed_info{$stmt}{tempfiles}{maxsize})) { 
-                               $normalyzed_info{$stmt}{tempfiles}{maxsize} = $_normalyzed_info{$stmt}{tempfiles}{maxsize};
+                       if (exists $_normalyzed_info{$curdb}{$stmt}{tempfiles}) {
+                               $normalyzed_info{$curdb}{$stmt}{tempfiles}{count} += $_normalyzed_info{$curdb}{$stmt}{tempfiles}{count};
+                               $normalyzed_info{$curdb}{$stmt}{tempfiles}{size} += $_normalyzed_info{$curdb}{$stmt}{tempfiles}{size};
+                               if (!exists $normalyzed_info{$curdb}{$stmt}{tempfiles}{minsize} || ($normalyzed_info{$curdb}{$stmt}{tempfiles}{minsize} > $_normalyzed_info{$curdb}{$stmt}{tempfiles}{minsize})) {
+                                       $normalyzed_info{$curdb}{$stmt}{tempfiles}{minsize} = $_normalyzed_info{$curdb}{$stmt}{tempfiles}{minsize};
+                               }
+                               if (!exists $normalyzed_info{$curdb}{$stmt}{tempfiles}{maxsize} || ($normalyzed_info{$curdb}{$stmt}{tempfiles}{maxsize} < $_normalyzed_info{$curdb}{$stmt}{tempfiles}{maxsize})) {
+                                       $normalyzed_info{$curdb}{$stmt}{tempfiles}{maxsize} = $_normalyzed_info{$curdb}{$stmt}{tempfiles}{maxsize};
+                               }
                        }
-               }
 
-               if (exists $_normalyzed_info{$stmt}{cancelled}) {
-                       $normalyzed_info{$stmt}{cancelled}{count} += $_normalyzed_info{$stmt}{cancelled}{count};
-               }
+                       if (exists $_normalyzed_info{$curdb}{$stmt}{cancelled}) {
+                               $normalyzed_info{$curdb}{$stmt}{cancelled}{count} += $_normalyzed_info{$curdb}{$stmt}{cancelled}{count};
+                       }
 
-               foreach my $u (keys %{$_normalyzed_info{$stmt}{users}} ) {
-                       foreach my $k (keys %{$_normalyzed_info{$stmt}{users}{$u}} ) {
-                               $normalyzed_info{$stmt}{users}{$u}{$k} += $_normalyzed_info{$stmt}{users}{$u}{$k};
+                       foreach my $u (keys %{$_normalyzed_info{$curdb}{$stmt}{users}} ) {
+                               foreach my $k (keys %{$_normalyzed_info{$curdb}{$stmt}{users}{$u}} ) {
+                                       $normalyzed_info{$curdb}{$stmt}{users}{$u}{$k} += $_normalyzed_info{$curdb}{$stmt}{users}{$u}{$k};
+                               }
                        }
-               }
-               foreach my $u (keys %{$_normalyzed_info{$stmt}{apps}} ) {
-                       foreach my $k (keys %{$_normalyzed_info{$stmt}{apps}{$u}} ) {
-                               $normalyzed_info{$stmt}{apps}{$u}{$k} += $_normalyzed_info{$stmt}{apps}{$u}{$k};
+                       foreach my $u (keys %{$_normalyzed_info{$curdb}{$stmt}{apps}} ) {
+                               foreach my $k (keys %{$_normalyzed_info{$curdb}{$stmt}{apps}{$u}} ) {
+                                       $normalyzed_info{$curdb}{$stmt}{apps}{$u}{$k} += $_normalyzed_info{$curdb}{$stmt}{apps}{$u}{$k};
+                               }
                        }
                }
        }
 
        ### session_info ###
 
-       foreach my $db (keys %{ $_session_info{database}}) {
-               $session_info{database}{$db}{count} += $_session_info{database}{$db}{count};
-               $session_info{database}{$db}{duration} += $_session_info{database}{$db}{duration};
-       }
+       foreach my $curdb (keys %_session_info) {
+               foreach my $db (keys %{ $_session_info{$curdb}{database}}) {
+                       $session_info{$curdb}{database}{$db}{count} += $_session_info{$curdb}{database}{$db}{count};
+                       $session_info{$curdb}{database}{$db}{duration} += $_session_info{$curdb}{database}{$db}{duration};
+               }
 
-       $session_info{count} += $_session_info{count};
+               $session_info{$curdb}{count} += $_session_info{$curdb}{count};
 
-       foreach my $day (keys %{ $_session_info{chronos}}) {
-               foreach my $hour (keys %{ $_session_info{chronos}{$day}}) {
-                       $session_info{chronos}{$day}{$hour}{count} += $_session_info{chronos}{$day}{$hour}{count};
-                       $session_info{chronos}{$day}{$hour}{duration} += $_session_info{chronos}{$day}{$hour}{duration};
+               foreach my $day (keys %{ $_session_info{$curdb}{chronos}}) {
+                       foreach my $hour (keys %{ $_session_info{$curdb}{chronos}{$day}}) {
+                               $session_info{$curdb}{chronos}{$day}{$hour}{count} += $_session_info{$curdb}{chronos}{$day}{$hour}{count};
+                               $session_info{$curdb}{chronos}{$day}{$hour}{duration} += $_session_info{$curdb}{chronos}{$day}{$hour}{duration};
+                       }
                }
-       }
 
-       foreach my $user (keys %{ $_session_info{user}}) {
-               $session_info{user}{$user}{count}    += $_session_info{user}{$user}{count};
-               $session_info{user}{$user}{duration} += $_session_info{user}{$user}{duration};
-       }
+               foreach my $user (keys %{ $_session_info{$curdb}{user}}) {
+                       $session_info{$curdb}{user}{$user}{count}    += $_session_info{$curdb}{user}{$user}{count};
+                       $session_info{$curdb}{user}{$user}{duration} += $_session_info{$curdb}{user}{$user}{duration};
+               }
 
-       $session_info{duration} += $_session_info{duration};
+               $session_info{$curdb}{duration} += $_session_info{$curdb}{duration};
 
-       foreach my $host (keys %{ $_session_info{host}}) {
-               $session_info{host}{$host}{count}    += $_session_info{host}{$host}{count};
-               $session_info{host}{$host}{duration} += $_session_info{host}{$host}{duration};
-       }
+               foreach my $host (keys %{ $_session_info{$curdb}{host}}) {
+                       $session_info{$curdb}{host}{$host}{count}    += $_session_info{$curdb}{host}{$host}{count};
+                       $session_info{$curdb}{host}{$host}{duration} += $_session_info{$curdb}{host}{$host}{duration};
+               }
 
-       foreach my $app (keys %{ $_session_info{app}}) {
-               $session_info{app}{$app}{count}    += $_session_info{app}{$app}{count};
-               $session_info{app}{$app}{duration} += $_session_info{app}{$app}{duration};
+               foreach my $app (keys %{ $_session_info{$curdb}{app}}) {
+                       $session_info{$curdb}{app}{$app}{count}    += $_session_info{$curdb}{app}{$app}{count};
+                       $session_info{$curdb}{app}{$app}{duration} += $_session_info{$curdb}{app}{$app}{duration};
+               }
        }
 
        ### pgbouncer session_info ###
@@ -936,35 +996,51 @@ sub load_stats
                $pgb_session_info{host}{$host}{duration} += $_pgb_session_info{host}{$host}{duration};
        }
 
+
        ### tempfile_info ###
 
-       $tempfile_info{count} += $_tempfile_info{count}
-               if defined $_tempfile_info{count};
-       $tempfile_info{size} += $_tempfile_info{size}
-               if defined $_tempfile_info{size};
-       $tempfile_info{maxsize} = $_tempfile_info{maxsize}
-               if defined $_tempfile_info{maxsize} and ( not defined $tempfile_info{maxsize}
-                       or $tempfile_info{maxsize} < $_tempfile_info{maxsize} );
+       foreach my $curdb (keys %_tempfile_info)
+       {
+               $tempfile_info{$curdb}{count} += $_tempfile_info{$curdb}{count}
+                       if defined $_tempfile_info{$curdb}{count};
+               $tempfile_info{$curdb}{size} += $_tempfile_info{$curdb}{size}
+                       if defined $_tempfile_info{$curdb}{size};
+               $tempfile_info{$curdb}{maxsize} = $_tempfile_info{$curdb}{maxsize}
+                       if defined $_tempfile_info{$curdb}{maxsize} and ( not defined $tempfile_info{$curdb}{maxsize}
+                               or $tempfile_info{$curdb}{maxsize} < $_tempfile_info{$curdb}{maxsize} );
+       }
 
        ### top_slowest ###
-       my @tmp_top_slowest = sort {$b->[0] <=> $a->[0]} (@top_slowest, @_top_slowest);
-       @top_slowest = ();
-       for (my $i = 0; $i <= $#tmp_top_slowest; $i++) {
-               push(@top_slowest, $tmp_top_slowest[$i]);
+       foreach my $curdb (keys %_top_slowest)
+       {
+               my @tmp_top_slowest = sort {$b->[0] <=> $a->[0]} (@{$top_slowest{$curdb}}, @{$_top_slowest{$curdb}});
+               @{$top_slowest{$curdb}} = ();
+               for (my $i = 0; $i <= $#tmp_top_slowest; $i++) {
+                       push(@{$top_slowest{$curdb}}, $tmp_top_slowest[$i]);
+                       last if ($i == $end_top);
+               }
        }
 
        ### top_locked ###
-       my @tmp_top_locked_info = sort {$b->[0] <=> $a->[0]} (@top_locked_info, @_top_locked_info);
-       @top_locked_info = ();
-       for (my $i = 0; $i <= $#tmp_top_locked_info; $i++) {
-               push(@top_locked_info, $tmp_top_locked_info[$i]);
+       foreach my $curdb (keys %_top_locked_info)
+       {
+               my @tmp_top_locked_info = sort {$b->[0] <=> $a->[0]} (@{$top_locked_info{$curdb}}, @{$_top_locked_info{$curdb}});
+               @{$top_locked_info{$curdb}} = ();
+               for (my $i = 0; $i <= $#tmp_top_locked_info; $i++) {
+                       push(@{$top_locked_info{$curdb}}, $tmp_top_locked_info[$i]);
+                       last if ($i == $end_top);
+               }
        }
 
        ### top_tempfile ###
-       my @tmp_top_tempfile_info = sort {$b->[0] <=> $a->[0]} (@top_tempfile_info, @_top_tempfile_info);
-       @top_tempfile_info = ();
-       for (my $i = 0; $i <= $#tmp_top_tempfile_info; $i++) {
-               push(@top_tempfile_info, $tmp_top_tempfile_info[$i]);
+       foreach my $curdb (keys %_top_tempfile_info)
+       {
+               my @tmp_top_tempfile_info = sort {$b->[0] <=> $a->[0]} (@{$top_tempfile_info{$curdb}}, @{$_top_tempfile_info{$curdb}});
+               @{$top_tempfile_info{$curdb}} = ();
+               for (my $i = 0; $i <= $#tmp_top_tempfile_info; $i++) {
+                       push(@{$top_tempfile_info{$curdb}}, $tmp_top_tempfile_info[$i]);
+                       last if ($i == $end_top);
+               }
        }
 
        ### checkpoint_info ###
@@ -975,50 +1051,62 @@ sub load_stats
        $checkpoint_info{total} += $_checkpoint_info{total};
        $checkpoint_info{file_added} += $_checkpoint_info{file_added};
        $checkpoint_info{write} += $_checkpoint_info{write};
+       $checkpoint_info{distance} += $_checkpoint_info{distance};
+       $checkpoint_info{estimate} += $_checkpoint_info{estimate};
+       $checkpoint_info{warning} += $_checkpoint_info{warning};
+       $checkpoint_info{warning_seconds} += $_checkpoint_info{warning_seconds};
 
        #### Autovacuum info ####
 
-       $autovacuum_info{count} += $_autovacuum_info{count};
+       foreach my $curdb (keys %_autovacuum_info)
+       {
+               $autovacuum_info{$curdb}{count} += $_autovacuum_info{$curdb}{count};
 
-       foreach my $day (keys %{ $_autovacuum_info{chronos} }) {
-               foreach my $hour (keys %{ $_autovacuum_info{chronos}{$day} }) {
-                       $autovacuum_info{chronos}{$day}{$hour}{count} += $_autovacuum_info{chronos}{$day}{$hour}{count};
+               foreach my $day (keys %{ $_autovacuum_info{$curdb}{chronos} }) {
+                       foreach my $hour (keys %{ $_autovacuum_info{$curdb}{chronos}{$day} }) {
+                               $autovacuum_info{$curdb}{chronos}{$day}{$hour}{count} += $_autovacuum_info{$curdb}{chronos}{$day}{$hour}{count};
+                       }
+               }
+               foreach my $table (keys %{ $_autovacuum_info{$curdb}{tables} }) {
+                       $autovacuum_info{$curdb}{tables}{$table}{vacuums} += $_autovacuum_info{$curdb}{tables}{$table}{vacuums};
+                       $autovacuum_info{$curdb}{tables}{$table}{idxscans} += $_autovacuum_info{$curdb}{tables}{$table}{idxscans};
+                       $autovacuum_info{$curdb}{tables}{$table}{tuples}{removed} += $_autovacuum_info{$curdb}{tables}{$table}{tuples}{removed};
+                       $autovacuum_info{$curdb}{tables}{$table}{pages}{removed} += $_autovacuum_info{$curdb}{tables}{$table}{pages}{removed};
+               }
+               if ($_autovacuum_info{$curdb}{peak}{system_usage}{elapsed} > $autovacuum_info{$curdb}{peak}{system_usage}{elapsed}) {
+                       $autovacuum_info{$curdb}{peak}{system_usage}{elapsed} = $_autovacuum_info{$curdb}{peak}{system_usage}{elapsed};
+                       $autovacuum_info{$curdb}{peak}{system_usage}{table} = $_autovacuum_info{$curdb}{peak}{system_usage}{table};
+                       $autovacuum_info{$curdb}{peak}{system_usage}{date} = $_autovacuum_info{$curdb}{peak}{system_usage}{date};
                }
        }
-       foreach my $table (keys %{ $_autovacuum_info{tables} }) {
-               $autovacuum_info{tables}{$table}{vacuums} += $_autovacuum_info{tables}{$table}{vacuums};
-               $autovacuum_info{tables}{$table}{idxscans} += $_autovacuum_info{tables}{$table}{idxscans};
-               $autovacuum_info{tables}{$table}{tuples}{removed} += $_autovacuum_info{tables}{$table}{tuples}{removed};
-               $autovacuum_info{tables}{$table}{pages}{removed} += $_autovacuum_info{tables}{$table}{pages}{removed};
-       }
-       if ($_autovacuum_info{peak}{system_usage}{elapsed} > $autovacuum_info{peak}{system_usage}{elapsed}) {
-               $autovacuum_info{peak}{system_usage}{elapsed} = $_autovacuum_info{peak}{system_usage}{elapsed};
-               $autovacuum_info{peak}{system_usage}{table} = $_autovacuum_info{peak}{system_usage}{table};
-               $autovacuum_info{peak}{system_usage}{date} = $_autovacuum_info{peak}{system_usage}{date};
-       }
+
        #### Autoanalyze info ####
 
-       $autoanalyze_info{count} += $_autoanalyze_info{count};
+       foreach my $curdb (keys %_autoanalyze_info)
+       {
+               $autoanalyze_info{$curdb}{count} += $_autoanalyze_info{$curdb}{count};
 
-       foreach my $day (keys %{ $_autoanalyze_info{chronos} }) {
-               foreach my $hour (keys %{ $_autoanalyze_info{chronos}{$day} }) {
-                       $autoanalyze_info{chronos}{$day}{$hour}{count} += $_autoanalyze_info{chronos}{$day}{$hour}{count};
+               foreach my $day (keys %{ $_autoanalyze_info{$curdb}{chronos} }) {
+                       foreach my $hour (keys %{ $_autoanalyze_info{$curdb}{chronos}{$day} }) {
+                               $autoanalyze_info{$curdb}{chronos}{$day}{$hour}{count} += $_autoanalyze_info{$curdb}{chronos}{$day}{$hour}{count};
+                       }
+               }
+               foreach my $table (keys %{ $_autoanalyze_info{$curdb}{tables} }) {
+                       $autoanalyze_info{$curdb}{tables}{$table}{analyzes} += $_autoanalyze_info{$curdb}{tables}{$table}{analyzes};
+               }
+               if ($_autoanalyze_info{$curdb}{peak}{system_usage}{elapsed} > $autoanalyze_info{$curdb}{peak}{system_usage}{elapsed}) {
+                       $autoanalyze_info{$curdb}{peak}{system_usage}{elapsed} = $_autoanalyze_info{$curdb}{peak}{system_usage}{elapsed};
+                       $autoanalyze_info{$curdb}{peak}{system_usage}{table} = $_autoanalyze_info{$curdb}{peak}{system_usage}{table};
+                       $autoanalyze_info{$curdb}{peak}{system_usage}{date} = $_autoanalyze_info{$curdb}{peak}{system_usage}{date};
                }
-       }
-       foreach my $table (keys %{ $_autoanalyze_info{tables} }) {
-               $autoanalyze_info{tables}{$table}{analyzes} += $_autoanalyze_info{tables}{$table}{analyzes};
-       }
-       if ($_autoanalyze_info{peak}{system_usage}{elapsed} > $autoanalyze_info{peak}{system_usage}{elapsed}) {
-               $autoanalyze_info{peak}{system_usage}{elapsed} = $_autoanalyze_info{peak}{system_usage}{elapsed};
-               $autoanalyze_info{peak}{system_usage}{table} = $_autoanalyze_info{peak}{system_usage}{table};
-               $autoanalyze_info{peak}{system_usage}{date} = $_autoanalyze_info{peak}{system_usage}{date};
        }
 
        use strict;
+
        return;
 }
 
+
 # Do minimal query formatting.
 # Add carriage return to be more human readable
 sub fmtquery
@@ -1043,33 +1131,35 @@ sub fmtquery
 # Dump top slowest queries as EXPLAIN statement.
 sub dump_slowest_queries
 {
+       my $curdb = shift;
+
        # Global information
        my $curdate    = localtime(time);
        my $logfile_str = join(',', @log_files);
 
-       for (my $i = 0 ; $i <= $#top_slowest ; $i++) {
+       for (my $i = 0 ; $i <= $#{$top_slowest{$curdb}} ; $i++) {
 
                # Do not process request that are slower than $max_duration
-               next if ( $max_duration && ($top_slowest[$i]->[0] > $max_duration) );
+               next if ( $max_duration && ($top_slowest{$curdb}[$i]->[0] > $max_duration) );
 
                my $head = qq{-- Generated on $curdate
 -- Log file: $logfile_str
 -- Log start from $overall_stat{'first_log_ts'} to $overall_stat{'last_log_ts'}
 --
 };
-               $head .= "-- duration: $top_slowest[$i]->[0]\n" if ($top_slowest[$i]->[0]);
-               $head .= "-- database: $top_slowest[$i]->[3]\n" if ($top_slowest[$i]->[3]);
-               $head .= "-- user: $top_slowest[$i]->[4]\n" if ($top_slowest[$i]->[4]);
-               $head .= "-- remote: $top_slowest[$i]->[5]\n" if ($top_slowest[$i]->[5]);
-               $head .= "-- app: $top_slowest[$i]->[6]\n" if ($top_slowest[$i]->[6]);
-               $head .= "--, bind query: yes\n" if ($top_slowest[$i]->[7]);
+               $head .= "-- duration: $top_slowest{$curdb}[$i]->[0]\n" if ($top_slowest{$curdb}[$i]->[0]);
+               $head .= "-- database: $top_slowest{$curdb}[$i]->[3]\n" if ($top_slowest{$curdb}[$i]->[3]);
+               $head .= "-- user: $top_slowest{$curdb}[$i]->[4]\n" if ($top_slowest{$curdb}[$i]->[4]);
+               $head .= "-- remote: $top_slowest{$curdb}[$i]->[5]\n" if ($top_slowest{$curdb}[$i]->[5]);
+               $head .= "-- app: $top_slowest{$curdb}[$i]->[6]\n" if ($top_slowest{$curdb}[$i]->[6]);
+               $head .= "--, bind query: yes\n" if ($top_slowest{$curdb}[$i]->[7]);
                $head =~ s/^, //;
 
                my $explain = "EXPLAIN\n";
                if ($analyze) {
                        $explain = "BEGIN;\nEXPLAIN (ANALYZE, VERBOSE, BUFFERS)\n";
                }
-               $explain .= "$top_slowest[$i]->[2]\n";
+               $explain .= "$top_slowest{$curdb}[$i]->[2]\n";
                $explain .= "ROLLBACK;\n" if ($analyze);
                if ($file_per_query) {
                        my $fhqr = new IO::File;
@@ -1097,14 +1187,16 @@ sub dump_slowest_queries
 # Dump top time consuming queries as EXPLAIN statement.
 sub dump_times_consuming_queries
 {
+       my $curdb = shift;
+
        # Global information
        my $curdate    = localtime(time);
        my $logfile_str = join(',', @log_files);
 
         my $rank = 1;
-        foreach my $k (sort {$normalyzed_info{$b}{count} <=> $normalyzed_info{$a}{count}} keys %normalyzed_info) {
-                next if (!$normalyzed_info{$k}{count});
-                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
+        foreach my $k (sort {$normalyzed_info{$curdb}{$b}{count} <=> $normalyzed_info{$curdb}{$a}{count}} keys %{$normalyzed_info{$curdb}}) {
+                next if (!$normalyzed_info{$curdb}{$k}{count});
+                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$curdb}{$k}{samples}}) {
                        # Do not process request that are slower than $max_duration
                        next if ( $max_duration && ( $d > $max_duration) );
 
@@ -1114,18 +1206,18 @@ sub dump_times_consuming_queries
 --
 };
                        $head .= "-- duration: $d\n" if ($d);
-                       $head .= "-- database: $normalyzed_info{$k}{samples}{$d}{db}\n" if ($normalyzed_info{$k}{samples}{$d}{db});
-                       $head .= "-- user: $normalyzed_info{$k}{samples}{$d}{user}\n" if ($normalyzed_info{$k}{samples}{$d}{user});
-                       $head .= "-- remote: $normalyzed_info{$k}{samples}{$d}{remote}\n" if ($normalyzed_info{$k}{samples}{$d}{remote});
-                       $head .= "-- app: $normalyzed_info{$k}{samples}{$d}{app}\n" if ($normalyzed_info{$k}{samples}{$d}{app});
-                       $head .= "--, bind query: yes\n" if ($normalyzed_info{$k}{samples}{$d}{bind});
+                       $head .= "-- database: $normalyzed_info{$curdb}{$k}{samples}{$d}{db}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{db});
+                       $head .= "-- user: $normalyzed_info{$curdb}{$k}{samples}{$d}{user}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{user});
+                       $head .= "-- remote: $normalyzed_info{$curdb}{$k}{samples}{$d}{remote}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{remote});
+                       $head .= "-- app: $normalyzed_info{$curdb}{$k}{samples}{$d}{app}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{app});
+                       $head .= "--, bind query: yes\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{bind});
                        $head =~ s/^, //;
 
                        my $explain = "EXPLAIN\n";
                        if ($analyze) {
                                $explain = "BEGIN;\nEXPLAIN (ANALYZE, VERBOSE, BUFFERS)\n";
                        }
-                       $explain .= "$normalyzed_info{$k}{samples}{$d}{query}\n";
+                       $explain .= "$normalyzed_info{$curdb}{$k}{samples}{$d}{query}\n";
                        $explain .= "ROLLBACK;\n" if ($analyze);
                        if ($file_per_query) {
                                my $fhqr = new IO::File;
@@ -1158,14 +1250,16 @@ sub dump_times_consuming_queries
 # Dump top normalized slowest queries as EXPLAIN statement.
 sub dump_normalized_slowest_queries
 {
+       my $curdb = shift;
+
        # Global information
        my $curdate    = localtime(time);
        my $logfile_str = join(',', @log_files);
 
         my $rank = 1;
-       foreach my $k (sort {$normalyzed_info{$b}{average} <=> $normalyzed_info{$a}{average}} keys %normalyzed_info) {
-                next if (!$normalyzed_info{$k}{count});
-                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
+       foreach my $k (sort {$normalyzed_info{$curdb}{$b}{average} <=> $normalyzed_info{$curdb}{$a}{average}} keys %{$normalyzed_info{$curdb}}) {
+                next if (!$normalyzed_info{$curdb}{$k}{count});
+                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$curdb}{$k}{samples}}) {
                        # Do not process request that are slower than $max_duration
                        next if ( $max_duration && ( $d > $max_duration) );
 
@@ -1175,18 +1269,18 @@ sub dump_normalized_slowest_queries
 --
 };
                        $head .= "-- duration: $d\n" if ($d);
-                       $head .= "-- database: $normalyzed_info{$k}{samples}{$d}{db}\n" if ($normalyzed_info{$k}{samples}{$d}{db});
-                       $head .= "-- user: $normalyzed_info{$k}{samples}{$d}{user}\n" if ($normalyzed_info{$k}{samples}{$d}{user});
-                       $head .= "-- remote: $normalyzed_info{$k}{samples}{$d}{remote}\n" if ($normalyzed_info{$k}{samples}{$d}{remote});
-                       $head .= "-- app: $normalyzed_info{$k}{samples}{$d}{app}\n" if ($normalyzed_info{$k}{samples}{$d}{app});
-                       $head .= "--, bind query: yes\n" if ($normalyzed_info{$k}{samples}{$d}{bind});
+                       $head .= "-- database: $normalyzed_info{$curdb}{$k}{samples}{$d}{db}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{db});
+                       $head .= "-- user: $normalyzed_info{$curdb}{$k}{samples}{$d}{user}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{user});
+                       $head .= "-- remote: $normalyzed_info{$curdb}{$k}{samples}{$d}{remote}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{remote});
+                       $head .= "-- app: $normalyzed_info{$curdb}{$k}{samples}{$d}{app}\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{app});
+                       $head .= "--, bind query: yes\n" if ($normalyzed_info{$curdb}{$k}{samples}{$d}{bind});
                        $head =~ s/^, //;
 
                        my $explain = "EXPLAIN\n";
                        if ($analyze) {
                                $explain = "BEGIN;\nEXPLAIN (ANALYZE, VERBOSE, BUFFERS)\n";
                        }
-                       $explain .= "$normalyzed_info{$k}{samples}{$d}{query}\n";
+                       $explain .= "$normalyzed_info{$curdb}{$k}{samples}{$d}{query}\n";
                        $explain .= "ROLLBACK;\n" if ($analyze);
                        if ($file_per_query) {
                                my $fhqr = new IO::File;
@@ -1219,6 +1313,8 @@ sub dump_normalized_slowest_queries
 # Export time consuming queries as CSV
 sub csv_times_consuming_queries
 {
+       my $curdb = shift;
+
        my $fhcsv = undef;
 
        my $csv = Text::CSV->new({
@@ -1229,23 +1325,23 @@ sub csv_times_consuming_queries
        $csv->print($fhcsv, ['Database','Rank','Total_Duration','Times_Executed','Min','Max','Avg','Query']);
 
         my $rank = 1;
-        foreach my $k (sort {$normalyzed_info{$b}{count} <=> $normalyzed_info{$a}{count}} keys %normalyzed_info) {
-                next if (!$normalyzed_info{$k}{count});
-                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
+        foreach my $k (sort {$normalyzed_info{$curdb}{$b}{count} <=> $normalyzed_info{$curdb}{$a}{count}} keys %{$normalyzed_info{$curdb}}) {
+                next if (!$normalyzed_info{$curdb}{$k}{count});
+                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$curdb}{$k}{samples}}) {
                        # Do not process request that are slower than $max_duration
                        next if ( $max_duration && ( $d > $max_duration) );
 
-                       $normalyzed_info{$k}{average} = $normalyzed_info{$k}{duration} / $normalyzed_info{$k}{count};
+                       $normalyzed_info{$curdb}{$k}{average} = $normalyzed_info{$curdb}{$k}{duration} / $normalyzed_info{$curdb}{$k}{count};
 
                        $csv->print ($fhcsv, [
-                               $normalyzed_info{$k}{samples}{$d}{db},
+                               $normalyzed_info{$curdb}{$k}{samples}{$d}{db},
                                $rank,
                                $d,
-                               $normalyzed_info{$k}{count},
-                               $normalyzed_info{$k}{min},
-                               $normalyzed_info{$k}{max},
-                               $normalyzed_info{$k}{average},
-                               $normalyzed_info{$k}{samples}{$d}{query}
+                               $normalyzed_info{$curdb}{$k}{count},
+                               $normalyzed_info{$curdb}{$k}{min},
+                               $normalyzed_info{$curdb}{$k}{max},
+                               $normalyzed_info{$curdb}{$k}{average},
+                               $normalyzed_info{$curdb}{$k}{samples}{$d}{query}
                        ]);
                        # Report only the first sample
                        last;
@@ -1261,6 +1357,8 @@ sub csv_times_consuming_queries
 # Export normalized slowest queries as CSV
 sub csv_normalized_queries
 {
+       my $curdb = shift;
+
        my $fhcsv = undef;
 
        my $csv = Text::CSV->new({
@@ -1271,21 +1369,21 @@ sub csv_normalized_queries
        $csv->print($fhcsv, ['Database','Rank','Total_Duration','Times_Executed','Min','Max','Avg','Query']);
 
         my $rank = 1;
-        foreach my $k (sort {$normalyzed_info{$b}{average} <=> $normalyzed_info{$a}{average}} keys %normalyzed_info) {
-                next if (!$normalyzed_info{$k}{count});
-                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
+        foreach my $k (sort {$normalyzed_info{$curdb}{$b}{average} <=> $normalyzed_info{$curdb}{$a}{average}} keys %{$normalyzed_info{$curdb}}) {
+                next if (!$normalyzed_info{$curdb}{$k}{count});
+                foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$curdb}{$k}{samples}}) {
                        # Do not process request that are slower than $max_duration
                        next if ( $max_duration && ( $d > $max_duration) );
 
                        $csv->print ($fhcsv, [
-                               $normalyzed_info{$k}{samples}{$d}{db},
+                               $normalyzed_info{$curdb}{$k}{samples}{$d}{db},
                                $rank,
                                $d,
-                               $normalyzed_info{$k}{count},
-                               $normalyzed_info{$k}{min},
-                               $normalyzed_info{$k}{max},
-                               $normalyzed_info{$k}{average},
-                               $normalyzed_info{$k}{samples}{$d}{query}
+                               $normalyzed_info{$curdb}{$k}{count},
+                               $normalyzed_info{$curdb}{$k}{min},
+                               $normalyzed_info{$curdb}{$k}{max},
+                               $normalyzed_info{$curdb}{$k}{average},
+                               $normalyzed_info{$curdb}{$k}{samples}{$d}{query}
                        ]);
                        # Report only the first sample
                        last;
@@ -1301,6 +1399,8 @@ sub csv_normalized_queries
 # Export slowest queries as CSV
 sub csv_slowest_queries
 {
+       my $curdb = shift;
+
        my $fhcsv = undef;
 
        my $csv = Text::CSV->new({
@@ -1311,16 +1411,16 @@ sub csv_slowest_queries
        $csv->print($fhcsv, ['Database','Rank','Duration','Query']);
 
        my $rank = 1;
-       for (my $i = 0 ; $i <= $#top_slowest ; $i++) {
+       for (my $i = 0 ; $i <= $#{$top_slowest{$curdb}} ; $i++) {
 
                # Do not process request that are slower than $max_duration
-               next if ( $max_duration && ($top_slowest[$i]->[0] > $max_duration) );
+               next if ( $max_duration && ($top_slowest{$curdb}[$i]->[0] > $max_duration) );
 
                $csv->print ($fhcsv, [
-                       $top_slowest[$i]->[3],
+                       $top_slowest{$curdb}[$i]->[3],
                        $rank,
-                       $top_slowest[$i]->[0],
-                       $top_slowest[$i]->[2]
+                       $top_slowest{$curdb}[$i]->[0],
+                       $top_slowest{$curdb}[$i]->[2]
                ]);
                 last if ($rank > $top);
                 $rank++;