Есть два сервера. На 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, пока не понятно как