#c# #.net-core #db2
Вопрос:
У меня есть приложение-контейнер dotnet core (linux), использующее следующий код для выполнения асинхронного вызова ВЫБОРА в db2 (z/os):
var result = new DataTable();
var query = "SELECT * FROM DB.TABLE WITH UR;"
using (var connection = new DB2Connection(_connection))
{
await connection.OpenAsync();
using (var command = new DB2Command(query, connection))
{
using (var myReader = await command.ExecuteReaderAsync()) // fails here when query > 1190 chars
{
result.Columns.AddRange(myReader.GetColumnSchema()
.Select(x => new DataColumn(x.ColumnName, x.DataType))
.ToArray());
result.BeginLoadData();
while (await myReader.ReadAsync())
{
var contents = new object[myReader.FieldCount];
myReader.GetValues(contents);
result.LoadDataRow(contents, false);
}
result.EndLoadData();
}
}
}
Этот код отлично работает для любого запроса длиной менее 1190 символов. Когда я увеличиваю строку sql до 1191 символа или более, вызов зависает и заканчивается со следующей ошибкой:
Исключение IBM.Data.DB2.Core.DB2Exception (0x80004005): ОШИБКА [08001] [IBM] SQL30081N Обнаружена ошибка связи. Используемый протокол связи: «TCP/IP». Используемый API связи: «СОКЕТЫ». Место, где была обнаружена ошибка: «170.2.8.84». Функция связи, обнаруживающая ошибку: «recv». Специфичный для протокола код(ы) ошибки): «110», ««, ««. SQLSTATE=08001
Проблема не возникает при локальной работе с докером. Я не могу запустить контейнеры Windows на хосте-нарушителе, поэтому это сравнение недоступно.
Клиент:
# db2level
DB21085I This instance or install (instance name, where applicable: "*") uses
"64" bits and DB2 code release "SQL11055" with level identifier "0606010F".
Informational tokens are "DB2 v11.5.5.1", "s2103171200", "DYN2103171200AMD64",
and Fix Pack "1".
Product is installed at "/app/clidriver".
Администратор базы данных не смог увидеть никаких действий для запросов с истекшим временем ожидания. Что может препятствовать этим вызовам на основе этого определенного порога размера?
Комментарии:
1. Устранение неполадок, необходимых с вашей стороны. Вы запускаете свою программу на C# в Linux? Возникает ли симптом, если вы запускаете запрос через
db2cli
? Код «110»-это тайм-аут, вы определили какие-либо значения, отличные от значений по умолчанию? Что происходит на Db2-сервере, что находится в его диагностике? Посмотрите на это более опытными глазами, но, скорее всего, только ваш сайт может устранить неполадки2. @mao Да, в Linux. Я пытаюсь выполнить ваше предложение и пытаюсь выполнить запрос через
db2cli execsql
, но получаю отказ в учетных данных (SQL30082N Security processing failed with reason "24"
). Устранение неполадок, которые сейчас устраняются, будут обновлены, когда я закончу. Спасибо3. Хоть убей меня, я не могу передать команду из
db2cli execsql
-заSQL30082N
. Это было бы хорошим тестом, однако сейчас я от него отказываюсь.4. попробуйте воспользоваться предложением в ответе, чтобы проверить, может ли инструмент db2cli работать для вас. Вы можете изменить сценарий, чтобы добавить свой конкретный длинный запрос в файл inputsql. Это работает для меня с планом Db2-on-cloud lite, начиная с linux, ваш пробег может отличаться.
5. Кроме того, необходимо выполнить основные исключения. Правильно ли выполняется более длинный SQL, когда программа c# запускается в microsoft-windows, используя ту же базу данных и те же учетные данные? Не забудьте отредактировать свой вопрос, чтобы добавить факты о платформе Db2-сервера
db2level
вывод текста вместе сdb2level
выводом из вашего клиента Linux. Наконец, средство трассировки cli покажет, какой именно SQL отправляется из linux в Db2, и это может быть не то, что вы предполагаете.
Ответ №1:
Чтобы проверить, может ли ваш db2cli выполнять ту же инструкцию SQL (т. Е. независимо от C# и независимо от .net core), вы можете скопировать и изменить приведенный ниже сценарий, скопировав имя хоста, имя пользователя, пароль и номер порта из файла json с учетными данными (или там, где вы получили данные строки подключения).
Если ваше соединение НЕ зашифровано с помощью SSL/TLS, измените сценарий, чтобы удалить параметры Security=SSL из приведенных ниже определений базы данных и dsn, и используйте правильный номер порта, отличный от SSL.
Если ваш пароль содержит какие-либо символы, которые ваша оболочка Linux считает особыми, экранируйте каждый такой специальный символ обратной косой чертой при назначении переменной пароля ниже в сценарии. В противном случае вы получите SQL30082N по причине «24».
После изменения этого файла chmod x файл и запустите его.
#!/bin/bash
#
# populate db2dsdriver.cfg for Db2-on-cloud lite and verify db2cli connects and runs SQL statements.
#
# Prereq: (1) an IBM Db2 CLI driver is already installed and on the PATH for current userid.
# Prereq: (2) the version of the CLI driver matches the version of the Db2-lite instance (per the UI dashboard)
# Prereq: (3) after you modify this file, remember to `chmod x` this file before running it.
#
# This script works with clidriver , with the Db2 runtime client, with the Db2 data server client (fat client).
# Can re-run this script, overwrites current matching entries in db2dsdriver.cfg (if exists) else creates that file.
#
# For IBM Db2-on-cloud (lite plan , kostenlos ).
# Configure the db2dsdriver.cfg file for use with db2cli tool to connect to Db2-on-cloud from command-line bash.
#
# You must modify the variable-values below by copying username, password, port, hostname from your credentials json file.
# And remember to escape ( precede with ) any and all special-character in password, otherwise connect will fail.
#
# Note 1: this expects the Db2-on-cloud hostname to have SSL/TLS encrypted-connections to BLUDB which is the default
# for all IBM Db2-on-cloud hostnames ending with pattern *appdomain.cloud
#
# Note 2: at clidriver version 11.5.6.0 , db2cli tool can return exit-code 0 even on failure, doh!
#
# Note 3: to get your username and password, host and port-number , download the credentials json file and view it to see them.
# Then copy their values into the appropriate variables below before making this script executable and run it.
#
set -u
typeset which=/usr/bin/which
typeset db2cli=$( ${which} db2cli )
[[ -z ${db2cli:=""} ]] amp;amp; print "nERROR: please either dot in a db2profile to allow db2cli to be on the PATHnor edit your PATH environment variable to put the clidriver/bin directory on the PATH" amp;amp; exit 1
typeset dbname=bludb # default database-name for Db2-on-cloud lite plan shared databases.
typeset hostname="change me"
typeset ssl_port_number=32733 # from credentials json
typeset password="change me" # remember to escape any special characters here, copy from credentials json file.
typeset username="change me" # copy from credentials json file.
typeset dbalias=bludb # you can use whatever alias-name you like, 8 bytes long max
typeset input_sql_tmpfile=/tmp/db2cli_inputsql.sql
${db2cli} writecfg add -database ${dbname} -host ${hostname} -port ${ssl_port_number} -parameter Security=SSL
rc=$?
(( rc > 0 )) amp;amp; print "nERROR: failed to write the database to the config filen" amp;amp; exit 1
${db2cli} writecfg add -dsn ${dbalias} -database ${dbname} -host ${hostname} -port ${ssl_port_number} -parameter Security=SSL
rc=$?
(( rc > 0 )) amp;amp; print "nERROR: failed to write the dsn to the config filen" amp;amp; exit 1
${db2cli} validate -dsn ${dbalias} -connect -user ${username} -passwd ${password}
rc=$?
(( rc > 0 )) amp;amp; print "nERROR: failed to connect to the dsn with supplied credentialsn" amp;amp; exit 1
# Verify that the db2cli tool can run some SQL statements by putting them into a file and passing the file to db2cli
#create an inputfile containing SQL statements ( make a temp file for this purpose)
# note that the default statement delimiter for db2cli is crlf (or lf on linux) not semicolon as with db2clp.
echo "values current timestamp" > ${input_sql_tmpfile}
echo "values current server" >> ${input_sql_tmpfile}
echo "values current user" >> ${input_sql_tmpfile}
${db2cli} execsql -execute -dsn ${dbalias} -user ${username} -passwd ${password} -inputsql ${input_sql_tmpfile}
Комментарии:
1. Ах, проблема заключалась в специальном символе в пароле. Теперь я могу подключиться — отправка большого запроса по-прежнему приводит к тайм-ауту. Курсор просто зависает после отображения sql.
2. Хорошо, это важное исключение. Это означает, что проблема, вероятно, кроется не в конце linux. Теперь вы должны обратить внимание на то, что происходит на Db2-сервере И сетевом пути между клиентом и сервером. Вы все еще не ответили на уточнение о том, на какой платформе Db2 (z/os, серия i, облако, linux/unix/windows) работает Db2-сервер, а также версия/пакет исправлений сервера Db2 и что находится в диагностике Db2-сервера. Сейчас это очень важная информация. Кроме того , вы не ответили на вопрос, нормально ли работает c# с этим длинным запросом от Microsoft-Windows.
3. Еще одним простым устранением является обновление clidriver до нынешней версии 11.5.6.0. Если у вас есть контракт на поддержку Db2 с IBM, они в любом случае попросят вас сделать это в дополнение к проверке того, возникает ли тот же симптом при запуске программы c# в microsoft-windows.
4. Сервер-это z/os, мне нужна лицензия для подключения. Будет изучено обновление cli… Я просто использую все, что предлагается с помощью новейшего nuget от IBM, для простоты. Я также посмотрю, смогу ли я получить больше информации о сервере — мне удалось встретиться с администратором базы данных, который не видел активных потоков для зависшего соединения.