Удостоверьтесь, что только единственный экземпляр программы работает

Предупреждение: mysql_connect (): доступ запрещен для имени пользователя '@' host '

Это предупреждение появляется при подключении к серверу MySQL / MariaDB с недопустимыми или отсутствующими учетными данными (имя пользователя / пароль). Таким образом, это обычно не проблема с кодом, а проблема конфигурации сервера.

  • См. Справочную страницу в mysql_connect("localhost", "user", "pw") для примеров.

  • Убедитесь, что вы действительно использовали кнопки $username и $password.

    • Необычно, что вы получаете доступ без пароля - вот что произошло, когда Предупреждение: сказано (using password: NO).
    • Только локальный тестовый сервер обычно позволяет подключаться с именем пользователя root, без пароля и с именем базы данных test.

    • Вы можете проверить, действительно ли они исправлены с помощью клиента командной строки:
      mysql --user="username" --password="password" testdb

    • Имя пользователя и пароль с учетом регистра и пробел не игнорируется. Если ваш пароль содержит метасимволы, такие как $, откройте их или поместите пароль в одиночные кавычки .

    • Большинство хостинг-провайдеров предопределяют учетные записи mysql в отношении учетной записи пользователя unix (иногда просто префиксы или дополнительные числовые суффиксы). См. Документы для шаблона или документации, а также CPanel или любой другой интерфейс для установки пароля.

    • См. Руководство по MySQL в Добавление учетных записей пользователей с помощью командной строки. При подключении к администратору вы можете выдать запрос, например:
      CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';

    • Или использовать Администратор или [ 1137] WorkBench или любой другой графический инструмент для создания, проверки или исправления данных учетной записи.

    • Если вы не можете исправить свои учетные данные, тогда запрос в Интернете «пожалуйста, помогите» не будет иметь никакого эффекта. Только у вас и вашего хостинг-провайдера есть разрешения и достаточный доступ для диагностики и исправления.

  • Убедитесь, что вы могли достигнуть сервера базы данных, используя имя хоста, указанное вашим провайдером:
    ping dbserver.hoster.example.net

      ]
    • Проверьте это с консоли SSH непосредственно на своем веб-сервере. Тестирование с вашего локального клиента разработки на ваш хостинг-сервер редко имеет смысл.

    • Часто вы просто хотите, чтобы имя сервера было "localhost", которое обычно использует локальный именованный сокет, когда он доступен. В других случаях вы можете попробовать "127.0.0.1" как резерв.

    • Если ваш сервер MySQL / MariaDB прослушивает другой порт, используйте "servername:3306".

    • Если это не удается, тогда есть проблема с брандмауэром.

  • При использовании констант , таких как, например, [11144]. DB_USER или DB_PASSWORD, убедитесь, что они на самом деле определены .

    • Если вы получите "Warning: Access defined for 'DB_USER'@'host'" и "Notice: use of undefined constant 'DB_PASS'", то это ваша проблема.

    • Убедитесь, что ваш, например, xy/db-config.php был фактически включен и что угодно.

  • Проверьте правильность установки GRANT разрешений .

    • Недостаточно иметь пару username + password.

    • Каждая учетная запись MySQL / MariaDB может иметь прикрепленный набор разрешений.

    • Те могут ограничить, к каким базам данных вам разрешено подключаться, из которых клиент или сервер может возникнуть соединение и какие запросы разрешены.

    • Предупреждение «Доступ запрещен» может также отображаться для вызовов mysql_query , если у вас нет прав на SELECT из определенной таблицы или INSERT / UPDATE, и чаще всего DELETE.

    • Вы можете адаптировать разрешения учетной записи при подключении к каждому клиенту командной строки с помощью учетной записи администратора с запросом типа:
      GRANT ALL ON yourdb.* TO 'username'@'localhost';

  • Если предупреждение появляется сначала с помощью Warning: mysql_query(): Access denied for user ''@'localhost', тогда у вас может быть php.ini-preconfigured учетной записи / пароля .

    • Убедитесь, что mysql.default_user= и mysql.default_password= имеют значимые значения.

    • Часто это конфигурация провайдера. Поэтому обратитесь к их поддержке несоответствий.

  • Найдите документацию вашего хостинг-провайдера:

  • Обратите внимание, что вы также можете исчерпать доступный пул соединений . Вы получите доступ к запрещенным предупреждениям для слишком большого количества параллельных подключений.

  • Ваша версия клиента libmysql может быть несовместимой с сервер базы данных. Обычно MySQL и MariaDB-серверы можно получить с помощью PHP, скомпилированных в драйвере. Если у вас есть пользовательская настройка или устаревшая версия PHP, а также гораздо более новый сервер базы данных или значительно устаревший - тогда несоответствие версии может препятствовать подключению. (Нет, вам нужно исследовать себя. Никто не может угадать вашу настройку).

Дополнительные ссылки:

Кстати, вы, вероятно, больше не хотите использовать функции mysql_* [1156 ]. Новички часто мигрируют в mysqli , что, однако, так же утомительно. Вместо этого прочитайте в PDO и подготовленные утверждения .
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");

blockquote>

112
задан Mike 3 July 2019 в 20:13
поделиться

8 ответов

Следующий код должен выполнить эту работу, он кроссплатформенный и работает на Python 2.4-3.2. Я тестировал его в Windows, OS X и Linux.

from tendo import singleton
me = singleton.SingleInstance() # will sys.exit(-1) if other instance is running

Доступна последняя версия кода singleton.py . Пожалуйста, сообщайте об ошибках здесь .

Вы можете установить тенд, используя один из следующих методов:

91
ответ дан 24 November 2019 в 02:50
поделиться

Используя файл блокировки довольно общий подход на Unix. Если это отказывает, необходимо вымыться вручную. Вы могли stor PID в файле, и на проверке запуска, если существует процесс с этим PID, переопределяя файл блокировки если нет. (Однако Вам также нужна блокировка вокруг read-file-check-pid-rewrite-file). Вы найдете то, в чем Вы нуждаетесь для получения и проверки изодромного с предварением в os - пакет. Распространенный способ проверить, существует ли там процесс с данным изодромным с предварением, состоит в том, чтобы отправить ему нефатальный сигнал.

Другие альтернативы могли комбинировать это со скоплением или posix семафорами.

Открытие сетевой сокет, как saua предложенный, вероятно, был бы самым легким и самым портативным.

3
ответ дан Rolf Rander 24 November 2019 в 02:50
поделиться

Это может работать.

  1. Попытка создают файл PID к известному местоположению. Если Вы перестали работать, кому-то заблокировали файл, Вы сделаны.

  2. , Когда Вы обычно заканчиваете, закройте и удалите файл PID, таким образом, кто-то еще может перезаписать его.

можно обернуть программу в сценарии оболочки, который удаляет файл PID, даже если программа отказывает.

можно, также, использовать файл PID для закрытия программы, если это зависает.

5
ответ дан S.Lott 24 November 2019 в 02:50
поделиться

Вы уже нашли ответ на подобный вопрос в другом потоке, таким образом, для пользы полноты видят, как достигнуть того же на нелугу Windows, названном взаимным исключением.

http://code.activestate.com/recipes/474070/

6
ответ дан zgoda 24 November 2019 в 02:50
поделиться

Используйте изодромный с предварением файл. Вы имеете некоторое известное расположение, "/path/to/pidfile", и при запуске Вы делаете что-то вроде этого (частично псевдокод, потому что я - предварительный кофе и не хочу работать все что трудно):

import os, os.path
pidfilePath = """/path/to/pidfile"""
if os.path.exists(pidfilePath):
   pidfile = open(pidfilePath,"r")
   pidString = pidfile.read()
   if <pidString is equal to os.getpid()>:
      # something is real weird
      Sys.exit(BADCODE)
   else:
      <use ps or pidof to see if the process with pid pidString is still running>
      if  <process with pid == 'pidString' is still running>:
          Sys.exit(ALREADAYRUNNING)
      else:
          # the previous server must have crashed
          <log server had crashed>
          <reopen pidfilePath for writing>
          pidfile.write(os.getpid())
else:
    <open pidfilePath for writing>
    pidfile.write(os.getpid())

Так, другими словами, Вы проверяете, существует ли pidfile; в противном случае запишите свое изодромное с предварением в тот файл. Если pidfile действительно существует, то проверьте, чтобы видеть, является ли изодромным с предварением изодромный с предварением из рабочего процесса; если так, тогда Вы имеете другое живое выполнение процесса, поэтому просто закрываетесь. В противном случае тогда предыдущий разрушенный процесс, так зарегистрируйте его, и затем запишите Ваше собственное изодромное с предварением в файл вместо старого. Тогда продолжите.

10
ответ дан Charlie Martin 24 November 2019 в 02:50
поделиться

Я не знаю, является ли это pythonic достаточно, но в мире Java, слушающем на определенном порте, симпатичное широко используемое решение, поскольку это работает над всеми основными платформами и не имеет никаких проблем с отказывающими программами.

Другое преимущество слушания порта состоит в том, что Вы могли отправить команду в рабочий экземпляр. Например, когда пользователи запускают программу во второй раз, когда Вы могли отправить рабочему экземпляру команду, чтобы сказать ей открывать другое окно (это - то, что Firefox делает, например. Я не знаю, используют ли они порты TCP или именованные каналы или что-то как этот, 'хотя).

23
ответ дан Joachim Sauer 24 November 2019 в 02:50
поделиться

Простой, межплатформенное решение, найденное в другой вопрос zgoda:

import fcntl, sys
pid_file = 'program.pid'
fp = open(pid_file, 'w')
try:
    fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
    # another instance is running
    sys.exit(0)

Много как предложение S.Lott, но с кодом.

37
ответ дан Community 24 November 2019 в 02:50
поделиться

Этот код специфичен для Linux. Он использует «абстрактные» доменные сокеты UNIX, но он прост и не оставляет устаревших файлов блокировки. Я предпочитаю это решение, потому что оно не требует специально зарезервированного TCP-порта.

try:
    import socket
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ## Create an abstract socket, by prefixing it with null. 
    s.bind( '\0postconnect_gateway_notify_lock') 
except socket.error as e:
    error_code = e.args[0]
    error_string = e.args[1]
    print "Process already running (%d:%s ). Exiting" % ( error_code, error_string) 
    sys.exit (0) 

Уникальная строка postconnect_gateway_notify_lock может быть изменена, чтобы разрешить использование нескольких программ, которым требуется один экземпляр.

28
ответ дан 24 November 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: