При исполнении обычного SQL запроса через ODBC требует ненормальное количество памяти. Как исправить?

Есть два сервера. На CentOS 6.8 и на Debian Jessie (8.8). На каждом есть apache, php, клиентские библиотеки Firebird и установлен пакет для ODBC (unixODBC и там, и там).

Детальные конфигурации:
CentOS 6.8, 64bit, PHP 5.3.3 (cli) (built: Aug 11 2016 20:33:53), apache2, php-odbc-5.3.3-48.el6_8.x86_64

Debian Jessie 8.8, 64bit, PHP 5.6.30-0+deb8u1 (cli) (built: Feb 8 2017 08:50:21), apache2, php5-odbc, unixodbc (oldstable,now 2.3.1-3 amd64 [installed])

Есть тестовый файл:
#!/usr/bin/php
<?php
$connect = odbc_connect("ProgrDB","USERUSER","pwrdpwrd");

if(odbc_error($connect)) {
	$err = odbc_errormsg($connect);
	print $err;
}

	if ($connect <= 0) {
		echo 'c ' . odbc_error($connect), ' ', odbc_errormsg($connect);
	}
	else {
		$query = "select coalesce(title, '') from SITE_POSITIONS_LIST(0) ";
		$res = odbc_exec($connect, $query);
		if( $res <= 0 ) {
			echo 'e ' . odbc_error($res), ' ', odbc_errormsg($res);
		}
		else
		{
			echo 'All OK!';
		}
	}
?>


Целевой сервер с БД (еще одна машина) на Windows, там Firebird 3.0.2. Нареканий в работе всего, что с ним связано - нет.

Итак:
При выполнении на CentOS получаем 'All OK!'.

При выполнении на Debian

PHP Fatal error: Out of memory (allocated 262144) (tried to allocate 140307991625985 bytes) in /var/www/html/site/odbctest.php on line 15

Само соединение устанавливается и там, и там. Также работает вызов указанной функции напрямую из isql на Debain.

Что я делал, чтобы решить проблему:
Я узнал, что это ошибка может значить: 99,8% случаев в интернете касаются банального ограничения php по памяти. Но вряд ли 95 петабайт, это то, что нужно php, чтобы выполнить odbc_exec, который показывает 5 строк (из таблицы в 5 строк) типа таких:

Строка1
Строка2
Строка3
Строка4
Строка5

Про 95 петабайт

tried to allocate выдает немного разные значения, это один из результатов, в сообщении выше результат другой


Остальные 0.1% - это ошибки odbc драйверов, например проблемы с NULL из-за того, что кто-то перешел с архитектуры 32bit на 64bit, а драйвер сделал плохо. Вопрос расположения бита, который отвечает за NULL. Поэтому я добавил в код coalesce, хоть моя процедура и так не возвращает null значений.

А остальные - мой случай. У других пользователей (насчитал ровно 3 счастливчика на стековерфлоу, чьи вопросы, конечно, остались без ответа) требуются другие значения, скажем 13 экзабайт памяти...

Еще о настройках:
ProgrDB настроена в odbc.ini:
[ProgrDB]
Description = Firebird connection to DB for site
Driver = Firebird64
Dbname = 192.168.0.20:E:\BASE\PRG.fdb
User = USERUSER
Password = pwrdpwrd
Role =
CharacterSet =
ReadOnly = No
NoWait = No


odbcinst.ini:
[Firebird64]
Description = InterBase/Firebird ODBC Driver
Driver = /usr/lib/libOdbcFb.so
Setup = /usr/lib/libOdbcFbS.so
Threading = 1
FileUsage = 1
CPTimeout =
CPReuse =

Отличается только тем, что на CentOS пути немного другие: /usr/lib/odbc/

Я пытался понять, в чем моя ошибка, искал различия:
libOdbcFb.so одинаковые, libfbclient.so.3.0.2 взята на Debian с CentOS, там лежала в папке /usr/lib64, здесь отдельной папки в usr нет, по инструкциям еще размещают в /usr/lib.

Проверял работу strace-ом. Но это для меня сложновато: единственный кусок, который я отметил - вот:
mmap(NULL, 139629387190272, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7efe8c000000
munmap(0x7efe90000000, 67108864)        = 0
mprotect(0x7efe8c000000, 135168, PROT_READ|PROT_WRITE) = 0
mmap(NULL, 139629387059200, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
write(2, "PHP Fatal error:  Out of memory "..., 146PHP Fatal error:  Out of memory (allocated 262144) (tried to allocate 139629386793217 bytes) in /var/www/html/site/odbctest.php on line 15
) = 146
close(2)                                = 0


Не знаю, что и делать. Прошу, подскажите!

UPD 10.11.2017: Поставили PHP 7.0, ситуация не изменилась. Думаю на 1) odbc, 2) драйвер Firebird odbc, 3) звено связку php-odbc.

UPD 2:
unixodbc trace log
Ошибки не вижу в логе, хотя выполнение скрипта завершилось ошибкой как обычно
[ODBC][7660][1510327527.078817][__handles.c][460]
                Exit:[SQL_SUCCESS]
                        Environment = 0x560bc180d060
[ODBC][7660][1510327527.078879][SQLAllocHandle.c][375]
                Entry:
                        Handle Type = 2
                        Input Handle = 0x560bc180d060
[ODBC][7660][1510327527.078901][SQLAllocHandle.c][493]
                Exit:[SQL_SUCCESS]
                        Output Handle = 0x560bc1848c10
[ODBC][7660][1510327527.078921][SQLConnect.c][3703]
                Entry:
                        Connection = 0x560bc1848c10
                        Server Name = [ProgrDB][length = 7 (SQL_NTS)]
                        User Name = [USERUSER][length = 8 (SQL_NTS)]
                        Authentication = [********][length = 8 (SQL_NTS)]
                UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

[ODBC][7660][1510327527.166194][SQLConnect.c][4276]
                Exit:[SQL_SUCCESS_WITH_INFO]
[ODBC][7660][1510327527.166282][SQLAllocHandle.c][540]
                Entry:
                        Handle Type = 3
                        Input Handle = 0x560bc1848c10
[ODBC][7660][1510327527.166347][SQLAllocHandle.c][1081]
                Exit:[SQL_SUCCESS]
                        Output Handle = 0x560bc1878f20
[ODBC][7660][1510327527.166377][SQLGetInfo.c][554]
                Entry:
                        Connection = 0x560bc1848c10
                        Info Type = SQL_FETCH_DIRECTION (8)
                        Info Value = 0x7fff16a35a54
                        Buffer Length = 4
                        StrLen = (nil)
[ODBC][7660][1510327527.166402][SQLGetInfo.c][617]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.166420][SQLSetStmtOption.c][197]
                Entry:
                        Statement = 0x560bc1878f20
                        Option = SQL_ATTR_CURSOR_TYPE
                        Value = 3
[ODBC][7660][1510327527.166441][SQLSetStmtOption.c][474]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.166460][SQLExecDirect.c][240]
                Entry:
                        Statement = 0x560bc1878f20
                        SQL = [select coalesce(title, '') from SITE_POSITIONS_LIST(0) ][length = 55 (SQL_NTS)]
[ODBC][7660][1510327527.171816][SQLExecDirect.c][503]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.171845][SQLNumResultCols.c][156]
                Entry:
                        Statement = 0x560bc1878f20
                        Column Count = 0x7f915bc551d0
[ODBC][7660][1510327527.171877][SQLNumResultCols.c][248]
                Exit:[SQL_SUCCESS]
                        Count = 0x7f915bc551d0 -> 1
[ODBC][7660][1510327527.171905][SQLColAttribute.c][293]
                Entry:
                        Statement = 0x560bc1878f20
                        Column Number = 1
                        Field Identifier = SQL_DESC_NAME
                        Character Attr = 0x7f915bc5b280
                        Buffer Length = 256
                        String Length = 0x7fff16a35962
                        Numeric Attribute = (nil)
[ODBC][7660][1510327527.171933][SQLColAttribute.c][664]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.171952][SQLColAttribute.c][293]
                Entry:
                        Statement = 0x560bc1878f20
                        Column Number = 1
                        Field Identifier = SQL_DESC_CONCISE_TYPE
                        Character Attr = (nil)
                        Buffer Length = 0
                        String Length = (nil)
                        Numeric Attribute = 0x7f915bc5b390
[ODBC][7660][1510327527.171970][SQLColAttribute.c][664]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.171987][SQLColAttribute.c][293]
                Entry:
                        Statement = 0x560bc1878f20
                        Column Number = 1
                        Field Identifier = SQL_DESC_OCTET_LENGTH
                        Character Attr = (nil)
                        Buffer Length = 0
                        String Length = (nil)
                        Numeric Attribute = 0x7fff16a35968
[ODBC][7660][1510327527.172004][SQLColAttribute.c][664]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.172565][SQLDisconnect.c][208]
                Entry:
                        Connection = 0x560bc1848c10
[ODBC][7660][1510327527.182080][SQLDisconnect.c][364]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.182117][SQLFreeHandle.c][284]
                Entry:
                        Handle Type = 2
                        Input Handle = 0x560bc1848c10
[ODBC][7660][1510327527.182136][SQLFreeHandle.c][333]
                Exit:[SQL_SUCCESS]
[ODBC][7660][1510327527.182152][SQLFreeHandle.c][219]
                Entry:
                        Handle Type = 1
                        Input Handle = 0x560bc180d060

Есть подозрение на версию библиотеки: стоит последняя, стоит попробовать 2.2.12, пока не понятно как
  • Вопрос задан
  • 1078 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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