Diag/scalixdb

From Scalix Wiki
Revision as of 20:02, 20 March 2008 by Dboreham (Talk | contribs) (Using pgAdmin)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Diagnosing ScalixDB

Configure enhanced Postgresql logging

The default Postgresql error logging configuration is very terse. Errors are logged, but not time-stamped. The SQL statement that caused the error is not logged. This makes it hard to determine what caused a database error, or even when it happened. Edit the configuration file at /var/opt/scalix/<instance>/postgres/data/posgresql.conf, modifying the logging configuration as follows:

 					#   panic
 
 #log_error_verbosity = default		# terse, default, or verbose messages
 
-#log_min_error_statement = panic	# Values in order of increasing severity:
+log_min_error_statement = error	# Values in order of increasing severity:
 				 	#   debug5
 					#   debug4
 					#   debug3
 					#   debug2
@@ -294,9 +294,9 @@
 #debug_pretty_print = off
 #log_connections = off
 #log_disconnections = off
 #log_duration = off
-#log_line_prefix = ''			# Special values:
+log_line_prefix = '%d %m '			# Special values:
 					#   %u = user name
 					#   %d = database name
 					#   %r = remote host and port
 					#   %h = remote host

Note that because the Postgresql package is inherited from the operating system distribution, and changes may occur in this file between revisions, your file may not look exactly like this. The new log_min_error_statement directive tells Postgresql to log the SQL statement that led to any error. The log_line_prefix directive adds a time stamp and the name of the database to every log record.

Postgresql log files

Postgresql log files are found at /var/opt/scalix/<instance>/postgres/data/pg_log:

[root@goat pg_log]# pwd
/var/opt/scalix/gt/postgres/data/pg_log
[root@goat pg_log]# ls -l
total 20
-rw------- 1 postgres postgres 7355 Feb 27 10:55 postgresql-Fri.log
-rw------- 1 postgres postgres    0 Feb 23 00:00 postgresql-Mon.log
-rw------- 1 postgres postgres 1459 Feb 22 02:22 postgresql-Sun.log
-rw------- 1 postgres postgres    0 Feb 26 00:00 postgresql-Thu.log
-rw------- 1 postgres postgres    0 Feb 24 00:00 postgresql-Tue.log
-rw------- 1 postgres postgres 4387 Feb 25 23:42 postgresql-Wed.log

After making the logging configuration changes described above, you should see log output similar to this:

[root@goat pg_log]# cat postgresql-Fri.log 
scalix 2009-02-27 10:42:52.435 MST ERROR:  schema "sx_93e5be502d5a44ca48459ac0d2ff621f" does not exist
scalix 2009-02-27 10:42:52.435 MST STATEMENT:  set search_path to sx_93e5be502d5a44ca48459ac0d2ff621f
scalix 2009-02-27 10:42:52.437 MST ERROR:  current transaction is aborted, commands ignored until end of transaction block
scalix 2009-02-27 10:42:52.437 MST STATEMENT:  SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,  CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema'  WHEN true THEN CASE  WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TABLE'   WHEN 'v' THEN 'SYSTEM VIEW'   WHEN 'i' THEN 'SYSTEM INDEX'   ELSE NULL   END  WHEN n.nspname = 'pg_toast' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TOAST TABLE'   WHEN 'i' THEN 'SYSTEM TOAST INDEX'   ELSE NULL   END  ELSE CASE c.relkind   WHEN 'r' THEN 'TEMPORARY TABLE'   WHEN 'i' THEN 'TEMPORARY INDEX'   ELSE NULL   END  END  WHEN false THEN CASE c.relkind  WHEN 'r' THEN 'TABLE'  WHEN 'i' THEN 'INDEX'  WHEN 'S' THEN 'SEQUENCE'  WHEN 'v' THEN 'VIEW'  ELSE NULL  END  ELSE NULL  END  AS TABLE_TYPE, d.description AS REMARKS  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c  LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)  LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')  WHERE c.relnamespace = n.oid  AND c.relname LIKE 'PROBABLYNOT'  AND (false  OR ( c.relkind = 'r' AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' ) )  ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME 
scalix 2009-02-27 10:42:52.948 MST ERROR:  schema "sx_93e5be502d5a44ca48459ac0d2ff621f" does not exist
scalix 2009-02-27 10:42:52.948 MST STATEMENT:  set search_path to sx_93e5be502d5a44ca48459ac0d2ff621f
scalix 2009-02-27 10:42:52.981 MST ERROR:  current transaction is aborted, commands ignored until end of transaction block
scalix 2009-02-27 10:42:52.981 MST STATEMENT:  SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,  CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema'  WHEN true THEN CASE  WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TABLE'   WHEN 'v' THEN 'SYSTEM VIEW'   WHEN 'i' THEN 'SYSTEM INDEX'   ELSE NULL   END  WHEN n.nspname = 'pg_toast' THEN CASE c.relkind   WHEN 'r' THEN 'SYSTEM TOAST TABLE'   WHEN 'i' THEN 'SYSTEM TOAST INDEX'   ELSE NULL   END  ELSE CASE c.relkind   WHEN 'r' THEN 'TEMPORARY TABLE'   WHEN 'i' THEN 'TEMPORARY INDEX'   ELSE NULL   END  END  WHEN false THEN CASE c.relkind  WHEN 'r' THEN 'TABLE'  WHEN 'i' THEN 'INDEX'  WHEN 'S' THEN 'SEQUENCE'  WHEN 'v' THEN 'VIEW'  ELSE NULL  END  ELSE NULL  END  AS TABLE_TYPE, d.description AS REMARKS  FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c  LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)  LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')  LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')  WHERE c.relnamespace = n.oid  AND c.relname LIKE 'PROBABLYNOT'  AND (false  OR ( c.relkind = 'r' AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' ) )  ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME 
scalix 2009-02-27 10:42:53.073 MST NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "folder_status_pkey" for table "folder_status"
scalix 2009-02-27 10:42:53.115 MST NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "message_pkey" for table "message"
scalix 2009-02-27 10:42:53.120 MST NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "deleted_pkey" for table "deleted"

Direct access to the database

Sometimes it is useful to inspect and even change the contents of the database directly. This requires three things:

  1. Configuration that allows the appropriate client IP address access to the database.
  2. A database client utility.
  3. Some understanding of the database schema used by Scalix Messaging Services.

Host-based access control

In the interests of maintaing the highest level of security, the default Postgresql configuration uses host-based access control (HBA) to limit access to the ScalixDB. Only clients connecting from the instance IP address are allowed in. In addition, Postgresql is configured to only listen on the instance IP address. Therefore, an attempt to connect from the same machine using localhost will fail:

[root@goat bin]# telnet localhost 5733
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host: Connection refused

While an attempt to connect using the instance IP address (which in smaller deployments is usually the same as 'hostname'), succeeds:

[root@goat bin]# telnet goat 5733
Trying xx.xx.xx.xx...
Connected to goat.example.com (xx.xx.xx.xx).
Escape character is '^]'.
^]
telnet> quit
Connection closed.

Note also that for ScalixDB, Postgresql is configured to listen on port 5733 (not the standard port 5432). Often it is useful to run a Postgresql client utility on a machine other than the server. For example the Windows PGAdmin tool might be used. In that case, the file pg_hba.conf must be edited to allow the client access. Remember to revert back to the original configuration once any database diagnosis has been completed.

Connecting to the Database with psql

The psql command-line Postgresql client utility can be used to insepect ScalixDB content. Invoke psql with the appropriate host name, the ScalixDB port number 5733, the 'scalix' database and the user 'scalix':

[root@goat ~]# psql -h goat -p 5733 -d scalix scalix
Password for user scalix:
psql: FATAL:  password authentication failed for user "scalix"
[root@goat ~]# psql -h goat -p 5733 -d scalix scalix
Password for user scalix:
Welcome to psql 8.1.11, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

scalix=#

The password was originally supplied at the time Scalix was installed. Scalix Messaging Services stores message data in the database using one Postgresql schema per user. The schema names always begin with the prefix "sx_". Use the \dn command to list the schemas:

scalix=# \dn sx*
               List of schemas
                Name                 | Owner
-------------------------------------+--------
 sx_93e5be502d5a44ca48459ac0d2ff621f | scalix
(1 row)

scalix=#

It is not easy to identify the schema belonging to a specific user. Use this script to translate user ids to their corresponding schema name. psql's search path can be changed to avoid typing the schema name for each query:

scalix=# set search_path to sx_93e5be502d5a44ca48459ac0d2ff621f;
SET
scalix=# 

Having set the search path to that particular user's schema, we can now see their tables with the \dt command:

scalix=# \dt
                          List of relations
               Schema                |     Name      | Type  | Owner
-------------------------------------+---------------+-------+--------
 sx_93e5be502d5a44ca48459ac0d2ff621f | deleted       | table | scalix
 sx_93e5be502d5a44ca48459ac0d2ff621f | folder_status | table | scalix
 sx_93e5be502d5a44ca48459ac0d2ff621f | message       | table | scalix
 sx_93e5be502d5a44ca48459ac0d2ff621f | version       | table | scalix
(4 rows)

Similarly table content can be displayed:

scalix=# select * from folder_status;
    direct_ref    | last_synched
------------------+---------------
 00011c00664eb912 | 1235756595556
(1 row)

scalix=#

Using pgAdmin

pgAdmin provides a graphical alternative to pgadmin and is available for a wide range of platforms, including Windows and MacOSX. The screen shot below shows pgAdmin accessing the same ScalixDB instance used in the psql examples above:


Moz-screenshot-9.jpg

pgAdmin is particularly useful for displaying message table content (due to the large number of columns):

Moz-screenshot-10.jpg