como eliminar a seleção longa na inicialização do servidor postgresql 9.4

0

Eu tenho um grande (~ 6 GB) postgis-2.1 postgresql-9.4 db contendo contornos de elevação em um netbook executando jessie debian. Toda vez que eu inicio o sistema, eu vejo um processo como este:

00:00:01 postgres: nome de usuário contornos :: 1 (33525) SELECT

Este processo será executado por cerca de 30-40 minutos no meu netbook que eu uso para navegação no meu caminhão, então ele mostrará o processo como ocioso. Durante esse tempo, o netbook é inútil. Esse processo toma muito espaço na memória e o disco de E / S é realmente o matador.

Minha pergunta é: como posso impedir que esse select seja iniciado? Eu fiz o meu melhor para isolar o problema para o servidor postgresql. Nenhum outro aplicativo está iniciando esta consulta.

Os processos postgres em execução no momento em que isso está acontecendo são:

  • processo de checkpointer
  • processo escritor
  • processo de escritor wal
  • processo de iniciação autovacuum
  • processo de colecionador de estatísticas

Atualizar: OK, com a ajuda do filiprem, consegui rastrear a instrução select que está causando esse problema:

SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext) FROM (SELECT ST_Extent(way) as ext from planet_osm_line) as tmp

O problema é que eu ainda não sei de onde esta declaração está sendo (especificamente) gerada. O comando que causa isso é:

liteserv.py -p 8034 -c --config=topo.cfg topo.xml

topo.cfg não tem nada de pertinente. Fiz um grep no topo.xml procurando por select statements e encontrei (3):

(select way,contour_ext,ele from &prefix;_line where contour_ext='elevation_minor') as contour_minor
(select way,contour_ext,ele from &prefix;_line where contour_ext='elevation_medium') as contour_medium
(select way,contour_ext,ele from &prefix;_line where contour_ext='elevation_major') as contour_major

Aqui está o conteúdo do liteserv.py:

#!/usr/bin/env python

import os
import sys
import socket
from optparse import OptionParser
from wsgiref.simple_server import make_server, WSGIServer, WSGIRequestHandler
import logging

CONFIG = 'tilelite.cfg'
MAP_FROM_ENV = 'MAPNIK_MAP_FILE'

parser = OptionParser(usage="""
        python liteserv.py <mapfile.xml> [options]
        """)

parser.add_option('-i', '--ip', default='0.0.0.0', dest='host',
        help='Specify a ip to listen on (defaults to 0.0.0.0/localhost)'
        )

parser.add_option('-p', '--port', default=8000, dest='port', type='int',
        help='Specify a custom port to run on: eg. 8080'
        )

parser.add_option('--config', default=None, dest='config',
        help='''Specify the use of a custom TileLite config file to override default settings. By default looks for a file locally called 'tilelite.cfg'.'''
        )

parser.add_option('-s', '--size', default=None, dest='size', type='int',
        help='Specify a custom tile size (defaults to 256)'
        )

parser.add_option('-b', '--buffer-size', default=None, dest='buffer_size', type='int',
        help='Specify a custom map buffer_size (defaults to 128)'
        )

parser.add_option('-z', '--max-zoom', default=None, dest='max_zoom', type='int',
        help='Max zoom level to support (defaults to 22)'
        )

parser.add_option('-f', '--format', default=None, dest='format',
        help='Specify a custom image format (png or jpeg) (defaults to png)'
        )

parser.add_option('--paletted', default=False, dest='paletted', action='store_true',
        help='Use paletted/8bit PNG (defaults to False)'
        )

parser.add_option('-d','--debug', default=True, dest='debug', type="choice", choices=('True','False'),
        help='Run in debug mode (defaults to True)'
        )

parser.add_option('-c','--caching', default=False, dest='caching', action='store_true',
        help='Turn on tile caching mode (defaults to False)'
        )

parser.add_option('--cache-path', default=None, dest='cache_path',
        help='Path to tile cache directory (defaults to "/tmp")'
        )

parser.add_option('--cache-force', default=False, dest='cache_force', action='store_true',
        help='Force regeneration of tiles while in caching mode (defaults to False)'
        )

parser.add_option('--processes', default=1, dest='num_processes', type='int',
        help='If werkzeug is installed, number of rendering processes to allow'
        )

def run(process):
        try:
                process.serve_forever()
        except KeyboardInterrupt:
                process.server_close()
                sys.exit(0)

def strip_opts(options):
        remove = [None,'config','port','host']
        params = {}
        for k,v in options.items():
                if not k in remove and not v is None:
                        params[k] = v
        return params

def print_url(options):
        if not application.debug:
                logging.warning('TileLite debug mode is *off*...')
        logging.warning("Listening on %s:%s...\n" % (options.host,options.port))
        logging.warning("To access locally view: http://localhost:%s\n" % options.port)
        remote = "To access remotely view: http://%s" % socket.getfqdn()
        if not options.port == 80:
                remote += ":%s" % options.port
        remote += "\nor view: http://%s" % socket.gethostbyname(socket.gethostname())
        if not options.port == 80:
                remote += ":%s" % options.port
        logging.warning('%s\n' % remote)

if __name__ == '__main__':
        (options, args) = parser.parse_args()
        logging.basicConfig(filename='/tmp/liteserv%s.log' % options.port, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %H:%M:%S')

        if len(args) < 1:
                try:
                        mapfile = os.environ[MAP_FROM_ENV]
                except:
                        sys.exit("\nPlease provide either the path to a mapnik xml or\nset an environment setting called '%s'\n" % (MAP_FROM_ENV))
        else:
                mapfile = args[0]
                if not os.path.exists(mapfile):
                        sys.exit('Could not locate mapfile.')

        logging.warning("[TileLite Debug] --> Using mapfile: '%s'" % os.path.abspath(mapfile))
        logging.warning("options.config: %s" % options.config)
        if options.config:
                if not os.path.isfile(options.config):
                        sys.exit('That does not appear to be a valid config file')
                else:
                        CONFIG = options.config

        if not os.path.exists(CONFIG):
                if options.config:
                        sys.exit('Could not locate custom config file')
                else:
                        CONFIG = None

        if CONFIG:
                logging.warning("[TileLite Debug] --> Using config file: '%s'" % os.path.abspath(CONFIG))      

        if options.cache_path and not options.caching:
                options.caching = True

        if options.cache_force and not options.caching:
                options.caching = True

        #parser.error("Caching must be turned on with '--caching' flag for liteserv.py to accept '--cache-path' option")
        #http_setup = options.host, options.port
        #httpd = simple_server.WSGIServer(http_setup, WSGIRequestHandler)
        #httpd.set_app(application)

        from tilelite import Server
        application = Server(mapfile, CONFIG)
        application.absorb_options(strip_opts(options.__dict__))

        try:
                from werkzeug import run_simple
                print_url(options)
                run_simple(options.host, options.port, application, threaded=False, processes=options.num_processes)
        except:
                if options.num_processes > 1:
                        sys.exit('The werkzeug python server must be installed to run multi-process\n')
                logging.warning('Note: werkzeug is not installed so falling back to built-in python wsgiref server.\n')
                logging.warning('Install werkzeug from http://werkzeug.pocoo.org/\n\n')

                from wsgiref import simple_server
                # below code was for testing multi-threaded rendering
                # which only works if we copy a map object per thread
                # so avoid this and only run multiprocess...
                #from SocketServer import ThreadingMixIn
                #class myServer(ThreadingMixIn, simple_server.WSGIServer):
                #    pass 
                #httpd = myServer(('',options.port), simple_server.WSGIRequestHandler,)
                #httpd.set_app(application)
                httpd = make_server(options.host, options.port, application)        
                print_url(options)
                run(httpd)

Eu não vejo nada lá que, obviamente, levaria a que a declaração selecionada acima seja emitida. Alguém mais?

nomadicME
fonte

Respostas:

0

O servidor PostgreSQL não inicia nenhuma instrução SELECT de execução longa.

Deve ser uma conexão do cliente executando essa consulta na inicialização.

Você pode fazer várias coisas:

1) Ativar log e ver de onde vem a consulta. Editar postgresql.conf e adicione isto:

logging_collector = on
log_line_prefix = '%t %p %r %d %u '
log_connections = on
log_statement = all

2) Quando você vê a consulta real, você pode executar EXPLAIN para ver por que demora tanto tempo. Talvez possa ser otimizado?

3) Verifique as preferências do seu aplicativo para quaisquer configurações de inicialização. Talvez o recurso de atualização possa ser desativado?

filiprem
fonte
filiprem, obrigado por suas sugestões. Eles me ajudaram a avançar um pouco mais no processo de solução do problema. Atualizei a questão, com informações sobre a instrução que está causando o problema, mas ainda estou com dificuldades para descobrir de onde essa instrução está sendo emitida.
nomadicME