Как вы решаете проблему сбоя SQL-запроса?

#sql-server #tsql

#sql-сервер #tsql #sql-server

Вопрос:

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

Пожалуйста, обратите внимание, что в таблицах, используемых в запросе, нет изменений между сценариями успешного выполнения и сбоя. Они точно такие же. Как упоминалось ниже, запрос объединяет пару таблиц, и результат запроса должен быть пустым. Но иногда ADO выдает ошибку.

Как можно выяснить основную причину проблемы?

Я намеренно опустил некоторые детали, поскольку мне интересно узнать общий подход к решению проблем при сбоях SQL-запроса.


Вот некоторые подробности, которые также следует знать о любых конкретных альтернативных подходах.

  • Microsoft SQL Server 2008
  • Использование запроса соединяет две таблицы
  • Запрос передается из .NET через interop, а COM-компонент обрабатывает ADO для выполнения запроса.
  • Информация об ошибке 0x80004005(-2147467259) [DBNETLIB][ConnectionOpen (Connect()).]SQL Server не существует или доступ запрещен.

Обновить:

Для этой конкретной проблемы я решил, что у клиента заканчиваются доступные TCP-порты. Согласно настройкам по умолчанию, 5000 портов — это максимальное количество TCP-портов. В моем случае ADO создает неявные соединения, которые создают TCP-порт каждый раз, когда выполняется запрос.

netstat показал мне, что количество открытых портов резко увеличилось, когда я запустил рабочий процесс. Примерно на 4000 портах запрос завершается ошибкой (0-1023 — зарезервированные порты). Ответ от Джибкова Добрева в здесь указал мне правильное направление.

Комментарии:

1. Под «сбоем» вы подразумеваете «он возвращает неправильные данные» или «он возвращает сообщение об ошибке вместо каких-либо данных»?

2. -1 — Скорее всего, проблема взаимоблокировки или тайм-аут, связанный с блокировкой. К сожалению, OP does it funny заставляет нас гадать и не хочет получать ответ — в противном случае он выдал бы сообщение об ошибке. Отклонено как неполное.

3. @Mark Bannister: Результат запроса пустой, что правильно, но я получаю неверный HRESULT от ADO 0x80004005 (-2147467259) [DBNETLIB][ConnectionOpen (Connect()).]SQL Server не существует или доступ запрещен.

4. @TomTom: зачем человеку утруждать себя написанием вопроса, если его не интересует ответ? Я не предоставил сообщение об ошибке, потому что хотел знать, каков общий подход к такого рода проблемам; сообщение об ошибке привело бы к «вам просто нужно сделать это для решения этой проблемы», чего я здесь не хотел.

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

Ответ №1:

Прочитайте сообщение об ошибке!

На самом деле запрос «завершается ошибкой» только по нескольким причинам:

  • нарушение уникальности, проверки или другого ограничения
  • проблема с типом данных (несоответствие, переполнение)
  • ???

Во время анализа будут обнаружены неправильные или противоречивые агрегированные данные или синтаксис. Но…

  • в случае динамического SQL это может привести к «сбою», потому что это синтаксически неправильно

Это может быть медленным или выдавать неправильные данные, но это не «сбой» как таковой.

Редактировать:

Это не ошибка запроса: это ошибка подключения, не связанная с какой-либо командой SQL.

Как правило, теперь вам нужно решить, связано ли это с одним клиентом или это общая проблема

Комментарии:

1. вы правы. это не сбой запроса. это ошибка подключения. спасибо за ваши предложения.

Ответ №2:

«Общий подход к решению проблем» при сбое SQL-запроса такой же, как и при любом другом сбое кода:

  • Определите, что он делает.
  • Определите, что он должен делать.
  • Определите, почему это отличается.
  • Исправьте это.

РЕДАКТИРОВАТЬ: после предоставления более подробной информации в следующей статье базы знаний Microsoft: http://support.microsoft.com/kb/328306 рассматриваются возможные причины и способы решения этой проблемы.

Комментарии:

1. Спасибо. Я подробнее остановлюсь на деталях.

Ответ №3:

В статье KB «потенциальные причины» отсутствует статья, которая решила эту проблему для меня — «вы не можете получить доступ к базе данных SQL Server с помощью поставщика OLE DB для SQL Server, когда ваше приложение находится в сценарии с высокой нагрузкой»http://support.microsoft.com/kb/907264

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

Запуск ‘netstat -an’ покажет все IP-адреса / порты, открытые во время выполнения процесса. Для меня они находятся на уровне 20 или около того, пока не будет достигнут определенный блок кода … затем быстро увеличиваются до 4000 , и приложение завершается сбоем

Комментарии:

1. Это именно то, что произошло со мной в этом конкретном случае. Исчерпан лимит портов. По соображениям безопасности Windows ограничивает его (5000). Я использовал набор записей на стороне клиента, который был подходящим и решил проблему за меня.

Ответ №4:

Вы можете:

Запустите sql profiler для захвата запроса, убедитесь, что запрос правильно сформирован. Вы можете оставить трассировку запущенной столько, сколько захотите.

Запустите захваченный запрос в management Studio, sql server выдаст все ошибки, с которыми он столкнется.

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

Возможно, даже зарегистрируйте созданный запрос и результат в файле журнала из .net и сравните разницу в запросах.

В зависимости от того, как вы настроили подключение к данным, Visual Studio также позволяет facilty пошагово выполнять хранимые процедуры.

Комментарии:

1. Это был бы подход, если бы постоянно возникали какие-то проблемы с конкретным запросом; но мой запрос в большинстве случаев выполняется успешно, и периодически он завершается неудачей. Задаетесь вопросом о том, как устранить проблемы такого рода.

2. Всегда ли запрос идентичен? или могут ли параметры, содержащиеся в нем, измениться? если они могут, вам нужно записать сбойный запрос .. как-нибудь протоколировать его. если это не изменяется, то причиной этого является среда, будь то блокировка записей в БД, разрыв соединения с БД, тайм-аут из-за занятости сервера и т.д., Которые будет сложнее изолировать.. может быть, запустить трассировку и посмотреть, сможете ли вы обнаружить неудачный запрос и сравнить его со статистикой сервера. Вам необходимо изолировать параметры вокруг запроса.

3. Да, это сложная сторона. Это среда. Хотя это параметризованный запрос. Но я пришел к выводу, что сбой не относится к каким-либо конкретным значениям.

Ответ №5:

Специфично для

0x80004005(-2147467259) [DBNETLIB][ConnectionOpen (Connect()).]SQL Server не существует или доступ к нему запрещен.

похоже, это хорошая отправная точка для расследования: возможные причины сообщения об ошибке «SQL Server не существует или доступ запрещен»