У меня есть большой (~ 6 ГБ) postgis-2.1 postgisql-9.4 дБ, содержащий контуры высот на нетбуке под управлением Debian Jessie. Каждый раз, когда я запускаю систему, я получаю процесс, который выглядит следующим образом:

00:00:01 postgres: контуры имени пользователя :: 1(33525) SELECT

Этот процесс будет длиться около 30-40 минут на моем нетбуке, который я использую для навигации в своем грузовике, затем он будет показывать, что процесс простаивает. За это время нетбук бесполезен. Этот процесс занимает слишком много места в памяти, и дисковый ввод-вывод действительно является убийцей.

У меня вопрос, как я могу остановить этот выбор из запуска? Я сделал все возможное, чтобы изолировать проблему на сервере postgresql. Никакие другие приложения не инициируют этот запрос.

Процессы postgres, запущенные во время этого процесса:

  • процесс контрольной точки
  • писательский процесс
  • писательский процесс
  • процесс автоматического запуска
  • процесс сбора статистики

Обновление: ОК, с помощью filiprem мне удалось отследить оператор select, который вызывает эту проблему:

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

Проблема в том, что я до сих пор не знаю, откуда (конкретно) генерируется это утверждение. Команда, которая вызывает это:

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

В topo.cfg нет ничего подходящего. Я сделал grep на topo.xml в поиске операторов select и нашел (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

Вот содержание 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)

Я не вижу там ничего, что, очевидно, привело бы к тому, что вышеприведенное заявление было опубликовано. Кто-нибудь еще?

1 ответ1

0

Сервер PostgreSQL сам по себе не запускает никаких длительных операторов SELECT.

Это должно быть клиентское соединение, выполняющее этот запрос при запуске.

Вы можете сделать несколько вещей:

1) Включите ведение журнала и посмотрите, откуда поступил запрос. Отредактируйте postgresql.conf и добавьте это:

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

2) Когда вы видите реальный запрос, вы можете запустить EXPLAIN чтобы понять, почему он так долго. Может быть, это можно оптимизировать?

3) Проверьте настройки приложения для любых параметров запуска. Может быть, функция обновления может быть отключена?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .