Диагностика драйвера go-mssqldb

В этой статье представлены решения распространённых ошибок и проблем с подключением драйвера go-mssqldb .

Начните с самых простых проверок

Прежде чем включить подробное журналирование или изменить настройки пула, пройдитесь по следующему списку:

  1. Проверьте базовую доступность: имя сервера, порт, правила межсетевого экрана и то, принимает ли SQL Server или Azure SQL соединения.
  2. Проверьте входные данные аутентификации: имя драйвера, имя пользователя, пароль, формат домена или fedauth конфигурацию.
  3. Проверьте настройки TLS: encrypt, пути к сертификатам, hostnameincertificate, и подходит ли TrustServerCertificate для данной среды.
  4. Только убедившись, что подключение настроено правильно, анализируйте исчерпание пула соединений, устаревшие соединения, логику повторных попыток и диагностику медленных или заблокированных запросов.

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

Ошибки подключения

Следующие разделы охватывают распространённые сообщения об ошибках, связанных с соединением, и их решения.

Невозможно открыть TCP-соединение

Сообщение об ошибке:unable to open tcp connection with host 'localhost:1433': dial tcp 127.0.0.1:1433: connectex: No connection could be made because the target machine actively refused it.

Причины и решения

  • SQL Server не запускается. Запустите службу SQL Server.
  • TCP/IP не включён. Откройте диспетчер конфигурации SQL Server и включите TCP/IP в разделе SQL Server Network Configuration>Протоколы.
  • Неправильный порт. Проверьте порт в диспетчер конфигурации SQL Server или используйте SQL Server Browser для именованных экземпляров.
  • Файрвол блокирует порт. Добавьте правило для входящего порта 1433 (или вашего настроенного порта).

Сбой входа для пользователя

Сообщение об ошибке:mssql: login error: Login failed for user '<user>'.

Причины и решения

  • Неправильное имя пользователя или пароль. Проверьте учетные данные.
  • Аутентификация SQL Server отключена. Включите режим аутентификации SQL Server и Windows в свойствах сервера.
  • Логин не существует. Создайте логин в SQL Server.
  • Логин не имеет доступа к целевой базе данных. Предоставьте доступ к базе данных с помощью CREATE USER.

Ошибки проверки сертификатов

Сообщение об ошибке:TLS Handshake failed: x509: certificate signed by unknown authority

Причины и решения

  • Сервер использует самоподписанный сертификат. Укажите путь к сертификату с помощью параметра certificate или serverCertificate, либо установите TrustServerCertificate=true только для разработки.
  • Сертификат CA отсутствует в системном хранилище доверия. Добавьте сертификат УЦ в хранилище доверенных сертификатов ОС или укажите его с помощью параметра certificate.
  • Несоответствие имени узла. Используйте hostnameincertificate для указания ожидаемого имени в сертификате.

Для получения дополнительной информации см. раздел Шифрование и сертификаты.

Время ожидания для подключения истекло

Сообщение об ошибке:unable to open tcp connection with host '<server>:1433': dial tcp: i/o timeout

Причины и решения

  • Проблемы с сетевым подключением. Проверьте, что можно связаться с сервером, используя telnet <server> 1433 или Test-NetConnection -ComputerName <server> -Port 1433.
  • Сбой разрешения DNS. Проверьте, правильно ли разрешается имя хоста.
  • Увеличить dial timeout или connection timeout в строке подключения.

Ошибки проверки подлинности

Следующие разделы охватывают сообщения об ошибках аутентификации.

Ошибки аутентификации NTLM

Сообщение об ошибке:NTLM authentication failed

Причины и решения

  • Неправильный формат домена. Используйте DOMAIN\user в параметре user id. В URL-формате закодируйте символ обратной косой черты как %5C.
  • Неправильный пароль. Проверьте пароль домена.

Сбои проверки подлинности Kerberos

Сообщение об ошибке:krb5: cannot resolve KDC for realm

Причины и решения

  • Отсутствует или неправильно настроен /etc/krb5.conf. Проверьте, что [realms] раздел содержит правильный KDC-адрес для вашего домена.
  • Нет действительного билета. Выполните klist, чтобы проверить наличие действительного билета, или выполните kinit, чтобы получить его.
  • Файл keytab не найден. Проверьте путь в параметре krb5-keytabfile .

Для получения дополнительной информации см. разделы SQL Server и проверка подлинности Windows.

Сбои аутентификации Microsoft Entra ID

Сообщение об ошибке: clientCredentialFromCert: error reading certificate: ... или DefaultAzureCredential: failed to acquire a token

Причины и решения

  • Неправильный идентификатор клиента, идентификатор арендатора или секрет клиента. Проверьте значения в строка подключения или переменных окружения.
  • Управляемая идентичность не настроена на хосте. Проверьте личность в портале Azure.
  • Отсутствует импорт пакета azuread. Импортируйте github.com/microsoft/go-mssqldb/azuread и используйте имя azuresql драйвера.

Дополнительные сведения см. в разделе проверки подлинности Идентификатора Microsoft Entra.

Вход не был выполнен для пользователя '' (пустое имя пользователя)

Сообщение об ошибке:mssql: login error: Login failed for user ''.

Причина: Вы использовали параметр fedauth с sql.Open("sqlserver", ...). Для аутентификации Entra ID требуется имя драйвера azuresql, зарегистрированное пакетом azuread. В стандартном sqlserver драйвере параметр fedauth игнорируется, и драйвер пытается выполнить SQL-аутентификацию без имени пользователя.

Решение: импортировать azuread пакет и использовать azuresql имя драйвера:

import _ "github.com/microsoft/go-mssqldb/azuread"

db, err := sql.Open("azuresql",
    "sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
    panic(err)
}

Дополнительные сведения см. в разделе проверки подлинности Идентификатора Microsoft Entra.

Ошибки запросов

В следующих разделах рассматриваются сообщения об ошибках при выполнении запросов.

LastInsertId не поддерживается

Сообщение об ошибке:LastInsertId is not supported. Please use the OUTPUT clause or add 'select ID = convert(bigint, SCOPE_IDENTITY())' to the end of your query.

Решение: драйвер go-mssqldb не поддерживает LastInsertId(). Используйте отдельное OUTPUT предложение или запрос SCOPE_IDENTITY() .

Временная таблица не найдена

Сообщение об ошибке:mssql: Invalid object name '#TempTable'.

Причина: временные таблицы рассчитаны на каждое соединение. Если создать временную таблицу в одном вызове, а в другом обратиться к ней с запросом, эти вызовы могут использовать разные соединения из пула.

Решение: используйте db.Conn(ctx), чтобы закрепить одно соединение, или оберните операции в транзакцию.

Дополнительные сведения см. в разделе "Хранимые процедуры".

Ошибки Azure SQL

В следующих разделах рассматриваются ошибки, специфичные для База данных SQL Azure.

Коды временных ошибок подключения

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

Следующие ошибки являются временными, когда они происходят во время создания подключения или при отправке запроса на сервер. Повторите попытку на коротком, ограниченном обратном выходе. Ошибки, которые сохраняются после нескольких повторных попыток, обычно указывают на проблему конфигурации (неправильный сервер, отсутствующие разрешения, исчерпанную квоту), которая не исправится.

Error Message Troubleshooting
64 A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) Tcp-подключение удаляется в середине подтверждения. Это не ошибка учетных данных. Если он сохраняется, проверьте нестабильность сети на стороне клиента или промежуточное устройство, которое удаляет половину установленных подключений.
233 The client was unable to establish a connection because of an error during connection initialization process before login. Сбой транспорта предварительного входа или TLS. Сервер обычно возвращает его, когда он не может принимать подключение (исчерпание ресурсов, достигнуто максимальное число подключений или неподдерживаемый клиент). Это не ошибка учетных данных. Проверьте работоспособность сервера, а затем проверьте время ожидания входа клиента, параметры TLS и совместимость версий TLS клиента и сервера.
4060 Cannot open database "%.*ls" requested by the login. The login failed. Вход в систему проходит проверку подлинности, но не удаётся открыть запрошенную базу данных. К временным причинам относятся переходное состояние базы данных (переключение на резервный ресурс, восстановление, масштабирование) или ее автоматическая приостановка. Постоянные причины (база данных не существует, логин не имеет доступа) не будут устранены повторной попыткой; проверьте имя базы данных, сопоставление логина и состояние базы данных.
4221 Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. Реплика недоступна для входа в систему, так как для транзакций, которые ещё выполнялись в момент пересоздания реплики, отсутствуют версии строк. Откатите или зафиксируйте активные транзакции на основном сервере, чтобы устранить проблему. Снизьте влияние этой проблемы, избегая длительных транзакций записи на основном сервере.
10053 A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.) Локальная сторона прерывает подключение. Проверьте работоспособность сети на стороне клиента и любой локальный брандмауэр или VPN-клиент.
10054 A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) Удаленная сторона отправляет сброс TCP. Распространенные причины: сбой однорангового процесса, брандмауэр ввел сброс или шлюз Azure SQL закрыл неактивное подключение. Для сценариев сброса простаивающих соединений включите TCP keepalive на стороне клиента или сократите тайм-аут простоя пула подключений.
10928 Resource ID: %d. The %s limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. База данных превышает ограничение Azure SQL управления ресурсами. Идентификатор ресурса 1 указывает на лимит рабочих процессов, а идентификатор ресурса 2 — на лимит сеансов. Определите тип ограничения из сообщения, а затем уменьшите параллелизм, масштабируйте базу данных или сократите длительные операции хранения ресурса.
10929 Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. База данных превысила минимально гарантированный уровень, и лежащий в ее основе сервер ограничивает производительность. Повторная попытка обычно бывает успешной, когда нагрузка на соседний узел снижается. Постоянное повторение таких случаев означает, что вам нужен более высокий тарифный план или менее шумная среда.
40020, 40143, 40166, 40540 Сообщение в слоте Error code %d об ошибке 40197 во время переключения при отказе. Встроенные в сообщение об аварийном переключении 40197 подкоды, которые в некоторых путях появляются как основной код ошибки. Обработайте их так же, как 40197.
40197 The service has encountered an error processing your request. Please try again. Error code %d. Обновление программного обеспечения, сбой оборудования или другое событие переключения при отказе в Azure SQL. Повторное подключение маршрутизирует вас к работоспособной реплике. Встроенный код ошибки определяет тип переключения при отказе. Если ошибка сохраняется, запишите идентификатор трассировки сеанса и обратитесь в службу поддержки.
40501 The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. Ограничение производительности ядра Azure SQL. Рекомендуемая минимальная задержка перед повторной попыткой — 10 секунд. Постоянное ограничение пропускной способности указывает на то, что рабочая нагрузка превысила выделенные базе данных ресурсы; увеличьте уровень обслуживания или уменьшите степень параллелизма.
40613 Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'. База данных недоступна, как правило, во время переключения при отказе или ненадолго во время операции масштабирования. Повторите попытку с увеличивающейся задержкой; если проблема сохраняется дольше нескольких минут, запишите идентификатор трассировки сеанса и создайте обращение в службу поддержки.
42108 Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. Выделенный пул SQL (Synapse) находится в приостановленном состоянии. Повторная попытка будет успешной только после возобновления пула. Возобновите пул явным образом или запланируйте рабочую нагрузку после возобновления работы пула.
42109 The SQL pool is warming up. Please try again. Выделенный пул SQL возобновляется. Повторяйте попытки с увеличивающейся задержкой, пока пул не перейдёт в состояние онлайн; прогрев обычно занимает несколько минут.
49918 Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. Сервер в настоящее время не может выделить достаточно ресурсов для удовлетворения запроса. Повторите попытку на обратном выходе. Если ошибка сохраняется, увеличьте вычислительные ресурсы базы данных или эластичного пула.
49919 Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". Ограничение параллелизма на уровне подписки для операций управления. Уменьшите количество параллельных вызовов создания и обновления или разнесите их по времени.
49920 Cannot process request. Too many operations in progress for subscription "%ld". Ограничение параллелизма на уровне подписки для операций в полете. Уменьшите параллелизм или дождитесь завершения выполняющихся операций.

Ошибки на уровне инструкций не входят в этот список, поскольку они возникают после установления соединения, и после такого сбоя сеанс остаётся пригодным для использования. Наиболее распространёнными ошибками инструкций, допускающих повторное выполнение, являются 1205 (жертва взаимоблокировки) и 1222 (превышение времени ожидания запроса блокировки). Повторите всю транзакцию, а не одну инструкцию сбоя.

Текст сообщения об ошибке взят из временных ошибок подключения к Azure SQL. Отдельные драйверы поддерживают собственные встроенные списки повторных попыток; в этом каталоге описываются ошибки, которые могут быть повторами в SQL Server, База данных SQL Azure, Управляемый экземпляр SQL Azure, базе данных SQL в Microsoft Fabric и выделенных пулах SQL в Azure Synapse Analytics.

Нельзя открыть сервер (файрвол)

Сообщение об ошибке:mssql: login error: Cannot open server '<server>' requested by the login. Client with IP address '203.0.113.42' is not allowed to access the server.

Причины и решения

  • IP вашего клиента отсутствует в правилах межсетевого экрана Azure SQL. Добавьте правило межсетевого экрана в портале Azure: SQL server>Networking>Добавьте правило межсетевого экрана.
  • Если ваше приложение работает в Azure, включите Разрешить службам и ресурсам Azure доступ к этому серверу.
  • Для приватного подключения настройте приватную конечную точку.

Достигнуто ограничение ресурсов

Сообщение об ошибке:mssql: Resource ID: 1. The session limit for the database is 300 and has been reached.

Причины и решения

  • Слишком много одновременных соединений для уровня Azure SQL. Уменьшите значение MaxOpenConns в конфигурации пула.
  • Утечки соединений (незакрытые строки или транзакции). Проверьте, не отсутствуют ли вызовы defer rows.Close() или defer tx.Rollback().
  • Несколько приложений используют базу данных. Разделите лимит соединения между всеми клиентами.

Для ограничений соединения Azure SQL по уровню см. База данных SQL Azure.

Сервис сейчас перегружен (ограничение запросов)

Сообщение об ошибке:mssql: The service is currently busy. Retry the request after 10 seconds. Code: 40501.

Причины и решения

  • База данных сильно загружена. Реализуйте логику повторных попыток с экспоненциальной задержкой.
  • Рабочая нагрузка превышает емкость DTU или vCore выбранного уровня. Подумайте о масштабировании.

Для шаблонов повторной реализации см. разделы «Обработка ошибок и повторные шаблоны».

База данных в настоящее время недоступна

Сообщение об ошибке:mssql: Database 'AdventureWorks2025' on server '<server>' is not currently available. Code: 40613.

Причина: Azure SQL перенастраивает базу данных (переключение, обновление или масштабирование). Это состояние является временной ошибкой.

Решение: повторить операцию. База данных обычно становится доступной в течение нескольких секунд. Дополнительные сведения см. в разделе «Обработка ошибок и шаблоны повторных попыток».

Плохие ошибки соединения

Ошибка driver: bad connection означает, что драйвер обнаружил, что существующее соединение больше не пригодно использовать. database/sql Пул автоматически повторяет операцию на новом соединении для нетранзакционных вызовов, но операции внутри активной транзакции сразу же завершаются.

Не начинайте с этого раздела, если приложение так и не подключилось успешно. driver: bad connection Обычно указывает на повторное использование соединения, резервирование, тайм-аут в режиме простоя или перерывы сети после того, как первоначальное соединение уже работало.

Распространенные причины

Причина Типичный сценарий Исправление
Тайм-аут простоя шлюза Azure SQL Соединение неактивно более 30 минут за шлюзом Azure. Настройте db.SetConnMaxIdleTime(2 * time.Minute) на переработку холостых соединений до того, как шлюз их отключит.
Прерывание сети Временный сбой сети между клиентом и сервером. Реализовать логику повторного тестирования для нетранзакционных операций. См. обработку ошибок.
Завершение сеанса на стороне сервера DBA закрыл сессию или сервер был перезапущен. Повторите попытку. Настройте db.SetConnMaxLifetime на вращение соединений.
Перенастройка Azure SQL Аварийное переключение, масштабирование или обновление привело к разрыву соединения. Установите ConnMaxLifetime на 5 минут или менее. Реализуйте логику повторных попыток.
Долгосрочный тайм-аут транзакций Azure SQL завершил сессию (ошибка 40549). Держите транзакции короткими. Разбейте большие операции на небольшие партии.

Как база данных/SQL справляются с плохими соединениями

Для вызовов вне транзакции (db.QueryContext, db.ExecContext), database/sql пул автоматически повторяет операцию на новом соединении, если драйвер сообщает о плохом соединении. Эта попытка прозрачна для вашего кода.

Для вызовов внутри транзакции (tx.QueryContext, tx.ExecContext), пул не может повторить попытку, потому что состояние транзакции теряется. Ваш код должен обнаружить ошибку, откатить назад и повторить всю транзакцию.

Настройте пул с учетом тайм-аутов шлюза Azure и аварийного переключения:

db.SetConnMaxLifetime(5 * time.Minute)  // Rotate connections to recover from failovers.
db.SetConnMaxIdleTime(2 * time.Minute)  // Recycle before Azure gateway drops idle connections (30 min).
db.SetMaxIdleConns(10)                  // Keep warm connections for quick recovery.
db.SetMaxOpenConns(20)                  // Stay below your tier's connection limit.

Для локального использования SQL Server ConnMaxIdleTime менее критичен, потому что там нет тайм-аута на шлюзе. Однако его настройка предотвращает устаревшие соединения после сбоев сети.

Для подробного руководства по конфигурации см. База данных SQL Azure.

Истощение бассейна

Исчерпание пула соединений происходит, когда все соединения в пуле заняты, а новые запросы блокируются в ожидании свободного соединения.

Симптомы

  • Запросы замедляются или перерываются под нагрузкой.
  • db.Stats().WaitCount растёт непрерывно.
  • db.Stats().InUse равно MaxOpenConns.
  • Контекстный срок превышал ошибки во время пикового трафика.

Диагноз

Добавьте мониторинг пула в своё приложение:

stats := db.Stats()
log.Printf("Pool: open=%d inUse=%d idle=%d waitCount=%d waitDuration=%v",
    stats.OpenConnections, stats.InUse, stats.Idle,
    stats.WaitCount, stats.WaitDuration)

Распространенные проблемы и их решения

Причина Способы определения Исправление
rows.Close() не вызывается InUse Растёт со временем, никогда не уменьшается. Добавляйте defer rows.Close() после каждого QueryContext.
Длительные транзакции InUse остаётся высоким во время пакетной обработки. Держите транзакции короткими. Обрабатывайте большие партии меньшими кусками.
MaxOpenConns слишком низко WaitCount Растёт стабильно при нормальной нагрузке после того, как вы исключите закреплённые ресурсы и утечки. Увеличьте MaxOpenConns.
MaxOpenConns не задано Сотни открытых соединений при пиковом скачке нагрузки. Установите MaxOpenConns в ограниченное значение.
Утечка горутин при вызове db.Conn InUse растёт без соответствующего увеличения числа запросов. Убедитесь, что каждый результат db.Conn() закрывается с помощью defer conn.Close().

Для подробного руководства по конфигурации пула см. раздел Пулирование соединений.

Медленная или заблокированная диагностика запросов

Установка тайм-аутов запросов

Используйте дедлайны контекста, чтобы выявлять медленные запросы и не допускать, чтобы заблокированные SQL-вызовы удерживали соединения и блокировали вызывающий код:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

rows, err := db.QueryContext(ctx, "SELECT * FROM LargeTable WHERE Status = @s",
    sql.Named("s", "active"))
if err != nil {
    // Check if the error was a timeout.
    if ctx.Err() == context.DeadlineExceeded {
        log.Println("Query exceeded 5-second timeout")
    }
    return err
}
defer rows.Close()

Для полного процесса исследования производительности, включая хранилище запросов, DMV, анализ отсутствующего индекса и бенчмаркинг, см. Настройка производительности.

Диагностика блокировки

Сообщение об ошибке:mssql: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Номер ошибки: 1205

Решение: Тупиковые блокировки возникают в параллельных системах. Реализуйте логику автоматического повтора для ошибки 1205. Описание функции-обёртки для повторных попыток при взаимной блокировке см. в разделе Transactions.

Стратегии предотвращения:

  • Доступ к таблицам в одинаковом порядке для всех запросов.
  • Держите транзакции короткими и избегайте взаимодействия пользователей во время транзакций.
  • Используйте READ COMMITTED SNAPSHOT изоляцию, чтобы уменьшить борьбу за замки.

Повторяющиеся тупики по одному и тому же запросу указывают на проблему проектирования. Используйте граф взаимоблокировки (полученный с помощью Extended Events или сеанса system health), чтобы выявить конфликтующие инструкции и типы блокировок. Для полного прохождения смотрите руководство по Deadlocks. Для стратегий управления тупиками в Go см. Обработка тупиков и Обработка тупиков.

Ошибки сертификатов с контейнерами (Go 1.23 и более поздние версии)

Сообщение об ошибке:x509: negative serial number

Причина: Go 1.23 строго применяет RFC 5280. Самоподписанный сертификат, который SQL Server генерирует в контейнерах Docker, использует отрицательный серийный номер, который Go отклоняет.

Решения:

  • Для тестовых сред добавьте TrustServerCertificate=true для пропуска проверки сертификатов или encrypt=disable полностью отключите шифрование.
  • Для CI/CD установите GODEBUG=x509negativeserial=1 переменную среды так, чтобы она восстановила поведение до Go 1.23, не меняя строка подключения.
  • В go.mod (Go 1.23 и более поздние версии) добавьте godebug x509negativeserial=1 директиву для применения оверрайда во время сборки.

Предостережение

Не используйте TrustServerCertificate=true или encrypt=disable в рабочей среде. Эти опции отключают проверки безопасности. Для производства используйте правильно подписанный сертификат.

Ошибки сертификата SHA-1 (версии Go 1.24 и более поздние)

Сообщение об ошибке: tls: handshake failure или TLS Handshake failed: EOF при подключении к старым экземплярам SQL Server.

Причина: Go 1.24 по умолчанию запрещает использовать алгоритмы подписи SHA-1 в сертификатах TLS. Старые версии SQL Server и некоторые локальные установки используют сертификаты, подписанные SHA-1.

Решения:

  • Рекомендуется переиздавать сертификат сервера с SHA-256 или более поздним вариантом.
  • Установите GODEBUG=tlssha1=1 переменную среды так, чтобы временно вновь включить поддержку SHA-1.
  • В go.mod (в Go 1.23 и более поздних версиях) добавьте директиву godebug tlssha1=1.

Когда использовать encrypt=disable , а когда — TrustServerCertificate=true

Настройки Что делает Когда использовать
TrustServerCertificate=true Шифрует трафик, но пропускает проверку сертификатов. Локальная разработка и тестирование, когда сервер использует самоподписанный сертификат.
encrypt=disable Отправляет трафик в открытом тексте (без TLS). Устаревшие среды, где TLS недоступен. Не рекомендуется.
encrypt=strict TDS 8.0 с полной TLS-валидацией с первого байта. Продакшн на SQL Server 2022 или Azure SQL.

Для получения дополнительной информации см. раздел Тестирование и шифрование и сертификаты.

Вопросы кодирования и сопоставления

Неявные предупреждения о преобразовании

Если вы передаете string параметры (отправленные как nvarchar) в varchar столбцы, SQL Server выполняет неявное преобразование, которое может предотвратить использование индекса.

Этот пример продолжает настройку database/sql и mssql из предыдущих фрагментов этой статьи.

Решение: Использование mssql.VarChar для varchar столбцов:

db.QueryContext(ctx, "SELECT * FROM Production.Product WHERE ProductNumber = @p1",
    mssql.VarChar("FR-R92B-58"))

Ошибка CharsetToUTF8 с нелатинскими символами

Сообщение об ошибке: CharsetToUTF8: ... при выполнении запроса к столбцам varchar, содержащим китайские, японские или другие нелатинские символы и использующим параметры сортировки, такие как SQL_Latin1_General_CP1_CI_AS.

Причина: Драйвер пытается преобразовать кодовую страницу столбца в UTF-8, но сохранённые байты не соответствуют кодировке, ожидаемой правилами сортировки.

Решения:

  • Используйте nvarchar вместо varchar для столбцов, где хранится нелатинский текст. nvarchar хранит данные в формате UTF-16 и избегает преобразования кодовых страниц.
  • Если не удаётся изменить тип столбца, проверьте, что анализ базы данных поддерживает тот набор символов, который вы храните.

Включение ведения журнала диагностики

Используйте log параметр соединения для включения логирования на уровне драйвера:

sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=63

Флаги журнала — это значения битовых масок: 1 (ошибки), 2 (сообщения), 4 (строки), 8 (SQL), 16 (параметры), 32 (транзакции), 64 (отладка). Объедините значения, сложив их (например, 63 = все, кроме отладки, 127 = все).

Для программного логирования используйте SetLogger или SetContextLogger. См. ведение журнала и диагностику.

Контрольный список устранения неполадок

Симптом Первый шаг
В подключении отказано Проверьте, что SQL Server запущен и TCP/IP включён.
Сбой входа Проверьте учетные данные и режим аутентификации.
Ошибка сертификата Проверьте сертификат сервера или задайте TrustServerCertificate=true (только для разработки).
Время соединения истекло Проверьте сетевой путь с помощью Test-NetConnection. Проверьте правила брандмауэра.
брандмауэр Azure SQL Добавьте свой IP в правила межсетевого экрана Azure SQL.
Ошибки регулирования Реализуйте повторные попытки с экспоненциальной задержкой. Повысить уровень.
Плохое соединение Установите значение ConnMaxIdleTime меньше 30 минут для Azure SQL. Реализуйте логику повторных попыток.
Истощение бассейна Отслеживайте db.Stats(). Исправьте незакрытые строки и транзакции. Увеличьте MaxOpenConns.
Медленные запросы Установите тайм-ауты в контексте. Выполните запрос к DMV для поиска ресурсоёмких запросов.
Взаимоблокировки Реализуйте повторную попытку при ошибке 1205. Обращайтесь к таблицам в одном и том же порядке.
Неявное преобразование Используйте mssql.VarChar для varchar колонок.